wikiparser-node 0.4.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 (87) hide show
  1. package/config/default.json +129 -66
  2. package/config/zhwiki.json +4 -4
  3. package/index.js +97 -65
  4. package/lib/element.js +159 -302
  5. package/lib/node.js +384 -198
  6. package/lib/ranges.js +3 -4
  7. package/lib/text.js +65 -36
  8. package/lib/title.js +9 -8
  9. package/mixin/fixedToken.js +4 -4
  10. package/mixin/hidden.js +2 -0
  11. package/mixin/sol.js +16 -7
  12. package/package.json +14 -3
  13. package/parser/brackets.js +8 -2
  14. package/parser/commentAndExt.js +1 -1
  15. package/parser/converter.js +1 -1
  16. package/parser/externalLinks.js +2 -2
  17. package/parser/hrAndDoubleUnderscore.js +8 -7
  18. package/parser/links.js +8 -9
  19. package/parser/magicLinks.js +1 -1
  20. package/parser/selector.js +5 -5
  21. package/parser/table.js +18 -16
  22. package/src/arg.js +71 -42
  23. package/src/atom/index.js +7 -5
  24. package/src/attribute.js +102 -64
  25. package/src/charinsert.js +91 -0
  26. package/src/converter.js +34 -15
  27. package/src/converterFlags.js +87 -40
  28. package/src/converterRule.js +59 -53
  29. package/src/extLink.js +45 -37
  30. package/src/gallery.js +71 -16
  31. package/src/hasNowiki/index.js +42 -0
  32. package/src/hasNowiki/pre.js +40 -0
  33. package/src/heading.js +41 -18
  34. package/src/html.js +76 -48
  35. package/src/imageParameter.js +73 -51
  36. package/src/imagemap.js +205 -0
  37. package/src/imagemapLink.js +43 -0
  38. package/src/index.js +243 -138
  39. package/src/link/category.js +10 -14
  40. package/src/link/file.js +112 -56
  41. package/src/link/galleryImage.js +74 -10
  42. package/src/link/index.js +86 -61
  43. package/src/magicLink.js +48 -21
  44. package/src/nested/choose.js +24 -0
  45. package/src/nested/combobox.js +23 -0
  46. package/src/nested/index.js +88 -0
  47. package/src/nested/references.js +23 -0
  48. package/src/nowiki/comment.js +18 -4
  49. package/src/nowiki/dd.js +2 -2
  50. package/src/nowiki/doubleUnderscore.js +16 -11
  51. package/src/nowiki/index.js +12 -0
  52. package/src/nowiki/quote.js +28 -1
  53. package/src/onlyinclude.js +15 -8
  54. package/src/paramTag/index.js +83 -0
  55. package/src/paramTag/inputbox.js +42 -0
  56. package/src/parameter.js +73 -46
  57. package/src/syntax.js +9 -1
  58. package/src/table/index.js +58 -44
  59. package/src/table/td.js +63 -63
  60. package/src/table/tr.js +52 -35
  61. package/src/tagPair/ext.js +60 -43
  62. package/src/tagPair/include.js +11 -1
  63. package/src/tagPair/index.js +29 -20
  64. package/src/transclude.js +214 -166
  65. package/tool/index.js +720 -439
  66. package/util/base.js +17 -0
  67. package/util/debug.js +1 -1
  68. package/{test/util.js → util/diff.js} +15 -19
  69. package/util/lint.js +40 -0
  70. package/util/string.js +37 -20
  71. package/.eslintrc.json +0 -714
  72. package/errors/README +0 -1
  73. package/jsconfig.json +0 -7
  74. package/printed/README +0 -1
  75. package/printed/example.json +0 -120
  76. package/test/api.js +0 -83
  77. package/test/real.js +0 -133
  78. package/test/test.js +0 -28
  79. package/typings/api.d.ts +0 -13
  80. package/typings/array.d.ts +0 -28
  81. package/typings/event.d.ts +0 -24
  82. package/typings/index.d.ts +0 -94
  83. package/typings/node.d.ts +0 -29
  84. package/typings/parser.d.ts +0 -16
  85. package/typings/table.d.ts +0 -14
  86. package/typings/token.d.ts +0 -22
  87. package/typings/tool.d.ts +0 -11
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');
@@ -49,12 +50,12 @@ class TdToken extends fixedToken(TrToken) {
49
50
 
50
51
  /** 内部wikitext */
51
52
  get innerText() {
52
- return this.lastElementChild.text();
53
+ return this.lastChild.text();
53
54
  }
54
55
 
55
56
  /** 是否位于行首 */
56
57
  isIndependent() {
57
- return this.firstElementChild.text()[0] === '\n';
58
+ return this.firstChild.text()[0] === '\n';
58
59
  }
59
60
 
60
61
  /**
@@ -63,7 +64,7 @@ class TdToken extends fixedToken(TrToken) {
63
64
  * @complexity `n`
64
65
  */
65
66
  getSyntax() {
66
- const syntax = this.firstElementChild.text(),
67
+ const syntax = this.firstChild.text(),
67
68
  esc = syntax.includes('{{'),
68
69
  char = syntax.at(-1);
69
70
  let subtype = 'td';
@@ -75,14 +76,14 @@ class TdToken extends fixedToken(TrToken) {
75
76
  if (this.isIndependent()) {
76
77
  return {subtype, escape: esc, correction: false};
77
78
  }
78
- const {previousElementSibling} = this;
79
- if (previousElementSibling?.type !== 'td') {
79
+ const {previousSibling} = this;
80
+ if (previousSibling?.type !== 'td') {
80
81
  return {subtype, escape: esc, correction: true};
81
82
  }
82
- const result = previousElementSibling.getSyntax();
83
+ const result = previousSibling.getSyntax();
83
84
  result.escape ||= esc;
84
- result.correction = previousElementSibling.lastElementChild
85
- .toString('comment, ext, include, noinclude, arg, template, magic-word, html')
85
+ result.correction = previousSibling.lastChild
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"!');
@@ -144,7 +182,7 @@ class TdToken extends fixedToken(TrToken) {
144
182
  }
145
183
  const token = Parser.run(() => new TdToken('\n|', undefined, config));
146
184
  token.setSyntax(subtype);
147
- token.lastElementChild.safeReplaceWith(inner);
185
+ token.lastChild.safeReplaceWith(inner);
148
186
  for (const [k, v] of Object.entries(attr)) {
149
187
  token.setAttr(k, v);
150
188
  }
@@ -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
  /**
@@ -201,7 +228,7 @@ class TdToken extends fixedToken(TrToken) {
201
228
  * @complexity `n`
202
229
  */
203
230
  #correct() {
204
- if (String(this.children[1])) {
231
+ if (String(this.childNodes[1])) {
205
232
  this.#innerSyntax ||= '|';
206
233
  }
207
234
  const {subtype, escape, correction} = this.getSyntax();
@@ -221,33 +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 {children: [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
- return 0;
246
- }
247
- this.#correct();
248
- return this.#innerSyntax.length;
249
- }
250
-
251
251
  /**
252
252
  * @override
253
253
  * @returns {string}
@@ -255,7 +255,7 @@ class TdToken extends fixedToken(TrToken) {
255
255
  */
256
256
  text() {
257
257
  this.#correct();
258
- const {children: [syntax, attr, inner]} = this;
258
+ const {childNodes: [syntax, attr, inner]} = this;
259
259
  return `${syntax.text()}${attr.text()}${this.#innerSyntax}${inner.text()}`;
260
260
  }
261
261
 
@@ -286,7 +286,7 @@ class TdToken extends fixedToken(TrToken) {
286
286
  value = value === 1 ? false : String(value);
287
287
  }
288
288
  const /** @type {boolean} */ result = super.setAttr(key, value);
289
- if (!String(this.children[1])) {
289
+ if (!String(this.childNodes[1])) {
290
290
  this.#innerSyntax = '';
291
291
  }
292
292
  return result;
@@ -295,7 +295,7 @@ class TdToken extends fixedToken(TrToken) {
295
295
  /** @override */
296
296
  escape() {
297
297
  super.escape();
298
- if (String(this.children[1])) {
298
+ if (String(this.childNodes[1])) {
299
299
  this.#innerSyntax ||= '{{!}}';
300
300
  }
301
301
  if (this.#innerSyntax === '|') {
package/src/table/tr.js CHANGED
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- const attributeParent = require('../../mixin/attributeParent'),
3
+ const {generateForChild} = require('../../util/lint'),
4
+ attributeParent = require('../../mixin/attributeParent'),
4
5
  Parser = require('../..'),
5
6
  AstText = require('../../lib/text'),
6
7
  Token = require('..'),
7
- SyntaxToken = require('../syntax'),
8
- AttributeToken = require('../attribute');
8
+ SyntaxToken = require('../syntax');
9
9
 
10
10
  const openingPattern = /^\n[^\S\n]*(?:\|-+|\{\{\s*!\s*\}\}-+|\{\{\s*!-\s*\}\}-*)$/u;
11
11
 
@@ -14,11 +14,10 @@ const openingPattern = /^\n[^\S\n]*(?:\|-+|\{\{\s*!\s*\}\}-+|\{\{\s*!-\s*\}\}-*)
14
14
  * @param {SyntaxToken} syntax 表格语法节点
15
15
  */
16
16
  const escapeTable = syntax => {
17
- const wikitext = syntax.childNodes.map(
17
+ const templates = {'{|': '(!', '|}': '!)', '||': '!!', '|': '!'},
18
+ wikitext = syntax.childNodes.map(
18
19
  child => child.type === 'text'
19
- ? String(child).replaceAll('{|', '{{(!}}').replaceAll('|}', '{{!)}}')
20
- .replaceAll('||', '{{!!}}')
21
- .replaceAll('|', '{{!}}')
20
+ ? String(child).replaceAll(/\{\||\|\}|\|{2}|\|/gu, p => `{{${templates[p]}}}`)
22
21
  : String(child),
23
22
  ).join(''),
24
23
  token = Parser.parse(wikitext, syntax.getAttribute('include'), 2, syntax.getAttribute('config'));
@@ -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: ':',
@@ -49,6 +49,23 @@ class TrToken extends attributeParent(Token, 1) {
49
49
  this.getAttribute('protectChildren')(0, 1);
50
50
  }
51
51
 
52
+ /**
53
+ * @override
54
+ * @param {number} start 起始位置
55
+ */
56
+ lint(start = 0) {
57
+ const errors = super.lint(start),
58
+ inter = this.childNodes.find(({type}) => type === 'table-inter'),
59
+ str = String(inter).trim();
60
+ if (inter && str && !/^<!--.*-->$/su.test(str)) {
61
+ const error = generateForChild(inter, this.getRootNode().posFromIndex(start), '将被移出表格的内容');
62
+ error.startLine++;
63
+ error.startCol = 0;
64
+ errors.push(error);
65
+ }
66
+ return errors;
67
+ }
68
+
52
69
  /**
53
70
  * @override
54
71
  * @this {TrToken & {constructor: typeof TrToken}}
@@ -57,12 +74,12 @@ class TrToken extends attributeParent(Token, 1) {
57
74
  const [syntax, attr, inner, ...cloned] = this.cloneChildNodes();
58
75
  return Parser.run(() => {
59
76
  const token = new this.constructor(undefined, undefined, this.getAttribute('config'));
60
- token.firstElementChild.safeReplaceWith(syntax);
61
- token.children[1].safeReplaceWith(attr);
77
+ token.firstChild.safeReplaceWith(syntax);
78
+ token.childNodes[1].safeReplaceWith(attr);
62
79
  if (token.type === 'td') { // TdToken
63
- token.children[2].safeReplaceWith(inner);
80
+ token.childNodes[2].safeReplaceWith(inner);
64
81
  } else if (inner !== undefined) {
65
- token.appendChild(inner);
82
+ token.insertAt(inner);
66
83
  }
67
84
  token.append(...cloned);
68
85
  return token;
@@ -71,13 +88,13 @@ class TrToken extends attributeParent(Token, 1) {
71
88
 
72
89
  /** 修复简单的表格语法错误 */
73
90
  #correct() {
74
- const {children: [,, child]} = this;
75
- if (child?.isPlain()) {
76
- const /** @type {{firstChild: AstText}} */ {firstChild: {type, data}} = child;
77
- if (type !== 'text') {
91
+ const {childNodes: [,, child]} = this;
92
+ if (child?.constructor === Token) {
93
+ const /** @type {{firstChild: AstText}} */ {firstChild} = child;
94
+ if (firstChild.type !== 'text') {
78
95
  child.prepend('\n');
79
- } else if (data[0] !== '\n') {
80
- child.setText(`\n${data}`);
96
+ } else if (firstChild.data[0] !== '\n') {
97
+ firstChild.insertData(0, '\n');
81
98
  }
82
99
  }
83
100
  }
@@ -103,7 +120,7 @@ class TrToken extends attributeParent(Token, 1) {
103
120
  * @complexity `n`
104
121
  */
105
122
  escape() {
106
- for (const child of this.children) {
123
+ for (const child of this.childNodes) {
107
124
  if (child instanceof SyntaxToken) {
108
125
  escapeTable(child);
109
126
  } else if (child instanceof TrToken) {
@@ -118,10 +135,10 @@ class TrToken extends attributeParent(Token, 1) {
118
135
  * @param {boolean} esc 是否需要转义
119
136
  */
120
137
  setSyntax(syntax, esc) {
121
- const {firstElementChild} = this;
122
- firstElementChild.replaceChildren(syntax);
138
+ const {firstChild} = this;
139
+ firstChild.replaceChildren(syntax);
123
140
  if (esc) {
124
- escapeTable(firstElementChild);
141
+ escapeTable(firstChild);
125
142
  }
126
143
  }
127
144
 
@@ -134,9 +151,9 @@ class TrToken extends attributeParent(Token, 1) {
134
151
  const TdToken = require('./td');
135
152
  const child = this.childNodes.at(i);
136
153
  if (child instanceof TdToken && child.isIndependent()) {
137
- const {nextElementSibling} = child;
138
- if (nextElementSibling?.type === 'td') {
139
- nextElementSibling.independence();
154
+ const {nextSibling} = child;
155
+ if (nextSibling?.type === 'td') {
156
+ nextSibling.independence();
140
157
  }
141
158
  }
142
159
  return super.removeAt(i);
@@ -169,14 +186,14 @@ class TrToken extends attributeParent(Token, 1) {
169
186
  */
170
187
  getRowCount() {
171
188
  const TdToken = require('./td');
172
- return Number(this.children.some(
173
- child => child instanceof TdToken && child.isIndependent() && child.firstElementChild.text().at(-1) !== '+',
189
+ return Number(this.childNodes.some(
190
+ child => child instanceof TdToken && child.isIndependent() && child.firstChild.text().at(-1) !== '+',
174
191
  ));
175
192
  }
176
193
 
177
194
  /**
178
195
  * 获取相邻行
179
- * @param {(children: Token[], index: number) => Token[]} subset 筛选兄弟节点的方法
196
+ * @param {(childNodes: Token[], index: number) => Token[]} subset 筛选兄弟节点的方法
180
197
  * @complexity `n`
181
198
  */
182
199
  #getSiblingRow(subset) {
@@ -184,9 +201,9 @@ class TrToken extends attributeParent(Token, 1) {
184
201
  if (!parentNode) {
185
202
  return undefined;
186
203
  }
187
- const {children} = parentNode,
188
- index = children.indexOf(this);
189
- for (const child of subset(children, index)) {
204
+ const {childNodes} = parentNode,
205
+ index = childNodes.indexOf(this);
206
+ for (const child of subset(childNodes, index)) {
190
207
  if (child instanceof TrToken && child.getRowCount()) {
191
208
  return child;
192
209
  }
@@ -199,7 +216,7 @@ class TrToken extends attributeParent(Token, 1) {
199
216
  * @complexity `n`
200
217
  */
201
218
  getNextRow() {
202
- return this.#getSiblingRow((children, index) => children.slice(index + 1));
219
+ return this.#getSiblingRow((childNodes, index) => childNodes.slice(index + 1));
203
220
  }
204
221
 
205
222
  /**
@@ -207,7 +224,7 @@ class TrToken extends attributeParent(Token, 1) {
207
224
  * @complexity `n`
208
225
  */
209
226
  getPreviousRow() {
210
- return this.#getSiblingRow((children, index) => children.slice(0, index).reverse());
227
+ return this.#getSiblingRow((childNodes, index) => childNodes.slice(0, index).reverse());
211
228
  }
212
229
 
213
230
  /**
@@ -218,7 +235,7 @@ class TrToken extends attributeParent(Token, 1) {
218
235
  const TdToken = require('./td');
219
236
  let count = 0,
220
237
  last = 0;
221
- for (const child of this.children) {
238
+ for (const child of this.childNodes) {
222
239
  if (child instanceof TdToken) {
223
240
  last = child.isIndependent() ? Number(child.subtype !== 'caption') : last;
224
241
  count += last;
@@ -236,7 +253,7 @@ class TrToken extends attributeParent(Token, 1) {
236
253
  * @throws `RangeError` 不存在对应单元格
237
254
  */
238
255
  getNthCol(n, insert) {
239
- if (typeof n !== 'number') {
256
+ if (!Number.isInteger(n)) {
240
257
  this.typeError('getNthCol', 'Number');
241
258
  }
242
259
  const nCols = this.getColCount();
@@ -246,7 +263,7 @@ class TrToken extends attributeParent(Token, 1) {
246
263
  }
247
264
  const TdToken = require('./td');
248
265
  let last = 0;
249
- for (const child of this.children.slice(2)) {
266
+ for (const child of this.childNodes.slice(2)) {
250
267
  if (child instanceof TdToken) {
251
268
  if (child.isIndependent()) {
252
269
  last = Number(child.subtype !== 'caption');
@@ -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,27 +97,24 @@ 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
- innerToken.type = 'ext-inner';
85
- innerToken.setAttribute('name', lcName);
86
- if (lcName === 'pre') {
87
- innerToken.setAttribute('stage', Parser.MAX_STAGE - 1);
88
- }
89
- super(name, attrToken, innerToken, closed, config, accum, acceptable);
103
+ innerToken.setAttribute('name', lcName).type = 'ext-inner';
104
+ super(name, attrToken, innerToken, closed, config, accum);
90
105
  }
91
106
 
92
107
  /** @override */
93
108
  cloneNode() {
94
- const inner = this.lastElementChild.cloneNode(),
109
+ const inner = this.lastChild.cloneNode(),
95
110
  tags = this.getAttribute('tags'),
96
111
  config = this.getAttribute('config'),
97
- attr = String(this.firstElementChild),
98
- token = Parser.run(() => new ExtToken(tags[0], attr, '', this.selfClosing ? undefined : tags[1], config));
99
- token.lastElementChild.safeReplaceWith(inner);
100
- 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
+ });
101
118
  }
102
119
  }
103
120
 
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const hidden = require('../../mixin/hidden'),
4
+ {generateForSelf} = require('../../util/lint'),
4
5
  Parser = require('../..'),
5
6
  TagPairToken = require('.');
6
7
 
@@ -19,7 +20,16 @@ class IncludeToken extends hidden(TagPairToken) {
19
20
  * @param {accum} accum
20
21
  */
21
22
  constructor(name, attr = '', inner = undefined, closed = undefined, config = Parser.getConfig(), accum = []) {
22
- 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
+ }
25
+
26
+ /**
27
+ * @override
28
+ * @param {number} start 起始位置
29
+ * @returns {LintError[]}
30
+ */
31
+ lint(start = 0) {
32
+ return this.closed ? [] : [generateForSelf(this, this.getRootNode().posFromIndex(start), '未闭合的标签')];
23
33
  }
24
34
 
25
35
  /** @override */