wikilint 2.8.0 → 2.9.1

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.
Files changed (113) hide show
  1. package/dist/base.d.ts +4 -2
  2. package/dist/base.js +1 -0
  3. package/dist/index.d.ts +3 -7
  4. package/dist/index.js +8 -2
  5. package/dist/lib/element.d.ts +0 -13
  6. package/dist/lib/element.js +4 -11
  7. package/dist/lib/node.d.ts +1 -1
  8. package/dist/lib/node.js +1 -1
  9. package/dist/lib/rect.d.ts +18 -0
  10. package/dist/lib/rect.js +32 -0
  11. package/dist/lib/text.d.ts +0 -6
  12. package/dist/lib/text.js +6 -17
  13. package/dist/mixin/attributesParent.js +2 -1
  14. package/dist/mixin/hidden.d.ts +2 -0
  15. package/dist/mixin/hidden.js +9 -4
  16. package/dist/parser/braces.js +16 -4
  17. package/dist/parser/commentAndExt.js +1 -8
  18. package/dist/parser/converter.js +2 -3
  19. package/dist/parser/externalLinks.js +2 -9
  20. package/dist/parser/hrAndDoubleUnderscore.js +1 -1
  21. package/dist/parser/html.js +1 -1
  22. package/dist/parser/links.js +1 -1
  23. package/dist/parser/magicLinks.js +28 -17
  24. package/dist/parser/redirect.js +1 -1
  25. package/dist/parser/table.js +1 -1
  26. package/dist/src/arg.d.ts +0 -4
  27. package/dist/src/arg.js +6 -5
  28. package/dist/src/atom.d.ts +2 -2
  29. package/dist/src/atom.js +3 -4
  30. package/dist/src/attribute.d.ts +0 -4
  31. package/dist/src/attribute.js +6 -18
  32. package/dist/src/attributes.d.ts +0 -2
  33. package/dist/src/attributes.js +5 -10
  34. package/dist/src/converter.d.ts +0 -2
  35. package/dist/src/converter.js +2 -2
  36. package/dist/src/converterFlags.d.ts +0 -4
  37. package/dist/src/converterFlags.js +4 -3
  38. package/dist/src/converterRule.d.ts +0 -2
  39. package/dist/src/converterRule.js +2 -2
  40. package/dist/src/extLink.d.ts +0 -4
  41. package/dist/src/extLink.js +3 -3
  42. package/dist/src/gallery.d.ts +0 -4
  43. package/dist/src/gallery.js +3 -3
  44. package/dist/src/heading.d.ts +0 -4
  45. package/dist/src/heading.js +5 -10
  46. package/dist/src/hidden.d.ts +1 -1
  47. package/dist/src/hidden.js +53 -3
  48. package/dist/src/html.d.ts +2 -7
  49. package/dist/src/html.js +16 -36
  50. package/dist/src/imageParameter.d.ts +0 -4
  51. package/dist/src/imageParameter.js +5 -5
  52. package/dist/src/imagemap.d.ts +0 -4
  53. package/dist/src/imagemap.js +6 -5
  54. package/dist/src/index.d.ts +0 -11
  55. package/dist/src/index.js +34 -32
  56. package/dist/src/link/base.d.ts +0 -4
  57. package/dist/src/link/base.js +4 -8
  58. package/dist/src/link/file.d.ts +0 -2
  59. package/dist/src/link/file.js +7 -7
  60. package/dist/src/link/galleryImage.d.ts +0 -2
  61. package/dist/src/link/galleryImage.js +2 -3
  62. package/dist/src/link/index.d.ts +0 -2
  63. package/dist/src/link/index.js +1 -1
  64. package/dist/src/link/redirectTarget.d.ts +0 -4
  65. package/dist/src/link/redirectTarget.js +4 -4
  66. package/dist/src/magicLink.d.ts +7 -5
  67. package/dist/src/magicLink.js +37 -7
  68. package/dist/src/nested.d.ts +0 -2
  69. package/dist/src/nested.js +5 -5
  70. package/dist/src/nowiki/base.d.ts +2 -2
  71. package/dist/src/nowiki/base.js +3 -4
  72. package/dist/src/nowiki/comment.d.ts +3 -6
  73. package/dist/src/nowiki/comment.js +78 -28
  74. package/dist/src/nowiki/doubleUnderscore.d.ts +3 -3
  75. package/dist/src/nowiki/doubleUnderscore.js +68 -19
  76. package/dist/src/nowiki/index.d.ts +0 -2
  77. package/dist/src/nowiki/index.js +2 -2
  78. package/dist/src/nowiki/noinclude.d.ts +1 -1
  79. package/dist/src/nowiki/noinclude.js +53 -3
  80. package/dist/src/nowiki/quote.d.ts +0 -2
  81. package/dist/src/nowiki/quote.js +19 -25
  82. package/dist/src/paramTag/index.d.ts +0 -4
  83. package/dist/src/paramTag/index.js +5 -5
  84. package/dist/src/parameter.d.ts +0 -2
  85. package/dist/src/parameter.js +4 -3
  86. package/dist/src/pre.d.ts +0 -2
  87. package/dist/src/pre.js +1 -1
  88. package/dist/src/redirect.d.ts +4 -5
  89. package/dist/src/redirect.js +83 -33
  90. package/dist/src/syntax.d.ts +2 -4
  91. package/dist/src/syntax.js +4 -5
  92. package/dist/src/table/index.d.ts +2 -5
  93. package/dist/src/table/index.js +7 -6
  94. package/dist/src/table/td.d.ts +0 -4
  95. package/dist/src/table/td.js +13 -7
  96. package/dist/src/table/tr.d.ts +2 -2
  97. package/dist/src/table/tr.js +1 -2
  98. package/dist/src/table/trBase.d.ts +0 -2
  99. package/dist/src/table/trBase.js +2 -2
  100. package/dist/src/tagPair/ext.d.ts +0 -2
  101. package/dist/src/tagPair/ext.js +6 -8
  102. package/dist/src/tagPair/include.d.ts +6 -6
  103. package/dist/src/tagPair/include.js +76 -26
  104. package/dist/src/tagPair/index.d.ts +2 -4
  105. package/dist/src/tagPair/index.js +6 -7
  106. package/dist/src/transclude.d.ts +0 -4
  107. package/dist/src/transclude.js +10 -14
  108. package/dist/util/debug.js +10 -1
  109. package/dist/util/lint.js +4 -3
  110. package/dist/util/string.js +5 -5
  111. package/i18n/zh-hans.json +1 -0
  112. package/i18n/zh-hant.json +1 -0
  113. package/package.json +12 -12
package/dist/base.d.ts CHANGED
@@ -11,8 +11,8 @@ export interface Config {
11
11
  readonly variants: string[];
12
12
  readonly excludes?: string[];
13
13
  }
14
- export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'list' | 'dd' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
15
- export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext"];
14
+ export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
15
+ export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext"];
16
16
  export declare namespace LintError {
17
17
  type Severity = 'error' | 'warning';
18
18
  type Rule = typeof rules[number];
@@ -49,6 +49,8 @@ interface AstElement extends AstNode {
49
49
  export interface Parser {
50
50
  config: Config | string;
51
51
  i18n: Record<string, string> | string | undefined;
52
+ /** 获取当前的解析设置 */
53
+ getConfig(): Config;
52
54
  /**
53
55
  * 解析wikitext
54
56
  * @param include 是否嵌入
package/dist/base.js CHANGED
@@ -11,6 +11,7 @@ exports.rules = [
11
11
  'invalid-gallery',
12
12
  'invalid-imagemap',
13
13
  'invalid-invoke',
14
+ 'invalid-isbn',
14
15
  'lonely-apos',
15
16
  'lonely-bracket',
16
17
  'lonely-http',
package/dist/index.d.ts CHANGED
@@ -8,18 +8,14 @@ declare interface Parser extends ParserBase {
8
8
  * @param title 标题(含或不含命名空间前缀)
9
9
  * @param defaultNs 命名空间
10
10
  * @param include 是否嵌入
11
- * @param halfParsed 是否是半解析状态
12
- * @param decode 是否需要解码
13
- * @param selfLink 是否允许selfLink
14
11
  */
15
- normalizeTitle(title: string, defaultNs?: number, include?: boolean, config?: Config, halfParsed?: boolean, decode?: boolean, selfLink?: boolean): Title;
12
+ normalizeTitle(title: string, defaultNs?: number, include?: boolean, config?: Config): Title;
16
13
  parse(wikitext: string, include?: boolean, maxStage?: number, config?: Config): Token;
17
14
  }
18
15
  declare const Parser: Parser;
19
16
  // @ts-expect-error mixed export styles
20
17
  export = Parser;
18
+ export default Parser;
21
19
  export type { Config, LintError };
22
20
  export type * from './internal';
23
- declare global {
24
- type Acceptable = unknown;
25
- }
21
+ declare global { type Acceptable = unknown; }
package/dist/index.js CHANGED
@@ -43,7 +43,11 @@ const Parser = {
43
43
  return new Title(title, defaultNs, config, decode, selfLink);
44
44
  }
45
45
  const { Token } = require('./src/index');
46
- const token = debug_1.Shadow.run(() => new Token(title, config).parseOnce(0, include).parseOnce()), titleObj = new Title(String(token), defaultNs, config, decode, selfLink);
46
+ const token = debug_1.Shadow.run(() => {
47
+ const root = new Token(title, config);
48
+ root.type = 'root';
49
+ return root.parseOnce(0, include).parseOnce();
50
+ }), titleObj = new Title(token.toString(), defaultNs, config, decode, selfLink);
47
51
  debug_1.Shadow.run(() => {
48
52
  for (const key of ['main', 'fragment']) {
49
53
  const str = titleObj[key];
@@ -60,13 +64,14 @@ const Parser = {
60
64
  const { Token } = require('./src/index');
61
65
  const root = debug_1.Shadow.run(() => {
62
66
  const token = new Token(wikitext, config);
67
+ token.type = 'root';
63
68
  try {
64
69
  return token.parse(maxStage, include);
65
70
  }
66
71
  catch (e) {
67
72
  if (e instanceof Error) {
68
73
  const file = path.join(__dirname, '..', 'errors', new Date().toISOString()), stage = token.getAttribute('stage');
69
- fs.writeFileSync(file, stage === constants_1.MAX_STAGE ? wikitext : String(token));
74
+ fs.writeFileSync(file, stage === constants_1.MAX_STAGE ? wikitext : token.toString());
70
75
  fs.writeFileSync(`${file}.err`, e.stack);
71
76
  fs.writeFileSync(`${file}.json`, JSON.stringify({ stage, include, config }, null, '\t'));
72
77
  }
@@ -88,4 +93,5 @@ for (const key in Parser) {
88
93
  }
89
94
  }
90
95
  Object.defineProperties(Parser, def);
96
+ exports.default = Parser;
91
97
  module.exports = Parser;
@@ -8,13 +8,6 @@ export declare abstract class AstElement extends AstNode {
8
8
  readonly data: undefined;
9
9
  /** 子节点总数 */
10
10
  get length(): number;
11
- /**
12
- * 可见部分
13
- * @param separator 子节点间的连接符
14
- */
15
- text(separator?: string): string;
16
- /** 合并相邻的文本子节点 */
17
- normalize(): void;
18
11
  /**
19
12
  * 移除子节点
20
13
  * @param i 移除位置
@@ -57,10 +50,4 @@ export declare abstract class AstElement extends AstNode {
57
50
  * @param i 子节点位置
58
51
  */
59
52
  setText(str: string, i?: number): string;
60
- /**
61
- * @override
62
- * @param start
63
- * @param re 用于`AstText`后代节点的正则表达式
64
- */
65
- lint(start?: number, re?: RegExp): LintError[];
66
53
  }
@@ -10,14 +10,11 @@ class AstElement extends node_1.AstNode {
10
10
  get length() {
11
11
  return this.childNodes.length;
12
12
  }
13
- /**
14
- * 可见部分
15
- * @param separator 子节点间的连接符
16
- */
13
+ /** @private */
17
14
  text(separator) {
18
15
  return (0, string_1.text)(this.childNodes, separator);
19
16
  }
20
- /** 合并相邻的文本子节点 */
17
+ /** @private */
21
18
  normalize() {
22
19
  const childNodes = [...this.childNodes];
23
20
  /**
@@ -164,17 +161,13 @@ class AstElement extends node_1.AstNode {
164
161
  toString(separator = '') {
165
162
  return this.childNodes.map(String).join(separator);
166
163
  }
167
- /**
168
- * @override
169
- * @param start
170
- * @param re 用于`AstText`后代节点的正则表达式
171
- */
164
+ /** @private */
172
165
  lint(start = this.getAbsoluteIndex(), re) {
173
166
  const errors = [];
174
167
  for (let i = 0, cur = start + this.getAttribute('padding'); i < this.length; i++) {
175
168
  const child = this.childNodes[i];
176
169
  errors.push(...child.lint(cur, re));
177
- cur += String(child).length + this.getGaps(i);
170
+ cur += child.toString().length + this.getGaps(i);
178
171
  }
179
172
  return errors;
180
173
  }
@@ -19,7 +19,7 @@ export declare abstract class AstNode implements AstNodeBase {
19
19
  type: TokenTypes | 'text';
20
20
  data?: string | undefined;
21
21
  readonly childNodes: readonly AstNodes[];
22
- abstract lint(): LintError[];
22
+ lint(): LintError[];
23
23
  /** 首位子节点 */
24
24
  get firstChild(): AstNodes | undefined;
25
25
  /** 末位子节点 */
package/dist/lib/node.js CHANGED
@@ -14,7 +14,7 @@ const getDimension = (str) => {
14
14
  * @param j 子节点序号
15
15
  * @param parent 父节点
16
16
  */
17
- const getIndex = (j, parent) => parent.childNodes.slice(0, j).reduce((acc, cur, i) => acc + String(cur).length + parent.getGaps(i), 0)
17
+ const getIndex = (j, parent) => parent.childNodes.slice(0, j).reduce((acc, cur, i) => acc + cur.toString().length + parent.getGaps(i), 0)
18
18
  + parent.getAttribute('padding');
19
19
  /** 类似Node */
20
20
  class AstNode {
@@ -0,0 +1,18 @@
1
+ import type { AstNodes, Position } from './node';
2
+ /** 节点位置 */
3
+ export declare class BoundingRect {
4
+ #private;
5
+ readonly token: AstNodes;
6
+ readonly start: number;
7
+ /** 起点行 */
8
+ get top(): number;
9
+ /** 起点列 */
10
+ get left(): number;
11
+ /**
12
+ * @param token 节点
13
+ * @param start 起点
14
+ */
15
+ constructor(token: AstNodes, start: number);
16
+ /** 计算位置 */
17
+ getPosition(): Position;
18
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BoundingRect = void 0;
4
+ /** 节点位置 */
5
+ class BoundingRect {
6
+ #pos;
7
+ token;
8
+ start;
9
+ /** 起点行 */
10
+ get top() {
11
+ this.#pos ??= this.getPosition();
12
+ return this.#pos.top;
13
+ }
14
+ /** 起点列 */
15
+ get left() {
16
+ this.#pos ??= this.getPosition();
17
+ return this.#pos.left;
18
+ }
19
+ /**
20
+ * @param token 节点
21
+ * @param start 起点
22
+ */
23
+ constructor(token, start) {
24
+ this.token = token;
25
+ this.start = start;
26
+ }
27
+ /** 计算位置 */
28
+ getPosition() {
29
+ return this.token.getRootNode().posFromIndex(this.start);
30
+ }
31
+ }
32
+ exports.BoundingRect = BoundingRect;
@@ -10,12 +10,6 @@ export declare class AstText extends AstNode {
10
10
  constructor(text: string);
11
11
  /** 可见部分 */
12
12
  text(): string;
13
- /**
14
- * @override
15
- * @param start
16
- * @throws `Error` 孤立文本节点
17
- */
18
- lint(start?: number, errorRegex?: RegExp): LintError[];
19
13
  /**
20
14
  * 替换字符串
21
15
  * @param text 替换的字符串
package/dist/lib/text.js CHANGED
@@ -4,14 +4,7 @@ exports.AstText = void 0;
4
4
  const string_1 = require("../util/string");
5
5
  const index_1 = require("../index");
6
6
  const node_1 = require("./node");
7
- const source = '<\\s*(?:\\/\\s*)?([a-z]\\w*)' // 疑似标签
8
- + '|'
9
- + '\\{+|\\}+' // `{`、`}`
10
- + '|'
11
- + '\\[{2,}|\\[(?![^[]*?\\])' // `[`
12
- + '|'
13
- + '((?:^|\\])[^[]*?)\\]+', // `]`
14
- errorSyntax = new RegExp(`${source}|https?[:/]\\/+`, 'giu'), errorSyntaxUrl = new RegExp(source, 'giu'), extImage = new RegExp(`^https?:\\/\\/${string_1.extUrlCharFirst}${string_1.extUrlChar}\\.(?:gif|png|jpg|jpeg)$`, 'iu'), regexes = {
7
+ const source = String.raw `<\s*(?:/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])|((?:^|\])[^[]*?)\]+`, errorSyntax = new RegExp(String.raw `${source}|https?[:/]/+`, 'giu'), errorSyntaxUrl = new RegExp(source, 'giu'), extImage = new RegExp(String.raw `^https?://${string_1.extUrlCharFirst}${string_1.extUrlChar}\.(?:gif|png|jpg|jpeg)$`, 'iu'), regexes = {
15
8
  '[': /[[\]]/u,
16
9
  '{': /[{}]/u,
17
10
  ']': /[[\]](?=[^[\]]*$)/u,
@@ -73,15 +66,11 @@ class AstText extends node_1.AstNode {
73
66
  text() {
74
67
  return this.data;
75
68
  }
76
- /**
77
- * @override
78
- * @param start
79
- * @throws `Error` 孤立文本节点
80
- */
69
+ /** @private */
81
70
  lint(start = this.getAbsoluteIndex(), errorRegex) {
82
71
  const { data, parentNode, nextSibling, previousSibling } = this;
83
72
  if (!parentNode) {
84
- throw new Error('无法对孤立文本节点进行语法分析!');
73
+ throw new Error('An isolated text node cannot be linted!');
85
74
  }
86
75
  const { type, name, parentNode: grandparent } = parentNode;
87
76
  let isHtmlAttrVal = false;
@@ -129,7 +118,7 @@ class AstText extends node_1.AstNode {
129
118
  else if (char === 'h' && index === 0 && type === 'ext-link-text' && extImage.test(data)) {
130
119
  continue;
131
120
  }
132
- const startIndex = start + index, endIndex = startIndex + length, rootStr = String(root), nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], severity = length > 1 && !(char === '<' && !/[\s/>]/u.test(nextChar ?? '')
121
+ const startIndex = start + index, endIndex = startIndex + length, rootStr = root.toString(), nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], severity = length > 1 && !(char === '<' && !/[\s/>]/u.test(nextChar ?? '')
133
122
  || isHtmlAttrVal && (char === '[' || char === ']'))
134
123
  || char === '{' && (nextChar === char || previousChar === '-')
135
124
  || char === '}' && (previousChar === char || nextChar === '-')
@@ -190,7 +179,7 @@ class AstText extends node_1.AstNode {
190
179
  ];
191
180
  }
192
181
  else if (char === '[' && type === 'ext-link-text') {
193
- const i = parentNode.getAbsoluteIndex() + String(parentNode).length;
182
+ const i = parentNode.getAbsoluteIndex() + parentNode.toString().length;
194
183
  e.suggestions = [
195
184
  {
196
185
  desc: 'escape',
@@ -200,7 +189,7 @@ class AstText extends node_1.AstNode {
200
189
  ];
201
190
  }
202
191
  else if (char === ']' && previousType === 'free-ext-link' && severity === 'error') {
203
- const i = start - String(previousSibling).length;
192
+ const i = start - previousSibling.toString().length;
204
193
  e.fix = {
205
194
  range: [i, i],
206
195
  text: '[',
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.attributesParent = void 0;
4
+ const debug_1 = require("../util/debug");
4
5
  /**
5
6
  * 子节点含有AttributesToken的类
6
7
  * @param i AttributesToken子节点的位置
@@ -19,7 +20,7 @@ const attributesParent = (i = 0) => (constructor, _) => {
19
20
  return this.#attributesChild.getAttr(key);
20
21
  }
21
22
  }
22
- Object.defineProperty(AttributesParent, 'name', { value: constructor.name });
23
+ (0, debug_1.mixin)(AttributesParent, constructor);
23
24
  return AttributesParent;
24
25
  };
25
26
  exports.attributesParent = attributesParent;
@@ -1,4 +1,6 @@
1
1
  /**
2
2
  * 解析后不可见的类
3
+ * @param linter 是否覆写 lint 方法
3
4
  * @param constructor 基类
5
+ * @param _ context
4
6
  */
@@ -1,22 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hiddenToken = void 0;
4
+ const debug_1 = require("../util/debug");
4
5
  /**
5
6
  * 解析后不可见的类
7
+ * @param linter 是否覆写 lint 方法
6
8
  * @param constructor 基类
9
+ * @param _ context
7
10
  */
8
- const hiddenToken = (constructor) => {
11
+ const hiddenToken = (linter) => (constructor, _) => {
9
12
  /** 解析后不可见的类 */
10
13
  class AnyHiddenToken extends constructor {
11
14
  /** 没有可见部分 */
12
15
  text() {
13
16
  return '';
14
17
  }
15
- /** @override */
16
- lint() {
17
- return [];
18
+ /** @private */
19
+ lint(start) {
20
+ // @ts-expect-error private argument
21
+ return linter ? [] : super.lint(start);
18
22
  }
19
23
  }
24
+ (0, debug_1.mixin)(AnyHiddenToken, constructor);
20
25
  return AnyHiddenToken;
21
26
  };
22
27
  exports.hiddenToken = hiddenToken;
@@ -5,6 +5,12 @@ const string_1 = require("../util/string");
5
5
  const heading_1 = require("../src/heading");
6
6
  const transclude_1 = require("../src/transclude");
7
7
  const arg_1 = require("../src/arg");
8
+ const closes = {
9
+ '=': '\n',
10
+ '{': String.raw `\}{2,}|\|`,
11
+ '-': String.raw `\}-`,
12
+ '[': String.raw `\]\]`,
13
+ }, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~']]), re = new RegExp(String.raw `\{\{\s*(${[...marks.keys()].map(string_1.escapeRegExp).join('|')})\s*\}\}(?!\})`, 'gu');
8
14
  /**
9
15
  * 解析花括号
10
16
  * @param wikitext
@@ -13,8 +19,14 @@ const arg_1 = require("../src/arg");
13
19
  * @throws TranscludeToken.constructor()
14
20
  */
15
21
  const parseBraces = (wikitext, config, accum) => {
16
- const source = `${config.excludes?.includes('heading') ? '' : '^(\0\\d+c\x7F)*={1,6}|'}\\[\\[|\\{{2,}|-\\{(?!\\{)`, { parserFunction: [, , , subst] } = config, stack = [], closes = { '=': '\n', '{': '\\}{2,}|\\|', '-': '\\}-', '[': '\\]\\]' }, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~']]);
17
- let regex = new RegExp(source, 'gmu'), mt = regex.exec(wikitext), moreBraces = wikitext.includes('}}'), lastIndex;
22
+ const source = String.raw `${config.excludes?.includes('heading') ? '' : String.raw `^(\0\d+c\x7F)*={1,6}|`}\[\[|\{{2,}|-\{(?!\{)`, { parserFunction: [, , , subst] } = config, stack = [];
23
+ wikitext = wikitext.replace(re, (m, p1) => {
24
+ // @ts-expect-error abstract class
25
+ new transclude_1.TranscludeToken(m.slice(2, -2), [], config, accum);
26
+ return `\0${accum.length - 2}${marks.get(p1)}\x7F`;
27
+ });
28
+ const lastBraces = wikitext.lastIndexOf('}}') - wikitext.length;
29
+ let regex = new RegExp(source, 'gmu'), mt = regex.exec(wikitext), moreBraces = lastBraces + wikitext.length !== -1, lastIndex;
18
30
  while (mt
19
31
  || lastIndex !== undefined && lastIndex <= wikitext.length && stack[stack.length - 1]?.[0]?.startsWith('=')) {
20
32
  if (mt?.[1]) {
@@ -86,7 +98,7 @@ const parseBraces = (wikitext, config, accum) => {
86
98
  }
87
99
  }
88
100
  catch (e) {
89
- if (e instanceof SyntaxError && e.message === '非法的模板名称') {
101
+ if (e instanceof SyntaxError && e.message === 'Invalid template name') {
90
102
  skip = true;
91
103
  }
92
104
  else {
@@ -113,7 +125,7 @@ const parseBraces = (wikitext, config, accum) => {
113
125
  }
114
126
  stack.push(...'0' in top ? [top] : [], mt);
115
127
  }
116
- moreBraces &&= wikitext.slice(lastIndex).includes('}}');
128
+ moreBraces &&= lastBraces + wikitext.length >= lastIndex;
117
129
  let curTop = stack[stack.length - 1];
118
130
  if (!moreBraces && curTop?.[0]?.startsWith('{')) {
119
131
  stack.pop();
@@ -49,14 +49,7 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
49
49
  return str;
50
50
  }
51
51
  }
52
- const ext = config.ext.join('|'), noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly', regex = new RegExp('<!--.*?(?:-->|$)' // comment
53
- + '|'
54
- + `<${noincludeRegex}(?:\\s[^>]*)?/?>|</${noincludeRegex}\\s*>` // <noinclude>
55
- + '|'
56
- + `<(${ext})(\\s[^>]*?)?(?:/>|>(.*?)</(\\1\\s*)>)` // 扩展标签
57
- + '|'
58
- + `<(${includeRegex})(\\s[^>]*?)?(?:/>|>(.*?)(?:</(${includeRegex}\\s*)>|$))`, // <includeonly>
59
- 'gisu');
52
+ const ext = config.ext.join('|'), noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly', regex = new RegExp(String.raw `<!--.*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext})(\s[^>]*?)?(?:/>|>(.*?)</(\1\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>(.*?)(?:</(${includeRegex}\s*)>|$))`, 'gisu');
60
53
  return wikitext.replace(regex, (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
61
54
  const str = `\0${accum.length}${name ? 'e' : 'c'}\x7F`;
62
55
  if (name) {
@@ -9,13 +9,12 @@ const converter_1 = require("../src/converter");
9
9
  * @param accum
10
10
  */
11
11
  const parseConverter = (text, config, accum) => {
12
- const regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, stack = [];
12
+ const variants = `(?:${config.variants.join('|')})`, regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, regex3 = new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*${variants}\s*:|(?:\s|\0\d+c\x7F)*$)`, 'u'), stack = [];
13
13
  let regex = regex1, mt = regex.exec(text);
14
14
  while (mt) {
15
15
  const { 0: syntax, index } = mt;
16
16
  if (syntax === '}-') {
17
- const top = stack.pop(), { length } = accum, str = text.slice(top.index + 2, index), i = str.indexOf('|'), [flags, raw] = i === -1 ? [[], str] : [str.slice(0, i).split(';'), str.slice(i + 1)], temp = raw.replace(/(&[#a-z\d]+);/giu, '$1\x01'), variants = `(?:${config.variants.join('|')})`, rules = temp.split(new RegExp(`;(?=(?:[^;]*?=>)?\\s*${variants}\\s*:|(?:\\s|\0\\d+c\x7F)*$)`, 'u'))
18
- .map(rule => rule.replace(/\x01/gu, ';'));
17
+ const top = stack.pop(), { length } = accum, str = text.slice(top.index + 2, index), i = str.indexOf('|'), [flags, raw] = i === -1 ? [[], str] : [str.slice(0, i).split(';'), str.slice(i + 1)], temp = raw.replace(/(&[#a-z\d]+);/giu, '$1\x01'), rules = temp.split(regex3).map(rule => rule.replace(/\x01/gu, ';'));
19
18
  // @ts-expect-error abstract class
20
19
  new converter_1.ConverterToken(flags, rules, config, accum);
21
20
  text = `${text.slice(0, top.index)}\0${length}v\x7F${text.slice(index + 2)}`;
@@ -12,14 +12,7 @@ const magicLink_1 = require("../src/magicLink");
12
12
  * @param inFile 是否在图链中
13
13
  */
14
14
  const parseExternalLinks = (wikitext, config, accum, inFile) => {
15
- const regex = new RegExp('\\[' // 左括号
16
- + `(${'\0\\d+f\x7F' // 预先解析的MagicLinkToken
17
- + '|'
18
- + `(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\\d+m\x7F)${string_1.extUrlChar}(?=[[\\]<>"\\t\\p{Zs}]|\0\\d)`})` // 链接网址
19
- + '(\\p{Zs}*(?=\\P{Zs}))' // 空格
20
- + '([^\\]\x01-\x08\x0A-\x1F\uFFFD]*)' // 链接文字
21
- + '\\]', // 右括号
22
- 'giu');
15
+ const regex = new RegExp(String.raw `\[(\0\d+f\x7F|(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\d+m\x7F)${string_1.extUrlChar}(?=[[\]<>"\t\p{Zs}]|\0\d))(\p{Zs}*(?!\p{Zs}))([^\]\x01-\x08\x0A-\x1F\uFFFD]*)\]`, 'giu');
23
16
  return wikitext.replace(regex, (_, url, space, text) => {
24
17
  const { length } = accum, mt = /&[lg]t;/u.exec(url);
25
18
  if (mt) {
@@ -29,7 +22,7 @@ const parseExternalLinks = (wikitext, config, accum, inFile) => {
29
22
  }
30
23
  if (inFile) {
31
24
  // @ts-expect-error abstract class
32
- new magicLink_1.MagicLinkToken(url, true, config, accum);
25
+ new magicLink_1.MagicLinkToken(url, 'ext-link-url', config, accum);
33
26
  return `[\0${length}f\x7F${space}${text}]`;
34
27
  }
35
28
  // @ts-expect-error abstract class
@@ -19,7 +19,7 @@ const parseHrAndDoubleUnderscore = ({ firstChild: { data }, type, name }, config
19
19
  // @ts-expect-error abstract class
20
20
  new hr_1.HrToken(m, config, accum);
21
21
  return `${lead}\0${accum.length - 1}r\x7F`;
22
- }).replace(new RegExp(`__(${doubleUnderscore.flat().join('|')})__`, 'giu'), (m, p1) => {
22
+ }).replace(new RegExp(`__(${[...doubleUnderscore[0], ...doubleUnderscore[1]].join('|')})__`, 'giu'), (m, p1) => {
23
23
  const caseSensitive = sensitive.has(p1);
24
24
  if (caseSensitive || insensitive.has(p1.toLowerCase())) {
25
25
  // @ts-expect-error abstract class
@@ -10,7 +10,7 @@ const html_1 = require("../src/html");
10
10
  * @param accum
11
11
  */
12
12
  const parseHtml = (wikitext, config, accum) => {
13
- const regex = /^(\/?)([a-z][^\s/>]*)((?:\s|\/(?!>))[^>]*?)?(\/?>)([^<]*)$/iu, elements = new Set(config.html.flat()), bits = wikitext.split('<');
13
+ const regex = /^(\/?)([a-z][^\s/>]*)((?:\s|\/(?!>))[^>]*?)?(\/?>)([^<]*)$/iu, { html } = config, elements = new Set([...html[0], ...html[1], ...html[2]]), bits = wikitext.split('<');
14
14
  let text = bits.shift();
15
15
  for (const x of bits) {
16
16
  const mt = regex.exec(x), t = mt?.[2], name = t?.toLowerCase();
@@ -16,7 +16,7 @@ const category_1 = require("../src/link/category");
16
16
  const parseLinks = (wikitext, config, accum) => {
17
17
  const regex = true // eslint-disable-line no-constant-condition, @typescript-eslint/no-unnecessary-condition
18
18
  ? /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]]))?\]\](.*)$/su
19
- : /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]])?)?\]\](.*)$/su, regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(.*)$/su, regexExt = new RegExp(`^\\s*(?:${config.protocol}|//)`, 'iu'), bits = wikitext.split('[[');
19
+ : /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]])?)?\]\](.*)$/su, regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(.*)$/su, regexExt = new RegExp(String.raw `^\s*(?:${config.protocol}|//)`, 'iu'), bits = wikitext.split('[[');
20
20
  let s = bits.shift();
21
21
  for (let i = 0; i < bits.length; i++) {
22
22
  let mightBeImg = false, link, delimiter, text, after;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseMagicLinks = void 0;
4
4
  const string_1 = require("../util/string");
5
5
  const magicLink_1 = require("../src/magicLink");
6
+ const sepRegex = /[^,;\\.:!?)][,;\\.:!?)]+$/u, sepLparRegex = /[^,;\\.:!?][,;\\.:!?]+$/u;
6
7
  /**
7
8
  * 解析自由外链
8
9
  * @param wikitext
@@ -10,29 +11,39 @@ const magicLink_1 = require("../src/magicLink");
10
11
  * @param accum
11
12
  */
12
13
  const parseMagicLinks = (wikitext, config, accum) => {
13
- const regex = new RegExp(`(^|[^\\p{L}\\d_])(?:${config.protocol})(${string_1.extUrlCharFirst}${string_1.extUrlChar})`, 'giu');
14
+ const space = String.raw `[\p{Zs}\t]|&nbsp;|&#0*160;|&#x0*a0;`, spdash = `(?:${space}|-)`, regex = new RegExp(String.raw `(^|[^\p{L}\d_])(?:(?:${config.protocol})(${string_1.extUrlCharFirst}${string_1.extUrlChar})|(?:RFC|PMID)(?:${space})+\d+\b|ISBN(?:${space})+(?:97[89]${spdash}?)?(?:\d${spdash}?){9}[\dx]\b)`, 'giu');
14
15
  return wikitext.replace(regex, (m, lead, p1) => {
15
- let trail = '', url = lead ? m.slice(lead.length) : m;
16
- const m2 = /&(?:lt|gt|nbsp|#x0*(?:3[ce]|a0)|#0*(?:6[02]|160));/iu.exec(url);
17
- if (m2) {
18
- trail = url.slice(m2.index);
19
- url = url.slice(0, m2.index);
20
- }
21
- const sep = new RegExp(`[,;\\\\.:!?${url.includes('(') ? '' : ')'}]+$`, 'u'), sepChars = sep.exec(url);
22
- if (sepChars) {
23
- let correction = 0;
24
- if (sepChars[0].startsWith(';') && /&(?:[a-z]+|#x[\da-f]+|#\d+)$/iu.test(url.slice(0, sepChars.index))) {
25
- correction = 1;
16
+ let url = lead ? m.slice(lead.length) : m;
17
+ if (p1) {
18
+ let trail = '';
19
+ const m2 = /&(?:lt|gt|nbsp|#x0*(?:3[ce]|a0)|#0*(?:6[02]|160));/iu.exec(url);
20
+ if (m2) {
21
+ trail = url.slice(m2.index);
22
+ url = url.slice(0, m2.index);
23
+ }
24
+ const sep = url.includes('(') ? sepLparRegex : sepRegex, sepChars = sep.exec(url);
25
+ if (sepChars) {
26
+ let correction = 1;
27
+ if (sepChars[0][1] === ';'
28
+ && /&(?:[a-z]+|#x[\da-f]+|#\d+)$/iu.test(url.slice(0, sepChars.index))) {
29
+ correction = 2;
30
+ }
31
+ trail = url.slice(sepChars.index + correction) + trail;
32
+ url = url.slice(0, sepChars.index + correction);
33
+ }
34
+ if (trail.length >= p1.length) {
35
+ return m;
26
36
  }
27
- trail = url.slice(sepChars.index + correction) + trail;
28
- url = url.slice(0, sepChars.index + correction);
37
+ // @ts-expect-error abstract class
38
+ new magicLink_1.MagicLinkToken(url, undefined, config, accum);
39
+ return `${lead}\0${accum.length - 1}w\x7F${trail}`;
29
40
  }
30
- if (trail.length >= p1.length) {
41
+ else if (!/^(?:RFC|PMID|ISBN)/u.test(url)) {
31
42
  return m;
32
43
  }
33
44
  // @ts-expect-error abstract class
34
- new magicLink_1.MagicLinkToken(url, false, config, accum);
35
- return `${lead}\0${accum.length - 1}w\x7F${trail}`;
45
+ new magicLink_1.MagicLinkToken(url, 'magic-link', config, accum);
46
+ return `${lead}\0${accum.length - 1}i\x7F`;
36
47
  });
37
48
  };
38
49
  exports.parseMagicLinks = parseMagicLinks;
@@ -10,7 +10,7 @@ const redirect_1 = require("../src/redirect");
10
10
  * @param accum
11
11
  */
12
12
  const parseRedirect = (text, config, accum) => {
13
- const re = new RegExp(`^(\\s*)((?:${config.redirection.join('|')})\\s*(?::\\s*)?)\\[\\[([^\\n|\\]]+)(\\|.*?)?\\]\\](\\s*)`, 'iu'), mt = re.exec(text);
13
+ const re = new RegExp(String.raw `^(\s*)((?:${config.redirection.join('|')})\s*(?::\s*)?)\[\[([^\n|\]]+)(\|.*?)?\]\](\s*)`, 'iu'), mt = re.exec(text);
14
14
  if (mt && index_1.default.normalizeTitle(mt[3], 0, false, config, true, true).valid) {
15
15
  text = `\0${accum.length}c\x7F${text.slice(mt[0].length)}`;
16
16
  // @ts-expect-error abstract class
@@ -40,7 +40,7 @@ const parseTable = ({ firstChild: { data }, type, name }, config, accum) => {
40
40
  topToken.insertAt(token);
41
41
  }
42
42
  else {
43
- lastChild.setText(String(lastChild) + str);
43
+ lastChild.setText(lastChild.toString() + str);
44
44
  }
45
45
  },
46
46
  /** 取出最近的表格行 */
package/dist/src/arg.d.ts CHANGED
@@ -16,8 +16,4 @@ export declare abstract class ArgToken extends Token {
16
16
  get default(): string | false;
17
17
  /** @param parts 以'|'分隔的各部分 */
18
18
  constructor(parts: readonly string[], config?: Parser.Config, accum?: Token[]);
19
- /** @override */
20
- text(): string;
21
- /** @override */
22
- lint(start?: number, re?: RegExp): LintError[];
23
19
  }