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.
- package/config/default.json +129 -66
- package/config/zhwiki.json +4 -4
- package/index.js +97 -65
- package/lib/element.js +159 -302
- package/lib/node.js +384 -198
- package/lib/ranges.js +3 -4
- package/lib/text.js +65 -36
- package/lib/title.js +9 -8
- package/mixin/fixedToken.js +4 -4
- package/mixin/hidden.js +2 -0
- package/mixin/sol.js +16 -7
- package/package.json +14 -3
- package/parser/brackets.js +8 -2
- package/parser/commentAndExt.js +1 -1
- package/parser/converter.js +1 -1
- package/parser/externalLinks.js +2 -2
- package/parser/hrAndDoubleUnderscore.js +8 -7
- package/parser/links.js +8 -9
- package/parser/magicLinks.js +1 -1
- package/parser/selector.js +5 -5
- package/parser/table.js +18 -16
- package/src/arg.js +71 -42
- package/src/atom/index.js +7 -5
- package/src/attribute.js +102 -64
- package/src/charinsert.js +91 -0
- package/src/converter.js +34 -15
- package/src/converterFlags.js +87 -40
- package/src/converterRule.js +59 -53
- package/src/extLink.js +45 -37
- package/src/gallery.js +71 -16
- package/src/hasNowiki/index.js +42 -0
- package/src/hasNowiki/pre.js +40 -0
- package/src/heading.js +41 -18
- package/src/html.js +76 -48
- package/src/imageParameter.js +73 -51
- package/src/imagemap.js +205 -0
- package/src/imagemapLink.js +43 -0
- package/src/index.js +243 -138
- package/src/link/category.js +10 -14
- package/src/link/file.js +112 -56
- package/src/link/galleryImage.js +74 -10
- package/src/link/index.js +86 -61
- package/src/magicLink.js +48 -21
- package/src/nested/choose.js +24 -0
- package/src/nested/combobox.js +23 -0
- package/src/nested/index.js +88 -0
- package/src/nested/references.js +23 -0
- package/src/nowiki/comment.js +18 -4
- package/src/nowiki/dd.js +2 -2
- package/src/nowiki/doubleUnderscore.js +16 -11
- package/src/nowiki/index.js +12 -0
- package/src/nowiki/quote.js +28 -1
- package/src/onlyinclude.js +15 -8
- package/src/paramTag/index.js +83 -0
- package/src/paramTag/inputbox.js +42 -0
- package/src/parameter.js +73 -46
- package/src/syntax.js +9 -1
- package/src/table/index.js +58 -44
- package/src/table/td.js +63 -63
- package/src/table/tr.js +52 -35
- package/src/tagPair/ext.js +60 -43
- package/src/tagPair/include.js +11 -1
- package/src/tagPair/index.js +29 -20
- package/src/transclude.js +214 -166
- package/tool/index.js +720 -439
- package/util/base.js +17 -0
- package/util/debug.js +1 -1
- package/{test/util.js → util/diff.js} +15 -19
- package/util/lint.js +40 -0
- package/util/string.js +37 -20
- package/.eslintrc.json +0 -714
- package/errors/README +0 -1
- package/jsconfig.json +0 -7
- package/printed/README +0 -1
- package/printed/example.json +0 -120
- package/test/api.js +0 -83
- package/test/real.js +0 -133
- package/test/test.js +0 -28
- package/typings/api.d.ts +0 -13
- package/typings/array.d.ts +0 -28
- package/typings/event.d.ts +0 -24
- package/typings/index.d.ts +0 -94
- package/typings/node.d.ts +0 -29
- package/typings/parser.d.ts +0 -16
- package/typings/table.d.ts +0 -14
- package/typings/token.d.ts +0 -22
- 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
|
-
{
|
|
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.
|
|
53
|
+
return this.lastChild.text();
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
/** 是否位于行首 */
|
|
56
57
|
isIndependent() {
|
|
57
|
-
return this.
|
|
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.
|
|
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 {
|
|
79
|
-
if (
|
|
79
|
+
const {previousSibling} = this;
|
|
80
|
+
if (previousSibling?.type !== 'td') {
|
|
80
81
|
return {subtype, escape: esc, correction: true};
|
|
81
82
|
}
|
|
82
|
-
const result =
|
|
83
|
+
const result = previousSibling.getSyntax();
|
|
83
84
|
result.escape ||= esc;
|
|
84
|
-
result.correction =
|
|
85
|
-
.toString('comment, ext, include, noinclude, arg, template, magic-word
|
|
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
|
-
|
|
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' &&
|
|
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.
|
|
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
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
throw new RangeError(`使用 ${this.constructor.name}.setAttribute 方法设置私有属性 #${key} 仅用于代码调试!`);
|
|
210
|
+
if (key === 'innerSyntax') {
|
|
211
|
+
this.#innerSyntax = String(value);
|
|
212
|
+
return this;
|
|
177
213
|
}
|
|
178
|
-
|
|
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.
|
|
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 {
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
17
|
+
const templates = {'{|': '(!', '|}': '!)', '||': '!!', '|': '!'},
|
|
18
|
+
wikitext = syntax.childNodes.map(
|
|
18
19
|
child => child.type === 'text'
|
|
19
|
-
? String(child).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.
|
|
61
|
-
token.
|
|
77
|
+
token.firstChild.safeReplaceWith(syntax);
|
|
78
|
+
token.childNodes[1].safeReplaceWith(attr);
|
|
62
79
|
if (token.type === 'td') { // TdToken
|
|
63
|
-
token.
|
|
80
|
+
token.childNodes[2].safeReplaceWith(inner);
|
|
64
81
|
} else if (inner !== undefined) {
|
|
65
|
-
token.
|
|
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 {
|
|
75
|
-
if (child?.
|
|
76
|
-
const /** @type {{firstChild: AstText}} */ {firstChild
|
|
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
|
-
|
|
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.
|
|
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 {
|
|
122
|
-
|
|
138
|
+
const {firstChild} = this;
|
|
139
|
+
firstChild.replaceChildren(syntax);
|
|
123
140
|
if (esc) {
|
|
124
|
-
escapeTable(
|
|
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 {
|
|
138
|
-
if (
|
|
139
|
-
|
|
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.
|
|
173
|
-
child => child instanceof TdToken && child.isIndependent() && child.
|
|
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 {(
|
|
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 {
|
|
188
|
-
index =
|
|
189
|
-
for (const child of subset(
|
|
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((
|
|
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((
|
|
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.
|
|
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 (
|
|
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.
|
|
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');
|
package/src/tagPair/ext.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
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
|
|
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 {
|
|
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 '
|
|
43
|
-
case '
|
|
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
|
-
|
|
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.
|
|
109
|
+
const inner = this.lastChild.cloneNode(),
|
|
95
110
|
tags = this.getAttribute('tags'),
|
|
96
111
|
config = this.getAttribute('config'),
|
|
97
|
-
attr = String(this.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
|
package/src/tagPair/include.js
CHANGED
|
@@ -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
|
|
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 */
|