wikiparser-node 0.2.2 → 0.3.0

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.
package/.eslintrc.json CHANGED
@@ -5,10 +5,7 @@
5
5
  },
6
6
  "extends": "eslint:recommended",
7
7
  "parserOptions": {
8
- "ecmaVersion": 13,
9
- "ecmaFeatures": {
10
- "impliedStrict": true
11
- }
8
+ "ecmaVersion": 13
12
9
  },
13
10
  "rules": {
14
11
  "array-callback-return": [
@@ -18,13 +15,39 @@
18
15
  }
19
16
  ],
20
17
  "no-await-in-loop": 2,
18
+ "no-constant-binary-expression": 2,
21
19
  "no-constructor-return": 2,
22
20
  "no-fallthrough": 1,
23
21
  "no-promise-executor-return": 2,
24
22
  "no-self-compare": 2,
25
23
  "no-template-curly-in-string": 2,
24
+ "no-undef": [
25
+ 2,
26
+ {
27
+ "typeof": true
28
+ }
29
+ ],
26
30
  "no-unmodified-loop-condition": 2,
27
31
  "no-unreachable-loop": 2,
32
+ "no-unsafe-negation": [
33
+ 2,
34
+ {
35
+ "enforceForOrderingRelations": true
36
+ }
37
+ ],
38
+ "no-unsafe-optional-chaining": [
39
+ 2,
40
+ {
41
+ "disallowArithmeticOperators": true
42
+ }
43
+ ],
44
+ "no-unused-vars": [
45
+ 2,
46
+ {
47
+ "varsIgnorePattern": "AstNode|AstElement|[a-zA-Z]*Token",
48
+ "ignoreRestSiblings": true
49
+ }
50
+ ],
28
51
  "no-use-before-define": [
29
52
  2,
30
53
  {
@@ -33,7 +56,12 @@
33
56
  "variables": false
34
57
  }
35
58
  ],
36
- "require-atomic-updates": 2,
59
+ "require-atomic-updates": [
60
+ 2,
61
+ {
62
+ "allowProperties": true
63
+ }
64
+ ],
37
65
  "block-scoped-var": 2,
38
66
  "class-methods-use-this": 0,
39
67
  "consistent-this": 2,
@@ -47,6 +75,13 @@
47
75
  2,
48
76
  "never"
49
77
  ],
78
+ "logical-assignment-operators": [
79
+ 2,
80
+ "always",
81
+ {
82
+ "enforceForIfStatements": true
83
+ }
84
+ ],
50
85
  "multiline-comment-style": 2,
51
86
  "new-cap": [
52
87
  1,
@@ -67,6 +102,12 @@
67
102
  ],
68
103
  "no-eval": 2,
69
104
  "no-extend-native": 2,
105
+ "no-extra-boolean-cast": [
106
+ 2,
107
+ {
108
+ "enforceForLogicalOperands": true
109
+ }
110
+ ],
70
111
  "no-floating-decimal": 2,
71
112
  "no-implied-eval": 2,
72
113
  "no-invalid-this": [
@@ -91,7 +132,12 @@
91
132
  "no-return-await": 2,
92
133
  "no-script-url": 2,
93
134
  "no-sequences": 2,
94
- "no-shadow": 2,
135
+ "no-shadow": [
136
+ 2,
137
+ {
138
+ "builtinGlobals": true
139
+ }
140
+ ],
95
141
  "no-undef-init": 2,
96
142
  "no-unneeded-ternary": [
97
143
  2,
@@ -139,6 +185,7 @@
139
185
  ],
140
186
  "require-await": 2,
141
187
  "spaced-comment": 2,
188
+ "strict": 2,
142
189
  "symbol-description": 2,
143
190
  "yoda": 2,
144
191
  "array-bracket-spacing": 2,
@@ -646,65 +646,28 @@
646
646
  "wikt",
647
647
  "wiktionary",
648
648
  "zhwiki",
649
- "acronym",
650
- "c2find",
649
+ "cc",
651
650
  "cm",
652
- "dictionary",
653
- "drumcorpswiki",
654
- "dwjwiki",
655
- "elibre",
656
- "emacswiki",
657
651
  "enmoe",
658
- "enwiki",
659
- "foldoc",
660
- "foxwiki",
661
- "freebsdman",
662
- "gentoo-wiki",
663
- "hammondwiki",
664
- "hrwiki",
652
+ "enwp",
653
+ "fandom",
654
+ "ghia",
655
+ "huiji",
665
656
  "jamoe",
666
- "kmwiki",
657
+ "jawp",
667
658
  "library",
668
- "linuxwiki",
669
- "lojban",
670
- "lqwiki",
671
- "mcwiki",
672
- "meatball",
673
- "memoryalpha",
674
659
  "meta",
675
- "metawiki",
676
- "mozillawiki",
677
- "oeis",
678
- "openwiki",
679
660
  "phab",
680
661
  "pmid",
681
- "pythoninfo",
682
- "rfc",
683
- "s23wiki",
684
- "seattlewireless",
685
- "senseislibrary",
686
662
  "shoutwiki",
687
- "sourceforge",
688
- "squeak",
689
- "theopedia",
690
- "tmbw",
691
- "tmnet",
692
663
  "translatewiki",
693
- "twiki",
694
- "uncyclopedia",
695
- "unreal",
696
- "usemod",
697
- "wiki",
698
- "wikif1",
699
- "wikihow",
700
664
  "zhmoe",
701
665
  "zhmoegirl",
702
666
  "zhtest",
667
+ "zhwp",
703
668
  "文库",
704
- "维基中文",
705
- "维基日文",
706
- "维基英文",
707
669
  "萌娘共享",
670
+ "萌娘文库",
708
671
  "萌百"
709
672
  ],
710
673
  "img": {
@@ -578,20 +578,14 @@
578
578
  ],
579
579
  "protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
580
580
  "interwiki": [
581
- "arxiv",
582
581
  "commons",
583
- "doi",
584
- "imdb",
585
- "jawiki",
586
582
  "mediawikiwiki",
587
583
  "metawikimedia",
588
584
  "mw",
589
- "wikia",
590
585
  "wikibooks",
591
586
  "wikidata",
592
587
  "wikimedia",
593
588
  "wikinews",
594
- "wikiinfo",
595
589
  "wikipedia",
596
590
  "wikiquote",
597
591
  "wikisource",
@@ -600,66 +594,31 @@
600
594
  "wikivoyage",
601
595
  "wikt",
602
596
  "wiktionary",
603
- "zhwiki",
604
- "acronym",
605
- "c2find",
597
+ "cc",
606
598
  "cm",
607
- "dictionary",
608
- "drumcorpswiki",
609
- "dwjwiki",
610
- "elibre",
611
- "emacswiki",
599
+ "en",
612
600
  "enmoe",
613
- "enwiki",
614
- "foldoc",
615
- "foxwiki",
616
- "freebsdman",
617
- "gentoo-wiki",
618
- "hammondwiki",
619
- "hrwiki",
601
+ "enwp",
602
+ "fandom",
603
+ "ghia",
604
+ "huiji",
605
+ "ja",
620
606
  "jamoe",
621
- "kmwiki",
607
+ "jawp",
622
608
  "library",
623
- "linuxwiki",
624
- "lojban",
625
- "lqwiki",
626
- "mcwiki",
627
- "meatball",
628
- "memoryalpha",
629
609
  "meta",
630
- "metawiki",
631
- "mozillawiki",
632
- "oeis",
633
- "openwiki",
634
610
  "phab",
635
611
  "pmid",
636
- "pythoninfo",
637
- "rfc",
638
- "s23wiki",
639
- "seattlewireless",
640
- "senseislibrary",
641
612
  "shoutwiki",
642
- "sourceforge",
643
- "squeak",
644
- "theopedia",
645
- "tmbw",
646
- "tmnet",
647
613
  "translatewiki",
648
- "twiki",
649
- "uncyclopedia",
650
- "unreal",
651
- "usemod",
652
- "wiki",
653
- "wikif1",
654
- "wikihow",
614
+ "zh",
655
615
  "zhmoe",
656
616
  "zhmoegirl",
657
617
  "zhtest",
618
+ "zhwp",
658
619
  "文库",
659
- "维基中文",
660
- "维基日文",
661
- "维基英文",
662
620
  "萌娘共享",
621
+ "萌娘文库",
663
622
  "萌百"
664
623
  ],
665
624
  "img": {
package/lib/element.js CHANGED
@@ -39,12 +39,12 @@ class AstElement extends AstNode {
39
39
  /** @complexity `n` */
40
40
  get nextElementSibling() {
41
41
  const children = this.parentElement?.children;
42
- return children?.[children?.indexOf(this) + 1];
42
+ return children && children[children.indexOf(this) + 1];
43
43
  }
44
44
  /** @complexity `n` */
45
45
  get previousElementSibling() {
46
46
  const children = this.parentElement?.children;
47
- return children?.[children?.indexOf(this) - 1];
47
+ return children && children[children.indexOf(this) - 1];
48
48
  }
49
49
  /** @complexity `n` */
50
50
  get hidden() {
@@ -673,18 +673,11 @@ class AstElement extends AstNode {
673
673
  }
674
674
 
675
675
  /**
676
- * 不作为特殊语法的文字
677
- * @returns {[number, string][]}
676
+ * @returns {boolean}
678
677
  * @complexity `n`
679
678
  */
680
- plain() {
681
- const index = this.getAbsoluteIndex();
682
- return this.childNodes.flatMap((node, i) => {
683
- if (node instanceof AstElement) {
684
- return node.plain();
685
- }
686
- return node ? [[index + this.getRelativeIndex(i), node]] : [];
687
- });
679
+ get eof() {
680
+ return this.type === 'root' || !this.nextSibling && this.parentElement.eof;
688
681
  }
689
682
 
690
683
  /**
@@ -743,6 +736,11 @@ class AstElement extends AstNode {
743
736
  }
744
737
  Parser.info(`${indent}</${type}>`);
745
738
  }
739
+
740
+ /** @param {number} n */
741
+ getLine(n) {
742
+ return this.toString().split('\n', n + 1).at(-1);
743
+ }
746
744
  }
747
745
 
748
746
  Parser.classes.AstElement = __filename;
package/lib/node.js CHANGED
@@ -22,12 +22,12 @@ class AstNode {
22
22
  /** @complexity `n` */
23
23
  get nextSibling() {
24
24
  const childNodes = this.#parentNode?.childNodes;
25
- return childNodes?.[childNodes?.indexOf(this) + 1];
25
+ return childNodes && childNodes[childNodes.indexOf(this) + 1];
26
26
  }
27
27
  /** @complexity `n` */
28
28
  get previousSibling() {
29
29
  const childNodes = this.#parentNode?.childNodes;
30
- return childNodes?.[childNodes?.indexOf(this) - 1];
30
+ return childNodes && childNodes[childNodes.indexOf(this) - 1];
31
31
  }
32
32
 
33
33
  debugOnly(method = 'debugOnly') {
package/lib/title.js CHANGED
@@ -5,6 +5,8 @@ const {ucfirst} = require('../util/string'),
5
5
 
6
6
  class Title {
7
7
  title = '';
8
+ main = '';
9
+ prefix = '';
8
10
  ns = 0;
9
11
  interwiki = '';
10
12
  fragment = '';
@@ -19,7 +21,7 @@ class Title {
19
21
  namespace = '';
20
22
  title = title.slice(1).trim();
21
23
  }
22
- const iw = Parser.isInterwiki(title, config);
24
+ const iw = defaultNs ? null : Parser.isInterwiki(title, config);
23
25
  if (iw) {
24
26
  this.interwiki = iw[1].toLowerCase();
25
27
  title = title.slice(iw[0].length);
@@ -48,8 +50,10 @@ class Title {
48
50
  this.fragment ||= fragment;
49
51
  title = title.slice(0, i).trim();
50
52
  }
51
- this.title = `${iw ? `${this.interwiki}:` : ''}${namespace}${namespace && ':'}${ucfirst(title)}`;
52
- this.valid = !/\x00\d+[eh!+-]\x7f|[<>[\]{}|]/.test(this.title);
53
+ this.main = ucfirst(title);
54
+ this.prefix = `${namespace}${namespace && ':'}`;
55
+ this.title = `${iw ? `${this.interwiki}:` : ''}${this.prefix}${this.main}`;
56
+ this.valid = Boolean(this.main) && !/\x00\d+[eh!+-]\x7f|[<>[\]{}|]/.test(this.title);
53
57
  }
54
58
  }
55
59
 
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const /** @type {Parser} */ Parser = require('..'),
4
- AttributeToken = require('../src/attribute'); // eslint-disable-line no-unused-vars
4
+ AttributeToken = require('../src/attribute');
5
5
 
6
6
  /**
7
7
  * @template T
8
8
  * @param {T} constructor
9
9
  * @returns {T}
10
10
  */
11
- const attributeParent = (constructor, i = 0) => class extends constructor {
11
+ const attributeParent = (ct, i = 0) => class extends ct {
12
12
  /**
13
13
  * @this {{children: AttributeToken[]}}
14
14
  * @param {string} key
@@ -7,7 +7,7 @@ const /** @type {Parser} */ Parser = require('..');
7
7
  * @param {T} constructor
8
8
  * @returns {T}
9
9
  */
10
- const fixedToken = constructor => class extends constructor {
10
+ const fixedToken = ct => class extends ct {
11
11
  static fixed = true;
12
12
 
13
13
  removeAt() {
package/mixin/hidden.js CHANGED
@@ -7,15 +7,10 @@ const /** @type {Parser} */ Parser = require('..');
7
7
  * @param {T} constructor
8
8
  * @returns {T}
9
9
  */
10
- const hidden = constructor => class extends constructor {
10
+ const hidden = ct => class extends ct {
11
11
  text() {
12
12
  return '';
13
13
  }
14
-
15
- /** @returns {[number, string][]} */
16
- plain() {
17
- return [];
18
- }
19
14
  };
20
15
 
21
16
  Parser.mixins.hidden = __filename;
package/mixin/sol.js CHANGED
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const /** @type {Parser} */ Parser = require('..'),
4
- Token = require('../src'); // eslint-disable-line no-unused-vars
4
+ Token = require('../src');
5
5
 
6
6
  /**
7
7
  * @template T
8
8
  * @param {T} constructor
9
9
  * @returns {T}
10
10
  */
11
- const sol = constructor => class extends constructor {
11
+ const sol = ct => class extends ct {
12
12
  /** @this {Token} */
13
13
  prependNewLine() {
14
14
  const {previousVisibleSibling = '', parentNode} = this;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikiparser-node",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "A Node.js parser for MediaWiki markup with AST",
5
5
  "keywords": [
6
6
  "mediawiki",
@@ -21,8 +21,8 @@
21
21
  "test": "echo 'Error: no test specified' && exit 1"
22
22
  },
23
23
  "devDependencies": {
24
- "eslint": "^8.8.0",
25
- "@types/node": "^17.0.23"
24
+ "@types/node": "^17.0.23",
25
+ "eslint": "^8.30.0"
26
26
  },
27
27
  "engines": {
28
28
  "node": "^18.4.0"
@@ -10,7 +10,7 @@ const parseHrAndDoubleUnderscore = (firstChild, config = Parser.getConfig(), acc
10
10
  const HrToken = require('../src/nowiki/hr'),
11
11
  DoubleUnderscoreToken = require('../src/nowiki/doubleUnderscore'),
12
12
  {doubleUnderscore} = config;
13
- return firstChild.replace(/^-{4,}/mg, m => {
13
+ return firstChild.replace(/(?<=^(?:\x00\d+c\x7f)*)-{4,}/mg, m => {
14
14
  new HrToken(m.length, config, accum);
15
15
  return `\x00${accum.length - 1}r\x7f`;
16
16
  }).replace(new RegExp(`__(${doubleUnderscore.flat().join('|')})__`, 'ig'), /** @param {string} p1 */(m, p1) => {
package/parser/links.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const /** @type {Parser} */ Parser = require('..'),
4
- Token = require('../src'); // eslint-disable-line no-unused-vars
4
+ Token = require('../src');
5
5
 
6
6
  /**
7
7
  * @param {string} firstChild
@@ -78,7 +78,7 @@ const parseLinks = (firstChild, config = Parser.getConfig(), accum = []) => {
78
78
  continue;
79
79
  }
80
80
  }
81
- text = text && parseQuotes(text, config, accum);
81
+ text &&= parseQuotes(text, config, accum);
82
82
  s += `\x00${accum.length}l\x7f${after}`;
83
83
  let LinkToken = require('../src/link');
84
84
  if (!force) {
package/parser/list.js CHANGED
@@ -7,13 +7,13 @@ const /** @type {Parser} */ Parser = require('..');
7
7
  * @param {accum} accum
8
8
  */
9
9
  const parseList = (text, config = Parser.getConfig(), accum = []) => {
10
- const mt = text.match(/^(?:[;:*#]|\x00\d+c\x7f)*[;:*#]/);
10
+ const mt = text.match(/^((?:\x00\d+c\x7f)*)([;:*#]+)/);
11
11
  if (!mt) {
12
12
  return text;
13
13
  }
14
14
  const ListToken = require('../src/nowiki/list'),
15
- [prefix] = mt;
16
- text = `\x00${accum.length}d\x7f${text.slice(prefix.length)}`;
15
+ [total, comment, prefix] = mt;
16
+ text = `${comment}\x00${accum.length}d\x7f${text.slice(total.length)}`;
17
17
  new ListToken(prefix, config, accum);
18
18
  let dt = prefix.split(';').length - 1;
19
19
  if (!dt) {
package/parser/quotes.js CHANGED
@@ -35,8 +35,8 @@ const parseQuotes = (text, config = Parser.getConfig(), accum = []) => {
35
35
  }
36
36
  } else if (arr[i - 1].at(-2) === ' ') {
37
37
  firstSingle = i;
38
- } else if (!firstMulti) {
39
- firstMulti = i;
38
+ } else {
39
+ firstMulti ||= i;
40
40
  }
41
41
  break;
42
42
  default:
package/parser/table.js CHANGED
@@ -36,6 +36,9 @@ const parseTable = ({firstChild, type}, config = Parser.getConfig(), accum = [])
36
36
  const line = outLine.slice(spaces.length),
37
37
  matchesStart = line.match(/^(:*)((?:\s|\x00\d+c\x7f)*)({\||{\x00\d+!\x7f|\x00\d+{\x7f)(.*)/);
38
38
  if (matchesStart) {
39
+ while (top && top.type !== 'td') {
40
+ top = stack.pop();
41
+ }
39
42
  const [, indent, moreSpaces, tableSyntax, attr] = matchesStart;
40
43
  if (indent) {
41
44
  new DdToken(indent, config, accum);
package/src/arg.js CHANGED
@@ -73,11 +73,6 @@ class ArgToken extends Token {
73
73
  return `{{{${text(this.children.slice(0, 2), '|')}}}}`;
74
74
  }
75
75
 
76
- /** @returns {[number, string][]} */
77
- plain() {
78
- return this.childNodes.length > 1 ? this.children[1].plain() : [];
79
- }
80
-
81
76
  /** @complexity `n` */
82
77
  removeRedundant() {
83
78
  Parser.run(() => {
package/src/attribute.js CHANGED
@@ -82,7 +82,7 @@ class AttributeToken extends Token {
82
82
  * @param {accum} accum
83
83
  */
84
84
  constructor(attr, type, name, config = Parser.getConfig(), accum = []) {
85
- super(attr, config, type !== 'ext-attr', accum, {[`Stage-${stages[type]}`]: ':'});
85
+ super(attr, config, true, accum, {[`Stage-${stages[type]}`]: ':'});
86
86
  this.type = type;
87
87
  this.setAttribute('name', name).#parseAttr();
88
88
  }
@@ -253,11 +253,6 @@ class AttributeToken extends Token {
253
253
  return this.type === 'table-attr' ? normalizeSpace(str) : str;
254
254
  }
255
255
 
256
- /** @returns {[number, string][]} */
257
- plain() {
258
- return [];
259
- }
260
-
261
256
  /**
262
257
  * @param {number} i
263
258
  * @complexity `n`
package/src/converter.js CHANGED
@@ -19,7 +19,7 @@ class ConverterToken extends Token {
19
19
  * @param {accum} accum
20
20
  */
21
21
  constructor(flags, rules, config = Parser.getConfig(), accum = []) {
22
- super(undefined, config, false, accum);
22
+ super(undefined, config, true, accum);
23
23
  this.append(new ConverterFlagsToken(flags, config, accum));
24
24
  if (rules.length) {
25
25
  const [firstRule] = rules,
@@ -65,11 +65,6 @@ class ConverterToken extends Token {
65
65
  return `-{${flags.text()}|${text(rules, ';')}}-`;
66
66
  }
67
67
 
68
- /** @returns {[number, string][]} */
69
- plain() {
70
- return this.children.slice(1).flatMap(child => child.plain());
71
- }
72
-
73
68
  /** @this {ConverterToken & {firstChild: ConverterFlagsToken}} */
74
69
  getAllFlags() {
75
70
  return this.firstChild.getAllFlags();
@@ -17,7 +17,7 @@ class ConverterFlagsToken extends Token {
17
17
  * @param {accum} accum
18
18
  */
19
19
  constructor(flags, config = Parser.getConfig(), accum = []) {
20
- super(undefined, config, false, accum, {AtomToken: ':'});
20
+ super(undefined, config, true, accum, {AtomToken: ':'});
21
21
  this.append(...flags.map(flag => new AtomToken(flag, 'converter-flag', config, accum)));
22
22
  }
23
23
 
@@ -86,11 +86,6 @@ class ConverterFlagsToken extends Token {
86
86
  return super.text(';');
87
87
  }
88
88
 
89
- /** @returns {[number, string][]} */
90
- plain() {
91
- return [];
92
- }
93
-
94
89
  /**
95
90
  * @param {string} flag
96
91
  * @returns {AtomToken[]}
@@ -47,7 +47,7 @@ class ConverterRuleToken extends Token {
47
47
 
48
48
  cloneNode() {
49
49
  const cloned = this.cloneChildren(),
50
- placeholders = ['', ':', '=>:'],
50
+ placeholders = ['', 'zh:', '=>zh:'],
51
51
  placeholder = placeholders[cloned.length - 1],
52
52
  token = Parser.run(() => new ConverterRuleToken(placeholder, placeholder, this.getAttribute('config')));
53
53
  for (let i = 0; i < cloned.length; i++) {
@@ -120,15 +120,6 @@ class ConverterRuleToken extends Token {
120
120
  return super.text(':');
121
121
  }
122
122
 
123
- /** @returns {[number, string][]} */
124
- plain() {
125
- const {firstElementChild, lastElementChild, unidirectional} = this;
126
- if (unidirectional) {
127
- return [...firstElementChild.plain(), ...lastElementChild.plain()];
128
- }
129
- return lastElementChild.plain();
130
- }
131
-
132
123
  noConvert() {
133
124
  for (let i = this.childNodes.length - 2; i >= 0; i--) {
134
125
  super.removeAt(i);
package/src/extLink.js CHANGED
@@ -47,6 +47,7 @@ class ExtLinkToken extends Token {
47
47
  if (text) {
48
48
  token.appendChild(text);
49
49
  }
50
+ return token;
50
51
  }
51
52
 
52
53
  #correct() {
@@ -77,14 +78,6 @@ class ExtLinkToken extends Token {
77
78
  return `[${super.text(' ').replaceAll('\n', ' ')}]`;
78
79
  }
79
80
 
80
- /**
81
- * @returns {[number, string][]}
82
- * @complexity `n`
83
- */
84
- plain() {
85
- return this.childNodes.length === 1 ? [] : this.lastElementChild.plain();
86
- }
87
-
88
81
  /** @this {ExtLinkToken & {firstElementChild: MagicLinkToken}} */
89
82
  getUrl() {
90
83
  return this.firstElementChild.getUrl();
package/src/gallery.js ADDED
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ const {text} = require('../util/string'),
4
+ /** @type {Parser} */ Parser = require('..'),
5
+ Token = require('.'),
6
+ GalleryImageToken = require('./link/galleryImage');
7
+
8
+ /**
9
+ * gallery标签
10
+ * @classdesc `{childNodes: (string|FileToken)[]]}`
11
+ */
12
+ class GalleryToken extends Token {
13
+ type = 'ext-inner';
14
+ name = 'gallery';
15
+
16
+ /**
17
+ * @param {string} inner
18
+ * @param {accum} accum
19
+ */
20
+ constructor(inner, config = Parser.getConfig(), accum = []) {
21
+ super(undefined, config, true, accum, {String: ':', GalleryImageToken: ':'});
22
+ for (const line of inner?.split('\n') ?? []) {
23
+ const matches = line.match(/^([^|]+)(?:\|(.*))?/);
24
+ if (!matches) {
25
+ this.appendChild(line);
26
+ continue;
27
+ }
28
+ const [, file, alt] = matches;
29
+ let title;
30
+ try {
31
+ title = this.normalizeTitle(decodeURIComponent(file), 6, true);
32
+ } catch {
33
+ title = this.normalizeTitle(file, 6, true);
34
+ }
35
+ if (!title.valid) {
36
+ this.appendChild(line);
37
+ } else {
38
+ this.appendChild(new GalleryImageToken(file, alt, title, config, accum));
39
+ }
40
+ }
41
+ }
42
+
43
+ cloneNode() {
44
+ const cloned = this.cloneChildren(),
45
+ token = Parser.run(() => new GalleryToken(undefined, this.getAttribute('config')));
46
+ token.append(...cloned);
47
+ return token;
48
+ }
49
+
50
+ toString() {
51
+ return super.toString('\n');
52
+ }
53
+
54
+ getGaps() {
55
+ return 1;
56
+ }
57
+
58
+ text() {
59
+ return text(this.children, '\n');
60
+ }
61
+ }
62
+
63
+ Parser.classes.GalleryToken = __filename;
64
+ module.exports = GalleryToken;
package/src/heading.js CHANGED
@@ -63,11 +63,6 @@ class HeadingToken extends fixedToken(sol(Token)) {
63
63
  return `${this.prependNewLine()}${equals}${this.firstElementChild.text()}${equals}${this.appendNewLine()}`;
64
64
  }
65
65
 
66
- /** @returns {[number, string][]} */
67
- plain() {
68
- return this.firstElementChild.plain();
69
- }
70
-
71
66
  /** @param {number} n */
72
67
  setLevel(n) {
73
68
  if (typeof n !== 'number') {
package/src/html.js CHANGED
@@ -62,11 +62,6 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
62
62
  return `<${this.closing ? '/' : ''}${this.#tag}${super.text()}${this.selfClosing ? '/' : ''}>`;
63
63
  }
64
64
 
65
- /** @returns {[number, string][]} */
66
- plain() {
67
- return [];
68
- }
69
-
70
65
  /** @param {string} tag */
71
66
  replaceTag(tag) {
72
67
  const name = tag.toLowerCase();
@@ -2,7 +2,7 @@
2
2
 
3
3
  const /** @type {Parser} */ Parser = require('../..'),
4
4
  LinkToken = require('.'),
5
- Token = require('..'); // eslint-disable-line no-unused-vars
5
+ Token = require('..');
6
6
 
7
7
  /**
8
8
  * 分类
@@ -12,6 +12,7 @@ class CategoryToken extends LinkToken {
12
12
  type = 'category';
13
13
  sortkey = '';
14
14
 
15
+ setLangLink = undefined;
15
16
  setFragment = undefined;
16
17
  asSelfLink = undefined;
17
18
  pipeTrick = undefined;
@@ -74,11 +75,6 @@ class CategoryToken extends LinkToken {
74
75
  return `[[${this.firstElementChild.text()}]]`;
75
76
  }
76
77
 
77
- /** @returns {[number, string][]} */
78
- plain() {
79
- return [];
80
- }
81
-
82
78
  /** @param {string} text */
83
79
  setSortkey(text) {
84
80
  this.setLinkText(text);
package/src/link/file.js CHANGED
@@ -15,6 +15,7 @@ class FileToken extends LinkToken {
15
15
  /** @type {Set<string>} */ #keys = new Set();
16
16
  /** @type {Record<string, Set<ImageParameterToken>>} */ #args = {};
17
17
 
18
+ setLangLink = undefined;
18
19
  setFragment = undefined;
19
20
  asSelfLink = undefined;
20
21
  setLinkText = undefined;
@@ -63,7 +64,7 @@ class FileToken extends LinkToken {
63
64
  super(link, undefined, title, config, accum);
64
65
  this.setAttribute('acceptable', {AtomToken: 0, ImageParameterToken: '1:'});
65
66
  this.append(...explode('-{', '}-', '|', text).map(part => new ImageParameterToken(part, config, accum)));
66
- this.seal(['setFragment', 'asSelfLink', 'setLinkText', 'pipeTrick']);
67
+ this.seal(['setLangLink', 'setFragment', 'asSelfLink', 'setLinkText', 'pipeTrick']);
67
68
  }
68
69
 
69
70
  /**
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ const /** @type {Parser} */ Parser = require('../..'),
4
+ Token = require('..'),
5
+ FileToken = require('./file');
6
+
7
+ /**
8
+ * 图片
9
+ * @classdesc `{childNodes: [AtomToken, ...ImageParameterToken]}`
10
+ */
11
+ class GalleryImageToken extends FileToken {
12
+ type = 'gallery-image';
13
+
14
+ size = undefined;
15
+ width = undefined;
16
+ height = undefined;
17
+
18
+ /**
19
+ * @param {string} link
20
+ * @param {string|undefined} text
21
+ * @param {Title} title
22
+ * @param {accum} accum
23
+ */
24
+ constructor(link, text, title, config = Parser.getConfig(), accum = []) {
25
+ let token;
26
+ if (text !== undefined) {
27
+ token = new Token(text, config, true, accum);
28
+ token.type = 'temp';
29
+ token.setAttribute('stage', 1);
30
+ for (let n = 1; n < Parser.MAX_STAGE; n++) {
31
+ token.parseOnce();
32
+ }
33
+ accum.splice(accum.indexOf(token), 1);
34
+ }
35
+ const newConfig = structuredClone(config);
36
+ newConfig.img = Object.fromEntries(Object.entries(config.img).filter(([, param]) => param !== 'width'));
37
+ super(link, token?.toString(), title, newConfig, accum);
38
+ this.seal(['size', 'width', 'height']);
39
+ }
40
+
41
+ getPadding() {
42
+ return 0;
43
+ }
44
+ }
45
+
46
+ Parser.classes.GalleryImageToken = __filename;
47
+ module.exports = GalleryImageToken;
package/src/link/index.js CHANGED
@@ -47,7 +47,7 @@ class LinkToken extends Token {
47
47
  title: this.name, interwiki: this.interwiki, fragment: this.fragment,
48
48
  }, this.getAttribute('config'));
49
49
  token.firstElementChild.safeReplaceWith(link);
50
- token.appendChild(...linkText);
50
+ token.append(...linkText);
51
51
  return token.afterBuild();
52
52
  });
53
53
  }
@@ -90,7 +90,8 @@ class LinkToken extends Token {
90
90
  }
91
91
 
92
92
  toString() {
93
- return `[[${super.toString('|')}]]`;
93
+ const str = super.toString('|');
94
+ return this.type === 'gallery-image' ? str : `[[${str}]]`;
94
95
  }
95
96
 
96
97
  getPadding() {
@@ -102,24 +103,20 @@ class LinkToken extends Token {
102
103
  }
103
104
 
104
105
  text() {
105
- return `[[${super.text('|')}]]`;
106
- }
107
-
108
- /** @returns {[number, string][]} */
109
- plain() {
110
- return this.childNodes.length === 1 ? [] : this.lastElementChild.plain();
106
+ const str = super.text('|');
107
+ return this.type === 'gallery-image' ? str : `[[${str}]]`;
111
108
  }
112
109
 
113
110
  /** @param {string} link */
114
111
  setTarget(link) {
115
112
  link = String(link);
116
- if (!/^\s*[:#]/.test(link)) {
113
+ if (link.type === 'link' && !/^\s*[:#]/.test(link)) {
117
114
  link = `:${link}`;
118
115
  }
119
116
  const root = Parser.parse(`[[${link}]]`, this.getAttribute('include'), 6, this.getAttribute('config')),
120
117
  {childNodes: {length}, firstElementChild} = root;
121
118
  if (length !== 1 || firstElementChild?.type !== this.type || firstElementChild.childNodes.length !== 1) {
122
- const msgs = {link: '内链', file: '文件链接', category: '分类'};
119
+ const msgs = {link: '内链', file: '文件链接', category: '分类', 'gallery-image': '文件链接'};
123
120
  throw new SyntaxError(`非法的${msgs[this.type]}目标:${link}`);
124
121
  }
125
122
  const {firstChild} = firstElementChild;
@@ -128,6 +125,33 @@ class LinkToken extends Token {
128
125
  this.firstElementChild.safeReplaceWith(firstChild);
129
126
  }
130
127
 
128
+ /**
129
+ * @param {string} lang
130
+ * @param {string} link
131
+ */
132
+ setLangLink(lang, link) {
133
+ if (typeof lang !== 'string') {
134
+ this.typeError('setLangLink', 'String');
135
+ }
136
+ link = String(link).trim();
137
+ if (link.startsWith('#')) {
138
+ throw new SyntaxError(`跨语言链接不能仅为fragment!`);
139
+ } else if (link.startsWith(':')) {
140
+ link = link.slice(1);
141
+ }
142
+ const root = Parser.parse(`[[${lang}:${link}]]`, this.getAttribute('include'), 6, this.getAttribute('config')),
143
+ /** @type {Token & {firstElementChild: LinkToken}} */ {childNodes: {length}, firstElementChild} = root;
144
+ if (length !== 1 || firstElementChild?.type !== 'link' || firstElementChild.childNodes.length !== 1
145
+ || firstElementChild.interwiki !== lang.toLowerCase()
146
+ ) {
147
+ throw new SyntaxError(`非法的跨语言链接目标:${lang}:${link}`);
148
+ }
149
+ const {firstChild} = firstElementChild;
150
+ root.destroy();
151
+ firstElementChild.destroy();
152
+ this.firstElementChild.safeReplaceWith(firstChild);
153
+ }
154
+
131
155
  /** @param {string} fragment */
132
156
  #setFragment(fragment, page = true) {
133
157
  fragment = String(fragment).replace(/[<>[]#|=!]/g, p => encodeURIComponent(p));
package/src/magicLink.js CHANGED
@@ -37,7 +37,7 @@ class MagicLinkToken extends Token {
37
37
  }
38
38
 
39
39
  afterBuild() {
40
- const ParameterToken = require('./parameter'), // eslint-disable-line no-unused-vars
40
+ const ParameterToken = require('./parameter'),
41
41
  /** @type {ParameterToken} */ parameter = this.closest('parameter');
42
42
  if (parameter?.getValue() === this.text()) {
43
43
  this.replaceWith(this.toString());
@@ -45,6 +45,16 @@ class MagicLinkToken extends Token {
45
45
  return this;
46
46
  }
47
47
 
48
+ cloneNode() {
49
+ const cloned = this.cloneChildren(),
50
+ token = Parser.run(() => new MagicLinkToken(
51
+ undefined, this.type === 'ext-link-url', this.getAttribute('config'),
52
+ ));
53
+ token.append(...cloned);
54
+ token.afterBuild();
55
+ return token;
56
+ }
57
+
48
58
  getUrl() {
49
59
  let url = this.text();
50
60
  if (url.startsWith('//')) {
package/src/nowiki/dd.js CHANGED
@@ -29,11 +29,6 @@ class DdToken extends NowikiToken {
29
29
  this.seal(['dt', 'ul', 'ol', 'indent']).#update(str);
30
30
  }
31
31
 
32
- /** @returns {[number, string][]} */
33
- plain() {
34
- return [];
35
- }
36
-
37
32
  /** @param {string} str */
38
33
  setText(str) {
39
34
  const src = this.type === 'dd' ? ':' : ';:*#';
package/src/nowiki/hr.js CHANGED
@@ -24,11 +24,6 @@ class HrToken extends sol(NowikiToken) {
24
24
  return Parser.run(() => new HrToken(this.firstChild.length, this.getAttribute('config')));
25
25
  }
26
26
 
27
- /** @returns {[number, string][]} */
28
- plain() {
29
- return [];
30
- }
31
-
32
27
  /** @param {string} str */
33
28
  setText(str) {
34
29
  if (!/^-{4,}$/.test(str)) {
@@ -16,7 +16,7 @@ class NowikiToken extends fixedToken(Token) {
16
16
  * @param {accum} accum
17
17
  */
18
18
  constructor(wikitext, config = Parser.getConfig(), accum = []) {
19
- super(wikitext, config, false, accum);
19
+ super(wikitext, config, true, accum);
20
20
  }
21
21
 
22
22
  /** @this {NowikiToken & {firstChild: string}} */
@@ -26,11 +26,6 @@ class QuoteToken extends NowikiToken {
26
26
  }
27
27
  return super.setText(str);
28
28
  }
29
-
30
- /** @returns {[number, string][]} */
31
- plain() {
32
- return [];
33
- }
34
29
  }
35
30
 
36
31
  Parser.classes.QuoteToken = __filename;
@@ -15,7 +15,7 @@ class OnlyincludeToken extends Token {
15
15
  * @param {accum} accum
16
16
  */
17
17
  constructor(inner, config = Parser.getConfig(), accum = []) {
18
- super(inner, config, false, accum);
18
+ super(inner, config, true, accum);
19
19
  }
20
20
 
21
21
  cloneNode() {
package/src/parameter.js CHANGED
@@ -85,11 +85,6 @@ class ParameterToken extends fixedToken(Token) {
85
85
  return this.anon ? this.lastElementChild.text() : super.text('=');
86
86
  }
87
87
 
88
- /** @returns {[number, string][]} */
89
- plain() {
90
- return this.lastElementChild.plain();
91
- }
92
-
93
88
  /**
94
89
  * @param {ParameterToken} token
95
90
  * @complexity `n`
package/src/syntax.js CHANGED
@@ -60,11 +60,6 @@ class SyntaxToken extends Token {
60
60
  return super.getAttribute(key);
61
61
  }
62
62
 
63
- /** @returns {[number, string][]} */
64
- plain() {
65
- return [];
66
- }
67
-
68
63
  /**
69
64
  * @param {...string|Token} elements
70
65
  * @complexity `n`
@@ -3,19 +3,19 @@
3
3
  const assert = require('assert/strict'),
4
4
  {noWrap} = require('../../util/string'),
5
5
  /** @type {Parser} */ Parser = require('../..'),
6
- Token = require('..'), // eslint-disable-line no-unused-vars
6
+ Token = require('..'),
7
7
  TrToken = require('./tr'),
8
8
  TdToken = require('./td'),
9
9
  SyntaxToken = require('../syntax'),
10
- AttributeToken = require('../attribute'); // eslint-disable-line no-unused-vars
10
+ AttributeToken = require('../attribute');
11
11
 
12
12
  /**
13
13
  * @param {TableCoords} coords1
14
14
  * @param {TableCoords} coords2
15
15
  */
16
16
  const cmpCoords = (coords1, coords2) => {
17
- const diff = coords1?.row - coords2?.row;
18
- return diff === 0 ? coords1?.column - coords2?.column : diff;
17
+ const diff = coords1.row - coords2.row;
18
+ return diff === 0 ? coords1.column - coords2.column : diff;
19
19
  };
20
20
  const isRowEnd = /** @param {Token} */ ({type}) => ['tr', 'table-syntax'].includes(type);
21
21
 
@@ -192,7 +192,7 @@ class TableToken extends TrToken {
192
192
  {length} = rows,
193
193
  /** @type {Layout} */ layout = new Layout(length).fill().map(() => []);
194
194
  for (const [i, rowToken] of rows.entries()) {
195
- if (i > stop.row ?? stop.y) {
195
+ if (i > (stop.row ?? stop.y)) {
196
196
  break;
197
197
  }
198
198
  const rowLayout = layout[i];
package/src/table/td.js CHANGED
@@ -45,7 +45,7 @@ class TdToken extends fixedToken(TrToken) {
45
45
  */
46
46
  getSyntax() {
47
47
  const syntax = this.firstElementChild.text(),
48
- escape = syntax.includes('{{');
48
+ esc = syntax.includes('{{');
49
49
  let subtype = 'td';
50
50
  if (syntax.endsWith('!')) {
51
51
  subtype = 'th';
@@ -53,14 +53,14 @@ class TdToken extends fixedToken(TrToken) {
53
53
  subtype = 'caption';
54
54
  }
55
55
  if (this.isIndependent()) {
56
- return {subtype, escape, correction: false};
56
+ return {subtype, escape: esc, correction: false};
57
57
  }
58
58
  const {previousElementSibling} = this;
59
59
  if (previousElementSibling?.type !== 'td') {
60
- return {subtype, escape, correction: true};
60
+ return {subtype, escape: esc, correction: true};
61
61
  }
62
62
  const result = previousElementSibling.getSyntax();
63
- result.escape ||= escape;
63
+ result.escape ||= esc;
64
64
  result.correction = previousElementSibling.lastElementChild.offsetHeight > 1;
65
65
  if (subtype === 'th' && result.subtype !== 'th') {
66
66
  result.subtype = 'th';
@@ -91,6 +91,7 @@ class TdToken extends fixedToken(TrToken) {
91
91
  if (innerSyntax) {
92
92
  [this.#innerSyntax] = innerSyntax;
93
93
  }
94
+ // eslint-disable-next-line no-unsafe-optional-chaining
94
95
  const innerToken = new Token(inner?.slice(innerSyntax?.index + this.#innerSyntax.length), config, true, accum);
95
96
  innerToken.type = 'td-inner';
96
97
  this.setAttribute('acceptable', {SyntaxToken: 0, AttributeToken: 1, Token: 2})
@@ -98,7 +99,7 @@ class TdToken extends fixedToken(TrToken) {
98
99
  }
99
100
 
100
101
  cloneNode() {
101
- const token = super.cloneNode();
102
+ const /** @type {TdToken} */ token = super.cloneNode();
102
103
  token.setAttribute('innerSyntax', this.#innerSyntax);
103
104
  return token;
104
105
  }
@@ -141,6 +142,7 @@ class TdToken extends fixedToken(TrToken) {
141
142
  * @template {string} T
142
143
  * @param {T} key
143
144
  * @param {TokenAttribute<T>} value
145
+ * @return {this}
144
146
  */
145
147
  setAttribute(key, value) {
146
148
  if (key !== 'innerSyntax') {
@@ -162,8 +164,8 @@ class TdToken extends fixedToken(TrToken) {
162
164
  static #aliases = {td: '\n|', th: '\n!', caption: '\n|+'};
163
165
 
164
166
  /** @param {string} syntax */
165
- setSyntax(syntax, escape = false) {
166
- super.setSyntax(TdToken.#aliases[syntax] ?? syntax, escape);
167
+ setSyntax(syntax, esc = false) {
168
+ super.setSyntax(TdToken.#aliases[syntax] ?? syntax, esc);
167
169
  }
168
170
 
169
171
  /** @complexity `n` */
@@ -171,17 +173,17 @@ class TdToken extends fixedToken(TrToken) {
171
173
  if (this.children[1].toString()) {
172
174
  this.#innerSyntax ||= '|';
173
175
  }
174
- const {subtype, escape, correction} = this.getSyntax();
176
+ const {subtype, escape: esc, correction} = this.getSyntax();
175
177
  if (correction) {
176
- this.setSyntax(subtype, escape);
178
+ this.setSyntax(subtype, esc);
177
179
  }
178
180
  }
179
181
 
180
182
  /** @complexity `n` */
181
183
  independence() {
182
184
  if (!this.isIndependent()) {
183
- const {subtype, escape} = this.getSyntax();
184
- this.setSyntax(subtype, escape);
185
+ const {subtype, escape: esc} = this.getSyntax();
186
+ this.setSyntax(subtype, esc);
185
187
  }
186
188
  }
187
189
 
package/src/table/tr.js CHANGED
@@ -93,10 +93,10 @@ class TrToken extends attributeParent(Token, 1) {
93
93
  }
94
94
 
95
95
  /** @param {string} syntax */
96
- setSyntax(syntax, escape = false) {
96
+ setSyntax(syntax, esc = false) {
97
97
  const {firstElementChild} = this;
98
98
  firstElementChild.replaceChildren(syntax);
99
- if (escape) {
99
+ if (esc) {
100
100
  TrToken.escape(firstElementChild);
101
101
  }
102
102
  }
@@ -202,7 +202,7 @@ class TrToken extends attributeParent(Token, 1) {
202
202
  if (n < 0 || n > nCols || n === nCols && !insert) {
203
203
  throw new RangeError(`不存在第 ${n} 个单元格!`);
204
204
  }
205
- const TdToken = require('./td'); // eslint-disable-line no-unused-vars
205
+ const TdToken = require('./td');
206
206
  let last = 0;
207
207
  for (const child of this.children.slice(2)) {
208
208
  if (child instanceof TdToken) {
@@ -23,7 +23,7 @@ class ExtToken extends attributeParent(TagPairToken) {
23
23
  attrToken = new AttributeToken(attr, 'ext-attr', lcName, config, accum),
24
24
  newConfig = structuredClone(config),
25
25
  ext = new Set(newConfig.ext);
26
- let /** @type {acceptable} */ acceptable, innerToken;
26
+ let /** @type {acceptable} */ acceptable, /** @type {Token} */ innerToken;
27
27
  switch (lcName) {
28
28
  case 'choose':
29
29
  ext.add('option');
@@ -42,15 +42,23 @@ class ExtToken extends attributeParent(TagPairToken) {
42
42
  innerToken = new Token(inner, newConfig, false, accum);
43
43
  break;
44
44
  }
45
+ case 'gallery': {
46
+ ext.delete(lcName);
47
+ newConfig.ext = [...ext];
48
+ const GalleryToken = require('../gallery');
49
+ acceptable = {AttributeToken: 0, GalleryToken: 1};
50
+ innerToken = new GalleryToken(inner, newConfig, accum);
51
+ break;
52
+ }
45
53
  /*
46
54
  * 更多定制扩展的代码示例:
47
55
  * ```
48
56
  * case 'extensionName': {
49
- * ext.delete(this.name);
57
+ * ext.delete(lcName);
50
58
  * newConfig.ext = [...ext];
51
59
  * const ExtensionToken = require('../extension');
52
60
  * acceptable = {AttributeToken: 0, ExtensionToken: 1};
53
- * innerToken = new ExtensionToken(extInner, newConfig, false, accum);
61
+ * innerToken = new ExtensionToken(inner, newConfig, accum);
54
62
  * break;
55
63
  * }
56
64
  * ```
@@ -79,6 +87,10 @@ class ExtToken extends attributeParent(TagPairToken) {
79
87
  token.lastElementChild.safeReplaceWith(inner);
80
88
  return token;
81
89
  }
90
+
91
+ get innerText() {
92
+ return this.selfClosing ? '' : this.lastElementChild.text();
93
+ }
82
94
  }
83
95
 
84
96
  Parser.classes.ExtToken = __filename;
@@ -21,7 +21,7 @@ class TagPairToken extends fixedToken(Token) {
21
21
  * @param {accum} accum
22
22
  */
23
23
  constructor(name, attr, inner, closing, config = Parser.getConfig(), accum = []) {
24
- super(undefined, config);
24
+ super(undefined, config, true);
25
25
  this.setAttribute('name', name.toLowerCase()).#tags = [name, closing || name];
26
26
  this.selfClosing = closing === undefined;
27
27
  this.closed = closing !== '';
@@ -76,15 +76,6 @@ class TagPairToken extends fixedToken(Token) {
76
76
  ? `<${opening}${typeof firstChild === 'string' ? firstChild : firstChild.text()}/>`
77
77
  : `<${opening}${super.text('>')}${closed ? `</${closing}>` : ''}`;
78
78
  }
79
-
80
- /** @returns {[number, string][]} */
81
- plain() {
82
- const {lastChild} = this;
83
- if (typeof lastChild === 'string') {
84
- return lastChild ? [[this.getAbsoluteIndex() + this.getRelativeIndex(1), lastChild]] : [];
85
- }
86
- return lastChild.plain();
87
- }
88
79
  }
89
80
 
90
81
  Parser.classes.TagPairToken = __filename;
package/src/transclude.js CHANGED
@@ -209,10 +209,6 @@ class TranscludeToken extends Token {
209
209
  }}}`;
210
210
  }
211
211
 
212
- plain() {
213
- return this.getAllArgs().flatMap(child => child.plain());
214
- }
215
-
216
212
  /**
217
213
  * @param {number|ParameterToken} addedToken
218
214
  * @complexity `n`
package/util/string.js CHANGED
@@ -21,7 +21,7 @@ const escapeRegExp = str => str.replace(/[\\{}()|.?*+\-^$[\]]/g, '\\$&');
21
21
 
22
22
  /** @param {(string|AstNode)[]} childNodes */
23
23
  const text = (childNodes, separator = '') => {
24
- const AstNode = require('../lib/node'); // eslint-disable-line no-unused-vars
24
+ const AstNode = require('../lib/node');
25
25
  return childNodes.map(child => typeof child === 'string' ? child : child.text()).join(separator);
26
26
  };
27
27
 
@@ -62,7 +62,7 @@ const noWrap = str => str.replaceAll('\n', '\\n');
62
62
  * @returns {string}
63
63
  */
64
64
  const normalizeSpace = (token = '', separator = '') => {
65
- const Token = require('../src'); // eslint-disable-line no-unused-vars
65
+ const Token = require('../src');
66
66
  return typeof token === 'string'
67
67
  ? token.replaceAll('\n', ' ')
68
68
  : token.childNodes.map(child => typeof child === 'string' ? normalizeSpace(child) : child.toString())