1 | const { checkRule, hideStack } = require('./lib');
|
2 |
|
3 | /**
|
4 | * SyncReplaceable function receives the whole string and returns the result of transforms which are of interface `{ re: /reg-(exp)/, replacement(m, t) { return `transform-${t}` } }`
|
5 | * If the replacement is passed as a function, it will work in the same way as the replacer for `string.replace` method (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace), taking the `match` as the first argument, and matched `p1`, `p2`, _etc_ parameters as following arguments. The replacer can also be an async function.
|
6 | * @param {string|Buffer} input The string or buffer to transform synchronously using the replacements. Does not support asynchronous replacements.
|
7 | * @param {Rule[]} rules An array with rules.
|
8 | * @example
|
9 | *
|
10 | * // markdown __ to html emphasise implementation
|
11 | * const stream = SyncReplaceable('__hello world__', {
|
12 | * --re: /__(\S+)__/g,
|
13 | * --replacement(match, p1) {
|
14 | * ----return `<em>${p1}</em>`
|
15 | * --},
|
16 | * })
|
17 | */
|
18 | const SyncReplaceable = (input, rules) => {
|
19 | const fr = rules.filter(checkRule)
|
20 | const s = fr.reduce((acc, { re, replacement }) => {
|
21 | /** @type {string} */
|
22 | let Acc = acc
|
23 | if (this._broke) return Acc
|
24 |
|
25 | if (typeof replacement == 'string') {
|
26 | Acc = Acc.replace(re, replacement)
|
27 | } else {
|
28 | /** @type {function} */
|
29 | const R = replacement.bind(this)
|
30 | let commonError
|
31 | const t = Acc.replace(re, (match, ...args) => {
|
32 | commonError = new Error()
|
33 | try {
|
34 | if (this._broke) return match
|
35 | const p = R(match, ...args)
|
36 | return p
|
37 | } catch (e) { // hide stack for sync stack traces
|
38 | hideStack(commonError, e)
|
39 | }
|
40 | })
|
41 | return t
|
42 | }
|
43 | }, `${input}`)
|
44 | return s
|
45 | }
|
46 |
|
47 | module.exports=SyncReplaceable
|
48 |
|
49 | /* documentary types/rules.xml */
|
50 | /**
|
51 | * @typedef {(match: string, ...params: string[]) => string} Replacer
|
52 | *
|
53 | * @typedef {(match: string, ...params: string[]) => Promise.<string>} AsyncReplacer
|
54 | *
|
55 | * @typedef {Object} Rule A replacement rule.
|
56 | * @prop {RegExp} re A Regular expression to match against.
|
57 | * @prop {string|Replacer|AsyncReplacer} replacement A replacement string, or a replacement string function.
|
58 | */
|