wikiparser-node 1.0.0-beta.0 → 1.0.0-beta.2
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/.schema.json +26 -0
- package/dist/index.d.ts +11 -9
- package/dist/index.js +22 -24
- package/dist/internal.d.ts +44 -0
- package/dist/lib/element.d.ts +42 -32
- package/dist/lib/element.js +59 -56
- package/dist/lib/node.d.ts +29 -36
- package/dist/lib/node.js +33 -48
- package/dist/lib/range.d.ts +132 -0
- package/dist/lib/range.js +387 -0
- package/dist/lib/ranges.d.ts +2 -12
- package/dist/lib/ranges.js +6 -11
- package/dist/lib/text.d.ts +11 -5
- package/dist/lib/text.js +25 -13
- package/dist/lib/title.d.ts +4 -5
- package/dist/lib/title.js +17 -7
- package/dist/mixin/attributesParent.js +6 -3
- package/dist/mixin/fixed.js +8 -5
- package/dist/mixin/hidden.js +7 -3
- package/dist/mixin/singleLine.js +6 -3
- package/dist/mixin/sol.js +6 -3
- package/dist/parser/{brackets.js → braces.js} +34 -26
- package/dist/parser/commentAndExt.js +25 -15
- package/dist/parser/converter.js +16 -9
- package/dist/parser/externalLinks.js +15 -9
- package/dist/parser/hrAndDoubleUnderscore.js +17 -10
- package/dist/parser/html.js +18 -9
- package/dist/parser/links.js +22 -14
- package/dist/parser/list.js +20 -10
- package/dist/parser/magicLinks.js +14 -7
- package/dist/parser/quotes.js +21 -11
- package/dist/parser/selector.js +19 -12
- package/dist/parser/table.js +25 -16
- package/dist/src/arg.d.ts +7 -8
- package/dist/src/arg.js +27 -24
- package/dist/src/atom.d.ts +4 -5
- package/dist/src/atom.js +9 -7
- package/dist/src/attribute.d.ts +13 -13
- package/dist/src/attribute.js +28 -25
- package/dist/src/attributes.d.ts +11 -10
- package/dist/src/attributes.js +40 -45
- package/dist/src/converter.d.ts +5 -7
- package/dist/src/converter.js +22 -16
- package/dist/src/converterFlags.d.ts +11 -12
- package/dist/src/converterFlags.js +17 -14
- package/dist/src/converterRule.d.ts +9 -10
- package/dist/src/converterRule.js +27 -27
- package/dist/src/extLink.d.ts +4 -6
- package/dist/src/extLink.js +25 -22
- package/dist/src/gallery.d.ts +9 -13
- package/dist/src/gallery.js +28 -23
- package/dist/src/heading.d.ts +11 -11
- package/dist/src/heading.js +19 -19
- package/dist/src/hidden.d.ts +4 -5
- package/dist/src/hidden.js +10 -8
- package/dist/src/html.d.ts +15 -12
- package/dist/src/html.js +18 -15
- package/dist/src/imageParameter.d.ts +11 -13
- package/dist/src/imageParameter.js +21 -16
- package/dist/src/imagemap.d.ts +11 -15
- package/dist/src/imagemap.js +26 -21
- package/dist/src/imagemapLink.d.ts +12 -17
- package/dist/src/imagemapLink.js +19 -14
- package/dist/src/index.d.ts +24 -20
- package/dist/src/index.js +65 -75
- package/dist/src/link/base.d.ts +8 -10
- package/dist/src/link/base.js +28 -22
- package/dist/src/link/category.d.ts +2 -3
- package/dist/src/link/category.js +7 -5
- package/dist/src/link/file.d.ts +9 -11
- package/dist/src/link/file.js +53 -26
- package/dist/src/link/galleryImage.d.ts +8 -8
- package/dist/src/link/galleryImage.js +18 -16
- package/dist/src/link/index.d.ts +6 -6
- package/dist/src/link/index.js +14 -16
- package/dist/src/magicLink.d.ts +9 -6
- package/dist/src/magicLink.js +23 -18
- package/dist/src/nested.d.ts +10 -10
- package/dist/src/nested.js +25 -17
- package/dist/src/nowiki/base.d.ts +7 -8
- package/dist/src/nowiki/base.js +10 -8
- package/dist/src/nowiki/comment.d.ts +7 -7
- package/dist/src/nowiki/comment.js +12 -9
- package/dist/src/nowiki/dd.d.ts +2 -3
- package/dist/src/nowiki/dd.js +7 -11
- package/dist/src/nowiki/doubleUnderscore.d.ts +5 -7
- package/dist/src/nowiki/doubleUnderscore.js +11 -8
- package/dist/src/nowiki/hr.d.ts +6 -7
- package/dist/src/nowiki/hr.js +11 -8
- package/dist/src/nowiki/index.d.ts +5 -7
- package/dist/src/nowiki/index.js +8 -6
- package/dist/src/nowiki/list.d.ts +4 -4
- package/dist/src/nowiki/list.js +8 -6
- package/dist/src/nowiki/noinclude.d.ts +3 -3
- package/dist/src/nowiki/noinclude.js +8 -6
- package/dist/src/nowiki/quote.d.ts +6 -7
- package/dist/src/nowiki/quote.js +11 -8
- package/dist/src/onlyinclude.d.ts +3 -5
- package/dist/src/onlyinclude.js +9 -7
- package/dist/src/paramTag/index.d.ts +8 -10
- package/dist/src/paramTag/index.js +15 -13
- package/dist/src/paramTag/inputbox.d.ts +4 -6
- package/dist/src/paramTag/inputbox.js +10 -8
- package/dist/src/parameter.d.ts +11 -12
- package/dist/src/parameter.js +25 -22
- package/dist/src/pre.d.ts +5 -10
- package/dist/src/pre.js +16 -11
- package/dist/src/syntax.d.ts +6 -7
- package/dist/src/syntax.js +12 -10
- package/dist/src/table/base.d.ts +14 -9
- package/dist/src/table/base.js +18 -15
- package/dist/src/table/index.d.ts +24 -17
- package/dist/src/table/index.js +39 -67
- package/dist/src/table/td.d.ts +17 -21
- package/dist/src/table/td.js +20 -28
- package/dist/src/table/tr.d.ts +6 -11
- package/dist/src/table/tr.js +8 -6
- package/dist/src/table/trBase.d.ts +12 -22
- package/dist/src/table/trBase.js +23 -19
- package/dist/src/tagPair/ext.d.ts +10 -10
- package/dist/src/tagPair/ext.js +47 -24
- package/dist/src/tagPair/include.d.ts +6 -7
- package/dist/src/tagPair/include.js +11 -8
- package/dist/src/tagPair/index.d.ts +12 -11
- package/dist/src/tagPair/index.js +13 -11
- package/dist/src/transclude.d.ts +8 -10
- package/dist/src/transclude.js +70 -77
- package/dist/util/debug.js +2 -12
- package/dist/util/diff.js +4 -2
- package/dist/util/lint.js +5 -5
- package/dist/util/string.js +2 -31
- package/package.json +13 -13
- package/dist/util/base.js +0 -26
package/dist/src/transclude.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TranscludeToken = void 0;
|
|
2
4
|
const string_1 = require("../util/string");
|
|
3
5
|
const lint_1 = require("../util/lint");
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
6
|
+
const index_1 = require("../index");
|
|
7
|
+
const _1 = require(".");
|
|
8
|
+
const parameter_1 = require("./parameter");
|
|
9
|
+
const atom_1 = require("./atom");
|
|
10
|
+
const syntax_1 = require("./syntax");
|
|
9
11
|
/**
|
|
10
12
|
* 模板或魔术字
|
|
11
13
|
* @classdesc `{childNodes: [AtomToken|SyntaxToken, ...AtomToken, ...ParameterToken]}`
|
|
12
14
|
*/
|
|
13
|
-
class TranscludeToken extends Token {
|
|
15
|
+
class TranscludeToken extends _1.Token {
|
|
14
16
|
/** @browser */
|
|
15
17
|
type = 'template';
|
|
16
18
|
/** @browser */
|
|
@@ -21,7 +23,7 @@ class TranscludeToken extends Token {
|
|
|
21
23
|
#valid = true;
|
|
22
24
|
/** @browser */
|
|
23
25
|
#raw = false;
|
|
24
|
-
#args =
|
|
26
|
+
#args = new Map();
|
|
25
27
|
#keys = new Set();
|
|
26
28
|
/** 是否存在重复参数 */
|
|
27
29
|
get duplication() {
|
|
@@ -33,7 +35,7 @@ class TranscludeToken extends Token {
|
|
|
33
35
|
* @param parts 参数各部分
|
|
34
36
|
* @throws `SyntaxError` 非法的模板名称
|
|
35
37
|
*/
|
|
36
|
-
constructor(title, parts, config =
|
|
38
|
+
constructor(title, parts, config = index_1.default.getConfig(), accum = []) {
|
|
37
39
|
super(undefined, config, true, accum, {
|
|
38
40
|
AtomToken: 0, SyntaxToken: 0, ParameterToken: '1:',
|
|
39
41
|
});
|
|
@@ -41,19 +43,19 @@ class TranscludeToken extends Token {
|
|
|
41
43
|
const { parserFunction: [insensitive, sensitive] } = config, argSubst = /^(?:\s|\0\d+c\x7F)*\0\d+s\x7F/u.exec(title)?.[0];
|
|
42
44
|
if (argSubst) {
|
|
43
45
|
this.setAttribute('modifier', argSubst);
|
|
44
|
-
title = title.slice(argSubst.length);
|
|
46
|
+
title = title.slice(argSubst.length);
|
|
45
47
|
}
|
|
46
48
|
else if (title.includes(':')) {
|
|
47
49
|
const [modifier, ...arg] = title.split(':'), [mt] = /^(?:\s|\0\d+c\x7F)*/u.exec(arg[0] ?? '');
|
|
48
50
|
if (this.setModifier(`${modifier}:${mt}`)) {
|
|
49
|
-
title = arg.join(':').slice(mt.length);
|
|
51
|
+
title = arg.join(':').slice(mt.length);
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
if (title.includes(':') || parts.length === 0 && !this.#raw) {
|
|
53
55
|
const [magicWord, ...arg] = title.split(':'), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg.length > 0 ? 'trimStart' : 'trim'](), isSensitive = sensitive.includes(name), canonicalCame = insensitive[name.toLowerCase()];
|
|
54
56
|
if (isSensitive || canonicalCame) {
|
|
55
57
|
this.setAttribute('name', canonicalCame ?? name.toLowerCase()).type = 'magic-word';
|
|
56
|
-
const pattern = new RegExp(`^\\s*${name}\\s*$`, isSensitive ? 'u' : 'iu'), token = new SyntaxToken(magicWord, pattern, 'magic-word-name', config, accum, {
|
|
58
|
+
const pattern = new RegExp(`^\\s*${name}\\s*$`, isSensitive ? 'u' : 'iu'), token = new syntax_1.SyntaxToken(magicWord, pattern, 'magic-word-name', config, accum, {
|
|
57
59
|
'Stage-1': ':', '!ExtToken': '',
|
|
58
60
|
});
|
|
59
61
|
super.insertAt(token);
|
|
@@ -67,7 +69,7 @@ class TranscludeToken extends Token {
|
|
|
67
69
|
if (!part) {
|
|
68
70
|
break;
|
|
69
71
|
}
|
|
70
|
-
const invoke = new AtomToken(part.join('='), `invoke-${i ? 'function' : 'module'}`, config, accum, {
|
|
72
|
+
const invoke = new atom_1.AtomToken(part.join('='), `invoke-${i ? 'function' : 'module'}`, config, accum, {
|
|
71
73
|
'Stage-1': ':', '!ExtToken': '',
|
|
72
74
|
});
|
|
73
75
|
super.insertAt(invoke);
|
|
@@ -82,7 +84,7 @@ class TranscludeToken extends Token {
|
|
|
82
84
|
accum.pop();
|
|
83
85
|
throw new SyntaxError(`非法的模板名称:${(0, string_1.noWrap)(name)}`);
|
|
84
86
|
}
|
|
85
|
-
const token = new AtomToken(title, 'template-name', config, accum, {
|
|
87
|
+
const token = new atom_1.AtomToken(title, 'template-name', config, accum, {
|
|
86
88
|
'Stage-2': ':', '!HeadingToken': '',
|
|
87
89
|
});
|
|
88
90
|
super.insertAt(token);
|
|
@@ -99,7 +101,8 @@ class TranscludeToken extends Token {
|
|
|
99
101
|
part.unshift(i);
|
|
100
102
|
i++;
|
|
101
103
|
}
|
|
102
|
-
|
|
104
|
+
// @ts-expect-error abstract class
|
|
105
|
+
this.insertAt(new parameter_1.ParameterToken(...part, config, accum));
|
|
103
106
|
}
|
|
104
107
|
this.protectChildren(0);
|
|
105
108
|
}
|
|
@@ -109,16 +112,13 @@ class TranscludeToken extends Token {
|
|
|
109
112
|
* @param modifier 引用修饰符
|
|
110
113
|
*/
|
|
111
114
|
setModifier(modifier = '') {
|
|
112
|
-
if (typeof modifier !== 'string') {
|
|
113
|
-
this.typeError('setModifier', 'String');
|
|
114
|
-
}
|
|
115
115
|
const { parserFunction: [, , raw, subst] } = this.getAttribute('config'), lcModifier = (0, string_1.removeComment)(modifier).trim();
|
|
116
116
|
if (modifier && !lcModifier.endsWith(':')) {
|
|
117
117
|
return false;
|
|
118
118
|
}
|
|
119
119
|
const magicWord = lcModifier.slice(0, -1).toLowerCase(), isRaw = raw.includes(magicWord), isSubst = subst.includes(magicWord);
|
|
120
120
|
if (this.#raw && isRaw || !this.#raw && (isSubst || modifier === '')
|
|
121
|
-
|| (
|
|
121
|
+
|| (index_1.default.running || this.length > 1) && (isRaw || isSubst || modifier === '')) {
|
|
122
122
|
this.setAttribute('modifier', modifier);
|
|
123
123
|
this.#raw = isRaw;
|
|
124
124
|
return Boolean(modifier);
|
|
@@ -160,7 +160,7 @@ class TranscludeToken extends Token {
|
|
|
160
160
|
this.#fragment = fragment;
|
|
161
161
|
this.#valid = valid;
|
|
162
162
|
}
|
|
163
|
-
else if (oldKey !== newKey && prevTarget
|
|
163
|
+
else if (oldKey !== newKey && prevTarget instanceof parameter_1.ParameterToken) {
|
|
164
164
|
const oldArgs = this.getArgs(oldKey, false, false);
|
|
165
165
|
oldArgs.delete(prevTarget);
|
|
166
166
|
this.getArgs(newKey, false, false).add(prevTarget);
|
|
@@ -181,9 +181,9 @@ class TranscludeToken extends Token {
|
|
|
181
181
|
if (selector && this.matches(selector)) {
|
|
182
182
|
return '';
|
|
183
183
|
}
|
|
184
|
-
const { childNodes, firstChild, modifier } = this;
|
|
184
|
+
const { childNodes, length, firstChild, modifier } = this;
|
|
185
185
|
return `{{${modifier}${this.type === 'magic-word'
|
|
186
|
-
? `${firstChild.toString(selector)}${
|
|
186
|
+
? `${firstChild.toString(selector)}${length === 1 ? '' : ':'}${childNodes.slice(1).map(child => child.toString(selector)).join('|')}`
|
|
187
187
|
: super.toString(selector, '|')}}}`;
|
|
188
188
|
}
|
|
189
189
|
/**
|
|
@@ -191,11 +191,11 @@ class TranscludeToken extends Token {
|
|
|
191
191
|
* @browser
|
|
192
192
|
*/
|
|
193
193
|
text() {
|
|
194
|
-
const { childNodes, firstChild, modifier, type, name } = this;
|
|
194
|
+
const { childNodes, length, firstChild, modifier, type, name } = this;
|
|
195
195
|
return type === 'magic-word' && name === 'vardefine'
|
|
196
196
|
? ''
|
|
197
197
|
: `{{${modifier}${this.type === 'magic-word'
|
|
198
|
-
? `${firstChild.text()}${
|
|
198
|
+
? `${firstChild.text()}${length === 1 ? '' : ':'}${(0, string_1.text)(childNodes.slice(1), '|')}`
|
|
199
199
|
: super.text('|')}}}`;
|
|
200
200
|
}
|
|
201
201
|
/** @private */
|
|
@@ -203,17 +203,17 @@ class TranscludeToken extends Token {
|
|
|
203
203
|
return this.modifier.length + 2;
|
|
204
204
|
}
|
|
205
205
|
/** @private */
|
|
206
|
-
getGaps() {
|
|
207
|
-
return 1;
|
|
206
|
+
getGaps(i) {
|
|
207
|
+
return i < this.length - 1 ? 1 : 0;
|
|
208
208
|
}
|
|
209
209
|
/**
|
|
210
210
|
* @override
|
|
211
211
|
* @browser
|
|
212
212
|
*/
|
|
213
213
|
print() {
|
|
214
|
-
const { childNodes, firstChild, modifier } = this;
|
|
214
|
+
const { childNodes, length, firstChild, modifier } = this;
|
|
215
215
|
return `<span class="wpb-${this.type}">{{${modifier}${this.type === 'magic-word'
|
|
216
|
-
? `${firstChild.print()}${
|
|
216
|
+
? `${firstChild.print()}${length === 1 ? '' : ':'}${(0, string_1.print)(childNodes.slice(1), { sep: '|' })}`
|
|
217
217
|
: (0, string_1.print)(childNodes, { sep: '|' })}}}</span>`;
|
|
218
218
|
}
|
|
219
219
|
/**
|
|
@@ -254,8 +254,7 @@ class TranscludeToken extends Token {
|
|
|
254
254
|
else if (!this.hasArg(maxAnon, true)) {
|
|
255
255
|
this.#keys.delete(maxAnon);
|
|
256
256
|
}
|
|
257
|
-
|
|
258
|
-
for (let i = j; i < args.length; i++) {
|
|
257
|
+
for (let i = added ? args.indexOf(addedToken) : addedToken - 1; i < args.length; i++) {
|
|
259
258
|
const token = args[i], { name } = token, newName = String(i + 1);
|
|
260
259
|
if (name !== newName) {
|
|
261
260
|
this.getArgs(newName, false, false).add(token.setAttribute('name', newName));
|
|
@@ -304,18 +303,16 @@ class TranscludeToken extends Token {
|
|
|
304
303
|
* @param copy 是否返回一个备份
|
|
305
304
|
*/
|
|
306
305
|
getArgs(key, exact = false, copy = true) {
|
|
307
|
-
if (typeof key !== 'string' && typeof key !== 'number') {
|
|
308
|
-
this.typeError('getArgs', 'String', 'Number');
|
|
309
|
-
}
|
|
310
306
|
const keyStr = String(key).replace(/^[ \t\n\0\v]+|(?<=[^ \t\n\0\v])[ \t\n\0\v]+$/gu, '');
|
|
311
307
|
let args;
|
|
312
|
-
if (
|
|
313
|
-
args = this.#args
|
|
308
|
+
if (this.#args.has(keyStr)) {
|
|
309
|
+
args = this.#args.get(keyStr);
|
|
314
310
|
}
|
|
315
311
|
else {
|
|
316
312
|
args = new Set(this.getAllArgs().filter(({ name }) => keyStr === name));
|
|
317
|
-
this.#args
|
|
313
|
+
this.#args.set(keyStr, args);
|
|
318
314
|
}
|
|
315
|
+
// @ts-expect-error isNaN
|
|
319
316
|
if (exact && !isNaN(keyStr)) {
|
|
320
317
|
args = new Set([...args].filter(({ anon }) => typeof key === 'number' === anon));
|
|
321
318
|
}
|
|
@@ -331,8 +328,7 @@ class TranscludeToken extends Token {
|
|
|
331
328
|
*/
|
|
332
329
|
getDuplicatedArgs() {
|
|
333
330
|
if (this.isTemplate()) {
|
|
334
|
-
return
|
|
335
|
-
.map(([key, args]) => [key, [...args]]);
|
|
331
|
+
return [...this.#args].filter(([, { size }]) => size > 1).map(([key, args]) => [key, [...args]]);
|
|
336
332
|
}
|
|
337
333
|
throw new Error(`${this.constructor.name}.getDuplicatedArgs 方法仅供模板使用!`);
|
|
338
334
|
}
|
|
@@ -385,7 +381,8 @@ class TranscludeToken extends Token {
|
|
|
385
381
|
/** @override */
|
|
386
382
|
cloneNode() {
|
|
387
383
|
const [first, ...cloned] = this.cloneChildNodes(), config = this.getAttribute('config');
|
|
388
|
-
return
|
|
384
|
+
return index_1.default.run(() => {
|
|
385
|
+
// @ts-expect-error abstract class
|
|
389
386
|
const token = new TranscludeToken(this.type === 'template' ? '' : first.text(), [], config);
|
|
390
387
|
if (this.#raw) {
|
|
391
388
|
token.setModifier(this.modifier);
|
|
@@ -414,7 +411,7 @@ class TranscludeToken extends Token {
|
|
|
414
411
|
/** @private */
|
|
415
412
|
getAttribute(key) {
|
|
416
413
|
if (key === 'args') {
|
|
417
|
-
return
|
|
414
|
+
return new Map(this.#args);
|
|
418
415
|
}
|
|
419
416
|
else if (key === 'keys') {
|
|
420
417
|
return this.#keys;
|
|
@@ -461,7 +458,7 @@ class TranscludeToken extends Token {
|
|
|
461
458
|
* @param exact 是否匹配匿名性
|
|
462
459
|
*/
|
|
463
460
|
removeArg(key, exact = false) {
|
|
464
|
-
|
|
461
|
+
index_1.default.run(() => {
|
|
465
462
|
for (const token of this.getArgs(key, exact, false)) {
|
|
466
463
|
this.removeChild(token);
|
|
467
464
|
}
|
|
@@ -499,8 +496,12 @@ class TranscludeToken extends Token {
|
|
|
499
496
|
* @throws `SyntaxError` 非法的匿名参数
|
|
500
497
|
*/
|
|
501
498
|
newAnonArg(val) {
|
|
502
|
-
const templateLike = this.isTemplate(), wikitext = `{{${templateLike ? ':T|' : 'lc:'}${val}}}`, root =
|
|
503
|
-
if (length
|
|
499
|
+
const templateLike = this.isTemplate(), wikitext = `{{${templateLike ? ':T|' : 'lc:'}${val}}}`, root = index_1.default.parse(wikitext, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: transclude } = root, targetType = templateLike ? 'template' : 'magic-word';
|
|
500
|
+
if (length !== 1 || transclude.type !== targetType || transclude.length !== 2) {
|
|
501
|
+
throw new SyntaxError(`非法的匿名参数:${(0, string_1.noWrap)(val)}`);
|
|
502
|
+
}
|
|
503
|
+
const { name, lastChild } = transclude, targetName = templateLike ? 'T' : 'lc';
|
|
504
|
+
if (name === targetName && lastChild.anon) {
|
|
504
505
|
return this.insertAt(lastChild);
|
|
505
506
|
}
|
|
506
507
|
throw new SyntaxError(`非法的匿名参数:${(0, string_1.noWrap)(val)}`);
|
|
@@ -513,10 +514,7 @@ class TranscludeToken extends Token {
|
|
|
513
514
|
* @throws `SyntaxError` 非法的命名参数
|
|
514
515
|
*/
|
|
515
516
|
setValue(key, value) {
|
|
516
|
-
if (
|
|
517
|
-
this.typeError('setValue', 'String');
|
|
518
|
-
}
|
|
519
|
-
else if (!this.isTemplate()) {
|
|
517
|
+
if (!this.isTemplate()) {
|
|
520
518
|
throw new Error(`${this.constructor.name}.setValue 方法仅供模板使用!`);
|
|
521
519
|
}
|
|
522
520
|
const token = this.getArg(key);
|
|
@@ -524,11 +522,15 @@ class TranscludeToken extends Token {
|
|
|
524
522
|
token.setValue(value);
|
|
525
523
|
return;
|
|
526
524
|
}
|
|
527
|
-
const wikitext = `{{:T|${key}=${value}}}`, root =
|
|
528
|
-
if (length !== 1 || type !== 'template' ||
|
|
525
|
+
const wikitext = `{{:T|${key}=${value}}}`, root = index_1.default.parse(wikitext, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: template } = root;
|
|
526
|
+
if (length !== 1 || template.type !== 'template' || template.length !== 2) {
|
|
529
527
|
throw new SyntaxError(`非法的命名参数:${key}=${(0, string_1.noWrap)(value)}`);
|
|
530
528
|
}
|
|
531
|
-
|
|
529
|
+
const { name, lastChild: parameter } = template;
|
|
530
|
+
if (name === 'T' && parameter.name === key) {
|
|
531
|
+
this.insertAt(parameter);
|
|
532
|
+
}
|
|
533
|
+
throw new SyntaxError(`非法的命名参数:${key}=${(0, string_1.noWrap)(value)}`);
|
|
532
534
|
}
|
|
533
535
|
/**
|
|
534
536
|
* 将匿名参数改写为命名参数
|
|
@@ -552,14 +554,11 @@ class TranscludeToken extends Token {
|
|
|
552
554
|
if (this.type === 'magic-word') {
|
|
553
555
|
throw new Error(`${this.constructor.name}.replaceTemplate 方法仅用于更换模板!`);
|
|
554
556
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
const root = Parser.parse(`{{${title}}}`, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: template } = root;
|
|
559
|
-
if (length !== 1 || template.type !== 'template' || template.length !== 1) {
|
|
560
|
-
throw new SyntaxError(`非法的模板名称:${title}`);
|
|
557
|
+
const root = index_1.default.parse(`{{${title}}}`, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: template } = root;
|
|
558
|
+
if (length === 1 && template.type === 'template' && template.length === 1) {
|
|
559
|
+
this.firstChild.replaceChildren(...template.firstChild.childNodes);
|
|
561
560
|
}
|
|
562
|
-
|
|
561
|
+
throw new SyntaxError(`非法的模板名称:${title}`);
|
|
563
562
|
}
|
|
564
563
|
/**
|
|
565
564
|
* 替换模块名
|
|
@@ -571,10 +570,7 @@ class TranscludeToken extends Token {
|
|
|
571
570
|
if (this.type !== 'magic-word' || this.name !== 'invoke') {
|
|
572
571
|
throw new Error(`${this.constructor.name}.replaceModule 方法仅用于更换模块!`);
|
|
573
572
|
}
|
|
574
|
-
|
|
575
|
-
this.typeError('replaceModule', 'String');
|
|
576
|
-
}
|
|
577
|
-
const root = Parser.parse(`{{#invoke:${title}}}`, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: invoke } = root, { type, name, lastChild } = invoke;
|
|
573
|
+
const root = index_1.default.parse(`{{#invoke:${title}}}`, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: invoke } = root, { type, name, lastChild } = invoke;
|
|
578
574
|
if (length !== 1 || type !== 'magic-word' || name !== 'invoke' || invoke.length !== 2) {
|
|
579
575
|
throw new SyntaxError(`非法的模块名称:${title}`);
|
|
580
576
|
}
|
|
@@ -597,13 +593,10 @@ class TranscludeToken extends Token {
|
|
|
597
593
|
if (this.type !== 'magic-word' || this.name !== 'invoke') {
|
|
598
594
|
throw new Error(`${this.constructor.name}.replaceModule 方法仅用于更换模块!`);
|
|
599
595
|
}
|
|
600
|
-
else if (typeof func !== 'string') {
|
|
601
|
-
this.typeError('replaceFunction', 'String');
|
|
602
|
-
}
|
|
603
596
|
else if (this.length < 2) {
|
|
604
597
|
throw new Error('尚未指定模块名称!');
|
|
605
598
|
}
|
|
606
|
-
const root =
|
|
599
|
+
const root = index_1.default.parse(`{{#invoke:M|${func}}}`, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: invoke } = root, { type, name, lastChild } = invoke;
|
|
607
600
|
if (length !== 1 || type !== 'magic-word' || name !== 'invoke' || invoke.length !== 3) {
|
|
608
601
|
throw new SyntaxError(`非法的模块函数名:${func}`);
|
|
609
602
|
}
|
|
@@ -641,19 +634,19 @@ class TranscludeToken extends Token {
|
|
|
641
634
|
if (args.length <= 1) {
|
|
642
635
|
continue;
|
|
643
636
|
}
|
|
644
|
-
const values =
|
|
637
|
+
const values = new Map();
|
|
645
638
|
for (const arg of args) {
|
|
646
639
|
const val = arg.getValue().trim();
|
|
647
|
-
if (
|
|
648
|
-
values
|
|
640
|
+
if (values.has(val)) {
|
|
641
|
+
values.get(val).push(arg);
|
|
649
642
|
}
|
|
650
643
|
else {
|
|
651
|
-
values
|
|
644
|
+
values.set(val, [arg]);
|
|
652
645
|
}
|
|
653
646
|
}
|
|
647
|
+
// @ts-expect-error isNaN
|
|
654
648
|
let noMoreAnon = anonCount === 0 || isNaN(key);
|
|
655
|
-
const emptyArgs = values
|
|
656
|
-
.flatMap(([, curArgs]) => {
|
|
649
|
+
const emptyArgs = values.get('') ?? [], duplicatedArgs = [...values].filter(([val, { length }]) => val && length > 1).flatMap(([, curArgs]) => {
|
|
657
650
|
const anonIndex = noMoreAnon ? -1 : curArgs.findIndex(({ anon }) => anon);
|
|
658
651
|
if (anonIndex !== -1) {
|
|
659
652
|
noMoreAnon = true;
|
|
@@ -695,7 +688,7 @@ class TranscludeToken extends Token {
|
|
|
695
688
|
}
|
|
696
689
|
}
|
|
697
690
|
if (remaining > 1) {
|
|
698
|
-
|
|
691
|
+
index_1.default.error(`${this.type === 'template'
|
|
699
692
|
? this.name
|
|
700
693
|
: this.normalizeTitle(this.childNodes[1]?.text() ?? '', 828).title} 还留有 ${remaining} 个重复的 ${key} 参数:${[...this.getArgs(key)].map(arg => {
|
|
701
694
|
const { top, left } = arg.getBoundingClientRect();
|
|
@@ -716,24 +709,24 @@ class TranscludeToken extends Token {
|
|
|
716
709
|
if (!/\n[^\S\n]*(?::+\s*)?\{\|[^\n]*\n\s*(?:\S[^\n]*\n\s*)*\|\}/u.test(this.text()) || !count) {
|
|
717
710
|
return this;
|
|
718
711
|
}
|
|
719
|
-
const stripped = String(this).slice(2, -2), include = this.getAttribute('include'), config = this.getAttribute('config'), parsed =
|
|
712
|
+
const stripped = String(this).slice(2, -2), include = this.getAttribute('include'), config = this.getAttribute('config'), parsed = index_1.default.parse(stripped, include, 4, config);
|
|
720
713
|
for (const table of parsed.childNodes) {
|
|
721
714
|
if (table.type === 'table') {
|
|
722
715
|
table.escape();
|
|
723
716
|
}
|
|
724
717
|
}
|
|
725
|
-
const { firstChild,
|
|
726
|
-
if (
|
|
718
|
+
const { firstChild, length } = index_1.default.parse(`{{${String(parsed)}}}`, include, 2, config);
|
|
719
|
+
if (length !== 1 || !(firstChild instanceof TranscludeToken)) {
|
|
727
720
|
throw new Error('转义表格失败!');
|
|
728
721
|
}
|
|
729
722
|
const newCount = firstChild.hasDuplicatedArgs();
|
|
730
723
|
if (newCount === count) {
|
|
731
724
|
return this;
|
|
732
725
|
}
|
|
733
|
-
|
|
726
|
+
index_1.default.info(`共修复了 ${count - newCount} 个重复参数。`);
|
|
734
727
|
this.safeReplaceWith(firstChild);
|
|
735
728
|
return firstChild;
|
|
736
729
|
}
|
|
737
730
|
}
|
|
738
|
-
|
|
739
|
-
|
|
731
|
+
exports.TranscludeToken = TranscludeToken;
|
|
732
|
+
index_1.default.classes['TranscludeToken'] = __filename;
|
package/dist/util/debug.js
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.undo =
|
|
4
|
-
/**
|
|
5
|
-
* 定制TypeError消息
|
|
6
|
-
* @param {Function} Constructor 类
|
|
7
|
-
* @param args 可接受的参数类型
|
|
8
|
-
* @throws `TypeError`
|
|
9
|
-
*/
|
|
10
|
-
const typeError = ({ name }, method, ...args) => {
|
|
11
|
-
throw new TypeError(`${name}.${method} 方法仅接受 ${args.join('、')} 作为输入参数!`);
|
|
12
|
-
};
|
|
13
|
-
exports.typeError = typeError;
|
|
3
|
+
exports.undo = void 0;
|
|
14
4
|
/**
|
|
15
5
|
* 撤销最近一次Mutation
|
|
16
6
|
* @param e 事件
|
|
@@ -46,7 +36,7 @@ const undo = (e, data) => {
|
|
|
46
36
|
}
|
|
47
37
|
break;
|
|
48
38
|
default:
|
|
49
|
-
throw new RangeError(`无法撤销未知类型的事件:${type}`);
|
|
39
|
+
throw new RangeError(`无法撤销未知类型的事件:${String(type)}`);
|
|
50
40
|
}
|
|
51
41
|
};
|
|
52
42
|
exports.undo = undo;
|
package/dist/util/diff.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.diff = void 0;
|
|
3
4
|
const fs = require("fs/promises");
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
4
6
|
process.on('unhandledRejection', e => {
|
|
5
7
|
console.error(e);
|
|
6
8
|
});
|
|
@@ -66,4 +68,4 @@ const diff = async (oldStr, newStr, uid = -1) => {
|
|
|
66
68
|
await Promise.all([fs.unlink(oldFile), fs.unlink(newFile)]);
|
|
67
69
|
console.log(stdout?.split('\n')?.slice(4)?.join('\n'));
|
|
68
70
|
};
|
|
69
|
-
|
|
71
|
+
exports.diff = diff;
|
package/dist/util/lint.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateForSelf = exports.generateForChild = void 0;
|
|
4
|
-
const
|
|
4
|
+
const index_1 = require("../index");
|
|
5
5
|
/**
|
|
6
6
|
* 生成对于子节点的LintError对象
|
|
7
7
|
* @param child 子节点
|
|
@@ -10,8 +10,8 @@ const Parser = require("../index");
|
|
|
10
10
|
* @param severity 严重程度
|
|
11
11
|
*/
|
|
12
12
|
const generateForChild = (child, boundingRect, msg, severity = 'error') => {
|
|
13
|
-
const index = child.getRelativeIndex(), { offsetHeight, offsetWidth, parentNode } = child, { top: offsetTop, left: offsetLeft } = parentNode.posFromIndex(index), { start } = boundingRect, { top, left } = 'top' in boundingRect ? boundingRect : child.getRootNode().posFromIndex(start), str = String(child), excerpt = str.slice(0, 50), startIndex = start + index, endIndex = startIndex + str.length, startLine = top + offsetTop, endLine = startLine + offsetHeight - 1, startCol = offsetTop ? offsetLeft : left + offsetLeft, endCol = offsetHeight
|
|
14
|
-
return { message:
|
|
13
|
+
const index = child.getRelativeIndex(), { offsetHeight, offsetWidth, parentNode } = child, { top: offsetTop, left: offsetLeft } = parentNode.posFromIndex(index), { start } = boundingRect, { top, left } = 'top' in boundingRect ? boundingRect : child.getRootNode().posFromIndex(start), str = String(child), excerpt = str.slice(0, 50), startIndex = start + index, endIndex = startIndex + str.length, startLine = top + offsetTop, endLine = startLine + offsetHeight - 1, startCol = offsetTop ? offsetLeft : left + offsetLeft, endCol = offsetHeight === 1 ? startCol + offsetWidth : offsetWidth;
|
|
14
|
+
return { message: index_1.default.msg(msg), severity, startIndex, endIndex, startLine, endLine, startCol, endCol, excerpt };
|
|
15
15
|
};
|
|
16
16
|
exports.generateForChild = generateForChild;
|
|
17
17
|
/**
|
|
@@ -24,14 +24,14 @@ exports.generateForChild = generateForChild;
|
|
|
24
24
|
const generateForSelf = (token, boundingRect, msg, severity = 'error') => {
|
|
25
25
|
const { start } = boundingRect, { offsetHeight, offsetWidth } = token, str = String(token), { top, left } = 'top' in boundingRect ? boundingRect : token.getRootNode().posFromIndex(start);
|
|
26
26
|
return {
|
|
27
|
-
message:
|
|
27
|
+
message: index_1.default.msg(msg),
|
|
28
28
|
severity,
|
|
29
29
|
startIndex: start,
|
|
30
30
|
endIndex: start + str.length,
|
|
31
31
|
startLine: top,
|
|
32
32
|
endLine: top + offsetHeight - 1,
|
|
33
33
|
startCol: left,
|
|
34
|
-
endCol: offsetHeight
|
|
34
|
+
endCol: offsetHeight === 1 ? left + offsetWidth : offsetWidth,
|
|
35
35
|
excerpt: str.slice(0, 50),
|
|
36
36
|
};
|
|
37
37
|
};
|
package/dist/util/string.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalizeSpace = exports.noWrap = exports.toCase = exports.decodeHtml = exports.text = exports.
|
|
3
|
+
exports.normalizeSpace = exports.noWrap = exports.toCase = exports.decodeHtml = exports.text = exports.escapeRegExp = exports.print = exports.removeComment = exports.extUrlChar = exports.extUrlCharFirst = void 0;
|
|
4
4
|
exports.extUrlCharFirst = '(?:\\[[\\da-f:.]+\\]|[^[\\]<>"\\0-\\x1F\\x7F\\p{Zs}\\uFFFD])';
|
|
5
5
|
exports.extUrlChar = '(?:[^[\\]<>"\\0-\\x1F\\x7F\\p{Zs}\\uFFFD]|\\0\\d+c\\x7F)*';
|
|
6
6
|
/**
|
|
@@ -19,7 +19,7 @@ exports.removeComment = removeComment;
|
|
|
19
19
|
const print = (childNodes, opt = {}) => {
|
|
20
20
|
const { pre = '', post = '', sep = '' } = opt, entities = { '&': 'amp', '<': 'lt', '>': 'gt' };
|
|
21
21
|
return `${pre}${childNodes.map(child => child.type === 'text'
|
|
22
|
-
?
|
|
22
|
+
? child.data.replace(/[&<>]/gu, p => `&${entities[p]};`)
|
|
23
23
|
: child.print()).join(sep)}${post}`;
|
|
24
24
|
};
|
|
25
25
|
exports.print = print;
|
|
@@ -30,35 +30,6 @@ exports.print = print;
|
|
|
30
30
|
*/
|
|
31
31
|
const escapeRegExp = (str) => str.replace(/[\\{}()|.?*+^$[\]]/gu, '\\$&');
|
|
32
32
|
exports.escapeRegExp = escapeRegExp;
|
|
33
|
-
/**
|
|
34
|
-
* a more sophisticated string-explode function
|
|
35
|
-
* @browser
|
|
36
|
-
* @param start start syntax of a nested AST node
|
|
37
|
-
* @param end end syntax of a nested AST node
|
|
38
|
-
* @param separator syntax for explosion
|
|
39
|
-
* @param str string to be exploded
|
|
40
|
-
*/
|
|
41
|
-
const explode = (start, end, separator, str) => {
|
|
42
|
-
if (str === undefined) {
|
|
43
|
-
return [];
|
|
44
|
-
}
|
|
45
|
-
const regex = new RegExp(`${[start, end, separator].map(exports.escapeRegExp).join('|')}`, 'gu'), exploded = [];
|
|
46
|
-
let mt = regex.exec(str), depth = 0, lastIndex = 0;
|
|
47
|
-
while (mt) {
|
|
48
|
-
const { 0: match, index } = mt;
|
|
49
|
-
if (match !== separator) {
|
|
50
|
-
depth += match === start ? 1 : -1;
|
|
51
|
-
}
|
|
52
|
-
else if (depth === 0) {
|
|
53
|
-
exploded.push(str.slice(lastIndex, index));
|
|
54
|
-
({ lastIndex } = regex);
|
|
55
|
-
}
|
|
56
|
-
mt = regex.exec(str);
|
|
57
|
-
}
|
|
58
|
-
exploded.push(str.slice(lastIndex));
|
|
59
|
-
return exploded;
|
|
60
|
-
};
|
|
61
|
-
exports.explode = explode;
|
|
62
33
|
/**
|
|
63
34
|
* extract effective wikitext
|
|
64
35
|
* @browser
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikiparser-node",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"description": "A Node.js parser for MediaWiki markup with AST",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"url": "git+https://github.com/bhsd-harry/wikiparser-node.git"
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
|
-
"prepublishOnly": "rm -rf dist/; tsc;
|
|
30
|
-
"build": "rm -rf dist/; tsc; grep -rl --include='*.js'
|
|
29
|
+
"prepublishOnly": "rm -rf dist/; tsc; rm dist/internal.js; rm dist/[mpu]*/*.d.ts; grep -rl --include='*.d.ts' '@private' dist/ | xargs gsed -i '/@private/,+1d'",
|
|
30
|
+
"build": "rm -rf dist/; tsc; grep -rl --include='*.js' '@ts' dist/ | xargs gsed -i '/@ts/d'; eslint --fix dist/",
|
|
31
31
|
"doc": "node ./bin/doc.js",
|
|
32
32
|
"toc": "node ./bin/toc.js",
|
|
33
33
|
"lint:ts": "eslint --cache --ignore-pattern '/dist/' .",
|
|
@@ -37,21 +37,21 @@
|
|
|
37
37
|
"test:single": "node --prof test/single.js && node --prof-process isolate-0x*-v8.log > test/processed.txt && rm isolate-0x*-v8.log"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@types/node": "^
|
|
41
|
-
"eslint": "^8.
|
|
42
|
-
"eslint-plugin-n": "^
|
|
43
|
-
"eslint-plugin-regexp": "^1.
|
|
44
|
-
"eslint-plugin-unicorn": "^
|
|
45
|
-
"eslint-plugin-jsdoc": "^
|
|
40
|
+
"@types/node": "^20.9.0",
|
|
41
|
+
"eslint": "^8.53.0",
|
|
42
|
+
"eslint-plugin-n": "^16.3.1",
|
|
43
|
+
"eslint-plugin-regexp": "^2.1.1",
|
|
44
|
+
"eslint-plugin-unicorn": "^49.0.0",
|
|
45
|
+
"eslint-plugin-jsdoc": "^46.8.2",
|
|
46
46
|
"eslint-plugin-json-es": "^1.5.7",
|
|
47
47
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
48
|
-
"typescript": "^
|
|
49
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
50
|
-
"@typescript-eslint/parser": "^5.
|
|
48
|
+
"typescript": "^5.0.3",
|
|
49
|
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
50
|
+
"@typescript-eslint/parser": "^5.62.0",
|
|
51
51
|
"ajv-cli": "^5.0.0",
|
|
52
52
|
"request": "^2.88.2"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
55
|
-
"node": "^
|
|
55
|
+
"node": "^20.9.0"
|
|
56
56
|
}
|
|
57
57
|
}
|
package/dist/util/base.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.del = exports.isPlainObject = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* 是否是普通对象
|
|
6
|
-
* @param obj 对象
|
|
7
|
-
*/
|
|
8
|
-
const isPlainObject = (obj) => {
|
|
9
|
-
if (!obj) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
const prototype = Object.getPrototypeOf(obj);
|
|
13
|
-
return prototype === null || prototype.constructor === Object;
|
|
14
|
-
};
|
|
15
|
-
exports.isPlainObject = isPlainObject;
|
|
16
|
-
/**
|
|
17
|
-
* 从数组中删除指定元素
|
|
18
|
-
* @param arr 数组
|
|
19
|
-
* @param ele 元素
|
|
20
|
-
*/
|
|
21
|
-
const del = (arr, ele) => {
|
|
22
|
-
const set = new Set(arr);
|
|
23
|
-
set.delete(ele);
|
|
24
|
-
return [...set];
|
|
25
|
-
};
|
|
26
|
-
exports.del = del;
|