wikilint 2.3.4 → 2.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AstElement = void 0;
4
4
  const string_1 = require("../util/string");
5
+ const debug_1 = require("../util/debug");
5
6
  const node_1 = require("./node");
6
7
  /** 类似HTMLElement */
7
8
  class AstElement extends node_1.AstNode {
@@ -38,8 +39,7 @@ class AstElement extends node_1.AstNode {
38
39
  * @param i 移除位置
39
40
  */
40
41
  removeAt(i) {
41
- const { childNodes } = this, [node] = childNodes.splice(i, 1);
42
- return node;
42
+ return (0, debug_1.setChildNodes)(this, i, 1)[0];
43
43
  }
44
44
  /**
45
45
  * 插入子节点
@@ -47,9 +47,7 @@ class AstElement extends node_1.AstNode {
47
47
  * @param i 插入位置
48
48
  */
49
49
  insertAt(node, i = this.length) {
50
- const { childNodes } = this;
51
- node.setAttribute('parentNode', this);
52
- childNodes.splice(i, 0, node);
50
+ (0, debug_1.setChildNodes)(this, i, 0, [node]);
53
51
  return node;
54
52
  }
55
53
  /**
@@ -24,6 +24,13 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
24
24
  mt.index += length;
25
25
  }
26
26
  const { 0: syntax, index: curIndex } = mt ?? { 0: '\n', index: wikitext.length }, top = stack.pop() ?? {}, { 0: open, index, parts, findEqual: topFindEqual, pos: topPos } = top, innerEqual = syntax === '=' && topFindEqual;
27
+ /**
28
+ * 填入模板内容
29
+ * @param text wikitext全文
30
+ */
31
+ const push = (text) => {
32
+ parts.at(-1).push(text.slice(topPos, curIndex));
33
+ };
27
34
  if (syntax === ']]' || syntax === '}-') { // 情形1:闭合内链或转换
28
35
  lastIndex = curIndex + 2;
29
36
  }
@@ -42,7 +49,7 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
42
49
  }
43
50
  else if (syntax === '|' || innerEqual) { // 情形3:模板内部,含行首单个'='
44
51
  lastIndex = curIndex + 1;
45
- parts.at(-1).push(wikitext.slice(topPos, curIndex));
52
+ push(wikitext);
46
53
  if (syntax === '|') {
47
54
  parts.push([]);
48
55
  }
@@ -53,7 +60,7 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
53
60
  else if (syntax.startsWith('}}')) { // 情形4:闭合模板
54
61
  const close = syntax.slice(0, Math.min(open.length, 3)), rest = open.length - close.length, { length } = accum;
55
62
  lastIndex = curIndex + close.length; // 这不是最终的lastIndex
56
- parts.at(-1).push(wikitext.slice(topPos, curIndex));
63
+ push(wikitext);
57
64
  let skip = false, ch = 't';
58
65
  if (close.length === 3) {
59
66
  const argParts = parts.map(part => part.join('=')), str = argParts.length > 1 && (0, string_1.removeComment)(argParts[1]).trim();
@@ -16,27 +16,35 @@ const comment_1 = require("../src/nowiki/comment");
16
16
  */
17
17
  const parseCommentAndExt = (wikitext, config = Parser.getConfig(), accum = [], includeOnly = false) => {
18
18
  const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft;
19
+ /** 更新`<onlyinclude>`和`</onlyinclude>`的位置 */
20
+ const update = () => {
21
+ const i = wikitext.indexOf(onlyincludeLeft);
22
+ return { i, j: wikitext.indexOf(onlyincludeRight, i + length) };
23
+ };
19
24
  if (includeOnly) {
20
- let i = wikitext.indexOf(onlyincludeLeft), j = wikitext.indexOf(onlyincludeRight, i + length);
25
+ let { i, j } = update();
21
26
  if (i !== -1 && j !== -1) { // `<onlyinclude>`拥有最高优先级
22
27
  let str = '';
28
+ /**
29
+ * 忽略未被`<onlyinclude>`和`</onlyinclude>`包裹的内容
30
+ * @param text 未被包裹的内容
31
+ */
32
+ const noinclude = (text) => {
33
+ new noinclude_1.NoincludeToken(text, config, accum);
34
+ str += `\0${accum.length - 1}c\x7F`;
35
+ };
23
36
  while (i !== -1 && j !== -1) {
24
37
  const token = `\0${accum.length}e\x7F`;
25
38
  new onlyinclude_1.OnlyincludeToken(wikitext.slice(i + length, j), config, accum);
26
39
  if (i > 0) {
27
- new noinclude_1.NoincludeToken(wikitext.slice(0, i), config, accum);
28
- str += `\0${accum.length - 1}c\x7F${token}`;
29
- }
30
- else {
31
- str += token;
40
+ noinclude(wikitext.slice(0, i));
32
41
  }
42
+ str += token;
33
43
  wikitext = wikitext.slice(j + length + 1);
34
- i = wikitext.indexOf(onlyincludeLeft);
35
- j = wikitext.indexOf(onlyincludeRight, i + length);
44
+ ({ i, j } = update());
36
45
  }
37
46
  if (wikitext) {
38
- new noinclude_1.NoincludeToken(wikitext, config, accum);
39
- str += `\0${accum.length - 1}c\x7F`;
47
+ noinclude(wikitext);
40
48
  }
41
49
  return str;
42
50
  }
@@ -22,17 +22,24 @@ const parseList = (wikitext, config = Parser.getConfig(), accum = []) => {
22
22
  return text;
23
23
  }
24
24
  let regex = /:+|-\{/gu, ex = regex.exec(text), lc = 0;
25
+ /**
26
+ * 创建`DdToken`
27
+ * @param syntax `:`
28
+ * @param index 起点
29
+ */
30
+ const dd = (syntax, index) => {
31
+ new dd_1.DdToken(syntax, config, accum);
32
+ return `${text.slice(0, index)}\0${accum.length - 1}d\x7F${text.slice(index + syntax.length)}`;
33
+ };
25
34
  while (ex && dt) {
26
35
  const { 0: syntax, index } = ex;
27
36
  if (syntax.startsWith(':')) {
28
37
  if (syntax.length >= dt) {
29
- new dd_1.DdToken(':'.repeat(dt), config, accum);
30
- return `${text.slice(0, index)}\0${accum.length - 1}d\x7F${text.slice(index + dt)}`;
38
+ return dd(syntax.slice(0, dt), index);
31
39
  }
32
- text = `${text.slice(0, index)}\0${accum.length}d\x7F${text.slice(regex.lastIndex)}`;
33
40
  dt -= syntax.length;
34
41
  regex.lastIndex = index + 4 + String(accum.length).length;
35
- new dd_1.DdToken(syntax, config, accum);
42
+ text = dd(syntax, index);
36
43
  }
37
44
  else if (syntax === '-{') {
38
45
  if (!lc) {
@@ -7,7 +7,10 @@ const index_2 = require("../src/table/index");
7
7
  const tr_1 = require("../src/table/tr");
8
8
  const td_1 = require("../src/table/td");
9
9
  const dd_1 = require("../src/nowiki/dd");
10
- /** @ignore */
10
+ /**
11
+ * 判断是否为表格行或表格
12
+ * @param token 表格节点
13
+ */
11
14
  const isTr = (token) => token.lastChild.constructor !== index_1.Token;
12
15
  /**
13
16
  * 解析表格,注意`tr`和`td`包含开头的换行
@@ -19,30 +22,32 @@ const parseTable = ({ firstChild: { data }, type, name }, config = Parser.getCon
19
22
  const stack = [], lines = data.split('\n');
20
23
  let out = type === 'root' || type === 'parameter-value' || type === 'ext-inner' && name === 'poem'
21
24
  ? ''
22
- : `\n${lines.shift()}`;
25
+ : `\n${lines.shift()}`, top;
23
26
  /**
24
27
  * 向表格中插入纯文本
25
28
  * @param str 待插入的文本
26
- * @param top 当前解析的表格或表格行
29
+ * @param topToken 当前解析的表格或表格行
27
30
  */
28
- const push = (str, top) => {
29
- if (!top) {
31
+ const push = (str, topToken) => {
32
+ if (!topToken) {
30
33
  out += str;
31
34
  return;
32
35
  }
33
- const { lastChild } = top;
34
- if (isTr(top)) {
36
+ const { lastChild } = topToken;
37
+ if (isTr(topToken)) {
35
38
  const token = new index_1.Token(str, config, accum);
36
39
  token.type = 'table-inter';
37
40
  token.setAttribute('stage', 3);
38
- top.insertAt(token);
41
+ topToken.insertAt(token);
39
42
  }
40
43
  else {
41
44
  lastChild.setText(String(lastChild) + str);
42
45
  }
43
- };
46
+ },
47
+ /** 取出最近的表格行 */
48
+ pop = () => top.type === 'td' ? stack.pop() : top;
44
49
  for (const outLine of lines) {
45
- let top = stack.pop();
50
+ top = stack.pop();
46
51
  const [spaces] = /^(?:\s|\0\d+c\x7F)*/u.exec(outLine), line = outLine.slice(spaces.length), matchesStart = /^(:*)((?:\s|\0\d+c\x7F)*)(\{\||\{(?:\0\d+c\x7F)*\0\d+!\x7F|\0\d+\{\x7F)(.*)$/u
47
52
  .exec(line);
48
53
  if (matchesStart) {
@@ -78,9 +83,7 @@ const parseTable = ({ firstChild: { data }, type, name }, config = Parser.getCon
78
83
  push(attr, stack.at(-1));
79
84
  }
80
85
  else if (row) {
81
- if (top.type === 'td') {
82
- top = stack.pop();
83
- }
86
+ top = pop();
84
87
  if (top.type === 'tr') {
85
88
  top = stack.pop();
86
89
  }
@@ -89,20 +92,25 @@ const parseTable = ({ firstChild: { data }, type, name }, config = Parser.getCon
89
92
  top.insertAt(tr);
90
93
  }
91
94
  else {
92
- if (top.type === 'td') {
93
- top = stack.pop();
94
- }
95
+ top = pop();
95
96
  const regex = cell === '!' ? /!!|(?:\||\0\d+!\x7F){2}|\0\d+\+\x7F/gu : /(?:\||\0\d+!\x7F){2}|\0\d+\+\x7F/gu;
96
97
  let mt = regex.exec(attr), lastIndex = 0, lastSyntax = `\n${spaces}${cell}`;
98
+ /**
99
+ * 创建表格单元格
100
+ * @param tr 当前表格行
101
+ */
102
+ const createTd = (tr) => {
103
+ const td = new td_1.TdToken(lastSyntax, attr.slice(lastIndex, mt?.index), config, accum);
104
+ tr.insertAt(td);
105
+ return td;
106
+ };
97
107
  while (mt) {
98
- top.insertAt(new td_1.TdToken(lastSyntax, attr.slice(lastIndex, mt.index), config, accum));
108
+ createTd(top);
99
109
  ({ lastIndex } = regex);
100
110
  [lastSyntax] = mt;
101
111
  mt = regex.exec(attr);
102
112
  }
103
- const td = new td_1.TdToken(lastSyntax, attr.slice(lastIndex), config, accum);
104
- stack.push(top, td);
105
- top.insertAt(td);
113
+ stack.push(top, createTd(top));
106
114
  }
107
115
  }
108
116
  return out.slice(1);
@@ -7,9 +7,15 @@ const Parser = require("../index");
7
7
  const index_1 = require("./index");
8
8
  const atom_1 = require("./atom");
9
9
  const attribute_1 = require("./attribute");
10
- /** @ignore */
10
+ /**
11
+ * 将属性类型转换为单属性类型
12
+ * @param type 属性类型
13
+ */
11
14
  const toAttributeType = (type) => type.slice(0, -1);
12
- /** @ignore */
15
+ /**
16
+ * 将属性类型转换为无效属性类型
17
+ * @param type 属性类型
18
+ */
13
19
  const toDirty = (type) => `${toAttributeType(type)}-dirty`;
14
20
  /**
15
21
  * 扩展和HTML标签属性
@@ -26,7 +32,7 @@ class AttributesToken extends index_1.Token {
26
32
  this.type = type;
27
33
  this.setAttribute('name', name);
28
34
  if (attr) {
29
- const regex = new RegExp(`([^\\s/](?:(?!\0\\d+~\x7F)[^\\s/=])*)` // 属性名
35
+ const regex = new RegExp('([^\\s/](?:(?!\0\\d+~\x7F)[^\\s/=])*)' // 属性名
30
36
  + '(?:'
31
37
  + '((?:\\s|\0\\d+c\x7F)*' // `=`前的空白字符
32
38
  + '(?:=|\0\\d+~\x7F)' // `=`
@@ -6,7 +6,6 @@ const lint_1 = require("../util/lint");
6
6
  const Parser = require("../index");
7
7
  const index_1 = require("./index");
8
8
  exports.galleryParams = new Set(['alt', 'link', 'lang', 'page', 'caption']);
9
- /** @ignore */
10
9
  function validate(key, val, config = Parser.getConfig(), halfParsed = false) {
11
10
  val = val.trim();
12
11
  let value = val.replace(/\0\d+t\x7F/gu, '').trim();
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ImagemapToken = void 0;
4
4
  const lint_1 = require("../util/lint");
5
+ const debug_1 = require("../util/debug");
5
6
  const Parser = require("../index");
6
7
  const index_1 = require("./index");
7
8
  const noinclude_1 = require("./nowiki/noinclude");
@@ -15,7 +16,7 @@ class ImagemapToken extends index_1.Token {
15
16
  type = 'ext-inner';
16
17
  /** 图片 */
17
18
  get image() {
18
- return this.childNodes.find((child) => child.type === 'imagemap-image');
19
+ return this.childNodes.find((0, debug_1.isToken)('imagemap-image'));
19
20
  }
20
21
  /** @param inner 标签内部wikitext */
21
22
  constructor(inner, config = Parser.getConfig(), accum = []) {
@@ -19,7 +19,6 @@ export declare class Token extends AstElement {
19
19
  * @param i 插入位置
20
20
  */
21
21
  insertAt(child: string, i?: number): AstText;
22
- /** @ignore */
23
22
  insertAt<T extends AstNodes>(child: T, i?: number): T;
24
23
  /**
25
24
  * 规范化页面标题
package/dist/src/index.js CHANGED
@@ -71,6 +71,9 @@ class Token extends element_1.AstElement {
71
71
  if (n < this.#stage || !this.getAttribute('plain') || this.length === 0) {
72
72
  return this;
73
73
  }
74
+ else if (this.#stage >= constants_1.MAX_STAGE) {
75
+ return this;
76
+ }
74
77
  switch (n) {
75
78
  case 0:
76
79
  if (this.type === 'root') {
@@ -161,6 +164,7 @@ class Token extends element_1.AstElement {
161
164
  }
162
165
  /** @private */
163
166
  parse(n = constants_1.MAX_STAGE, include = false) {
167
+ n = Math.min(n, constants_1.MAX_STAGE);
164
168
  while (this.#stage < n) {
165
169
  this.parseOnce(this.#stage, include);
166
170
  }
@@ -297,7 +301,6 @@ class Token extends element_1.AstElement {
297
301
  super.setAttribute(key, value);
298
302
  }
299
303
  }
300
- /** @ignore */
301
304
  insertAt(child, i = this.length) {
302
305
  const token = typeof child === 'string' ? new text_1.AstText(child) : child;
303
306
  super.insertAt(token, i);
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TrBaseToken = void 0;
4
4
  const lint_1 = require("../../util/lint");
5
+ const debug_1 = require("../../util/debug");
5
6
  const base_1 = require("./base");
6
7
  /** 表格行或表格 */
7
8
  class TrBaseToken extends base_1.TableBaseToken {
@@ -11,11 +12,7 @@ class TrBaseToken extends base_1.TableBaseToken {
11
12
  if (!inter) {
12
13
  return errors;
13
14
  }
14
- const first = inter.childNodes.find(child => child.text().trim()), tdPattern = /^\s*(?:!|\{\{\s*![!-]?\s*\}\})/u,
15
- /** @ignore */
16
- isArg = (token) => token.type === 'arg',
17
- /** @ignore */
18
- isTransclude = (token) => token.type === 'magic-word';
15
+ const first = inter.childNodes.find(child => child.text().trim()), tdPattern = /^\s*(?:!|\{\{\s*![!-]?\s*\}\})/u, isArg = (0, debug_1.isToken)('arg'), isTransclude = (0, debug_1.isToken)('magic-word');
19
16
  if (!first
20
17
  || tdPattern.test(String(first))
21
18
  || isArg(first) && tdPattern.test(first.default || '')) {
@@ -51,7 +51,6 @@ export declare class TranscludeToken extends Token {
51
51
  getArgs(key: string | number, exact?: boolean, copy?: boolean): Set<ParameterToken>;
52
52
  /**
53
53
  * 获取重名参数
54
- * @throws `Error` 仅用于模板
55
54
  */
56
55
  getDuplicatedArgs(): readonly [string, ParameterToken[]][];
57
56
  /**
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TranscludeToken = void 0;
4
4
  const string_1 = require("../util/string");
5
5
  const lint_1 = require("../util/lint");
6
+ const debug_1 = require("../util/debug");
6
7
  const Parser = require("../index");
7
8
  const index_1 = require("./index");
8
9
  const parameter_1 = require("./parameter");
@@ -216,7 +217,7 @@ class TranscludeToken extends index_1.Token {
216
217
  }
217
218
  /** 获取所有参数 */
218
219
  getAllArgs() {
219
- return this.childNodes.filter((child) => child.type === 'parameter');
220
+ return this.childNodes.filter((0, debug_1.isToken)('parameter'));
220
221
  }
221
222
  /** 获取所有匿名参数 */
222
223
  getAnonArgs() {
@@ -242,7 +243,6 @@ class TranscludeToken extends index_1.Token {
242
243
  }
243
244
  /**
244
245
  * 获取重名参数
245
- * @throws `Error` 仅用于模板
246
246
  */
247
247
  getDuplicatedArgs() {
248
248
  if (this.isTemplate()) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Shadow = void 0;
3
+ exports.setChildNodes = exports.isToken = exports.Shadow = void 0;
4
4
  exports.Shadow = {
5
5
  /** @private */
6
6
  run(callback) {
@@ -8,3 +8,24 @@ exports.Shadow = {
8
8
  return result;
9
9
  },
10
10
  };
11
+ /**
12
+ * 是否是某一特定类型的节点
13
+ * @param type 节点类型
14
+ */
15
+ const isToken = (type) => (node) => node.type === type;
16
+ exports.isToken = isToken;
17
+ /**
18
+ * 更新chldNodes
19
+ * @param parent 父节点
20
+ * @param position 子节点位置
21
+ * @param deleteCount 移除的子节点数量
22
+ * @param inserted 插入的子节点
23
+ */
24
+ const setChildNodes = (parent, position, deleteCount, inserted = []) => {
25
+ const { childNodes } = parent, removed = childNodes.splice(position, deleteCount, ...inserted);
26
+ for (const node of inserted) {
27
+ node.setAttribute('parentNode', parent);
28
+ }
29
+ return removed;
30
+ };
31
+ exports.setChildNodes = setChildNodes;
package/dist/util/lint.js CHANGED
@@ -3,44 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateForSelf = exports.generateForChild = void 0;
4
4
  const Parser = require("../index");
5
5
  /**
6
- * 生成对于子节点的LintError对象
7
- * @param child 子节点
8
- * @param boundingRect 父节点的绝对定位
9
- * @param msg 错误信息
10
- * @param severity 严重程度
6
+ * 生成lint函数
7
+ * @param func lint函数
11
8
  */
12
- const generateForChild = (child, boundingRect, msg, severity = 'error') => {
13
- const index = child.getRelativeIndex(), { offsetHeight, offsetWidth, parentNode } = child, { top: offsetTop, left: offsetLeft } = parentNode.posFromIndex(index), { start } = boundingRect, { top, left } = 'top' in boundingRect ? boundingRect : child.getRootNode().posFromIndex(start), startIndex = start + index, startLine = top + offsetTop, startCol = offsetTop ? offsetLeft : left + offsetLeft;
9
+ const factory = (func) => (token, boundingRect, msg, severity = 'error') => {
10
+ const { start } = boundingRect, { top, left } = 'top' in boundingRect ? boundingRect : token.getRootNode().posFromIndex(start), { offsetHeight, offsetWidth } = token, { startIndex, startLine, startCol } = func(token, start, top, left);
14
11
  return {
15
12
  message: Parser.msg(msg),
16
13
  severity,
17
14
  startIndex,
18
- endIndex: startIndex + String(child).length,
15
+ endIndex: startIndex + String(token).length,
19
16
  startLine,
20
17
  endLine: startLine + offsetHeight - 1,
21
18
  startCol,
22
19
  endCol: offsetHeight === 1 ? startCol + offsetWidth : offsetWidth,
23
20
  };
24
21
  };
25
- exports.generateForChild = generateForChild;
26
- /**
27
- * 生成对于自己的LintError对象
28
- * @param token 节点
29
- * @param boundingRect 绝对定位
30
- * @param msg 错误信息
31
- * @param severity 严重程度
32
- */
33
- const generateForSelf = (token, boundingRect, msg, severity = 'error') => {
34
- const { start } = boundingRect, { offsetHeight, offsetWidth } = token, { top, left } = 'top' in boundingRect ? boundingRect : token.getRootNode().posFromIndex(start);
22
+ exports.generateForChild = factory((child, start, line, col) => {
23
+ const index = child.getRelativeIndex(), { top, left } = child.parentNode.posFromIndex(index);
35
24
  return {
36
- message: Parser.msg(msg),
37
- severity,
38
- startIndex: start,
39
- endIndex: start + String(token).length,
40
- startLine: top,
41
- endLine: top + offsetHeight - 1,
42
- startCol: left,
43
- endCol: offsetHeight === 1 ? left + offsetWidth : offsetWidth,
25
+ startIndex: start + index,
26
+ startLine: line + top,
27
+ startCol: top ? left : col + left,
44
28
  };
45
- };
46
- exports.generateForSelf = generateForSelf;
29
+ });
30
+ exports.generateForSelf = factory((_, startIndex, startLine, startCol) => ({ startIndex, startLine, startCol }));
@@ -4,17 +4,15 @@ exports.noWrap = exports.decodeHtml = exports.text = exports.escapeRegExp = expo
4
4
  exports.extUrlCharFirst = '(?:\\[[\\da-f:.]+\\]|[^[\\]<>"\\0-\\x1F\\x7F\\p{Zs}\\uFFFD])';
5
5
  exports.extUrlChar = '(?:[^[\\]<>"\\0-\\x1F\\x7F\\p{Zs}\\uFFFD]|\\0\\d+[c!~]\\x7F)*';
6
6
  /**
7
- * remove half-parsed comment-like tokens
8
- * @param str 原字符串
7
+ * 生成正则替换函数
8
+ * @param regex 正则表达式
9
+ * @param replace 替换字符串或函数
9
10
  */
10
- const removeComment = (str) => str.replace(/\0\d+c\x7F/gu, '');
11
- exports.removeComment = removeComment;
12
- /**
13
- * escape special chars for RegExp constructor
14
- * @param str RegExp source
15
- */
16
- const escapeRegExp = (str) => str.replace(/[\\{}()|.?*+^$[\]]/gu, '\\$&');
17
- exports.escapeRegExp = escapeRegExp;
11
+ const factory = (regex, replace) => (str) => str.replace(regex, replace);
12
+ /** remove half-parsed comment-like tokens */
13
+ exports.removeComment = factory(/\0\d+c\x7F/gu, '');
14
+ /** escape special chars for RegExp constructor */
15
+ exports.escapeRegExp = factory(/[\\{}()|.?*+^$[\]]/gu, '\\$&');
18
16
  /**
19
17
  * extract effective wikitext
20
18
  * @param childNodes a Token's contents
@@ -22,15 +20,7 @@ exports.escapeRegExp = escapeRegExp;
22
20
  */
23
21
  const text = (childNodes, separator = '') => childNodes.map(child => typeof child === 'string' ? child : child.text()).join(separator);
24
22
  exports.text = text;
25
- /**
26
- * decode HTML entities
27
- * @param str 原字符串
28
- */
29
- const decodeHtml = (str) => str.replace(/&#(\d+|x[\da-f]+);/giu, (_, code) => String.fromCodePoint(Number(`${code.toLowerCase().startsWith('x') ? '0' : ''}${code}`)));
30
- exports.decodeHtml = decodeHtml;
31
- /**
32
- * escape newlines
33
- * @param str 原字符串
34
- */
35
- const noWrap = (str) => str.replaceAll('\n', '\\n');
36
- exports.noWrap = noWrap;
23
+ /** decode HTML entities */
24
+ exports.decodeHtml = factory(/&#(\d+|x[\da-f]+);/giu, (_, code) => String.fromCodePoint(Number(`${code.toLowerCase().startsWith('x') ? '0' : ''}${code}`)));
25
+ /** escape newlines */
26
+ exports.noWrap = factory(/\n/gu, '\\n');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikilint",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
4
4
  "description": "A Node.js linter for MediaWiki markup",
5
5
  "keywords": [
6
6
  "mediawiki",