From 4f5bfc3f735311688a7e307c7672cfdbc68c7dc8 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 9 Jan 2023 13:08:00 +0100 Subject: [PATCH 1/8] Update dev-dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dcf4e0d..30e21ef 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "tape": "^5.0.0", "type-coverage": "^2.0.0", "typescript": "^4.0.0", - "xo": "^0.50.0" + "xo": "^0.53.0" }, "scripts": { "prepack": "npm run build && npm run format", From 974732b24733851d61810aab627ae3dada400484 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 9 Jan 2023 13:08:09 +0100 Subject: [PATCH 2/8] Update Actions --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 69924a4..89dc06c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,13 +7,13 @@ jobs: name: ${{matrix.node}} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: dcodeIO/setup-node-nvm@master + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: node-version: ${{matrix.node}} - run: npm install - run: npm test - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v3 strategy: matrix: node: From bc5a7ba53e7a9621f20327040ad1a3c780f647aa Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 9 Jan 2023 13:09:02 +0100 Subject: [PATCH 3/8] Update `tsconfig.json` --- lib/index.js | 2 +- package.json | 3 +-- tsconfig.json | 17 +++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/index.js b/lib/index.js index b353813..aeb57c7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -78,7 +78,7 @@ export function findAndReplace(tree, find, replace, options) { return tree - /** @type {import('unist-util-visit-parents/complex-types').BuildVisitor} */ + /** @type {import('unist-util-visit-parents/complex-types.js').BuildVisitor} */ function visitor(node, parents) { let index = -1 /** @type {Root|Element|undefined} */ diff --git a/package.json b/package.json index 30e21ef..d5b8106 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,6 @@ "prettier": "^2.0.0", "remark-cli": "^11.0.0", "remark-preset-wooorm": "^9.0.0", - "rimraf": "^3.0.0", "tape": "^5.0.0", "type-coverage": "^2.0.0", "typescript": "^4.0.0", @@ -52,7 +51,7 @@ }, "scripts": { "prepack": "npm run build && npm run format", - "build": "rimraf \"lib/**/*.d.ts\" \"*.d.ts\" && tsc && type-coverage", + "build": "tsc --build --clean && tsc --build && type-coverage", "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", "test-api": "node --conditions development test.js", "test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", diff --git a/tsconfig.json b/tsconfig.json index d377f01..1bc9e99 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,17 @@ { - "include": ["lib/**/*.js", "*.js"], + "include": ["**/**.js"], + "exclude": ["coverage/", "node_modules/"], "compilerOptions": { - "target": "ES2020", - "lib": ["ES2020"], - "module": "ES2020", - "moduleResolution": "node", - "allowJs": true, "checkJs": true, "declaration": true, "emitDeclarationOnly": true, - "allowSyntheticDefaultImports": true, + "exactOptionalPropertyTypes": true, + "forceConsistentCasingInFileNames": true, + "lib": ["es2020"], + "module": "node16", + "newLine": "lf", "skipLibCheck": true, - "strict": true + "strict": true, + "target": "es2020" } } From 355596a9c353f33f3039dce258ba561d0b4bc751 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 9 Jan 2023 13:23:49 +0100 Subject: [PATCH 4/8] Refactor code-style * Add support for `null` as input in API types * Add more docs to JSDoc --- lib/index.js | 92 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/lib/index.js b/lib/index.js index aeb57c7..d0a0e0d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,37 +1,52 @@ /** - * @typedef Options - * @property {Test} [ignore] - * * @typedef {import('hast').Text} Text - * @typedef {import('hast').Parent} Parent * @typedef {import('hast').Root} Root * @typedef {import('hast').Element} Element * @typedef {import('hast').Content} Content - * @typedef {Root|Content} Node - * * @typedef {import('hast-util-is-element').Test} Test * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +/** + * @typedef {Root | Content} Node * * @typedef RegExpMatchObject + * Info on the match. * @property {number} index + * The index of the search at which the result was found. * @property {string} input + * A copy of the search string in the text node. * @property {[Root, ...Array, Text]} stack + * All ancestors of the text node, where the last node is the text itself. * - * @typedef {string|RegExp} Find - * @typedef {string|ReplaceFunction} Replace + * @callback ReplaceFunction + * Callback called when a search matches. + * @param {...any} parameters + * The parameters are the result of the search expressions, which can be + * several if a regex captures groups. + * + * The last parameter is a `RegExpMatchObject`. + * @returns {Array | Content | string | false | undefined | null} + * Resulting nodes (where `string` is turned into a `Text` node). * + * The values `null` and `undefined` and an empty string mean the match is + * removed. + * + * The value `false` means that this isn’t a match after all, and it is not + * replaced. + * + * @typedef {string | RegExp} Find + * @typedef {string | ReplaceFunction} Replace * @typedef {[Find, Replace]} FindAndReplaceTuple * @typedef {Record} FindAndReplaceSchema * @typedef {Array} FindAndReplaceList - * * @typedef {[RegExp, ReplaceFunction]} Pair * @typedef {Array} Pairs - */ - -/** - * @callback ReplaceFunction - * @param {...any} parameters - * @returns {Array|Content|string|false|undefined|null} + * + * @typedef Options + * Configuration. + * @property {Test | null | undefined} [ignore] + * Test for which elements to ignore. */ import {visitParents} from 'unist-util-visit-parents' @@ -43,15 +58,25 @@ const own = {}.hasOwnProperty export const defaultIgnore = ['title', 'script', 'style', 'svg', 'math'] /** + * 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. + * * @param {Node} tree - * @param {Find|FindAndReplaceSchema|FindAndReplaceList} find - * @param {Replace|Options} [replace] - * @param {Options} [options] + * Tree to change. + * @param {Find | FindAndReplaceSchema | FindAndReplaceList} find + * Patterns to find. + * @param {Replace | Options | null | undefined} [replace] + * `Replace` (when `find` is `Find`) or configuration. + * @param {Options | null | undefined} [options] + * Configuration (when `find` is not `Find`). */ export function findAndReplace(tree, find, replace, options) { - /** @type {Options|undefined} */ + /** @type {Options | null | undefined} */ let settings - /** @type {FindAndReplaceSchema|FindAndReplaceList} */ + /** @type {FindAndReplaceSchema | FindAndReplaceList} */ let schema if (typeof find === 'string' || find instanceof RegExp) { @@ -81,7 +106,7 @@ export function findAndReplace(tree, find, replace, options) { /** @type {import('unist-util-visit-parents/complex-types.js').BuildVisitor} */ function visitor(node, parents) { let index = -1 - /** @type {Root|Element|undefined} */ + /** @type {Root | Element | undefined} */ let grandparent while (++index < parents.length) { @@ -107,9 +132,14 @@ export function findAndReplace(tree, find, replace, options) { } /** + * Handle a text node which is not in an ignored parent. + * * @param {Text} node - * @param {Array} parents + * Text node. + * @param {Array} parents + * Parents. * @returns {VisitorResult} + * Result. */ function handler(node, parents) { const parent = parents[parents.length - 1] @@ -120,15 +150,13 @@ export function findAndReplace(tree, find, replace, options) { let change = false /** @type {Array} */ let nodes = [] - /** @type {number|undefined} */ - let position find.lastIndex = 0 let match = find.exec(node.value) while (match) { - position = match.index + const position = match.index /** @type {RegExpMatchObject} */ const matchObject = { index: match.index, @@ -180,8 +208,12 @@ export function findAndReplace(tree, find, replace, options) { } /** - * @param {FindAndReplaceSchema|FindAndReplaceList} schema + * Turn a schema into pairs. + * + * @param {FindAndReplaceSchema | FindAndReplaceList} schema + * Schema. * @returns {Pairs} + * Clean pairs. */ function toPairs(schema) { /** @type {Pairs} */ @@ -215,16 +247,24 @@ function toPairs(schema) { } /** + * Turn a find into an expression. + * * @param {Find} find + * Find. * @returns {RegExp} + * Expression. */ function toExpression(find) { return typeof find === 'string' ? new RegExp(escape(find), 'g') : find } /** + * Turn a replace into a function. + * * @param {Replace} replace + * Replace. * @returns {ReplaceFunction} + * Function. */ function toFunction(replace) { return typeof replace === 'function' ? replace : () => replace From 94e30608134adb78ebb47cb31725d0fdfb528f6e Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 9 Jan 2023 13:24:47 +0100 Subject: [PATCH 5/8] Use Node test runner --- .github/workflows/main.yml | 2 +- package.json | 3 +-- test.js | 43 +++++++++++++++++++------------------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 89dc06c..ee318ca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,5 +17,5 @@ jobs: strategy: matrix: node: - - lts/fermium + - lts/hydrogen - node diff --git a/package.json b/package.json index d5b8106..1e105eb 100644 --- a/package.json +++ b/package.json @@ -38,13 +38,12 @@ "unist-util-visit-parents": "^5.0.0" }, "devDependencies": { - "@types/tape": "^4.0.0", + "@types/node": "^18.0.0", "c8": "^7.0.0", "hastscript": "^7.0.0", "prettier": "^2.0.0", "remark-cli": "^11.0.0", "remark-preset-wooorm": "^9.0.0", - "tape": "^5.0.0", "type-coverage": "^2.0.0", "typescript": "^4.0.0", "xo": "^0.53.0" diff --git a/test.js b/test.js index 0a926b7..0d498e8 100644 --- a/test.js +++ b/test.js @@ -1,9 +1,10 @@ -import test from 'tape' +import assert from 'node:assert/strict' +import test from 'node:test' import {h} from 'hastscript' import {findAndReplace} from './index.js' -test('findAndReplace', (t) => { - t.throws( +test('findAndReplace', () => { + assert.throws( () => { // @ts-expect-error runtime. findAndReplace(create(), true) @@ -12,7 +13,7 @@ test('findAndReplace', (t) => { 'should throw on invalid search and replaces' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), 'emphasis'), h('p', [ 'Some ', @@ -26,7 +27,7 @@ test('findAndReplace', (t) => { 'should remove without `replace`' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), 'emphasis', '!!!'), h('p', [ 'Some ', @@ -40,7 +41,7 @@ test('findAndReplace', (t) => { 'should work when given `find` and `replace`' ) - t.deepEqual( + assert.deepEqual( findAndReplace( create(), /em(\w+)is/, @@ -58,7 +59,7 @@ test('findAndReplace', (t) => { 'should work when given `find` as a `RegExp` and `replace` as a `Function`' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), 'emphasis', () => ''), h('p', [ 'Some ', @@ -72,7 +73,7 @@ test('findAndReplace', (t) => { 'should work when given `replace` returns an empty string' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), 'emphasis', () => h('a', h('b', 'c'))), h('p', [ 'Some ', @@ -86,7 +87,7 @@ test('findAndReplace', (t) => { 'should work when given `replace` returns a node' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), 'emphasis', () => [h('a'), h('b', 'c')]), h('p', [ 'Some ', @@ -100,7 +101,7 @@ test('findAndReplace', (t) => { 'should work when given `replace` returns a list of nodes' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), [ ['emphasis', '!!!'], ['importance', '???'] @@ -117,7 +118,7 @@ test('findAndReplace', (t) => { 'should work when given `search` as an matrix of strings' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), {code: 'hacks', ',': '!'}), h('p', [ 'Some ', @@ -133,7 +134,7 @@ test('findAndReplace', (t) => { 'should work when given `search` as an object of strings' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), /\Bmp\B/, '[MP]'), h('p', [ 'Some ', @@ -147,7 +148,7 @@ test('findAndReplace', (t) => { 'should work on partial matches' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), { emphasis() { return h('a', 'importance') @@ -166,7 +167,7 @@ test('findAndReplace', (t) => { 'should find-and-replace recursively' ) - t.deepEqual( + assert.deepEqual( findAndReplace( h('p', [ 'Some ', @@ -193,13 +194,13 @@ test('findAndReplace', (t) => { 'should ignore from options' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), 'emphasis', () => false), create(), 'should not replace when returning `false`' ) - t.deepEqual( + assert.deepEqual( findAndReplace(h('p', 'Some emphasis, importance, and code.'), { importance(/** @type {string} */ match) { return h('strong', match) @@ -215,7 +216,7 @@ test('findAndReplace', (t) => { 'should not be order-sensitive with strings' ) - t.deepEqual( + assert.deepEqual( findAndReplace(h('p', 'aaa bbb'), [ [ /\b\w+\b/g, @@ -227,7 +228,7 @@ test('findAndReplace', (t) => { h('p', [h('strong', 'aaa'), ' bbb']), 'should support a match, and then a `false`' ) - t.deepEqual( + assert.deepEqual( findAndReplace(h('p', 'Some emphasis, importance, and code.'), [ [ /importance/g, @@ -252,7 +253,7 @@ test('findAndReplace', (t) => { 'should not be order-sensitive with regexes' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), 'and', 'alert(1)'), h('p', [ 'Some ', @@ -268,7 +269,7 @@ test('findAndReplace', (t) => { 'security: replacer as string (safe)' ) - t.deepEqual( + assert.deepEqual( findAndReplace(create(), 'and', () => h('script', 'alert(1)')), h('p', [ 'Some ', @@ -283,8 +284,6 @@ test('findAndReplace', (t) => { ]), 'security: replacer as function (unsafe)' ) - - t.end() }) function create() { From a17aa0aee334e9e5e7346a9502d3503b22c968d2 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 9 Jan 2023 13:25:10 +0100 Subject: [PATCH 6/8] Add tests for exposed identifiers --- test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test.js b/test.js index 0d498e8..eff5d90 100644 --- a/test.js +++ b/test.js @@ -2,8 +2,15 @@ import assert from 'node:assert/strict' import test from 'node:test' import {h} from 'hastscript' import {findAndReplace} from './index.js' +import * as mod from './index.js' test('findAndReplace', () => { + assert.deepEqual( + Object.keys(mod).sort(), + ['defaultIgnore', 'findAndReplace'], + 'should expose the public api' + ) + assert.throws( () => { // @ts-expect-error runtime. From aa4c0063cfe5e6300a9b314f52b201ecb0e94bac Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 9 Jan 2023 15:11:57 +0100 Subject: [PATCH 7/8] Add improved docs --- lib/index.js | 52 ++++++++++---- readme.md | 198 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 209 insertions(+), 41 deletions(-) diff --git a/lib/index.js b/lib/index.js index d0a0e0d..dc36b52 100644 --- a/lib/index.js +++ b/lib/index.js @@ -22,26 +22,36 @@ * @callback ReplaceFunction * Callback called when a search matches. * @param {...any} parameters - * The parameters are the result of the search expressions, which can be - * several if a regex captures groups. + * The parameters are the result of corresponding search expression: * - * The last parameter is a `RegExpMatchObject`. + * * `value` (`string`) — whole match + * * `...capture` (`Array`) — matches from regex capture groups + * * `match` (`RegExpMatchObject`) — info on the match * @returns {Array | Content | string | false | undefined | null} - * Resulting nodes (where `string` is turned into a `Text` node). + * Thing to replace with. * - * The values `null` and `undefined` and an empty string mean the match is - * removed. - * - * The value `false` means that this isn’t a match after all, and it is not - * replaced. + * * when `null`, `undefined`, `''`, remove the match + * * …or when `false`, do not replace at all + * * …or when `string`, replace with a text node of that value + * * …or when `Node` or `Array`, replace with those nodes * * @typedef {string | RegExp} Find - * @typedef {string | ReplaceFunction} Replace - * @typedef {[Find, Replace]} FindAndReplaceTuple - * @typedef {Record} FindAndReplaceSchema + * Pattern to find. + * + * Strings are escaped and then turned into global expressions. + * * @typedef {Array} FindAndReplaceList + * Several find and replaces, in array form. + * @typedef {Record} FindAndReplaceSchema + * Several find and replaces, in object form. + * @typedef {[Find, Replace]} FindAndReplaceTuple + * Find and replace in tuple form. + * @typedef {string | ReplaceFunction} Replace + * Thing to replace with. * @typedef {[RegExp, ReplaceFunction]} Pair + * Normalized find and replace. * @typedef {Array} Pairs + * All find and replaced. * * @typedef Options * Configuration. @@ -55,7 +65,14 @@ import escape from 'escape-string-regexp' const own = {}.hasOwnProperty -export const defaultIgnore = ['title', 'script', 'style', 'svg', 'math'] +/** + * Default tag names to ignore. + * + * The defaults are `math`, `script`, `style`, `svg`, and `title`. + * + * @type {Array} + */ +export const defaultIgnore = ['math', 'script', 'style', 'svg', 'title'] /** * Find patterns in a tree and replace them. @@ -64,14 +81,18 @@ export const defaultIgnore = ['title', 'script', 'style', 'svg', 'math'] * nodes. * Partial matches are not supported. * - * @param {Node} tree + * @template {Node} Tree + * Node type. + * @param {Tree} tree * Tree to change. * @param {Find | FindAndReplaceSchema | FindAndReplaceList} find * Patterns to find. * @param {Replace | Options | null | undefined} [replace] - * `Replace` (when `find` is `Find`) or configuration. + * Things to replace with (when `find` is `Find`) or configuration. * @param {Options | null | undefined} [options] * Configuration (when `find` is not `Find`). + * @returns {Tree} + * Given, modified, tree. */ export function findAndReplace(tree, find, replace, options) { /** @type {Options | null | undefined} */ @@ -101,6 +122,7 @@ export function findAndReplace(tree, find, replace, options) { visitParents(tree, 'text', visitor) } + // To do next major: don’t return the given tree. return tree /** @type {import('unist-util-visit-parents/complex-types.js').BuildVisitor} */ diff --git a/readme.md b/readme.md index 8ec207a..28c350c 100644 --- a/readme.md +++ b/readme.md @@ -18,6 +18,15 @@ * [Use](#use) * [API](#api) * [`findAndReplace(tree, find, replace[, options])`](#findandreplacetree-find-replace-options) + * [`defaultIgnore`](#defaultignore) + * [`Find`](#find) + * [`FindAndReplaceList`](#findandreplacelist) + * [`FindAndReplaceSchema`](#findandreplaceschema) + * [`FindAndReplaceTuple`](#findandreplacetuple) + * [`Options`](#options) + * [`RegExpMatchObject`](#regexpmatchobject) + * [`Replace`](#replace) + * [`ReplaceFunction`](#replacefunction) * [Types](#types) * [Compatibility](#compatibility) * [Security](#security) @@ -40,7 +49,7 @@ One example is when you have some form of “mentions” (such as ## Install This package is [ESM only][esm]. -In Node.js (version 12.20+, 14.14+, or 16.0+), install with [npm][]: +In Node.js (version 14.14+ and or 16.0+), install with [npm][]: ```sh npm install hast-util-find-and-replace @@ -118,12 +127,14 @@ element

[9] ## API -This package exports the identifiers `findAndReplace` and `defaultIgnore`. +This package exports the identifiers [`defaultIgnore`][defaultignore] and +[`findAndReplace`][findandreplace]. 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`][text] nodes. Partial matches are not supported. @@ -136,41 +147,156 @@ Partial matches are not supported. ###### Parameters * `tree` ([`Node`][node]) -* `find` (`string` or `RegExp`) - — value to find and remove (`string`s are escaped and turned into a global - `RegExp`) -* `replace` (`string` or `Function`) - — value to insert. - `string`s are turned into a [`Text`][text] node, - `Function`s are called with the results of calling `RegExp.exec` as - arguments, and they can return a [`Node`][node], a `string` (which is - wrapped in a [`Text`][text] node), or `false` to not replace -* `search` (`Array` or `Object`) - — perform multiple find-and-replaces. - Either an `Array` of tuples (`Array`s) 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`][test] compatible test (the default list is - exported as `defaultIgnore`) + — tree to change +* `find` ([`Find`][find]) + — value to find and remove +* `replace` ([`Replace`][replace]) + — thing to replace with +* `search` ([`FindAndReplaceSchema`][findandreplaceschema] or + [`FindAndReplaceList`][findandreplacelist]) + — several find and replaces +* `options` ([`Options`][options]) + — configuration ###### Returns -The given `tree` ([`Node`][node]). +Given, modified, tree ([`Node`][node]). + +### `defaultIgnore` + +Default tag names to ignore. + +The defaults are `math`, `script`, `style`, `svg`, and `title`. + +###### Type + +```ts +type defaultIgnore = Array +``` + +### `Find` + +Pattern to find (TypeScript type). + +Strings are escaped and then turned into global expressions. + +###### Type + +```ts +type Find = string | RegExp +``` + +### `FindAndReplaceList` + +Several find and replaces, in array form (TypeScript type). + +###### Type + +```ts +type FindAndReplaceList = Array +``` + +See [`FindAndReplaceTuple`][findandreplacetuple]. + +### `FindAndReplaceSchema` + +Several find and replaces, in object form (TypeScript type). + +###### Type + +```ts +type FindAndReplaceSchema = Record +``` + +See [`Replace`][replace]. + +### `FindAndReplaceTuple` + +Find and replace in tuple form (TypeScript type). + +###### Type + +```ts +type FindAndReplaceTuple = [Find, Replace] +``` + +See [`Find`][find] and [`Replace`][replace]. + +### `Options` + +Configuration (TypeScript type). + +###### Fields + +* `ignore` ([`Test`][test], optional) + — test for which elements to ignore + +### `RegExpMatchObject` + +Info on the match (TypeScript type). + +###### Fields + +* `index` (`number`) + — the index of the search at which the result was found +* `input` (`string`) + — a copy of the search string in the text node +* `stack` ([`Array`][node]) + — all ancestors of the text node, where the last node is the text itself + +### `Replace` + +Thing to replace with (TypeScript type). + +###### Type + +```ts +type Replace = string | ReplaceFunction +``` + +See [`ReplaceFunction`][replacefunction]. + +### `ReplaceFunction` + +Callback called when a search matches (TypeScript type). + +###### Parameters + +The parameters are the result of corresponding search expression: + +* `value` (`string`) + — whole match +* `...capture` (`Array`) + — matches from regex capture groups +* `match` ([`RegExpMatchObject`][regexpmatchobject]) + — info on the match + +###### Returns + +Thing to replace with: + +* when `null`, `undefined`, `''`, remove the match +* …or when `false`, do not replace at all +* …or when `string`, replace with a text node of that value +* …or when `Node` or `Array`, replace with those nodes ## Types This package is fully typed with [TypeScript][]. -It exports the additional types `Find`, `Replace`, `ReplaceFunction`, -`FindAndReplaceTuple`, `FindAndReplaceSchema`, `FindAndReplaceList`, -`RegExpMatchObject`, and `Options`. +It exports the additional types [`Find`][find], +[`FindAndReplaceList`][findandreplacelist], +[`FindAndReplaceSchema`][findandreplaceschema], +[`FindAndReplaceTuple`][findandreplacetuple], +[`Options`][options], +[`RegExpMatchObject`][regexpmatchobject], +[`Replace`][replace], and +[`ReplaceFunction`][replacefunction]. ## 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+. +As of now, that is Node.js 14.14+ and 16.0+. Our projects sometimes work with older versions, but this is not guaranteed. ## Security @@ -277,4 +403,24 @@ abide by its terms. [hast-util-sanitize]: https://github.com/syntax-tree/hast-util-sanitize -[test]: https://github.com/syntax-tree/hast-util-is-element#api +[test]: https://github.com/syntax-tree/hast-util-is-element#test + +[defaultignore]: #defaultignore + +[findandreplace]: #findandreplacetree-find-replace-options + +[options]: #options + +[find]: #find + +[replace]: #replace + +[replacefunction]: #replacefunction + +[findandreplacelist]: #findandreplacelist + +[findandreplaceschema]: #findandreplaceschema + +[findandreplacetuple]: #findandreplacetuple + +[regexpmatchobject]: #regexpmatchobject From 79f4dd5af59440e38782f6584aa7c3622f971615 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 9 Jan 2023 15:13:58 +0100 Subject: [PATCH 8/8] 4.1.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1e105eb..d06db00 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hast-util-find-and-replace", - "version": "4.1.2", + "version": "4.1.3", "description": "hast utility to find and replace text in a tree", "license": "MIT", "keywords": [