wikiparser-node 0.8.1 → 0.9.0-m
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 +0 -1
- package/config/llwiki.json +0 -35
- package/config/moegirl.json +1 -44
- package/config/zhwiki.json +0 -466
- package/i18n/zh-hans.json +44 -0
- package/i18n/zh-hant.json +44 -0
- package/index.js +16 -256
- package/lib/element.js +29 -504
- package/lib/node.js +6 -542
- package/lib/text.js +10 -127
- package/lib/title.js +7 -32
- package/mixin/hidden.js +0 -3
- package/package.json +8 -8
- package/parser/brackets.js +8 -3
- package/parser/commentAndExt.js +1 -5
- package/parser/converter.js +0 -1
- package/parser/externalLinks.js +0 -1
- package/parser/hrAndDoubleUnderscore.js +0 -1
- package/parser/html.js +0 -1
- package/parser/links.js +5 -6
- package/parser/list.js +0 -1
- package/parser/magicLinks.js +0 -1
- package/parser/quotes.js +1 -2
- package/parser/table.js +0 -1
- package/src/arg.js +9 -119
- package/src/atom/hidden.js +0 -2
- package/src/atom/index.js +0 -17
- package/src/attribute.js +7 -181
- package/src/attributes.js +8 -312
- package/src/converter.js +2 -108
- package/src/converterFlags.js +3 -190
- package/src/converterRule.js +3 -187
- package/src/extLink.js +2 -121
- package/src/gallery.js +5 -62
- package/src/hasNowiki/index.js +0 -12
- package/src/hasNowiki/pre.js +0 -12
- package/src/heading.js +7 -58
- package/src/html.js +18 -127
- package/src/imageParameter.js +61 -200
- package/src/imagemap.js +7 -66
- package/src/imagemapLink.js +2 -14
- package/src/index.js +11 -534
- package/src/link/category.js +1 -37
- package/src/link/file.js +18 -168
- package/src/link/galleryImage.js +6 -64
- package/src/link/index.js +9 -277
- package/src/magicLink.js +2 -85
- package/src/nested/choose.js +0 -1
- package/src/nested/combobox.js +0 -1
- package/src/nested/index.js +3 -33
- package/src/nested/references.js +0 -1
- package/src/nowiki/comment.js +3 -27
- package/src/nowiki/dd.js +1 -47
- package/src/nowiki/doubleUnderscore.js +1 -31
- package/src/nowiki/hr.js +1 -20
- package/src/nowiki/index.js +3 -25
- package/src/nowiki/list.js +2 -5
- package/src/nowiki/noinclude.js +0 -14
- package/src/nowiki/quote.js +3 -17
- package/src/onlyinclude.js +1 -26
- package/src/paramTag/index.js +4 -27
- package/src/paramTag/inputbox.js +1 -4
- package/src/parameter.js +7 -149
- package/src/syntax.js +0 -68
- package/src/table/index.js +4 -942
- package/src/table/td.js +9 -230
- package/src/table/tr.js +4 -249
- package/src/tagPair/ext.js +13 -27
- package/src/tagPair/include.js +0 -24
- package/src/tagPair/index.js +2 -51
- package/src/transclude.js +38 -528
- package/util/lint.js +8 -7
- package/util/string.js +12 -44
- package/README.md +0 -39
- package/lib/ranges.js +0 -130
- package/mixin/attributeParent.js +0 -117
- package/mixin/fixedToken.js +0 -40
- package/mixin/singleLine.js +0 -31
- package/mixin/sol.js +0 -65
- package/parser/selector.js +0 -177
- package/src/charinsert.js +0 -97
- package/tool/index.js +0 -1202
- package/util/debug.js +0 -73
package/src/table/td.js
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const {generateForChild} = require('../../util/lint'),
|
|
4
|
-
fixedToken = require('../../mixin/fixedToken'),
|
|
5
|
-
{typeError} = require('../../util/debug'),
|
|
6
|
-
{isPlainObject} = require('../../util/base'),
|
|
7
4
|
Parser = require('../..'),
|
|
8
5
|
Token = require('..'),
|
|
9
6
|
TrToken = require('./tr');
|
|
10
7
|
|
|
11
|
-
const aliases = {td: '\n|', th: '\n!', caption: '\n|+'},
|
|
12
|
-
openingPattern = /^(?:\n[\S\n]*(?:[|!]|\|\+|\{\{\s*!\s*\}\}\+?)|(?:\||\{\{\s*!\s*\}\}){2}|!!|\{\{\s*!!\s*\}\})$/u;
|
|
13
|
-
|
|
14
8
|
/**
|
|
15
9
|
* `<td>`、`<th>`和`<caption>`
|
|
16
10
|
* @classdesc `{childNodes: [SyntaxToken, AttributesToken, Token]}`
|
|
17
11
|
*/
|
|
18
|
-
class TdToken extends
|
|
12
|
+
class TdToken extends TrToken {
|
|
19
13
|
type = 'td';
|
|
20
14
|
#innerSyntax = '';
|
|
21
15
|
|
|
@@ -27,46 +21,13 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
27
21
|
return this.getSyntax().subtype;
|
|
28
22
|
}
|
|
29
23
|
|
|
30
|
-
set subtype(subtype) {
|
|
31
|
-
this.setSyntax(subtype);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** rowspan */
|
|
35
|
-
get rowspan() {
|
|
36
|
-
return this.getAttr('rowspan');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
set rowspan(rowspan) {
|
|
40
|
-
this.setAttr('rowspan', rowspan);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** colspan */
|
|
44
|
-
get colspan() {
|
|
45
|
-
return this.getAttr('colspan');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
set colspan(colspan) {
|
|
49
|
-
this.setAttr('colspan', colspan);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** 内部wikitext */
|
|
53
|
-
get innerText() {
|
|
54
|
-
return this.lastChild.text();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** 是否位于行首 */
|
|
58
|
-
isIndependent() {
|
|
59
|
-
return this.firstChild.text()[0] === '\n';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
24
|
/**
|
|
63
25
|
* 获取单元格语法信息
|
|
64
|
-
* @returns {{subtype: 'td'|'th'|'caption'
|
|
26
|
+
* @returns {{subtype: 'td'|'th'|'caption'}}
|
|
65
27
|
* @complexity `n`
|
|
66
28
|
*/
|
|
67
29
|
getSyntax() {
|
|
68
30
|
const syntax = this.firstChild.text(),
|
|
69
|
-
esc = syntax.includes('{{'),
|
|
70
31
|
char = syntax.at(-1);
|
|
71
32
|
let subtype = 'td';
|
|
72
33
|
if (char === '!') {
|
|
@@ -74,23 +35,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
74
35
|
} else if (char === '+') {
|
|
75
36
|
subtype = 'caption';
|
|
76
37
|
}
|
|
77
|
-
|
|
78
|
-
return {subtype, escape: esc, correction: false};
|
|
79
|
-
}
|
|
80
|
-
const {previousSibling} = this;
|
|
81
|
-
if (previousSibling?.type !== 'td') {
|
|
82
|
-
return {subtype, escape: esc, correction: true};
|
|
83
|
-
}
|
|
84
|
-
const result = previousSibling.getSyntax();
|
|
85
|
-
result.escape ||= esc;
|
|
86
|
-
result.correction = previousSibling.lastChild
|
|
87
|
-
.toString('comment, ext, include, noinclude, arg, template, magic-word')
|
|
88
|
-
.includes('\n');
|
|
89
|
-
if (subtype === 'th' && result.subtype !== 'th') {
|
|
90
|
-
result.subtype = 'th';
|
|
91
|
-
result.correction = true;
|
|
92
|
-
}
|
|
93
|
-
return result;
|
|
38
|
+
return {subtype};
|
|
94
39
|
}
|
|
95
40
|
|
|
96
41
|
/**
|
|
@@ -105,7 +50,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
105
50
|
innerSyntax = undefined;
|
|
106
51
|
attr = '';
|
|
107
52
|
}
|
|
108
|
-
super(syntax, attr, config, accum
|
|
53
|
+
super(syntax, attr, config, accum);
|
|
109
54
|
if (innerSyntax) {
|
|
110
55
|
[this.#innerSyntax] = innerSyntax;
|
|
111
56
|
}
|
|
@@ -113,8 +58,6 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
113
58
|
const innerToken = new Token(inner?.slice(innerSyntax?.index + this.#innerSyntax.length), config, true, accum);
|
|
114
59
|
innerToken.type = 'td-inner';
|
|
115
60
|
this.insertAt(innerToken.setAttribute('stage', 4));
|
|
116
|
-
this.setAttribute('acceptable', {SyntaxToken: 0, AttributesToken: 1, Token: 2})
|
|
117
|
-
.seal(['getRowCount', 'getNthCol', 'insertTableCell'], true);
|
|
118
61
|
}
|
|
119
62
|
|
|
120
63
|
/** @override */
|
|
@@ -126,16 +69,12 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
126
69
|
|
|
127
70
|
/**
|
|
128
71
|
* @override
|
|
129
|
-
* @param {string} selector
|
|
130
72
|
* @returns {string}
|
|
131
73
|
* @complexity `n`
|
|
132
74
|
*/
|
|
133
75
|
toString(selector) {
|
|
134
|
-
this.#correct();
|
|
135
76
|
const {childNodes: [syntax, attr, inner]} = this;
|
|
136
|
-
return
|
|
137
|
-
? ''
|
|
138
|
-
: `${syntax.toString(selector)}${attr.toString(selector)}${this.#innerSyntax}${inner.toString(selector)}`;
|
|
77
|
+
return `${syntax.toString()}${attr.toString()}${this.#innerSyntax}${inner.toString()}`;
|
|
139
78
|
}
|
|
140
79
|
|
|
141
80
|
/**
|
|
@@ -144,7 +83,6 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
144
83
|
* @complexity `n`
|
|
145
84
|
*/
|
|
146
85
|
text() {
|
|
147
|
-
this.#correct();
|
|
148
86
|
const {childNodes: [syntax, attr, inner]} = this;
|
|
149
87
|
return `${syntax.text()}${attr.text()}${this.#innerSyntax}${inner.text()}`;
|
|
150
88
|
}
|
|
@@ -156,7 +94,6 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
156
94
|
getGaps(i = 0) {
|
|
157
95
|
i = i < 0 ? i + this.length : i;
|
|
158
96
|
if (i === 1) {
|
|
159
|
-
this.#correct();
|
|
160
97
|
return this.#innerSyntax.length;
|
|
161
98
|
}
|
|
162
99
|
return 0;
|
|
@@ -166,174 +103,16 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
166
103
|
* @override
|
|
167
104
|
* @param {number} start 起始位置
|
|
168
105
|
*/
|
|
169
|
-
lint(start =
|
|
170
|
-
const errors = super.lint(start)
|
|
171
|
-
{lastChild} = this;
|
|
106
|
+
lint(start = this.getAbsoluteIndex()) {
|
|
107
|
+
const errors = super.lint(start);
|
|
172
108
|
start += this.getRelativeIndex(-1);
|
|
173
|
-
for (const child of lastChild.childNodes) {
|
|
109
|
+
for (const child of this.lastChild.childNodes) {
|
|
174
110
|
if (child.type === 'text' && child.data.includes('|')) {
|
|
175
|
-
errors.push(generateForChild(child, {start}, '
|
|
111
|
+
errors.push(generateForChild(child, {start}, 'additional "|" in a table cell', 'warning'));
|
|
176
112
|
}
|
|
177
113
|
}
|
|
178
114
|
return errors;
|
|
179
115
|
}
|
|
180
|
-
|
|
181
|
-
/** @override */
|
|
182
|
-
print() {
|
|
183
|
-
const {childNodes: [syntax, attr, inner]} = this;
|
|
184
|
-
return `<span class="wpb-td">${syntax.print()}${attr.print()}${this.#innerSyntax}${inner.print()}</span>`;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/** @override */
|
|
188
|
-
cloneNode() {
|
|
189
|
-
const /** @type {TdToken} */ token = super.cloneNode();
|
|
190
|
-
token.setAttribute('innerSyntax', this.#innerSyntax);
|
|
191
|
-
return token;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* 创建新的单元格
|
|
196
|
-
* @param {string|Token} inner 内部wikitext
|
|
197
|
-
* @param {'td'|'th'|'caption'} subtype 单元格类型
|
|
198
|
-
* @param {Record<string, string>} attr 单元格属性
|
|
199
|
-
* @param {boolean} include 是否嵌入
|
|
200
|
-
* @throws `RangeError` 非法的单元格类型
|
|
201
|
-
*/
|
|
202
|
-
static create(inner, subtype = 'td', attr = {}, include = false, config = Parser.getConfig()) {
|
|
203
|
-
if (typeof inner !== 'string' && inner?.constructor !== Token || !isPlainObject(attr)) {
|
|
204
|
-
typeError(this, 'create', 'String', 'Token', 'Object');
|
|
205
|
-
} else if (subtype !== 'td' && subtype !== 'th' && subtype !== 'caption') {
|
|
206
|
-
throw new RangeError('单元格的子类型只能为 "td"、"th" 或 "caption"!');
|
|
207
|
-
} else if (typeof inner === 'string') {
|
|
208
|
-
inner = Parser.parse(inner, include, undefined, config);
|
|
209
|
-
}
|
|
210
|
-
const token = Parser.run(() => new TdToken('\n|', undefined, config));
|
|
211
|
-
token.setSyntax(subtype);
|
|
212
|
-
token.lastChild.safeReplaceWith(inner);
|
|
213
|
-
for (const [k, v] of Object.entries(attr)) {
|
|
214
|
-
token.setAttr(k, v);
|
|
215
|
-
}
|
|
216
|
-
return token;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* @override
|
|
221
|
-
* @template {string} T
|
|
222
|
-
* @param {T} key 属性键
|
|
223
|
-
* @returns {TokenAttribute<T>}
|
|
224
|
-
*/
|
|
225
|
-
getAttribute(key) {
|
|
226
|
-
return key === 'innerSyntax' ? this.#innerSyntax : super.getAttribute(key);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* @override
|
|
231
|
-
* @template {string} T
|
|
232
|
-
* @param {T} key 属性键
|
|
233
|
-
* @param {TokenAttribute<T>} value 属性值
|
|
234
|
-
* @returns {this}
|
|
235
|
-
*/
|
|
236
|
-
setAttribute(key, value) {
|
|
237
|
-
if (key === 'innerSyntax') {
|
|
238
|
-
this.#innerSyntax = String(value);
|
|
239
|
-
return this;
|
|
240
|
-
}
|
|
241
|
-
return super.setAttribute(key, value);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* @override
|
|
246
|
-
* @param {string} syntax 表格语法
|
|
247
|
-
* @param {boolean} esc 是否需要转义
|
|
248
|
-
*/
|
|
249
|
-
setSyntax(syntax, esc) {
|
|
250
|
-
super.setSyntax(aliases[syntax] ?? syntax, esc);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* 修复\<td\>语法
|
|
255
|
-
* @complexity `n`
|
|
256
|
-
*/
|
|
257
|
-
#correct() {
|
|
258
|
-
if (String(this.childNodes[1])) {
|
|
259
|
-
this.#innerSyntax ||= '|';
|
|
260
|
-
}
|
|
261
|
-
const {subtype, escape, correction} = this.getSyntax();
|
|
262
|
-
if (correction) {
|
|
263
|
-
this.setSyntax(subtype, escape);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* 改为独占一行
|
|
269
|
-
* @complexity `n`
|
|
270
|
-
*/
|
|
271
|
-
independence() {
|
|
272
|
-
if (!this.isIndependent()) {
|
|
273
|
-
const {subtype, escape} = this.getSyntax();
|
|
274
|
-
this.setSyntax(subtype, escape);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* 获取单元格属性
|
|
280
|
-
* @template {string} T
|
|
281
|
-
* @param {T} key 属性键
|
|
282
|
-
* @returns {T extends 'rowspan'|'colspan' ? number : string|true}
|
|
283
|
-
*/
|
|
284
|
-
getAttr(key) {
|
|
285
|
-
const /** @type {string|true} */ value = super.getAttr(key);
|
|
286
|
-
key = key?.toLowerCase()?.trim();
|
|
287
|
-
return key === 'rowspan' || key === 'colspan' ? Number(value) || 1 : value;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* 获取全部单元格属性
|
|
292
|
-
* @returns {{rowspan: number, colspan: number, [key: string]: string|true}}
|
|
293
|
-
*/
|
|
294
|
-
getAttrs() {
|
|
295
|
-
const /** @type {record<string, string|true>} */ attr = super.getAttrs();
|
|
296
|
-
if ('rowspan' in attr) {
|
|
297
|
-
attr.rowspan = Number(attr.rowspan);
|
|
298
|
-
}
|
|
299
|
-
if ('colspan' in attr) {
|
|
300
|
-
attr.colspan = Number(attr.colspan);
|
|
301
|
-
}
|
|
302
|
-
return attr;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* 设置单元格属性
|
|
307
|
-
* @template {string} T
|
|
308
|
-
* @param {T} key 属性键
|
|
309
|
-
* @param {T extends 'rowspan'|'colspan' ? number : string|boolean} value 属性值
|
|
310
|
-
*/
|
|
311
|
-
setAttr(key, value) {
|
|
312
|
-
if (typeof key !== 'string') {
|
|
313
|
-
this.typeError('setAttr', 'String');
|
|
314
|
-
}
|
|
315
|
-
key = key.toLowerCase().trim();
|
|
316
|
-
if (typeof value === 'number' && (key === 'rowspan' || key === 'colspan')) {
|
|
317
|
-
value = value === 1 ? false : String(value);
|
|
318
|
-
}
|
|
319
|
-
const /** @type {boolean} */ result = super.setAttr(key, value);
|
|
320
|
-
if (!String(this.childNodes[1])) {
|
|
321
|
-
this.#innerSyntax = '';
|
|
322
|
-
}
|
|
323
|
-
return result;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/** @override */
|
|
327
|
-
escape() {
|
|
328
|
-
super.escape();
|
|
329
|
-
if (String(this.childNodes[1])) {
|
|
330
|
-
this.#innerSyntax ||= '{{!}}';
|
|
331
|
-
}
|
|
332
|
-
if (this.#innerSyntax === '|') {
|
|
333
|
-
this.#innerSyntax = '{{!}}';
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
116
|
}
|
|
337
117
|
|
|
338
|
-
Parser.classes.TdToken = __filename;
|
|
339
118
|
module.exports = TdToken;
|
package/src/table/tr.js
CHANGED
|
@@ -1,35 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const {generateForChild} = require('../../util/lint'),
|
|
4
|
-
attributeParent = require('../../mixin/attributeParent'),
|
|
5
4
|
Parser = require('../..'),
|
|
6
|
-
AstText = require('../../lib/text'),
|
|
7
5
|
Token = require('..'),
|
|
8
6
|
SyntaxToken = require('../syntax'),
|
|
9
7
|
AttributesToken = require('../attributes');
|
|
10
8
|
|
|
11
|
-
const openingPattern = /^\n[^\S\n]*(?:\|-+|\{\{\s*!\s*\}\}-+|\{\{\s*!-\s*\}\}-*)$/u;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 转义表格语法
|
|
15
|
-
* @param {SyntaxToken} syntax 表格语法节点
|
|
16
|
-
*/
|
|
17
|
-
const escapeTable = syntax => {
|
|
18
|
-
const templates = {'{|': '(!', '|}': '!)', '||': '!!', '|': '!'},
|
|
19
|
-
wikitext = syntax.childNodes.map(
|
|
20
|
-
child => child.type === 'text'
|
|
21
|
-
? String(child).replace(/\{\||\|\}|\|{2}|\|/gu, p => `{{${templates[p]}}}`)
|
|
22
|
-
: String(child),
|
|
23
|
-
).join(''),
|
|
24
|
-
token = Parser.parse(wikitext, syntax.getAttribute('include'), 2, syntax.getAttribute('config'));
|
|
25
|
-
syntax.replaceChildren(...token.childNodes);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
9
|
/**
|
|
29
10
|
* 表格行,含开头的换行,不含结尾的换行
|
|
30
11
|
* @classdesc `{childNodes: [SyntaxToken, AttributesToken, ?Token, ...TdToken]}`
|
|
31
12
|
*/
|
|
32
|
-
class TrToken extends
|
|
13
|
+
class TrToken extends Token {
|
|
33
14
|
type = 'tr';
|
|
34
15
|
|
|
35
16
|
/**
|
|
@@ -38,24 +19,21 @@ class TrToken extends attributeParent(Token, 1) {
|
|
|
38
19
|
* @param {accum} accum
|
|
39
20
|
* @param {RegExp} pattern 表格语法正则
|
|
40
21
|
*/
|
|
41
|
-
constructor(syntax, attr = '', config = Parser.getConfig(), accum = [], pattern =
|
|
22
|
+
constructor(syntax, attr = '', config = Parser.getConfig(), accum = [], pattern = undefined) {
|
|
42
23
|
super(undefined, config, true, accum, {
|
|
43
|
-
Token: 2, SyntaxToken: 0, AttributesToken: 1, TdToken: '2:',
|
|
44
24
|
});
|
|
45
25
|
this.append(
|
|
46
26
|
new SyntaxToken(syntax, pattern, 'table-syntax', config, accum, {
|
|
47
|
-
'Stage-1': ':', '!ExtToken': '', TranscludeToken: ':',
|
|
48
27
|
}),
|
|
49
28
|
new AttributesToken(attr, 'table-attrs', this.type, config, accum),
|
|
50
29
|
);
|
|
51
|
-
this.getAttribute('protectChildren')(0, 1);
|
|
52
30
|
}
|
|
53
31
|
|
|
54
32
|
/**
|
|
55
33
|
* @override
|
|
56
34
|
* @param {number} start 起始位置
|
|
57
35
|
*/
|
|
58
|
-
lint(start =
|
|
36
|
+
lint(start = this.getAbsoluteIndex()) {
|
|
59
37
|
const TranscludeToken = require('../transclude'),
|
|
60
38
|
ArgToken = require('../arg');
|
|
61
39
|
const errors = super.lint(start),
|
|
@@ -75,7 +53,7 @@ class TrToken extends attributeParent(Token, 1) {
|
|
|
75
53
|
}
|
|
76
54
|
} catch {}
|
|
77
55
|
}
|
|
78
|
-
const error = generateForChild(inter, {start}, '
|
|
56
|
+
const error = generateForChild(inter, {start}, 'content to be moved out from the table');
|
|
79
57
|
errors.push({
|
|
80
58
|
...error,
|
|
81
59
|
startIndex: error.startIndex + 1,
|
|
@@ -88,232 +66,9 @@ class TrToken extends attributeParent(Token, 1) {
|
|
|
88
66
|
|
|
89
67
|
/** @override */
|
|
90
68
|
text() {
|
|
91
|
-
this.#correct();
|
|
92
69
|
const str = super.text();
|
|
93
70
|
return this.type === 'tr' && !str.trim().includes('\n') ? '' : str;
|
|
94
71
|
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @override
|
|
98
|
-
* @this {TrToken & {constructor: typeof TrToken}}
|
|
99
|
-
*/
|
|
100
|
-
cloneNode() {
|
|
101
|
-
const [syntax, attr, inner, ...cloned] = this.cloneChildNodes();
|
|
102
|
-
return Parser.run(() => {
|
|
103
|
-
const token = new this.constructor(undefined, undefined, this.getAttribute('config'));
|
|
104
|
-
token.firstChild.safeReplaceWith(syntax);
|
|
105
|
-
token.childNodes[1].safeReplaceWith(attr);
|
|
106
|
-
if (token.type === 'td') { // TdToken
|
|
107
|
-
token.childNodes[2].safeReplaceWith(inner);
|
|
108
|
-
} else if (inner !== undefined) {
|
|
109
|
-
token.insertAt(inner);
|
|
110
|
-
}
|
|
111
|
-
token.append(...cloned);
|
|
112
|
-
return token;
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/** 修复简单的表格语法错误 */
|
|
117
|
-
#correct() {
|
|
118
|
-
const {childNodes: [,, child]} = this;
|
|
119
|
-
if (child?.constructor === Token) {
|
|
120
|
-
const /** @type {{firstChild: AstText}} */ {firstChild} = child;
|
|
121
|
-
if (firstChild.type !== 'text') {
|
|
122
|
-
child.prepend('\n');
|
|
123
|
-
} else if (firstChild.data[0] !== '\n') {
|
|
124
|
-
firstChild.insertData(0, '\n');
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* @override
|
|
131
|
-
* @param {string} selector
|
|
132
|
-
*/
|
|
133
|
-
toString(selector) {
|
|
134
|
-
this.#correct();
|
|
135
|
-
return super.toString(selector);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* 转义表格语法
|
|
140
|
-
* @complexity `n`
|
|
141
|
-
*/
|
|
142
|
-
escape() {
|
|
143
|
-
for (const child of this.childNodes) {
|
|
144
|
-
if (child instanceof SyntaxToken) {
|
|
145
|
-
escapeTable(child);
|
|
146
|
-
} else if (child instanceof TrToken) {
|
|
147
|
-
child.escape();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* 设置表格语法
|
|
154
|
-
* @param {string} syntax 表格语法
|
|
155
|
-
* @param {boolean} esc 是否需要转义
|
|
156
|
-
*/
|
|
157
|
-
setSyntax(syntax, esc) {
|
|
158
|
-
const {firstChild} = this;
|
|
159
|
-
firstChild.replaceChildren(syntax);
|
|
160
|
-
if (esc) {
|
|
161
|
-
escapeTable(firstChild);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* @override
|
|
167
|
-
* @param {number} i 移除位置
|
|
168
|
-
* @complexity `n`
|
|
169
|
-
*/
|
|
170
|
-
removeAt(i) {
|
|
171
|
-
const TdToken = require('./td');
|
|
172
|
-
const child = this.childNodes.at(i);
|
|
173
|
-
if (child instanceof TdToken && child.isIndependent()) {
|
|
174
|
-
const {nextSibling} = child;
|
|
175
|
-
if (nextSibling?.type === 'td') {
|
|
176
|
-
nextSibling.independence();
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return super.removeAt(i);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* @override
|
|
184
|
-
* @template {AstText|Token} T
|
|
185
|
-
* @param {T} token 待插入的子节点
|
|
186
|
-
* @param {number} i 插入位置
|
|
187
|
-
* @returns {T}
|
|
188
|
-
* @complexity `n`
|
|
189
|
-
*/
|
|
190
|
-
insertAt(token, i = this.length) {
|
|
191
|
-
if (!Parser.running && !(token instanceof TrToken)) {
|
|
192
|
-
this.typeError('insertAt', 'TrToken');
|
|
193
|
-
}
|
|
194
|
-
const TdToken = require('./td');
|
|
195
|
-
const child = this.childNodes.at(i);
|
|
196
|
-
if (token instanceof TdToken && token.isIndependent() && child instanceof TdToken) {
|
|
197
|
-
child.independence();
|
|
198
|
-
}
|
|
199
|
-
return super.insertAt(token, i);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* 获取行数
|
|
204
|
-
* @returns {0|1}
|
|
205
|
-
* @complexity `n`
|
|
206
|
-
*/
|
|
207
|
-
getRowCount() {
|
|
208
|
-
const TdToken = require('./td');
|
|
209
|
-
return Number(this.childNodes.some(
|
|
210
|
-
child => child instanceof TdToken && child.isIndependent() && child.firstChild.text().at(-1) !== '+',
|
|
211
|
-
));
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* 获取相邻行
|
|
216
|
-
* @param {(childNodes: Token[], index: number) => Token[]} subset 筛选兄弟节点的方法
|
|
217
|
-
* @complexity `n`
|
|
218
|
-
*/
|
|
219
|
-
#getSiblingRow(subset) {
|
|
220
|
-
const {parentNode} = this;
|
|
221
|
-
if (!parentNode) {
|
|
222
|
-
return undefined;
|
|
223
|
-
}
|
|
224
|
-
const {childNodes} = parentNode,
|
|
225
|
-
index = childNodes.indexOf(this);
|
|
226
|
-
for (const child of subset(childNodes, index)) {
|
|
227
|
-
if (child instanceof TrToken && child.getRowCount()) {
|
|
228
|
-
return child;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return undefined;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* 获取下一行
|
|
236
|
-
* @complexity `n`
|
|
237
|
-
*/
|
|
238
|
-
getNextRow() {
|
|
239
|
-
return this.#getSiblingRow((childNodes, index) => childNodes.slice(index + 1));
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* 获取前一行
|
|
244
|
-
* @complexity `n`
|
|
245
|
-
*/
|
|
246
|
-
getPreviousRow() {
|
|
247
|
-
return this.#getSiblingRow((childNodes, index) => childNodes.slice(0, index).reverse());
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* 获取列数
|
|
252
|
-
* @complexity `n`
|
|
253
|
-
*/
|
|
254
|
-
getColCount() {
|
|
255
|
-
const TdToken = require('./td');
|
|
256
|
-
let count = 0,
|
|
257
|
-
last = 0;
|
|
258
|
-
for (const child of this.childNodes) {
|
|
259
|
-
if (child instanceof TdToken) {
|
|
260
|
-
last = child.isIndependent() ? Number(child.subtype !== 'caption') : last;
|
|
261
|
-
count += last;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return count;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* 获取第n列
|
|
269
|
-
* @param {number} n 列号
|
|
270
|
-
* @param {boolean} insert 是否用于判断插入新列的位置
|
|
271
|
-
* @returns {TdToken}
|
|
272
|
-
* @complexity `n`
|
|
273
|
-
* @throws `RangeError` 不存在对应单元格
|
|
274
|
-
*/
|
|
275
|
-
getNthCol(n, insert) {
|
|
276
|
-
if (!Number.isInteger(n)) {
|
|
277
|
-
this.typeError('getNthCol', 'Number');
|
|
278
|
-
}
|
|
279
|
-
const nCols = this.getColCount();
|
|
280
|
-
n = n < 0 ? n + nCols : n;
|
|
281
|
-
if (n < 0 || n > nCols || n === nCols && !insert) {
|
|
282
|
-
throw new RangeError(`不存在第 ${n} 个单元格!`);
|
|
283
|
-
}
|
|
284
|
-
const TdToken = require('./td');
|
|
285
|
-
let last = 0;
|
|
286
|
-
for (const child of this.childNodes.slice(2)) {
|
|
287
|
-
if (child instanceof TdToken) {
|
|
288
|
-
if (child.isIndependent()) {
|
|
289
|
-
last = Number(child.subtype !== 'caption');
|
|
290
|
-
}
|
|
291
|
-
n -= last;
|
|
292
|
-
if (n < 0) {
|
|
293
|
-
return child;
|
|
294
|
-
}
|
|
295
|
-
} else if (child.type === 'tr' || child.type === 'table-syntax') {
|
|
296
|
-
return child;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
return undefined;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* 插入新的单元格
|
|
304
|
-
* @param {string|Token} inner 单元格内部wikitext
|
|
305
|
-
* @param {TableCoords} coord 单元格坐标
|
|
306
|
-
* @param {'td'|'th'|'caption'} subtype 单元格类型
|
|
307
|
-
* @param {Record<string, string|boolean>} attr 单元格属性
|
|
308
|
-
* @returns {TdToken}
|
|
309
|
-
* @complexity `n`
|
|
310
|
-
*/
|
|
311
|
-
insertTableCell(inner, {column}, subtype = 'td', attr = {}) {
|
|
312
|
-
const TdToken = require('./td');
|
|
313
|
-
const token = TdToken.create(inner, subtype, attr, this.getAttribute('include'), this.getAttribute('config'));
|
|
314
|
-
return this.insertBefore(token, this.getNthCol(column, true));
|
|
315
|
-
}
|
|
316
72
|
}
|
|
317
73
|
|
|
318
|
-
Parser.classes.TrToken = __filename;
|
|
319
74
|
module.exports = TrToken;
|
package/src/tagPair/ext.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const {generateForSelf} = require('../../util/lint'),
|
|
4
|
-
attributeParent = require('../../mixin/attributeParent'),
|
|
5
|
-
path = require('path'),
|
|
6
4
|
Parser = require('../..'),
|
|
7
5
|
Token = require('..'),
|
|
8
6
|
TagPairToken = require('.'),
|
|
@@ -12,7 +10,7 @@ const {generateForSelf} = require('../../util/lint'),
|
|
|
12
10
|
* 扩展标签
|
|
13
11
|
* @classdesc `{childNodes: [AttributesToken, NowikiToken|Token]}`
|
|
14
12
|
*/
|
|
15
|
-
class ExtToken extends
|
|
13
|
+
class ExtToken extends TagPairToken {
|
|
16
14
|
type = 'ext';
|
|
17
15
|
closed = true;
|
|
18
16
|
|
|
@@ -60,17 +58,19 @@ class ExtToken extends attributeParent(TagPairToken) {
|
|
|
60
58
|
innerToken = new PreToken(inner, newConfig, accum);
|
|
61
59
|
break;
|
|
62
60
|
}
|
|
63
|
-
case '
|
|
64
|
-
const
|
|
65
|
-
innerToken = new
|
|
61
|
+
case 'references': {
|
|
62
|
+
const ReferencesToken = require('../nested/references');
|
|
63
|
+
innerToken = new ReferencesToken(inner, newConfig, accum);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case 'choose': {
|
|
67
|
+
const ChooseToken = require('../nested/choose');
|
|
68
|
+
innerToken = new ChooseToken(inner, newConfig, accum);
|
|
66
69
|
break;
|
|
67
70
|
}
|
|
68
|
-
case 'references':
|
|
69
|
-
case 'choose':
|
|
70
71
|
case 'combobox': {
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
innerToken = new NestedExtToken(inner, newConfig, accum);
|
|
72
|
+
const ComboboxToken = require('../nested/combobox');
|
|
73
|
+
innerToken = new ComboboxToken(inner, newConfig, accum);
|
|
74
74
|
break;
|
|
75
75
|
}
|
|
76
76
|
case 'imagemap': {
|
|
@@ -113,30 +113,16 @@ class ExtToken extends attributeParent(TagPairToken) {
|
|
|
113
113
|
* @override
|
|
114
114
|
* @param {number} start 起始位置
|
|
115
115
|
*/
|
|
116
|
-
lint(start =
|
|
116
|
+
lint(start = this.getAbsoluteIndex()) {
|
|
117
117
|
const errors = super.lint(start);
|
|
118
118
|
if (this.name !== 'nowiki' && this.closest('html-attrs, table-attrs')) {
|
|
119
119
|
const root = this.getRootNode(),
|
|
120
120
|
excerpt = String(root).slice(Math.max(0, start - 25), start + 25),
|
|
121
121
|
rect = {start, ...root.posFromIndex(start)};
|
|
122
|
-
errors.push({...generateForSelf(this, rect, 'HTML
|
|
122
|
+
errors.push({...generateForSelf(this, rect, 'extension tag in HTML tag attributes'), excerpt});
|
|
123
123
|
}
|
|
124
124
|
return errors;
|
|
125
125
|
}
|
|
126
|
-
|
|
127
|
-
/** @override */
|
|
128
|
-
cloneNode() {
|
|
129
|
-
const inner = this.lastChild.cloneNode(),
|
|
130
|
-
tags = this.getAttribute('tags'),
|
|
131
|
-
config = this.getAttribute('config'),
|
|
132
|
-
attr = String(this.firstChild);
|
|
133
|
-
return Parser.run(() => {
|
|
134
|
-
const token = new ExtToken(tags[0], attr, '', this.selfClosing ? undefined : tags[1], config);
|
|
135
|
-
token.lastChild.safeReplaceWith(inner);
|
|
136
|
-
return token;
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
126
|
}
|
|
140
127
|
|
|
141
|
-
Parser.classes.ExtToken = __filename;
|
|
142
128
|
module.exports = ExtToken;
|