Skip to content

syntax-tree/hast-util-find-and-replace

Repository files navigation

hast-util-find-and-replace

Build Coverage Downloads Size Sponsors Backers Chat

hast utility to find and replace things.

Contents

What is this?

This package is a utility that lets you find patterns (string, RegExp) in text and replace them with nodes (such as elements). It’s aware of HTML (such as ignoring <style> and <script> by default).

When should I use this?

This utility is typically useful when you have regexes and want to modify hast. One example is when you have some form of “mentions” (such as /@([a-z][_a-z0-9])\b/gi) and want to create links to persons from them.

Install

This package is ESM only. In Node.js (version 12.20+, 14.14+, or 16.0+), install with npm:

npm install hast-util-find-and-replace

In Deno with esm.sh:

import {findAndReplace} from 'https://esm.sh/hast-util-find-and-replace@4'

In browsers with esm.sh:

<script type="module">
  import {findAndReplace} from 'https://esm.sh/hast-util-find-and-replace@4?bundle'
</script>

Use

import {h} from 'hastscript'
import {findAndReplace} from 'hast-util-find-and-replace'
import {inspect} from 'unist-util-inspect'

const tree = h('p', [
  'Some ',
  h('em', 'emphasis'),
  ', ',
  h('strong', 'importance'),
  ', and ',
  h('code', 'code'),
  '.'
])

findAndReplace(tree, [
  [/and/gi, 'or'],
  [/emphasis/gi, 'em'],
  [/importance/gi, 'strong'],
  [
    /code/gi,
    function ($0) {
      return h('a', {href: '//example.com#' + $0}, $0)
    }
  ]
])

console.log(inspect(tree))

Yields:

element<p>[9]
│ properties: {}
├─0 text "Some "
├─1 element<em>[1]
│   │ properties: {}
│   └─0 text "em"
├─2 text ", "
├─3 element<strong>[1]
│   │ properties: {}
│   └─0 text "strong"
├─4 text ", "
├─5 text "or"
├─6 text " "
├─7 element<code>[1]
│   │ properties: {}
│   └─0 element<a>[1]
│       │ properties: {"href":"//example.com#code"}
│       └─0 text "code"
└─8 text "."

API

This package exports the identifiers findAndReplace and defaultIgnore. There is no default export.

findAndReplace(tree, find, replace[, options])

Find patterns in a tree and replace them. The algorithm searches the tree in preorder for complete values in Text nodes. Partial matches are not supported.

Signatures
  • findAndReplace(tree, find, replace[, options])
  • findAndReplace(tree, search[, options])
Parameters
  • tree (Node)
  • find (string or RegExp) — value to find and remove (strings are escaped and turned into a global RegExp)
  • replace (string or Function) — value to insert. strings are turned into a Text node, Functions are called with the results of calling RegExp.exec as arguments, and they can return a Node, a string (which is wrapped in a Text node), or false to not replace
  • search (Array or Object) — perform multiple find-and-replaces. Either an Array of tuples (Arrays) with find (at 0) and replace (at 1), or an Object where each key is find and each value is the corresponding replace
  • options.ignore (Test, default: ['title', 'script', 'style', 'svg', 'math']) — any hast-util-is-element compatible test (the default list is exported as defaultIgnore)
Returns

The given tree (Node).

Types

This package is fully typed with TypeScript. It exports the additional types Find, Replace, ReplaceFunction, FindAndReplaceTuple, FindAndReplaceSchema, FindAndReplaceList, RegExpMatchObject, and Options.

Compatibility

Projects maintained by the unified collective are compatible with all maintained versions of Node.js. As of now, that is Node.js 12.20+, 14.14+, and 16.0+. Our projects sometimes work with older versions, but this is not guaranteed.

Security

Use of hast-util-find-and-replace can open you up to a cross-site scripting (XSS) attack if a value used to replace is unsafe. Use hast-util-santize to make the hast tree safe.

The following example shows how a script is injected that runs when loaded in a browser.

const tree = h('p', 'This and that.')

findAndReplace(tree, 'and', () => h('script', 'alert(1)'))

Yields:

<p>This <script>alert(1)</script> that.</p>

Related

Contribute

See contributing.md in syntax-tree/.github for ways to get started. See support.md for ways to get help.

This project has a code of conduct. By interacting with this repository, organisation, or community you agree to abide by its terms.

License

MIT © Titus Wormer