mdast-util-find-and-replace
Advanced tools
Comparing version 1.1.1 to 2.0.0
297
index.js
@@ -1,155 +0,210 @@ | ||
'use strict' | ||
/** | ||
* @typedef Options Configuration. | ||
* @property {Test} [ignore] `unist-util-is` test used to assert parents | ||
* | ||
* @typedef {import('mdast').Text} Text | ||
* @typedef {import('mdast').Parent} Parent | ||
* @typedef {import('mdast').Root} Root | ||
* @typedef {import('mdast').PhrasingContent} PhrasingContent | ||
* @typedef {Parent['children'][number]|Root} Node | ||
* | ||
* @typedef {import('unist-util-visit-parents').Test} Test | ||
* @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult | ||
* | ||
* @typedef RegExpMatchObject | ||
* @property {number} index | ||
* @property {string} input | ||
* | ||
* @typedef {string|RegExp} Find | ||
* @typedef {string|ReplaceFunction} Replace | ||
* | ||
* @typedef {[Find, Replace]} FindAndReplaceTuple | ||
* @typedef {Object.<string, Replace>} FindAndReplaceSchema | ||
* @typedef {Array.<FindAndReplaceTuple>} FindAndReplaceList | ||
* | ||
* @typedef {[RegExp, ReplaceFunction]} Pair | ||
* @typedef {Array.<Pair>} Pairs | ||
*/ | ||
module.exports = findAndReplace | ||
/** | ||
* @callback ReplaceFunction | ||
* @param {...unknown} parameters | ||
* @returns {Array.<PhrasingContent>|PhrasingContent|string|false|undefined|null} | ||
*/ | ||
var visit = require('unist-util-visit-parents') | ||
var convert = require('unist-util-is/convert') | ||
var escape = require('escape-string-regexp') | ||
import escape from 'escape-string-regexp' | ||
import {visitParents} from 'unist-util-visit-parents' | ||
import {convert} from 'unist-util-is' | ||
var splice = [].splice | ||
var own = {}.hasOwnProperty | ||
function findAndReplace(tree, find, replace, options) { | ||
var settings | ||
var schema | ||
/** | ||
* @param tree mdast tree | ||
* @param find Value to find and remove. When `string`, escaped and made into a global `RegExp` | ||
* @param [replace] Value to insert. | ||
* * When `string`, turned into a Text node. | ||
* * When `Function`, called with the results of calling `RegExp.exec` as | ||
* arguments, in which case it can return a single or a list of `Node`, | ||
* a `string` (which is wrapped in a `Text` node), or `false` to not replace | ||
* @param [options] Configuration. | ||
*/ | ||
export const findAndReplace = | ||
/** | ||
* @type {( | ||
* ((tree: Node, find: Find, replace?: Replace, options?: Options) => Node) & | ||
* ((tree: Node, schema: FindAndReplaceSchema|FindAndReplaceList, options?: Options) => Node) | ||
* )} | ||
**/ | ||
( | ||
/** | ||
* @param {Node} tree | ||
* @param {Find|FindAndReplaceSchema|FindAndReplaceList} find | ||
* @param {Replace|Options} [replace] | ||
* @param {Options} [options] | ||
*/ | ||
function (tree, find, replace, options) { | ||
/** @type {Options} */ | ||
var settings | ||
/** @type {FindAndReplaceSchema|FindAndReplaceList} */ | ||
var schema | ||
if (typeof find === 'string' || (find && typeof find.exec === 'function')) { | ||
schema = [[find, replace]] | ||
} else { | ||
schema = find | ||
options = replace | ||
} | ||
if (typeof find === 'string' || find instanceof RegExp) { | ||
// @ts-expect-error don’t expect options twice. | ||
schema = [[find, replace]] | ||
settings = options | ||
} else { | ||
schema = find | ||
// @ts-expect-error don’t expect replace twice. | ||
settings = replace | ||
} | ||
settings = options || {} | ||
if (!settings) { | ||
settings = {} | ||
} | ||
search(tree, settings, handlerFactory(toPairs(schema))) | ||
var ignored = convert(settings.ignore || []) | ||
var pairs = toPairs(schema) | ||
var pairIndex = -1 | ||
return tree | ||
while (++pairIndex < pairs.length) { | ||
visitParents(tree, 'text', visitor) | ||
} | ||
function handlerFactory(pairs) { | ||
var pair = pairs[0] | ||
return tree | ||
return handler | ||
/** @type {import('unist-util-visit-parents').Visitor<Text>} */ | ||
function visitor(node, parents) { | ||
var index = -1 | ||
/** @type {Parent} */ | ||
var parent | ||
/** @type {Parent} */ | ||
var grandparent | ||
function handler(node, parent) { | ||
var find = pair[0] | ||
var replace = pair[1] | ||
var nodes = [] | ||
var start = 0 | ||
var index = parent.children.indexOf(node) | ||
var position | ||
var match | ||
var subhandler | ||
var value | ||
while (++index < parents.length) { | ||
// @ts-expect-error mdast vs. unist parent. | ||
parent = parents[index] | ||
find.lastIndex = 0 | ||
match = find.exec(node.value) | ||
while (match) { | ||
position = match.index | ||
value = replace.apply( | ||
null, | ||
[].concat(match, {index: match.index, input: match.input}) | ||
) | ||
if (value !== false) { | ||
if (start !== position) { | ||
nodes.push({type: 'text', value: node.value.slice(start, position)}) | ||
if ( | ||
ignored( | ||
parent, | ||
// @ts-expect-error mdast vs. unist parent. | ||
grandparent ? grandparent.children.indexOf(parent) : undefined, | ||
grandparent | ||
) | ||
) { | ||
return | ||
} | ||
if (typeof value === 'string' && value.length > 0) { | ||
value = {type: 'text', value: value} | ||
} | ||
grandparent = parent | ||
} | ||
if (value) { | ||
nodes = [].concat(nodes, value) | ||
} | ||
return handler(node, grandparent) | ||
} | ||
start = position + match[0].length | ||
} | ||
/** | ||
* @param {Text} node | ||
* @param {Parent} parent | ||
* @returns {VisitorResult} | ||
*/ | ||
function handler(node, parent) { | ||
var find = pairs[pairIndex][0] | ||
var replace = pairs[pairIndex][1] | ||
/** @type {Array.<PhrasingContent>} */ | ||
var nodes = [] | ||
var start = 0 | ||
var index = parent.children.indexOf(node) | ||
/** @type {number} */ | ||
var position | ||
/** @type {RegExpMatchArray} */ | ||
var match | ||
/** @type {Array.<PhrasingContent>|PhrasingContent|string|false|undefined|null} */ | ||
var value | ||
if (!find.global) { | ||
break | ||
} | ||
find.lastIndex = 0 | ||
match = find.exec(node.value) | ||
} | ||
if (position === undefined) { | ||
nodes = [node] | ||
index-- | ||
} else { | ||
if (start < node.value.length) { | ||
nodes.push({type: 'text', value: node.value.slice(start)}) | ||
} | ||
while (match) { | ||
position = match.index | ||
// @ts-expect-error this is perfectly fine, typescript. | ||
value = replace(...match, {index: match.index, input: match.input}) | ||
nodes.unshift(index, 1) | ||
splice.apply(parent.children, nodes) | ||
} | ||
if (typeof value === 'string' && value.length > 0) { | ||
value = {type: 'text', value} | ||
} | ||
if (pairs.length > 1) { | ||
subhandler = handlerFactory(pairs.slice(1)) | ||
position = -1 | ||
if (value !== false) { | ||
if (start !== position) { | ||
nodes.push({ | ||
type: 'text', | ||
value: node.value.slice(start, position) | ||
}) | ||
} | ||
while (++position < nodes.length) { | ||
node = nodes[position] | ||
if (value) { | ||
nodes = [].concat(nodes, value) | ||
} | ||
if (node.type === 'text') { | ||
subhandler(node, parent) | ||
} else { | ||
search(node, settings, subhandler) | ||
start = position + match[0].length | ||
} | ||
} | ||
} | ||
return index + nodes.length + 1 | ||
} | ||
} | ||
} | ||
if (!find.global) { | ||
break | ||
} | ||
function search(tree, settings, handler) { | ||
var ignored = convert(settings.ignore || []) | ||
var result = [] | ||
match = find.exec(node.value) | ||
} | ||
visit(tree, 'text', visitor) | ||
if (position === undefined) { | ||
nodes = [node] | ||
index-- | ||
} else { | ||
if (start < node.value.length) { | ||
nodes.push({type: 'text', value: node.value.slice(start)}) | ||
} | ||
return result | ||
parent.children.splice(index, 1, ...nodes) | ||
} | ||
function visitor(node, parents) { | ||
var index = -1 | ||
var parent | ||
var grandparent | ||
while (++index < parents.length) { | ||
parent = parents[index] | ||
if ( | ||
ignored( | ||
parent, | ||
grandparent ? grandparent.children.indexOf(parent) : undefined, | ||
grandparent | ||
) | ||
) { | ||
return | ||
return index + nodes.length + 1 | ||
} | ||
grandparent = parent | ||
} | ||
) | ||
return handler(node, grandparent) | ||
} | ||
} | ||
/** | ||
* @param {FindAndReplaceSchema|FindAndReplaceList} schema | ||
* @returns {Pairs} | ||
*/ | ||
function toPairs(schema) { | ||
var index = -1 | ||
/** @type {Pairs} */ | ||
var result = [] | ||
/** @type {string} */ | ||
var key | ||
var index | ||
if (typeof schema !== 'object') { | ||
throw new Error('Expected array or object as schema') | ||
throw new TypeError('Expected array or object as schema') | ||
} | ||
if ('length' in schema) { | ||
index = -1 | ||
if (Array.isArray(schema)) { | ||
while (++index < schema.length) { | ||
@@ -163,3 +218,5 @@ result.push([ | ||
for (key in schema) { | ||
result.push([toExpression(key), toFunction(schema[key])]) | ||
if (own.call(schema, key)) { | ||
result.push([toExpression(key), toFunction(schema[key])]) | ||
} | ||
} | ||
@@ -171,2 +228,6 @@ } | ||
/** | ||
* @param {Find} find | ||
* @returns {RegExp} | ||
*/ | ||
function toExpression(find) { | ||
@@ -176,8 +237,14 @@ return typeof find === 'string' ? new RegExp(escape(find), 'g') : find | ||
/** | ||
* @param {Replace} replace | ||
* @returns {ReplaceFunction} | ||
*/ | ||
function toFunction(replace) { | ||
return typeof replace === 'function' ? replace : returner | ||
/** @type {ReplaceFunction} */ | ||
function returner() { | ||
// @ts-expect-error it’s a string. | ||
return replace | ||
} | ||
} |
{ | ||
"name": "mdast-util-find-and-replace", | ||
"version": "1.1.1", | ||
"version": "2.0.0", | ||
"description": "mdast utility to find and replace text in a tree", | ||
@@ -26,24 +26,35 @@ "license": "MIT", | ||
], | ||
"sideEffects": false, | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"files": [ | ||
"index.d.ts", | ||
"index.js" | ||
], | ||
"dependencies": { | ||
"escape-string-regexp": "^4.0.0", | ||
"unist-util-is": "^4.0.0", | ||
"unist-util-visit-parents": "^3.0.0" | ||
"escape-string-regexp": "^5.0.0", | ||
"unist-util-is": "^5.0.0", | ||
"unist-util-visit-parents": "^4.0.0" | ||
}, | ||
"devDependencies": { | ||
"nyc": "^15.0.0", | ||
"@types/tape": "^4.0.0", | ||
"c8": "^7.0.0", | ||
"prettier": "^2.0.0", | ||
"remark-cli": "^9.0.0", | ||
"remark-preset-wooorm": "^8.0.0", | ||
"rimraf": "^3.0.0", | ||
"tape": "^5.0.0", | ||
"unist-builder": "^2.0.0", | ||
"xo": "^0.37.0" | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"unist-builder": "^3.0.0", | ||
"xo": "^0.39.0" | ||
}, | ||
"scripts": { | ||
"prepack": "npm run build && npm run format", | ||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"test-api": "node test", | ||
"test-coverage": "nyc --reporter lcov tape test.js", | ||
"test": "npm run format && npm run test-coverage" | ||
"test-api": "node test.js", | ||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
}, | ||
@@ -60,14 +71,7 @@ "prettier": { | ||
"prettier": true, | ||
"esnext": false, | ||
"rules": { | ||
"unicorn/prefer-type-error": "off", | ||
"guard-for-in": "off" | ||
"no-var": "off", | ||
"prefer-arrow-callback": "off" | ||
} | ||
}, | ||
"nyc": { | ||
"check-coverage": true, | ||
"lines": 100, | ||
"functions": 100, | ||
"branches": 100 | ||
}, | ||
"remarkConfig": { | ||
@@ -77,3 +81,8 @@ "plugins": [ | ||
] | ||
}, | ||
"typeCoverage": { | ||
"atLeast": 100, | ||
"detail": true, | ||
"strict": true | ||
} | ||
} |
@@ -15,2 +15,5 @@ # mdast-util-find-and-replace | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): | ||
Node 12+ is needed to use it and it must be `import`ed instead of `require`d. | ||
[npm][]: | ||
@@ -25,5 +28,5 @@ | ||
```js | ||
var u = require('unist-builder') | ||
var inspect = require('unist-util-inspect') | ||
var findAndReplace = require('mdast-util-find-and-replace') | ||
import {u} from 'unist-builder' | ||
import {inspect} from 'unist-util-inspect' | ||
import {findAndReplace} from 'mdast-util-find-and-replace' | ||
@@ -70,2 +73,5 @@ var tree = u('paragraph', [ | ||
This package exports the following identifiers: `findAndReplace`. | ||
There is no default export. | ||
### `findAndReplace(tree, find[, replace][, options])` | ||
@@ -72,0 +78,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
17117
5
272
194
Yes
11
1
+ Addedescape-string-regexp@5.0.0(transitive)
+ Addedunist-util-is@5.2.1(transitive)
+ Addedunist-util-visit-parents@4.1.1(transitive)
- Removedescape-string-regexp@4.0.0(transitive)
- Removedunist-util-is@4.1.0(transitive)
- Removedunist-util-visit-parents@3.1.1(transitive)
Updatedescape-string-regexp@^5.0.0
Updatedunist-util-is@^5.0.0