{"id":17471233,"url":"https://github.com/breuleux/hyper-replace","last_synced_at":"2025-04-14T20:08:18.335Z","repository":{"id":140046873,"uuid":"71500249","full_name":"breuleux/hyper-replace","owner":"breuleux","description":"Replace patterns in strings by arbitrary objects","archived":false,"fork":false,"pushed_at":"2016-10-21T22:55:29.000Z","size":9,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-31T05:44:48.193Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/breuleux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-20T20:09:54.000Z","updated_at":"2018-04-03T09:23:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"2153f3a9-a8cb-49c0-a120-9b5e4281e4dd","html_url":"https://github.com/breuleux/hyper-replace","commit_stats":{"total_commits":10,"total_committers":1,"mean_commits":10.0,"dds":0.0,"last_synced_commit":"044664af426b45b0bbcbd03d1c986c7e13ecf863"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breuleux%2Fhyper-replace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breuleux%2Fhyper-replace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breuleux%2Fhyper-replace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breuleux%2Fhyper-replace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/breuleux","download_url":"https://codeload.github.com/breuleux/hyper-replace/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238902586,"owners_count":19549776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-18T16:32:32.356Z","updated_at":"2025-02-16T11:40:33.497Z","avatar_url":"https://github.com/breuleux.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nhyper-replace\n=============\n\nThe point of `hyper-replace` is to be able to replace patterns in\nstrings by things that aren't strings. Here are a few things\n`hyper-replace` can help you with:\n\n* Replace all occurrences of a pattern (a hashtag, a youtube URL,\n  etc.) in a comment by a React component. `hyper-replace` will return\n  a suitable array of children. This will, of course, work just as\n  well for other frameworks!\n* Parse simple markup to a structure, for example Markdown to\n  virtual-dom, instead of outputting a string in a specific format\n  like HTML.\n\n`hyper-replace` returns an array of string parts interspersed with\narbitrary objects. It is also powerful enough to apply regular\nexpressions to that same data structure, which means that you can\ncompose calls to it.\n\n## Basic usage\n\n```js\nvar hyperReplace = require('hyper-replace');\nhyperReplace('I have the __POWER__!',\n             {pattern: /__([^_]+)__/g,\n              replacement: (_, text) =\u003e ({tag: 'strong', children: text})});\n\n// =\u003e ['I have the ', {tag: 'strong', children: 'POWER'}, '!']\n```\n\n`hyper-replace` can also operate on mixed arrays of strings and\nobjects. By that, I don't mean it applies the regexs to each string in\nthe array, I mean it stitches everything together and applies them to\nthe whole thing, so a single regex can span several elements in the\narray, including non-strings. Let me demonstrate:\n\n```js\nhyperReplace(['This is __', {tag: 'em', children: 'very important'}, '__'],\n             {pattern: /__([^_]+)__/g,\n              replacement: (_, text) =\u003e ({tag: 'strong', children: text})});\n\n// =\u003e ['This is ',\n//     {tag: 'strong', children: [{tag: 'em', children: 'very important'}]}]\n```\n\nNote that because of this feature, the arguments given to the\nreplacement function (the first of which is the full match, and the\nothers are the groups in the regular expression) may not be\nstrings. They may either be a string or an array of strings and\nobjects spanned by the match.\n\n## Multiple patterns\n\nFor convenience, hyperReplace can take a list of patterns:\n\n```js\nhyperReplace('__Emphasis__ on `code`',\n             [{pattern: /__([^_]+)__/g,\n               replacement: (_, text) =\u003e ({tag: 'strong', children: text})},\n              {pattern: /`([^`]+)`/g,\n               replacement: (_, text) =\u003e ({tag: 'code', children: text})}]);\n\n// =\u003e [{tag: 'strong', children: 'Emphasis'},\n//      ' on ',\n//     {tag: 'code', children: 'code'}]\n```\n\n### Overlapping patterns\n\nThe other in which the patterns are specified matters: `hyperReplace`\nwill apply them in that order. Furthermore, all replacements are\n\"closed off\": all patterns see the previous replacements as surrogate\n(invalid) characters, so while they can contain or encompass them,\nthey can't intersect. (This is arguably a feature: you don't have to\nworry that the return value of a replacement function will interfere\nwith the next pattern).\n\nIf you wish to match patterns that can be nested, your two options\nare:\n\n* Call `hyperReplace` recursively in the replacement function.\n* Apply the patterns from the inside out (smaller first). The\n  `applyUntilEquilibrium` option, described below, can help.\n\n### Apply until equilibrium\n\n`hyperReplace` can be told to apply one or more patterns over and over\nuntil there is nothing left to replace. Use this feature wisely.\n\n```js\nhyperReplace('\u003cspan\u003eDo \u003cb\u003enot\u003c/b\u003e \u003cs\u003eparse HTML\u003c/s\u003e with hyper-replace\u003c/span\u003e',\n             /\u003c([a-z]+)\u003e([^\u003c\u003e]*)\u003c\\/\\1\u003e/g,\n             (_, tag, text) =\u003e ({tag: tag, children: text}),\n             {applyUntilEquilibrium: true});\n\n// =\u003e [{tag: 'span',\n//      children: ['Do ',\n//                 {tag: 'b', children: 'not'},\n//                 ' ',\n//                 {tag: 's', children: 'parse HTML'},\n//                 ' with hyper-replace']}]\n```\n\nBasically, the regular expression will start by matching the innermost\ntags (that don't contain sub-tags) and will replace them all by\nsurrogates. Once that's done, the second innermost tags become\ninnermost, so you can apply the pattern again, and so on, until you\nget to the top level.\n\n## How it works\n\nWhen it is given a list like `['I ate ', chowder, ' and ', cake]`,\n`hyperReplace` stashes all non-strings in an array and creates the\nstring `'I ate \\uD801 and \\uD802'`. Characters in the `\\uD800-\\uDBFF`\nrange are supposed to be used in surrogate pairs in the high\nposition. They are invalid characters on their own, so they make for\ngood placeholders.\n\nSo `\\uD801` is a placeholder for the first non-string element in the\narray, `\\uD802` stands for the second, and so on. Then, when a\nreplacement is made, the replacement is stashed in the list and a new\nsurrogate is put in its place in the string.\n\nAt the end, the string is split along the lone surrogates we\nintroduced and filled in with the appropriate objects. This is also\ndone with the match strings before they are given to a replacement\nfunction, so the placeholders are never exposed.\n\n## Limitations\n\n* It is only guaranteed to work on valid Unicode strings.\n* It'll choke if it has to do more than 1024 replacements, because\n  then it runs out of surrogates. An exception will be raised if the\n  limit is reached. (This should be fixable, I'm just waiting to run\n  into the problem, or for somebody else to.)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbreuleux%2Fhyper-replace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbreuleux%2Fhyper-replace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbreuleux%2Fhyper-replace/lists"}