wikiparser-node 1.16.0 → 1.16.2

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 (63) hide show
  1. package/bundle/bundle.es7.js +26 -29
  2. package/config/default.json +0 -2
  3. package/config/zhwiki.json +0 -2
  4. package/data/.schema.json +56 -0
  5. package/data/signatures.json +2751 -0
  6. package/dist/addon/table.js +9 -3
  7. package/dist/addon/token.js +73 -90
  8. package/dist/addon/transclude.js +3 -3
  9. package/dist/base.d.mts +57 -9
  10. package/dist/base.d.ts +57 -9
  11. package/dist/index.d.ts +1 -2
  12. package/dist/index.js +6 -6
  13. package/dist/lib/attributes.d.ts +24 -0
  14. package/dist/lib/attributes.js +67 -0
  15. package/dist/lib/element.js +9 -9
  16. package/dist/lib/lsp.d.ts +45 -12
  17. package/dist/lib/lsp.js +361 -171
  18. package/dist/lib/node.d.ts +2 -0
  19. package/dist/lib/node.js +93 -50
  20. package/dist/lib/ranges.d.ts +4 -8
  21. package/dist/lib/ranges.js +12 -19
  22. package/dist/lib/text.js +6 -4
  23. package/dist/lib/title.js +3 -1
  24. package/dist/parser/braces.js +3 -3
  25. package/dist/parser/commentAndExt.js +2 -3
  26. package/dist/parser/hrAndDoubleUnderscore.js +1 -2
  27. package/dist/parser/links.js +1 -2
  28. package/dist/parser/magicLinks.js +4 -2
  29. package/dist/parser/selector.js +37 -30
  30. package/dist/src/html.js +6 -4
  31. package/dist/src/imageParameter.js +12 -13
  32. package/dist/src/imagemap.js +3 -3
  33. package/dist/src/index.d.ts +23 -19
  34. package/dist/src/index.js +74 -48
  35. package/dist/src/link/file.js +1 -2
  36. package/dist/src/magicLink.js +8 -6
  37. package/dist/src/nested.js +4 -1
  38. package/dist/src/nowiki/index.js +3 -3
  39. package/dist/src/nowiki/list.js +1 -1
  40. package/dist/src/redirect.js +1 -2
  41. package/dist/src/table/index.js +10 -4
  42. package/dist/src/table/td.js +47 -55
  43. package/dist/src/transclude.js +8 -7
  44. package/dist/util/constants.js +2 -0
  45. package/dist/util/debug.js +14 -18
  46. package/dist/util/html.js +2 -0
  47. package/dist/util/lint.js +24 -4
  48. package/dist/util/string.js +9 -5
  49. package/extensions/es7/base.js +41 -5
  50. package/extensions/es7/lint.js +20 -11
  51. package/extensions/typings.d.ts +2 -7
  52. package/package.json +6 -4
  53. package/bundle/bundle.lsp.js +0 -39
  54. package/bundle/bundle.min.js +0 -38
  55. package/extensions/dist/base.js +0 -250
  56. package/extensions/dist/codejar.js +0 -56
  57. package/extensions/dist/editor.js +0 -159
  58. package/extensions/dist/highlight.js +0 -30
  59. package/extensions/dist/lint.js +0 -72
  60. package/extensions/dist/lsp.js +0 -53
  61. package/extensions/dist/test-page.js +0 -89
  62. package/extensions/editor.css +0 -59
  63. package/extensions/ui.css +0 -162
@@ -20,11 +20,11 @@ function validate(key, val, config, halfParsed, ext) {
20
20
  if (!value) {
21
21
  return val;
22
22
  }
23
- /* eslint-disable @typescript-eslint/no-unused-expressions, es-x/no-regexp-unicode-property-escapes */
24
- /^(?:ftp:\/\/|\/\/|\0\d+m\x7F)/iu;
23
+ /^(?:ftp:\/\/|\/\/|\0\d+m\x7F)/iu; // eslint-disable-line @typescript-eslint/no-unused-expressions
24
+ const re1 = new RegExp(String.raw `^(?:${config.protocol}|//|\0\d+m\x7F)`, 'iu');
25
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, es-x/no-regexp-unicode-property-escapes
25
26
  /^(?:(?:ftp:\/\/|\/\/)(?:\[[\da-f:.]+\]|[^[\]<>"\t\n\p{Zs}])|\0\d+m\x7F)[^[\]<>"\0\t\n\p{Zs}]*$/iu;
26
- /* eslint-enable @typescript-eslint/no-unused-expressions, es-x/no-regexp-unicode-property-escapes */
27
- const re1 = new RegExp(String.raw `^(?:${config.protocol}|//|\0\d+m\x7F)`, 'iu'), re2 = new RegExp(String.raw `^(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\d+m\x7F)${string_1.extUrlChar}$`, 'iu');
27
+ const re2 = new RegExp(String.raw `^(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\d+m\x7F)${string_1.extUrlChar}$`, 'iu');
28
28
  if (re1.test(value)) {
29
29
  return re2.test(value) && val;
30
30
  }
@@ -117,15 +117,14 @@ class ImageParameterToken extends index_2.Token {
117
117
  /** @param str 图片参数 */
118
118
  constructor(str, extension, config = index_1.default.getConfig(), accum) {
119
119
  let mt;
120
- /* eslint-disable @typescript-eslint/no-unused-expressions */
121
- /^(\s*)link=(.*)(?=$|\n)(\s*)$/u;
122
- /^(\s*(?!\s))(.*)px(\s*)$/u;
123
- /* eslint-enable @typescript-eslint/no-unused-expressions */
124
- const regexes = Object.entries(config.img).map(([syntax, param]) => [
125
- syntax,
126
- param,
127
- new RegExp(String.raw `^(\s*(?!\s))${syntax.replace('$1', '(.*)')}${syntax.endsWith('$1') ? '(?=$|\n)' : ''}(\s*)$`, 'u'),
128
- ]), param = regexes.find(([, key, regex]) => {
120
+ const regexes = Object.entries(config.img).map(([syntax, param]) => {
121
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
122
+ /^(\s*)link=(.*)(?=$|\n)(\s*)$/u;
123
+ /^(\s*(?!\s))(.*)px(\s*)$/u;
124
+ /* eslint-enable @typescript-eslint/no-unused-expressions */
125
+ const re = new RegExp(String.raw `^(\s*(?!\s))${syntax.replace('$1', '(.*)')}${syntax.endsWith('$1') ? '(?=$|\n)' : ''}(\s*)$`, 'u');
126
+ return [syntax, param, re];
127
+ }), param = regexes.find(([, key, regex]) => {
129
128
  mt = regex.exec(str);
130
129
  return mt
131
130
  && (mt.length !== 4
@@ -41,10 +41,10 @@ class ImagemapToken extends index_2.Token {
41
41
  //
42
42
  }
43
43
  else if (first) {
44
- const [file, ...options] = line.split('|'), title = this.normalizeTitle(file, 0, true);
44
+ const pipe = line.indexOf('|'), file = pipe === -1 ? line : line.slice(0, pipe), title = this.normalizeTitle(file, 0, true);
45
45
  if (title.valid && !title.interwiki && title.ns === 6) {
46
46
  // @ts-expect-error abstract class
47
- const token = new galleryImage_1.GalleryImageToken('imagemap', file, options.length > 0 ? options.join('|') : undefined, config, accum);
47
+ const token = new galleryImage_1.GalleryImageToken('imagemap', file, pipe === -1 ? undefined : line.slice(pipe + 1), config, accum);
48
48
  super.insertAt(token);
49
49
  first = false;
50
50
  continue;
@@ -53,7 +53,7 @@ class ImagemapToken extends index_2.Token {
53
53
  error = true;
54
54
  }
55
55
  }
56
- else if (line.trim().split(/[\t ]/u)[0] === 'desc') {
56
+ else if (line.trim().split(/[\t ]/u, 1)[0] === 'desc') {
57
57
  super.insertAt(line);
58
58
  continue;
59
59
  }
@@ -7,7 +7,10 @@ import type { AstNodes, IncludeToken, HtmlToken, ExtToken, TranscludeToken, Comm
7
7
  import { Ranges } from '../lib/ranges';
8
8
  import { AstRange } from '../lib/range';
9
9
  import type { Range } from '../lib/ranges';
10
- import type { CaretPosition } from '../lib/node';
10
+ declare interface CaretPosition {
11
+ readonly offsetNode: AstNodes;
12
+ readonly offset: number;
13
+ }
11
14
  /**
12
15
  * 所有节点的基类
13
16
  * @classdesc `{childNodes: ...(AstText|Token)}`
@@ -31,6 +34,22 @@ export declare class Token extends AstElement {
31
34
  */
32
35
  insertAt(child: string, i?: number): AstText;
33
36
  insertAt<T extends AstNodes>(child: T, i?: number): T;
37
+ /**
38
+ * 找到给定位置
39
+ * @param index 位置
40
+ */
41
+ caretPositionFromIndex(index?: number): CaretPosition | undefined;
42
+ /**
43
+ * 找到给定位置所在的最外层节点
44
+ * @param index 位置
45
+ */
46
+ elementFromIndex(index?: number): Token | undefined;
47
+ /**
48
+ * 找到给定位置所在的最外层节点
49
+ * @param x 列数
50
+ * @param y 行数
51
+ */
52
+ elementFromPoint(x: number, y: number): Token | undefined;
34
53
  /**
35
54
  * @override
36
55
  * @param i 移除位置
@@ -66,39 +85,23 @@ export declare class Token extends AstElement {
66
85
  createTextNode(data?: string): AstText;
67
86
  /** 创建AstRange对象 */
68
87
  createRange(): AstRange;
69
- /**
70
- * 找到给定位置
71
- * @param index 位置
72
- */
73
- caretPositionFromIndex(index?: number): CaretPosition | undefined;
74
88
  /**
75
89
  * 找到给定位置
76
90
  * @param x 列数
77
91
  * @param y 行数
78
92
  */
79
93
  caretPositionFromPoint(x: number, y: number): CaretPosition | undefined;
80
- /**
81
- * 找到给定位置所在的最外层节点
82
- * @param index 位置
83
- */
84
- elementFromIndex(index?: number): AstNodes | undefined;
85
- /**
86
- * 找到给定位置所在的最外层节点
87
- * @param x 列数
88
- * @param y 行数
89
- */
90
- elementFromPoint(x: number, y: number): AstNodes | undefined;
91
94
  /**
92
95
  * 找到给定位置所在的所有节点
93
96
  * @param index 位置
94
97
  */
95
- elementsFromIndex(index?: number): AstNodes[];
98
+ elementsFromIndex(index?: number): Token[];
96
99
  /**
97
100
  * 找到给定位置所在的所有节点
98
101
  * @param x 列数
99
102
  * @param y 行数
100
103
  */
101
- elementsFromPoint(x: number, y: number): AstNodes[];
104
+ elementsFromPoint(x: number, y: number): Token[];
102
105
  /**
103
106
  * 判断标题是否是跨维基链接
104
107
  * @param title 标题
@@ -133,3 +136,4 @@ export declare class Token extends AstElement {
133
136
  /** 生成HTML */
134
137
  toHtml(): string;
135
138
  }
139
+ export {};
package/dist/src/index.js CHANGED
@@ -45,13 +45,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.Token = void 0;
46
46
  const string_1 = require("../util/string");
47
47
  const constants_1 = require("../util/constants");
48
- const debug_1 = require("../util/debug");
49
48
  const lint_1 = require("../util/lint");
50
49
  const index_1 = require("../index");
51
50
  const element_1 = require("../lib/element");
52
51
  const text_1 = require("../lib/text");
53
52
  /* NOT FOR BROWSER */
54
53
  const assert = require("assert/strict");
54
+ const debug_1 = require("../util/debug");
55
55
  const html_1 = require("../util/html");
56
56
  const ranges_1 = require("../lib/ranges");
57
57
  const range_1 = require("../lib/range");
@@ -412,12 +412,12 @@ class Token extends element_1.AstElement {
412
412
  /* NOT FOR BROWSER */
413
413
  const acceptable = this.getAcceptable();
414
414
  if (!debug_1.Shadow.running && acceptable) {
415
- const acceptableIndices = Object.fromEntries(Object.entries(acceptable).map(([str, ranges]) => [str, ranges.applyTo(this.length + 1)])), nodesAfter = this.childNodes.slice(i), insertedName = token.constructor.name;
416
- i += i < 0 ? this.length : 0;
417
- if (!acceptableIndices[insertedName]?.includes(i)) {
415
+ const { length, childNodes } = this, nodesAfter = childNodes.slice(i), insertedName = token.constructor.name;
416
+ i += i < 0 ? length : 0;
417
+ if (!acceptable[insertedName]?.has(i, length + 1)) {
418
418
  this.constructorError(`cannot insert a ${insertedName} at position ${i}`);
419
419
  }
420
- else if (nodesAfter.some(({ constructor: { name } }, j) => !acceptableIndices[name]?.includes(i + j + 1))) {
420
+ else if (nodesAfter.some(({ constructor: { name } }, j) => !acceptable[name]?.has(i + j + 1, length + 1))) {
421
421
  this.constructorError(`violates the order of acceptable nodes by inserting a child node at position ${i}`);
422
422
  }
423
423
  }
@@ -481,13 +481,11 @@ class Token extends element_1.AstElement {
481
481
  }
482
482
  }
483
483
  const regex = /<!--\s*lint-(disable(?:(?:-next)?-line)?|enable)(\s[\sa-z,-]*)?-->/gu, wikitext = this.toString(), ignores = [];
484
- let mt = regex.exec(wikitext), last = 0, curLine = 0;
484
+ let mt = regex.exec(wikitext);
485
485
  while (mt) {
486
486
  const { 1: type, index } = mt, detail = mt[2]?.trim();
487
- curLine += wikitext.slice(last, index).split('\n').length - 1;
488
- last = index;
489
487
  ignores.push({
490
- line: curLine + (type === 'disable-line' ? 0 : 1),
488
+ line: this.posFromIndex(index).top + (type === 'disable-line' ? 0 : 1),
491
489
  from: type === 'disable' ? regex.lastIndex : undefined,
492
490
  to: type === 'enable' ? regex.lastIndex : undefined,
493
491
  rules: detail ? new Set(detail.split(',').map(r => r.trim())) : undefined,
@@ -523,18 +521,69 @@ class Token extends element_1.AstElement {
523
521
  }
524
522
  /** @private */
525
523
  toString(skip, separator) {
526
- const { rev } = debug_1.Shadow, root = this.getRootNode();
527
- if (this.#string && this.#string[0] !== rev) {
528
- this.#string = undefined;
524
+ return skip
525
+ ? super.toString(true, separator)
526
+ : (0, lint_1.cache)(this.#string, () => super.toString(false, separator), value => {
527
+ const root = this.getRootNode();
528
+ if (root.type === 'root' && root.#built) {
529
+ this.#string = value;
530
+ }
531
+ });
532
+ }
533
+ /**
534
+ * 找到给定位置
535
+ * @param index 位置
536
+ */
537
+ caretPositionFromIndex(index) {
538
+ LSP: { // eslint-disable-line no-unused-labels
539
+ if (index === undefined) {
540
+ return undefined;
541
+ }
542
+ const { length } = this.toString();
543
+ if (index > length || index < -length) {
544
+ return undefined;
545
+ }
546
+ index += index < 0 ? length : 0;
547
+ let self = this, acc = 0, start = 0;
548
+ while (self.type !== 'text') {
549
+ const { childNodes } = self;
550
+ acc += self.getAttribute('padding');
551
+ for (let i = 0; acc < index && i < childNodes.length; i++) {
552
+ const cur = childNodes[i], l = cur.toString().length;
553
+ acc += l;
554
+ if (acc >= index) {
555
+ self = cur;
556
+ acc -= l;
557
+ start = acc;
558
+ break;
559
+ }
560
+ acc += self.getGaps(i);
561
+ }
562
+ if (self.childNodes === childNodes) {
563
+ return { offsetNode: self, offset: index - start };
564
+ }
565
+ }
566
+ return { offsetNode: self, offset: index - start };
529
567
  }
530
- if (!skip
531
- && root.type === 'root'
532
- && root.#built
533
- && index_1.default.viewOnly) {
534
- this.#string ??= [rev, super.toString(false, separator)];
535
- return this.#string[1];
568
+ }
569
+ /**
570
+ * 找到给定位置所在的最外层节点
571
+ * @param index 位置
572
+ */
573
+ elementFromIndex(index) {
574
+ LSP: { // eslint-disable-line no-unused-labels
575
+ const node = this.caretPositionFromIndex(index)?.offsetNode;
576
+ return node?.type === 'text' ? node.parentNode : node;
536
577
  }
537
- return super.toString(skip, separator);
578
+ }
579
+ /**
580
+ * 找到给定位置所在的最外层节点
581
+ * @param x 列数
582
+ * @param y 行数
583
+ */
584
+ elementFromPoint(x, y) {
585
+ // eslint-disable-next-line no-unused-labels
586
+ LSP: return this.elementFromIndex(this.indexFromPos(y, x));
538
587
  }
539
588
  /* NOT FOR BROWSER */
540
589
  /** @private */
@@ -559,16 +608,16 @@ class Token extends element_1.AstElement {
559
608
  * @param i 移除位置
560
609
  */
561
610
  removeAt(i) {
562
- i += i < 0 ? this.length : 0;
611
+ const { length, childNodes } = this;
612
+ i += i < 0 ? length : 0;
563
613
  if (!debug_1.Shadow.running) {
564
- const protectedIndices = this.#protectedChildren.applyTo(this.childNodes);
565
- if (protectedIndices.includes(i)) {
614
+ if (this.#protectedChildren.has(i, length)) {
566
615
  this.constructorError(`cannot remove the child node at position ${i}`);
567
616
  }
568
617
  const acceptable = this.getAcceptable();
569
618
  if (acceptable) {
570
- const acceptableIndices = Object.fromEntries(Object.entries(acceptable).map(([str, ranges]) => [str, ranges.applyTo(this.length - 1)])), nodesAfter = this.childNodes.slice(i + 1);
571
- if (nodesAfter.some(({ constructor: { name } }, j) => !acceptableIndices[name]?.includes(i + j))) {
619
+ const nodesAfter = childNodes.slice(i + 1);
620
+ if (nodesAfter.some(({ constructor: { name } }, j) => !acceptable[name]?.has(i + j, length - 1))) {
572
621
  this.constructorError(`violates the order of acceptable nodes by removing the child node at position ${i}`);
573
622
  }
574
623
  }
@@ -640,14 +689,6 @@ class Token extends element_1.AstElement {
640
689
  createRange() {
641
690
  return new range_1.AstRange();
642
691
  }
643
- /**
644
- * 找到给定位置
645
- * @param index 位置
646
- */
647
- caretPositionFromIndex(index) {
648
- require('../addon/token');
649
- return this.caretPositionFromIndex(index);
650
- }
651
692
  /**
652
693
  * 找到给定位置
653
694
  * @param x 列数
@@ -656,27 +697,12 @@ class Token extends element_1.AstElement {
656
697
  caretPositionFromPoint(x, y) {
657
698
  return this.caretPositionFromIndex(this.indexFromPos(y, x));
658
699
  }
659
- /**
660
- * 找到给定位置所在的最外层节点
661
- * @param index 位置
662
- */
663
- elementFromIndex(index) {
664
- return this.caretPositionFromIndex(index)?.offsetNode;
665
- }
666
- /**
667
- * 找到给定位置所在的最外层节点
668
- * @param x 列数
669
- * @param y 行数
670
- */
671
- elementFromPoint(x, y) {
672
- return this.elementFromIndex(this.indexFromPos(y, x));
673
- }
674
700
  /**
675
701
  * 找到给定位置所在的所有节点
676
702
  * @param index 位置
677
703
  */
678
704
  elementsFromIndex(index) {
679
- const offsetNode = this.caretPositionFromIndex(index)?.offsetNode;
705
+ const offsetNode = this.elementFromIndex(index);
680
706
  return offsetNode ? [...offsetNode.getAncestors().reverse(), offsetNode] : [];
681
707
  }
682
708
  /**
@@ -117,8 +117,7 @@ class FileToken extends base_1.LinkBaseToken {
117
117
  this.setAttribute('acceptable', { AtomToken: 0, ImageParameterToken: '1:' });
118
118
  /* NOT FOR BROWSER END */
119
119
  const { extension } = this.getTitle(true);
120
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
121
- /-\{|\}-|\|/gu;
120
+ /-\{|\}-|\|/gu; // eslint-disable-line @typescript-eslint/no-unused-expressions
122
121
  this.append(...explode('-{', '}-', '|', text).map(
123
122
  // @ts-expect-error abstract class
124
123
  (part) => new imageParameter_1.ImageParameterToken(part, extension, config, accum)));
@@ -45,15 +45,18 @@ const debug_1 = require("../util/debug");
45
45
  const constants_1 = require("../util/constants");
46
46
  const html_1 = require("../util/html");
47
47
  const syntax_1 = require("../mixin/syntax");
48
+ const space = String.raw `(?:[${string_1.zs}\t]|&nbsp;|&#0*160;|&#[xX]0*[aA]0;)`;
48
49
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions, es-x/no-regexp-unicode-property-escapes
49
50
  /(?:[\p{Zs}\t]|&nbsp;|&#0*160;|&#[xX]0*[aA]0;)+/gu;
50
- const space = String.raw `(?:[${string_1.zs}\t]|&nbsp;|&#0*160;|&#[xX]0*[aA]0;)`, spaceRegex = new RegExp(`${space}+`, 'gu');
51
+ const spaceRegex = new RegExp(`${space}+`, 'gu');
51
52
  /** NOT FOR BROWSER */
52
- /* eslint-disable @typescript-eslint/no-unused-expressions, es-x/no-regexp-unicode-property-escapes */
53
+ const spdash = String.raw `(?:[\p{Zs}\t-]|&nbsp;|&#0*160;|&#[xX]0*[aA]0;)`;
54
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, es-x/no-regexp-unicode-property-escapes
53
55
  /^(ISBN)[\p{Zs}\t]+(?:97[89][\p{Zs}\t-]?)?(?:\d[\p{Zs}\t-]?){9}[\dxX]$/u;
56
+ const isbnPattern = new RegExp(String.raw `^(ISBN)${space}+(?:97[89]${spdash}?)?(?:\d${spdash}?){9}[\dxX]$`, 'u');
57
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, es-x/no-regexp-unicode-property-escapes
54
58
  /^(RFC|PMID)[\p{Zs}\t]+\d+$/u;
55
- /* eslint-enable @typescript-eslint/no-unused-expressions, es-x/no-regexp-unicode-property-escapes */
56
- const spdash = String.raw `(?:[\p{Zs}\t-]|&nbsp;|&#0*160;|&#[xX]0*[aA]0;)`, isbnPattern = new RegExp(String.raw `^(ISBN)${space}+(?:97[89]${spdash}?)?(?:\d${spdash}?){9}[\dxX]$`, 'u'), rfcPattern = new RegExp(String.raw `^(RFC|PMID)${space}+\d+$`, 'u');
59
+ const rfcPattern = new RegExp(String.raw `^(RFC|PMID)${space}+\d+$`, 'u');
57
60
  /** NOT FOR BROWSER END */
58
61
  /**
59
62
  * 自由外链
@@ -133,8 +136,7 @@ let MagicLinkToken = (() => {
133
136
  pattern = url?.startsWith('ISBN') ? isbnPattern : rfcPattern;
134
137
  }
135
138
  else {
136
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
137
- /^(ftp:\/\/|\/\/)/iu;
139
+ /^(ftp:\/\/|\/\/)/iu; // eslint-disable-line @typescript-eslint/no-unused-expressions
138
140
  pattern = new RegExp(`^(${config.protocol}${type === 'ext-link-url' ? '|//' : ''})`, 'iu');
139
141
  }
140
142
  this.setAttribute('pattern', pattern);
@@ -55,7 +55,10 @@ class NestedToken extends index_2.Token {
55
55
  }
56
56
  /** @private */
57
57
  lint(start = this.getAbsoluteIndex(), re) {
58
- const rect = new rect_1.BoundingRect(this, start), noinclude = this.#regex ? 'includeonly' : 'noinclude', regex = typeof this.#regex === 'boolean'
58
+ const rect = new rect_1.BoundingRect(this, start), noinclude = this.#regex ? 'includeonly' : 'noinclude';
59
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
60
+ /^(?:<noinclude(?:\s[^>]*)?\/?>|<\/noinclude\s*>)$/iu;
61
+ const regex = typeof this.#regex === 'boolean'
59
62
  ? new RegExp(String.raw `^(?:<${noinclude}(?:\s[^>]*)?/?>|</${noinclude}\s*>)$`, 'iu')
60
63
  : /^<!--[\s\S]*-->$/u;
61
64
  return [
@@ -21,9 +21,9 @@ class NowikiToken extends base_1.NowikiBaseToken {
21
21
  e.fix = { range: [start, e.endIndex], text: '', desc: 'empty' };
22
22
  return [e];
23
23
  }
24
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
25
- /<\s*(?:\/\s*)?(nowiki)\b/giu;
26
- return super.lint(start, new RegExp(String.raw `<\s*(?:/\s*)${name === 'nowiki' ? '' : '?'}(${name})\b`, 'giu'));
24
+ /<\s*(?:\/\s*)?(nowiki)\b/giu; // eslint-disable-line @typescript-eslint/no-unused-expressions
25
+ const re = new RegExp(String.raw `<\s*(?:/\s*)${name === 'nowiki' ? '' : '?'}(${name})\b`, 'giu');
26
+ return super.lint(start, re);
27
27
  }
28
28
  }
29
29
  exports.NowikiToken = NowikiToken;
@@ -43,7 +43,7 @@ const syntax_1 = require("../../mixin/syntax");
43
43
  /* NOT FOR BROWSER END */
44
44
  /** 位于行首的`;:*#` */
45
45
  let ListToken = (() => {
46
- let _classDecorators = [(0, sol_1.sol)(true), (0, syntax_1.syntax)(/^[;:*#]+$/u)];
46
+ let _classDecorators = [(0, sol_1.sol)(true), (0, syntax_1.syntax)(/^[;:*#]+[^\S\n]*$/u)];
47
47
  let _classDescriptor;
48
48
  let _classExtraInitializers = [];
49
49
  let _classThis;
@@ -81,8 +81,7 @@ let RedirectToken = (() => {
81
81
  super(undefined, config, accum);
82
82
  this.#pre = pre;
83
83
  this.#post = post;
84
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
85
- /^(?:#redirect|#重定向)\s*(?::\s*)?$/iu;
84
+ /^(?:#redirect|#重定向)\s*(?::\s*)?$/iu; // eslint-disable-line @typescript-eslint/no-unused-expressions
86
85
  const pattern = new RegExp(String.raw `^(?:${config.redirection.join('|')})\s*(?::\s*)?$`, 'iu');
87
86
  this.append(new syntax_1.SyntaxToken(syntax, pattern, 'redirect-syntax', config, accum, {
88
87
  AstText: ':',
@@ -12,6 +12,12 @@ const html_1 = require("../../util/html");
12
12
  const constants_1 = require("../../util/constants");
13
13
  const string_1 = require("../../util/string");
14
14
  const closingPattern = /^\n[^\S\n]*(?:\|\}|\{\{\s*!\s*\}\}\}|\{\{\s*!\)\s*\}\})$/u;
15
+ /**
16
+ * 生成一个指定长度的空数组
17
+ * @param n 数组长度
18
+ * @param callback 回调函数
19
+ */
20
+ const emptyArray = (n, callback) => new Array(n).fill(undefined).map((_, i) => callback(i));
15
21
  /**
16
22
  * 是否是行尾
17
23
  * @param {Token} cell 表格单元格
@@ -23,10 +29,10 @@ class Layout extends Array {
23
29
  /* NOT FOR BROWSER */
24
30
  /** 打印表格布局 */
25
31
  print() {
26
- const hBorders = (0, debug_1.emptyArray)(this.length + 1, i => {
32
+ const hBorders = emptyArray(this.length + 1, i => {
27
33
  const prev = this[i - 1] ?? [], next = this[i] ?? [];
28
- return (0, debug_1.emptyArray)(Math.max(prev.length, next.length), j => prev[j] !== next[j]);
29
- }), vBorders = this.map(cur => (0, debug_1.emptyArray)(cur.length + 1, j => cur[j - 1] !== cur[j]));
34
+ return emptyArray(Math.max(prev.length, next.length), j => prev[j] !== next[j]);
35
+ }), vBorders = this.map(cur => emptyArray(cur.length + 1, j => cur[j - 1] !== cur[j]));
30
36
  let out = '';
31
37
  for (let i = 0; i <= this.length; i++) {
32
38
  const hBorder = hBorders[i].map(Number), vBorderTop = (vBorders[i - 1] ?? []).map(Number), vBorderBottom = (vBorders[i] ?? []).map(Number),
@@ -136,7 +142,7 @@ class TableToken extends trBase_1.TrBaseToken {
136
142
  * @param stop.y 中止列
137
143
  */
138
144
  getLayout(stop) {
139
- const rows = this.getAllRows(), { length } = rows, layout = new Layout(...(0, debug_1.emptyArray)(length, () => []));
145
+ const rows = this.getAllRows(), { length } = rows, layout = new Layout(...emptyArray(length, () => []));
140
146
  for (const [i, rowLayout] of layout.entries()) {
141
147
  /* NOT FOR BROWSER */
142
148
  if (i > (stop?.row ?? stop?.y ?? NaN)) {
@@ -37,12 +37,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
37
37
  exports.createTd = exports.TdToken = void 0;
38
38
  const lint_1 = require("../../util/lint");
39
39
  const constants_1 = require("../../util/constants");
40
- const debug_1 = require("../../util/debug");
41
40
  const rect_1 = require("../../lib/rect");
42
41
  const index_1 = require("../../index");
43
42
  const index_2 = require("../index");
44
43
  const base_1 = require("./base");
45
44
  /* NOT FOR BROWSER */
45
+ const debug_1 = require("../../util/debug");
46
46
  const string_1 = require("../../util/string");
47
47
  const fixed_1 = require("../../mixin/fixed");
48
48
  /* NOT FOR BROWSER END */
@@ -123,61 +123,53 @@ let TdToken = (() => {
123
123
  }
124
124
  /** 表格语法信息 */
125
125
  #getSyntax() {
126
- const { rev } = debug_1.Shadow;
127
- if (this.#syntax && this.#syntax[0] !== rev) {
128
- this.#syntax = undefined;
129
- }
130
- if (index_1.default.viewOnly) {
131
- this.#syntax ??= [rev, this.#computeSyntax()];
132
- return this.#syntax[1];
133
- }
134
- return this.#computeSyntax();
135
- }
136
- /** 表格语法信息 */
137
- #computeSyntax() {
138
- const syntax = this.firstChild.text(),
139
- /* NOT FOR BROWSER */
140
- esc = syntax.includes('{{'),
141
- /* NOT FOR BROWSER END */
142
- char = syntax.slice(-1);
143
- let subtype = 'td';
144
- if (char === '!') {
145
- subtype = 'th';
146
- }
147
- else if (char === '+') {
148
- subtype = 'caption';
149
- }
150
- if (this.isIndependent()) {
151
- return {
152
- subtype,
153
- /* NOT FOR BROWSER */
154
- escape: esc,
155
- correction: false,
156
- };
157
- }
158
- const { previousSibling } = this;
159
- /* NOT FOR BROWSER */
160
- if (!(previousSibling instanceof TdToken)) {
161
- return { subtype, escape: esc, correction: true };
162
- }
163
- /* NOT FOR BROWSER END */
164
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
165
- const result = { ...previousSibling.#getSyntax() };
166
- /* NOT FOR BROWSER */
167
- const str = previousSibling.lastChild.toString();
168
- result.escape ||= esc;
169
- result.correction = str.includes('\n') && debug_1.Shadow.run(() => {
170
- const config = this.getAttribute('config'), include = this.getAttribute('include');
171
- return new index_2.Token(str, config).parseOnce(0, include).parseOnce().parseOnce()
172
- .toString()
173
- .includes('\n');
126
+ return (0, lint_1.cache)(this.#syntax, () => {
127
+ const syntax = this.firstChild.text(),
128
+ /* NOT FOR BROWSER */
129
+ esc = syntax.includes('{{'),
130
+ /* NOT FOR BROWSER END */
131
+ char = syntax.slice(-1);
132
+ let subtype = 'td';
133
+ if (char === '!') {
134
+ subtype = 'th';
135
+ }
136
+ else if (char === '+') {
137
+ subtype = 'caption';
138
+ }
139
+ if (this.isIndependent()) {
140
+ return {
141
+ subtype,
142
+ /* NOT FOR BROWSER */
143
+ escape: esc,
144
+ correction: false,
145
+ };
146
+ }
147
+ const { previousSibling } = this;
148
+ /* NOT FOR BROWSER */
149
+ if (!(previousSibling instanceof TdToken)) {
150
+ return { subtype, escape: esc, correction: true };
151
+ }
152
+ /* NOT FOR BROWSER END */
153
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
154
+ const result = { ...previousSibling.#getSyntax() };
155
+ /* NOT FOR BROWSER */
156
+ const str = previousSibling.lastChild.toString();
157
+ result.escape ||= esc;
158
+ result.correction = str.includes('\n') && debug_1.Shadow.run(() => {
159
+ const config = this.getAttribute('config'), include = this.getAttribute('include');
160
+ return new index_2.Token(str, config).parseOnce(0, include).parseOnce().parseOnce()
161
+ .toString()
162
+ .includes('\n');
163
+ });
164
+ if (subtype === 'th' && result.subtype !== 'th') {
165
+ result.subtype = 'th';
166
+ result.correction = true;
167
+ }
168
+ /* NOT FOR BROWSER END */
169
+ return result;
170
+ }, value => {
171
+ this.#syntax = value;
174
172
  });
175
- if (subtype === 'th' && result.subtype !== 'th') {
176
- result.subtype = 'th';
177
- result.correction = true;
178
- }
179
- /* NOT FOR BROWSER END */
180
- return result;
181
173
  }
182
174
  /** @private */
183
175
  afterBuild() {
@@ -22,6 +22,7 @@ class TranscludeToken extends index_2.Token {
22
22
  #type = 'template';
23
23
  #raw = false;
24
24
  #args = new Map();
25
+ /* NOT FOR BROWSER */
25
26
  #keys = new Set();
26
27
  /* NOT FOR BROWSER END */
27
28
  get type() {
@@ -66,21 +67,21 @@ class TranscludeToken extends index_2.Token {
66
67
  }
67
68
  const isFunction = title.includes(':');
68
69
  if (isFunction || parts.length === 0 && !this.#raw) {
69
- const [magicWord, ...arg] = title.split(':'), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg.length > 0 ? 'trimStart' : 'trim'](), lcName = name.toLowerCase(), isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema
70
+ const colon = title.indexOf(':'), magicWord = colon === -1 ? title : title.slice(0, colon), arg = colon === -1 ? undefined : title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg === undefined ? 'trim' : 'trimStart'](), lcName = name.toLowerCase(), isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema
70
71
  ? sensitive.includes(name)
71
- : Object.prototype.hasOwnProperty.call(sensitive, name), canonicalName = Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName]
72
- || !isOldSchema && isSensitive && sensitive[name], isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
72
+ : Object.prototype.hasOwnProperty.call(sensitive, name), canonicalName = !isOldSchema && isSensitive
73
+ ? sensitive[name]
74
+ : Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName], isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
73
75
  if (isVar || isFunction && canonicalName) {
74
76
  this.setAttribute('name', canonicalName || lcName.replace(/^#/u, ''));
75
77
  this.#type = 'magic-word';
76
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
77
- /^\s*uc\s*$/iu;
78
+ /^\s*uc\s*$/iu; // eslint-disable-line @typescript-eslint/no-unused-expressions
78
79
  const pattern = new RegExp(String.raw `^\s*${name}\s*$`, isSensitive ? 'u' : 'iu'), token = new syntax_1.SyntaxToken(magicWord, pattern, 'magic-word-name', config, accum, {
79
80
  'Stage-1': ':', '!ExtToken': '',
80
81
  });
81
82
  super.insertAt(token);
82
- if (arg.length > 0) {
83
- parts.unshift([arg.join(':')]);
83
+ if (arg !== undefined) {
84
+ parts.unshift([arg]);
84
85
  }
85
86
  if (this.name === 'invoke') {
86
87
  /* NOT FOR BROWSER */
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
+ /* NOT FOR BROWSER */
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.states = exports.aliases = exports.parsers = exports.mixins = exports.classes = exports.BuildMethod = exports.MAX_STAGE = void 0;
5
+ /* NOT FOR BROWSER END */
4
6
  exports.MAX_STAGE = 11;
5
7
  var BuildMethod;
6
8
  (function (BuildMethod) {