wikiparser-node 0.5.0 → 0.6.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 (63) hide show
  1. package/config/default.json +129 -66
  2. package/config/zhwiki.json +4 -4
  3. package/index.js +74 -65
  4. package/lib/element.js +125 -152
  5. package/lib/node.js +251 -223
  6. package/lib/ranges.js +2 -2
  7. package/lib/text.js +64 -64
  8. package/lib/title.js +8 -7
  9. package/mixin/hidden.js +2 -0
  10. package/mixin/sol.js +1 -2
  11. package/package.json +4 -3
  12. package/parser/brackets.js +8 -2
  13. package/parser/externalLinks.js +1 -1
  14. package/parser/hrAndDoubleUnderscore.js +4 -4
  15. package/parser/links.js +7 -7
  16. package/parser/table.js +12 -10
  17. package/src/arg.js +53 -48
  18. package/src/atom/index.js +7 -5
  19. package/src/attribute.js +91 -80
  20. package/src/charinsert.js +91 -0
  21. package/src/converter.js +22 -11
  22. package/src/converterFlags.js +72 -62
  23. package/src/converterRule.js +49 -49
  24. package/src/extLink.js +30 -28
  25. package/src/gallery.js +56 -32
  26. package/src/hasNowiki/index.js +42 -0
  27. package/src/hasNowiki/pre.js +40 -0
  28. package/src/heading.js +15 -11
  29. package/src/html.js +38 -38
  30. package/src/imageParameter.js +64 -48
  31. package/src/imagemap.js +205 -0
  32. package/src/imagemapLink.js +43 -0
  33. package/src/index.js +222 -124
  34. package/src/link/category.js +4 -8
  35. package/src/link/file.js +95 -59
  36. package/src/link/galleryImage.js +74 -10
  37. package/src/link/index.js +61 -39
  38. package/src/magicLink.js +21 -22
  39. package/src/nested/choose.js +24 -0
  40. package/src/nested/combobox.js +23 -0
  41. package/src/nested/index.js +88 -0
  42. package/src/nested/references.js +23 -0
  43. package/src/nowiki/comment.js +17 -17
  44. package/src/nowiki/dd.js +2 -2
  45. package/src/nowiki/doubleUnderscore.js +14 -14
  46. package/src/nowiki/index.js +12 -0
  47. package/src/onlyinclude.js +10 -8
  48. package/src/paramTag/index.js +83 -0
  49. package/src/paramTag/inputbox.js +42 -0
  50. package/src/parameter.js +32 -18
  51. package/src/syntax.js +9 -1
  52. package/src/table/index.js +33 -32
  53. package/src/table/td.js +51 -57
  54. package/src/table/tr.js +6 -6
  55. package/src/tagPair/ext.js +58 -40
  56. package/src/tagPair/include.js +1 -1
  57. package/src/tagPair/index.js +21 -20
  58. package/src/transclude.js +158 -143
  59. package/tool/index.js +720 -439
  60. package/util/base.js +17 -0
  61. package/util/debug.js +1 -1
  62. package/util/diff.js +1 -1
  63. package/util/string.js +20 -20
@@ -3,12 +3,12 @@
3
3
  const assert = require('assert/strict'),
4
4
  {noWrap} = require('../../util/string'),
5
5
  {generateForChild} = require('../../util/lint'),
6
+ {isPlainObject} = require('../../util/base'),
6
7
  Parser = require('../..'),
7
8
  Token = require('..'),
8
9
  TrToken = require('./tr'),
9
10
  TdToken = require('./td'),
10
- SyntaxToken = require('../syntax'),
11
- AttributeToken = require('../attribute');
11
+ SyntaxToken = require('../syntax');
12
12
 
13
13
  const openingPattern = /^(?:\{\||\{\{\{\s*!\s*\}\}|\{\{\s*\(!\s*\}\})$/u,
14
14
  closingPattern = /^\n[^\S\n]*(?:\|\}|\{\{\s*!\s*\}\}\}|\{\{\s*!\)\s*\}\})$/u;
@@ -145,18 +145,6 @@ class TableToken extends TrToken {
145
145
  });
146
146
  }
147
147
 
148
- /**
149
- * @override
150
- * @param {number} start 起始位置
151
- */
152
- lint(start = 0) {
153
- const errors = super.lint(start);
154
- if (!this.closed) {
155
- errors.push(generateForChild(this.firstChild, this.getRootNode().posFromIndex(start), '未闭合的表格'));
156
- }
157
- return errors;
158
- }
159
-
160
148
  /**
161
149
  * @override
162
150
  * @template {TrToken|SyntaxToken} T
@@ -170,8 +158,8 @@ class TableToken extends TrToken {
170
158
  const previous = this.childNodes.at(i - 1);
171
159
  if (token.type === 'td' && previous.type === 'tr') {
172
160
  Parser.warn('改为将单元格插入当前行。');
173
- return previous.appendChild(token);
174
- } else if (!Parser.running && i === this.childNodes.length && token instanceof SyntaxToken
161
+ return previous.insertAt(token);
162
+ } else if (i > 0 && i === this.childNodes.length && token instanceof SyntaxToken
175
163
  && (token.getAttribute('pattern') !== closingPattern || !closingPattern.test(token.text()))
176
164
  ) {
177
165
  throw new SyntaxError(`表格的闭合部分不符合语法!${noWrap(String(token))}`);
@@ -179,6 +167,18 @@ class TableToken extends TrToken {
179
167
  return super.insertAt(token, i);
180
168
  }
181
169
 
170
+ /**
171
+ * @override
172
+ * @param {number} start 起始位置
173
+ */
174
+ lint(start = 0) {
175
+ const errors = super.lint(start);
176
+ if (!this.closed) {
177
+ errors.push(generateForChild(this.firstChild, this.getRootNode().posFromIndex(start), '未闭合的表格'));
178
+ }
179
+ return errors;
180
+ }
181
+
182
182
  /**
183
183
  * 闭合表格语法
184
184
  * @complexity `n`
@@ -196,7 +196,7 @@ class TableToken extends TrToken {
196
196
  } else if (lastChild instanceof SyntaxToken) {
197
197
  lastChild.replaceChildren(...inner.childNodes);
198
198
  } else {
199
- this.appendChild(Parser.run(() => {
199
+ super.insertAt(Parser.run(() => {
200
200
  const token = new SyntaxToken(syntax, closingPattern, 'table-syntax', config, accum, {
201
201
  'Stage-1': ':', '!ExtToken': '', TranscludeToken: ':',
202
202
  });
@@ -241,7 +241,7 @@ class TableToken extends TrToken {
241
241
  * @throws `RangeError` 不存在该行
242
242
  */
243
243
  getNthRow(n, force, insert) {
244
- if (typeof n !== 'number') {
244
+ if (!Number.isInteger(n)) {
245
245
  this.typeError('getNthRow', 'Number');
246
246
  }
247
247
  const nRows = this.getRowCount(),
@@ -357,7 +357,7 @@ class TableToken extends TrToken {
357
357
  * @complexity `n`
358
358
  */
359
359
  toRenderedCoords({row, column}) {
360
- if (typeof row !== 'number' || typeof column !== 'number') {
360
+ if (!Number.isInteger(row) || !Number.isInteger(column)) {
361
361
  this.typeError('toRenderedCoords', 'Number');
362
362
  }
363
363
  const rowLayout = this.getLayout({row, column})[row],
@@ -371,7 +371,7 @@ class TableToken extends TrToken {
371
371
  * @complexity `n`
372
372
  */
373
373
  toRawCoords({x, y}) {
374
- if (typeof x !== 'number' || typeof y !== 'number') {
374
+ if (!Number.isInteger(x) || !Number.isInteger(y)) {
375
375
  this.typeError('toRawCoords', 'Number');
376
376
  }
377
377
  const rowLayout = this.getLayout({x, y})[y],
@@ -392,7 +392,7 @@ class TableToken extends TrToken {
392
392
  * @complexity `n²`
393
393
  */
394
394
  getFullRow(y) {
395
- if (typeof y !== 'number') {
395
+ if (!Number.isInteger(y)) {
396
396
  this.typeError('getFullRow', 'Number');
397
397
  }
398
398
  const rows = this.getAllRows();
@@ -407,7 +407,7 @@ class TableToken extends TrToken {
407
407
  * @complexity `n`
408
408
  */
409
409
  getFullCol(x) {
410
- if (typeof x !== 'number') {
410
+ if (!Number.isInteger(x)) {
411
411
  this.typeError('getFullCol', 'Number');
412
412
  }
413
413
  const layout = this.getLayout(),
@@ -505,14 +505,14 @@ class TableToken extends TrToken {
505
505
  const row = Parser.run(() => new TrToken('\n|-', undefined, this.getAttribute('config'))),
506
506
  {childNodes} = this,
507
507
  [,, plain] = childNodes,
508
- start = plain?.isPlain() ? 3 : 2,
508
+ start = plain?.constructor === Token ? 3 : 2,
509
509
  /** @type {TdToken[]} */ tdChildren = childNodes.slice(start),
510
510
  index = tdChildren.findIndex(({type}) => type !== 'td');
511
511
  this.insertAt(row, index === -1 ? -1 : index + start);
512
512
  Parser.run(() => {
513
513
  for (const cell of tdChildren.slice(0, index === -1 ? undefined : index)) {
514
514
  if (cell.subtype !== 'caption') {
515
- row.appendChild(cell);
515
+ row.insertAt(cell);
516
516
  }
517
517
  }
518
518
  });
@@ -529,10 +529,11 @@ class TableToken extends TrToken {
529
529
  * @complexity `n`
530
530
  */
531
531
  insertTableRow(y, attr = {}, inner = undefined, subtype = 'td', innerAttr = {}) {
532
- if (typeof attr !== 'object') {
532
+ if (!isPlainObject(attr)) {
533
533
  this.typeError('insertTableRow', 'Object');
534
534
  }
535
535
  let reference = this.getNthRow(y, false, true);
536
+ const AttributeToken = require('../attribute');
536
537
  /** @type {TrToken & AttributeToken}} */
537
538
  const token = Parser.run(() => new TrToken('\n|-', undefined, this.getAttribute('config')));
538
539
  for (const [k, v] of Object.entries(attr)) {
@@ -552,7 +553,7 @@ class TableToken extends TrToken {
552
553
  for (let i = 0; i < maxCol; i++) {
553
554
  const coords = rowLayout[i];
554
555
  if (!coords) {
555
- token.appendChild(td.cloneNode());
556
+ token.insertAt(td.cloneNode());
556
557
  } else if (!set.has(coords)) {
557
558
  set.add(coords);
558
559
  if (coords.row < y) {
@@ -575,7 +576,7 @@ class TableToken extends TrToken {
575
576
  * @throws `RangeError` 列号过大
576
577
  */
577
578
  insertTableCol(x, inner, subtype = 'td', attr = {}) {
578
- if (typeof x !== 'number') {
579
+ if (!Number.isInteger(x)) {
579
580
  this.typeError('insertTableCol', 'Number');
580
581
  }
581
582
  const layout = this.getLayout(),
@@ -664,7 +665,7 @@ class TableToken extends TrToken {
664
665
  * @throws `RangeError` 待合并区域与外侧区域有重叠
665
666
  */
666
667
  mergeCells(xlim, ylim) {
667
- if ([...xlim, ...ylim].some(arg => typeof arg !== 'number')) {
668
+ if (![...xlim, ...ylim].every(Number.isInteger)) {
668
669
  this.typeError('mergeCells', 'Number');
669
670
  }
670
671
  const layout = this.getLayout(),
@@ -677,7 +678,7 @@ class TableToken extends TrToken {
677
678
  if ([...layout[ymin - 1] ?? [], ...layout[ymax] ?? []].some(coords => set.has(coords))
678
679
  || layout.some(rowLayout => set.has(rowLayout[xmin - 1]) || set.has(rowLayout[xmax]))
679
680
  ) {
680
- throw new RangeError(`待合并区域与外侧区域有重叠!`);
681
+ throw new RangeError('待合并区域与外侧区域有重叠!');
681
682
  }
682
683
  const corner = layout[ymin][xmin],
683
684
  rows = this.getAllRows(),
@@ -817,7 +818,7 @@ class TableToken extends TrToken {
817
818
  * @throws `RangeError` 无法移动
818
819
  */
819
820
  moveTableRowBefore(y, before) {
820
- if (typeof y !== 'number' || typeof before !== 'number') {
821
+ if (!Number.isInteger(y) || !Number.isInteger(before)) {
821
822
  this.typeError('moveTableRowBefore', 'Number');
822
823
  }
823
824
  const layout = this.getLayout();
@@ -857,7 +858,7 @@ class TableToken extends TrToken {
857
858
  * @throws `RangeError` 无法移动
858
859
  */
859
860
  moveTableRowAfter(y, after) {
860
- if (typeof y !== 'number' || typeof after !== 'number') {
861
+ if (!Number.isInteger(y) || !Number.isInteger(after)) {
861
862
  this.typeError('moveTableRowAfter', 'Number');
862
863
  }
863
864
  const layout = this.getLayout(),
@@ -910,7 +911,7 @@ class TableToken extends TrToken {
910
911
  * @throws `RangeError` 无法移动
911
912
  */
912
913
  #moveCol(x, reference, after = false) {
913
- if (typeof x !== 'number' || typeof reference !== 'number') {
914
+ if (!Number.isInteger(x) || !Number.isInteger(reference)) {
914
915
  this.typeError(`moveTableCol${after ? 'After' : 'Before'}`, 'Number');
915
916
  }
916
917
  const layout = this.getLayout();
package/src/table/td.js CHANGED
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const fixedToken = require('../../mixin/fixedToken'),
4
- {externalUse, typeError} = require('../../util/debug'),
4
+ {typeError} = require('../../util/debug'),
5
+ {isPlainObject} = require('../../util/base'),
5
6
  Parser = require('../..'),
6
7
  Token = require('..'),
7
8
  TrToken = require('./tr');
@@ -82,7 +83,7 @@ class TdToken extends fixedToken(TrToken) {
82
83
  const result = previousSibling.getSyntax();
83
84
  result.escape ||= esc;
84
85
  result.correction = previousSibling.lastChild
85
- .toString('comment, ext, include, noinclude, arg, template, magic-word, html')
86
+ .toString('comment, ext, include, noinclude, arg, template, magic-word')
86
87
  .includes('\n');
87
88
  if (subtype === 'th' && result.subtype !== 'th') {
88
89
  result.subtype = 'th';
@@ -91,10 +92,6 @@ class TdToken extends fixedToken(TrToken) {
91
92
  return result;
92
93
  }
93
94
 
94
- getRowCount = undefined;
95
- getNthCol = undefined;
96
- insertTableCell = undefined;
97
-
98
95
  /**
99
96
  * @param {string} syntax 单元格语法
100
97
  * @param {string} inner 内部wikitext
@@ -114,9 +111,50 @@ class TdToken extends fixedToken(TrToken) {
114
111
  // eslint-disable-next-line no-unsafe-optional-chaining
115
112
  const innerToken = new Token(inner?.slice(innerSyntax?.index + this.#innerSyntax.length), config, true, accum);
116
113
  innerToken.type = 'td-inner';
114
+ this.insertAt(innerToken.setAttribute('stage', 4));
117
115
  this.setAttribute('acceptable', {SyntaxToken: 0, AttributeToken: 1, Token: 2})
118
- .seal(['getRowCount', 'getNthCol', 'insertTableCell'], true)
119
- .appendChild(innerToken.setAttribute('stage', 4));
116
+ .seal(['getRowCount', 'getNthCol', 'insertTableCell'], true);
117
+ }
118
+
119
+ /** @override */
120
+ afterBuild() {
121
+ if (this.#innerSyntax.includes('\0')) {
122
+ this.#innerSyntax = this.getAttribute('buildFromStr')(this.#innerSyntax).map(String).join('');
123
+ }
124
+ return this;
125
+ }
126
+
127
+ /**
128
+ * @override
129
+ * @param {string} selector
130
+ * @returns {string}
131
+ * @complexity `n`
132
+ */
133
+ toString(selector) {
134
+ this.#correct();
135
+ const {childNodes: [syntax, attr, inner]} = this;
136
+ return selector && this.matches(selector)
137
+ ? ''
138
+ : `${syntax.toString(selector)}${attr.toString(selector)}${this.#innerSyntax}${inner.toString(selector)}`;
139
+ }
140
+
141
+ /**
142
+ * @override
143
+ * @param {number} i 子节点位置
144
+ */
145
+ getGaps(i = 0) {
146
+ i = i < 0 ? i + this.childNodes.length : i;
147
+ if (i === 1) {
148
+ this.#correct();
149
+ return this.#innerSyntax.length;
150
+ }
151
+ return 0;
152
+ }
153
+
154
+ /** @override */
155
+ print() {
156
+ const {childNodes: [syntax, attr, inner]} = this;
157
+ return `<span class="wpb-td">${syntax.print()}${attr.print()}${this.#innerSyntax}${inner.print()}</span>`;
120
158
  }
121
159
 
122
160
  /** @override */
@@ -135,7 +173,7 @@ class TdToken extends fixedToken(TrToken) {
135
173
  * @throws `RangeError` 非法的单元格类型
136
174
  */
137
175
  static create(inner, subtype = 'td', attr = {}, include = false, config = Parser.getConfig()) {
138
- if (typeof inner !== 'string' && (!(inner instanceof Token) || !inner.isPlain()) || typeof attr !== 'object') {
176
+ if (typeof inner !== 'string' && inner?.constructor !== Token || !isPlainObject(attr)) {
139
177
  typeError(this, 'create', 'String', 'Token', 'Object');
140
178
  } else if (subtype !== 'td' && subtype !== 'th' && subtype !== 'caption') {
141
179
  throw new RangeError('单元格的子类型只能为 "td"、"th" 或 "caption"!');
@@ -167,24 +205,13 @@ class TdToken extends fixedToken(TrToken) {
167
205
  * @param {T} key 属性键
168
206
  * @param {TokenAttribute<T>} value 属性值
169
207
  * @returns {this}
170
- * @throws `RangeError` 仅用于代码调试
171
208
  */
172
209
  setAttribute(key, value) {
173
- if (key !== 'innerSyntax') {
174
- return super.setAttribute(key, value);
175
- } else if (!Parser.debugging && externalUse('setAttribute')) {
176
- throw new RangeError(`使用 ${this.constructor.name}.setAttribute 方法设置私有属性 #${key} 仅用于代码调试!`);
210
+ if (key === 'innerSyntax') {
211
+ this.#innerSyntax = String(value);
212
+ return this;
177
213
  }
178
- this.#innerSyntax = String(value);
179
- return this;
180
- }
181
-
182
- /** @override */
183
- afterBuild() {
184
- if (this.#innerSyntax.includes('\0')) {
185
- this.#innerSyntax = this.getAttribute('buildFromStr')(this.#innerSyntax).map(String).join('');
186
- }
187
- return this;
214
+ return super.setAttribute(key, value);
188
215
  }
189
216
 
190
217
  /**
@@ -221,39 +248,6 @@ class TdToken extends fixedToken(TrToken) {
221
248
  }
222
249
  }
223
250
 
224
- /**
225
- * @override
226
- * @param {string} selector
227
- * @returns {string}
228
- * @complexity `n`
229
- */
230
- toString(selector) {
231
- this.#correct();
232
- const {childNodes: [syntax, attr, inner]} = this;
233
- return selector && this.matches(selector)
234
- ? ''
235
- : `${syntax.toString(selector)}${attr.toString(selector)}${this.#innerSyntax}${inner.toString(selector)}`;
236
- }
237
-
238
- /**
239
- * @override
240
- * @param {number} i 子节点位置
241
- */
242
- getGaps(i = 0) {
243
- i = i < 0 ? i + this.childNodes.length : i;
244
- if (i === 1) {
245
- this.#correct();
246
- return this.#innerSyntax.length;
247
- }
248
- return 0;
249
- }
250
-
251
- /** @override */
252
- print() {
253
- const {childNodes: [syntax, attr, inner]} = this;
254
- return `<span class="wpb-td">${syntax.print()}${attr.print()}${this.#innerSyntax}${inner.print()}</span>`;
255
- }
256
-
257
251
  /**
258
252
  * @override
259
253
  * @returns {string}
package/src/table/tr.js CHANGED
@@ -5,8 +5,7 @@ const {generateForChild} = require('../../util/lint'),
5
5
  Parser = require('../..'),
6
6
  AstText = require('../../lib/text'),
7
7
  Token = require('..'),
8
- SyntaxToken = require('../syntax'),
9
- AttributeToken = require('../attribute');
8
+ SyntaxToken = require('../syntax');
10
9
 
11
10
  const openingPattern = /^\n[^\S\n]*(?:\|-+|\{\{\s*!\s*\}\}-+|\{\{\s*!-\s*\}\}-*)$/u;
12
11
 
@@ -40,6 +39,7 @@ class TrToken extends attributeParent(Token, 1) {
40
39
  */
41
40
  constructor(syntax, attr = '', config = Parser.getConfig(), accum = [], pattern = openingPattern) {
42
41
  super(undefined, config, true, accum, {Token: 2, SyntaxToken: 0, AttributeToken: 1, TdToken: '2:'});
42
+ const AttributeToken = require('../attribute');
43
43
  this.append(
44
44
  new SyntaxToken(syntax, pattern, 'table-syntax', config, accum, {
45
45
  'Stage-1': ':', '!ExtToken': '', TranscludeToken: ':',
@@ -57,7 +57,7 @@ class TrToken extends attributeParent(Token, 1) {
57
57
  const errors = super.lint(start),
58
58
  inter = this.childNodes.find(({type}) => type === 'table-inter'),
59
59
  str = String(inter).trim();
60
- if (inter && str && !/^<!--.*-->$/u.test(str)) {
60
+ if (inter && str && !/^<!--.*-->$/su.test(str)) {
61
61
  const error = generateForChild(inter, this.getRootNode().posFromIndex(start), '将被移出表格的内容');
62
62
  error.startLine++;
63
63
  error.startCol = 0;
@@ -79,7 +79,7 @@ class TrToken extends attributeParent(Token, 1) {
79
79
  if (token.type === 'td') { // TdToken
80
80
  token.childNodes[2].safeReplaceWith(inner);
81
81
  } else if (inner !== undefined) {
82
- token.appendChild(inner);
82
+ token.insertAt(inner);
83
83
  }
84
84
  token.append(...cloned);
85
85
  return token;
@@ -89,7 +89,7 @@ class TrToken extends attributeParent(Token, 1) {
89
89
  /** 修复简单的表格语法错误 */
90
90
  #correct() {
91
91
  const {childNodes: [,, child]} = this;
92
- if (child?.isPlain()) {
92
+ if (child?.constructor === Token) {
93
93
  const /** @type {{firstChild: AstText}} */ {firstChild} = child;
94
94
  if (firstChild.type !== 'text') {
95
95
  child.prepend('\n');
@@ -253,7 +253,7 @@ class TrToken extends attributeParent(Token, 1) {
253
253
  * @throws `RangeError` 不存在对应单元格
254
254
  */
255
255
  getNthCol(n, insert) {
256
- if (typeof n !== 'number') {
256
+ if (!Number.isInteger(n)) {
257
257
  this.typeError('getNthCol', 'Number');
258
258
  }
259
259
  const nCols = this.getColCount();
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const attributeParent = require('../../mixin/attributeParent'),
3
+ const path = require('path'),
4
+ attributeParent = require('../../mixin/attributeParent'),
4
5
  Parser = require('../..'),
5
6
  TagPairToken = require('.');
6
7
 
@@ -10,11 +11,7 @@ const attributeParent = require('../../mixin/attributeParent'),
10
11
  */
11
12
  class ExtToken extends attributeParent(TagPairToken) {
12
13
  type = 'ext';
13
-
14
- /** @override */
15
- get closed() {
16
- return super.closed;
17
- }
14
+ closed = true;
18
15
 
19
16
  /**
20
17
  * @param {string} name 标签名
@@ -25,51 +22,74 @@ class ExtToken extends attributeParent(TagPairToken) {
25
22
  */
26
23
  constructor(name, attr = '', inner = '', closed = undefined, config = Parser.getConfig(), accum = []) {
27
24
  attr = !attr || attr.trimStart() !== attr ? attr : ` ${attr}`;
28
- const AttributeToken = require('../attribute');
25
+ const Token = require('..'),
26
+ AttributeToken = require('../attribute');
29
27
  const lcName = name.toLowerCase(),
30
28
  attrToken = new AttributeToken(attr, 'ext-attr', lcName, config, accum),
31
29
  newConfig = structuredClone(config),
32
30
  ext = new Set(newConfig.ext);
33
- let /** @type {acceptable} */ acceptable, /** @type {Token} */ innerToken;
31
+ let /** @type {Token} */ innerToken;
32
+ ext.delete(lcName);
33
+ newConfig.ext = [...ext];
34
34
  switch (lcName) {
35
- case 'choose':
36
- case 'option':
37
- case 'ref':
38
- case 'poem':
39
- case 'indicator':
40
35
  case 'tab':
36
+ ext.delete('tabs');
37
+ newConfig.ext = [...ext];
38
+ // fall through
39
+ case 'indicator':
40
+ case 'poem':
41
+ case 'ref':
42
+ case 'option':
43
+ case 'combooption':
41
44
  case 'tabs':
42
- case 'pre':
43
- case 'combobox':
44
- case 'combooption': {
45
- ext.delete(lcName);
46
- newConfig.ext = [
47
- ...ext,
48
- ...lcName === 'choose' ? ['option'] : [],
49
- ...lcName === 'combobox' ? ['combooption'] : [],
50
- ];
51
- const Token = require('..');
52
- acceptable = {AttributeToken: 0, Token: 1};
45
+ case 'poll':
46
+ case 'seo':
53
47
  innerToken = new Token(inner, newConfig, true, accum);
54
48
  break;
55
- }
56
49
  case 'gallery': {
57
- ext.delete(lcName);
58
- newConfig.ext = [...ext];
59
50
  const GalleryToken = require('../gallery');
60
- acceptable = {AttributeToken: 0, GalleryToken: 1};
61
51
  innerToken = new GalleryToken(inner, newConfig, accum);
62
52
  break;
63
53
  }
54
+ case 'pre': {
55
+ const PreToken = require('../hasNowiki/pre');
56
+ innerToken = new PreToken(inner, newConfig, accum);
57
+ break;
58
+ }
59
+ case 'charinsert': {
60
+ const CharinsertToken = require('../charinsert');
61
+ innerToken = new CharinsertToken(inner, newConfig, accum);
62
+ break;
63
+ }
64
+ case 'references':
65
+ case 'choose':
66
+ case 'combobox': {
67
+ const NestedToken = require('../nested'),
68
+ /** @type {typeof NestedToken} */ NestedExtToken = require(path.join('..', 'nested', lcName));
69
+ innerToken = new NestedExtToken(inner, newConfig, accum);
70
+ break;
71
+ }
72
+ case 'imagemap': {
73
+ const ImagemapToken = require('../imagemap');
74
+ innerToken = new ImagemapToken(inner, config, accum);
75
+ break;
76
+ }
77
+ case 'dynamicpagelist': {
78
+ const ParamTagToken = require('../paramTag');
79
+ innerToken = new ParamTagToken(inner, newConfig, accum);
80
+ break;
81
+ }
82
+ case 'inputbox': {
83
+ const InputboxToken = require('../paramTag/inputbox');
84
+ innerToken = new InputboxToken(inner, newConfig, accum);
85
+ break;
86
+ }
64
87
 
65
88
  /*
66
89
  * 更多定制扩展的代码示例:
67
90
  * ```
68
91
  * case 'extensionName': {
69
- * ext.delete(lcName);
70
- * newConfig.ext = [...ext];
71
92
  * const ExtensionToken = require('../extension');
72
- * acceptable = {AttributeToken: 0, ExtensionToken: 1};
73
93
  * innerToken = new ExtensionToken(inner, newConfig, accum);
74
94
  * break;
75
95
  * }
@@ -77,15 +97,11 @@ class ExtToken extends attributeParent(TagPairToken) {
77
97
  */
78
98
  default: {
79
99
  const NowikiToken = require('../nowiki');
80
- acceptable = {AttributeToken: 0, NowikiToken: 1};
81
100
  innerToken = new NowikiToken(inner, config);
82
101
  }
83
102
  }
84
103
  innerToken.setAttribute('name', lcName).type = 'ext-inner';
85
- if (lcName === 'pre') {
86
- innerToken.setAttribute('stage', Parser.MAX_STAGE - 1);
87
- }
88
- super(name, attrToken, innerToken, closed, config, accum, acceptable);
104
+ super(name, attrToken, innerToken, closed, config, accum);
89
105
  }
90
106
 
91
107
  /** @override */
@@ -93,10 +109,12 @@ class ExtToken extends attributeParent(TagPairToken) {
93
109
  const inner = this.lastChild.cloneNode(),
94
110
  tags = this.getAttribute('tags'),
95
111
  config = this.getAttribute('config'),
96
- attr = String(this.firstChild),
97
- token = Parser.run(() => new ExtToken(tags[0], attr, '', this.selfClosing ? undefined : tags[1], config));
98
- token.lastChild.safeReplaceWith(inner);
99
- return token;
112
+ attr = String(this.firstChild);
113
+ return Parser.run(() => {
114
+ const token = new ExtToken(tags[0], attr, '', this.selfClosing ? undefined : tags[1], config);
115
+ token.lastChild.safeReplaceWith(inner);
116
+ return token;
117
+ });
100
118
  }
101
119
  }
102
120
 
@@ -20,7 +20,7 @@ class IncludeToken extends hidden(TagPairToken) {
20
20
  * @param {accum} accum
21
21
  */
22
22
  constructor(name, attr = '', inner = undefined, closed = undefined, config = Parser.getConfig(), accum = []) {
23
- super(name, attr, inner ?? '', inner === undefined ? closed : closed ?? '', config, accum, {AstText: [0, 1]});
23
+ super(name, attr, inner ?? '', inner === undefined ? closed : closed ?? '', config, accum);
24
24
  }
25
25
 
26
26
  /**
@@ -13,6 +13,15 @@ class TagPairToken extends fixedToken(Token) {
13
13
  #closed;
14
14
  #tags;
15
15
 
16
+ /** getter */
17
+ get closed() {
18
+ return this.#closed;
19
+ }
20
+
21
+ set closed(value) {
22
+ this.#closed ||= Boolean(value);
23
+ }
24
+
16
25
  /** getter */
17
26
  get selfClosing() {
18
27
  return this.#selfClosing;
@@ -26,15 +35,6 @@ class TagPairToken extends fixedToken(Token) {
26
35
  this.#selfClosing = value;
27
36
  }
28
37
 
29
- /** getter */
30
- get closed() {
31
- return this.#closed;
32
- }
33
-
34
- set closed(value) {
35
- this.#closed ||= Boolean(value);
36
- }
37
-
38
38
  /** 内部wikitext */
39
39
  get innerText() {
40
40
  return this.#selfClosing ? undefined : this.lastChild.text();
@@ -49,7 +49,8 @@ class TagPairToken extends fixedToken(Token) {
49
49
  */
50
50
  constructor(name, attr, inner, closed, config = Parser.getConfig(), accum = []) {
51
51
  super(undefined, config, true);
52
- this.setAttribute('name', name.toLowerCase()).#tags = [name, closed || name];
52
+ this.setAttribute('name', name.toLowerCase());
53
+ this.#tags = [name, closed || name];
53
54
  this.#selfClosing = closed === undefined;
54
55
  this.#closed = closed !== '';
55
56
  this.append(attr, inner);
@@ -63,16 +64,6 @@ class TagPairToken extends fixedToken(Token) {
63
64
  accum.splice(index, 0, this);
64
65
  }
65
66
 
66
- /**
67
- * @override
68
- * @template {string} T
69
- * @param {T} key 属性键
70
- * @returns {TokenAttribute<T>}
71
- */
72
- getAttribute(key) {
73
- return key === 'tags' ? [...this.#tags] : super.getAttribute(key);
74
- }
75
-
76
67
  /**
77
68
  * @override
78
69
  * @param {string} selector
@@ -109,6 +100,16 @@ class TagPairToken extends fixedToken(Token) {
109
100
  : {pre: `&lt;${opening}`, sep: '&gt;', post: this.#closed ? `&lt;/${closing}&gt;` : ''});
110
101
  }
111
102
 
103
+ /**
104
+ * @override
105
+ * @template {string} T
106
+ * @param {T} key 属性键
107
+ * @returns {TokenAttribute<T>}
108
+ */
109
+ getAttribute(key) {
110
+ return key === 'tags' ? [...this.#tags] : super.getAttribute(key);
111
+ }
112
+
112
113
  /**
113
114
  * @override
114
115
  * @returns {string}