wikiparser-node 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/default.json +129 -66
- package/config/zhwiki.json +4 -4
- package/index.js +74 -65
- package/lib/element.js +125 -152
- package/lib/node.js +251 -223
- package/lib/ranges.js +2 -2
- package/lib/text.js +64 -64
- package/lib/title.js +8 -7
- package/mixin/hidden.js +2 -0
- package/mixin/sol.js +1 -2
- package/package.json +4 -3
- package/parser/brackets.js +8 -2
- package/parser/externalLinks.js +1 -1
- package/parser/hrAndDoubleUnderscore.js +4 -4
- package/parser/links.js +7 -7
- package/parser/table.js +12 -10
- package/src/arg.js +53 -48
- package/src/atom/index.js +7 -5
- package/src/attribute.js +91 -80
- package/src/charinsert.js +91 -0
- package/src/converter.js +22 -11
- package/src/converterFlags.js +72 -62
- package/src/converterRule.js +49 -49
- package/src/extLink.js +30 -28
- package/src/gallery.js +56 -32
- package/src/hasNowiki/index.js +42 -0
- package/src/hasNowiki/pre.js +40 -0
- package/src/heading.js +15 -11
- package/src/html.js +38 -38
- package/src/imageParameter.js +64 -48
- package/src/imagemap.js +205 -0
- package/src/imagemapLink.js +43 -0
- package/src/index.js +222 -124
- package/src/link/category.js +4 -8
- package/src/link/file.js +95 -59
- package/src/link/galleryImage.js +74 -10
- package/src/link/index.js +61 -39
- package/src/magicLink.js +21 -22
- 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 +17 -17
- package/src/nowiki/dd.js +2 -2
- package/src/nowiki/doubleUnderscore.js +14 -14
- package/src/nowiki/index.js +12 -0
- package/src/onlyinclude.js +10 -8
- package/src/paramTag/index.js +83 -0
- package/src/paramTag/inputbox.js +42 -0
- package/src/parameter.js +32 -18
- package/src/syntax.js +9 -1
- package/src/table/index.js +33 -32
- package/src/table/td.js +51 -57
- package/src/table/tr.js +6 -6
- package/src/tagPair/ext.js +58 -40
- package/src/tagPair/include.js +1 -1
- package/src/tagPair/index.js +21 -20
- package/src/transclude.js +158 -143
- package/tool/index.js +720 -439
- package/util/base.js +17 -0
- package/util/debug.js +1 -1
- package/util/diff.js +1 -1
- package/util/string.js +20 -20
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Parser = require('../..'),
|
|
4
|
+
NestedToken = require('.');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `<choose>`
|
|
8
|
+
* @classdesc `{childNodes: [...ExtToken|NoincludeToken]}`
|
|
9
|
+
*/
|
|
10
|
+
class ChooseToken extends NestedToken {
|
|
11
|
+
name = 'choose';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {string|undefined} wikitext wikitext
|
|
15
|
+
* @param {accum} accum
|
|
16
|
+
*/
|
|
17
|
+
constructor(wikitext, config = Parser.getConfig(), accum = []) {
|
|
18
|
+
const regex = /<(option|choicetemplate)(\s[^>]*)?>(.*?)<\/(\1)>/gsu;
|
|
19
|
+
super(wikitext, regex, ['option', 'choicetemplate'], config, accum);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Parser.classes.ChooseToken = __filename;
|
|
24
|
+
module.exports = ChooseToken;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Parser = require('../..'),
|
|
4
|
+
NestedToken = require('.');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `<combobox>`
|
|
8
|
+
* @classdesc `{childNodes: [...ExtToken|NoincludeToken]}`
|
|
9
|
+
*/
|
|
10
|
+
class ComboboxToken extends NestedToken {
|
|
11
|
+
name = 'combobox';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {string|undefined} wikitext wikitext
|
|
15
|
+
* @param {accum} accum
|
|
16
|
+
*/
|
|
17
|
+
constructor(wikitext, config = Parser.getConfig(), accum = []) {
|
|
18
|
+
super(wikitext, /<(combooption)(\s[^>]*)?>(.*?)<\/(combooption\s*)>/gisu, ['combooption'], config, accum);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Parser.classes.ComboboxToken = __filename;
|
|
23
|
+
module.exports = ComboboxToken;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {generateForChild} = require('../../util/lint'),
|
|
4
|
+
Parser = require('../..'),
|
|
5
|
+
Token = require('..');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 嵌套式的扩展标签
|
|
9
|
+
* @classdesc `{childNodes: [...ExtToken|NoincludeToken]}`
|
|
10
|
+
*/
|
|
11
|
+
class NestedToken extends Token {
|
|
12
|
+
type = 'ext-inner';
|
|
13
|
+
#tags;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string|undefined} wikitext wikitext
|
|
17
|
+
* @param {RegExp} regex 内层正则
|
|
18
|
+
* @param {string[]} tags 内层标签名
|
|
19
|
+
* @param {accum} accum
|
|
20
|
+
*/
|
|
21
|
+
constructor(wikitext, regex, tags, config = Parser.getConfig(), accum = []) {
|
|
22
|
+
const ExtToken = require('../tagPair/ext'),
|
|
23
|
+
NoincludeToken = require('../nowiki/noinclude');
|
|
24
|
+
const text = wikitext?.replaceAll(
|
|
25
|
+
regex,
|
|
26
|
+
/** @type {function(...string): string} */ (_, name, attr, inner, closing) => {
|
|
27
|
+
const str = `\0${accum.length + 1}e\x7F`;
|
|
28
|
+
new ExtToken(name, attr, inner, closing, config, accum);
|
|
29
|
+
return str;
|
|
30
|
+
},
|
|
31
|
+
)?.replaceAll(/(?<=^|\0\d+e\x7F).*?(?=$|\0\d+e\x7F)/gsu, substr => {
|
|
32
|
+
if (substr === '') {
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
new NoincludeToken(substr, config, accum);
|
|
36
|
+
return `\0${accum.length}c\x7F`;
|
|
37
|
+
});
|
|
38
|
+
super(text, config, true, accum, {NoincludeToken: ':', ExtToken: ':'});
|
|
39
|
+
this.#tags = tags;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @override
|
|
44
|
+
* @param {number} start 起始位置
|
|
45
|
+
*/
|
|
46
|
+
lint(start = 0) {
|
|
47
|
+
let rect;
|
|
48
|
+
return [
|
|
49
|
+
...super.lint(start),
|
|
50
|
+
...this.childNodes.filter(child => {
|
|
51
|
+
if (child.type === 'ext') {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const str = String(child).trim();
|
|
55
|
+
return str && !/^<!--.*-->$/u.test(str);
|
|
56
|
+
}).map(child => {
|
|
57
|
+
rect ||= this.getRootNode().posFromIndex(start);
|
|
58
|
+
return generateForChild(child, rect, `<${this.name}>内的无效内容`);
|
|
59
|
+
}),
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @override
|
|
65
|
+
* @template {string|Token} T
|
|
66
|
+
* @param {T} token 待插入的子节点
|
|
67
|
+
* @param {number} i 插入位置
|
|
68
|
+
*/
|
|
69
|
+
insertAt(token, i = this.childNodes.length) {
|
|
70
|
+
return token.type === 'ext' && !this.#tags.includes(token.name)
|
|
71
|
+
? this.typeError(`${this.constructor.name}只能以${this.#tags.join('或')}标签作为子节点!`)
|
|
72
|
+
: super.insertAt(token, i);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** @override */
|
|
76
|
+
cloneNode() {
|
|
77
|
+
const cloned = this.cloneChildNodes(),
|
|
78
|
+
config = this.getAttribute('config');
|
|
79
|
+
return Parser.run(() => {
|
|
80
|
+
const token = new this.constructor(undefined, config);
|
|
81
|
+
token.append(...cloned);
|
|
82
|
+
return token;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Parser.classes.NestedToken = __filename;
|
|
88
|
+
module.exports = NestedToken;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Parser = require('../..'),
|
|
4
|
+
NestedToken = require('.');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `<references>`
|
|
8
|
+
* @classdesc `{childNodes: [...ExtToken|NoincludeToken]}`
|
|
9
|
+
*/
|
|
10
|
+
class ReferencesToken extends NestedToken {
|
|
11
|
+
name = 'references';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {string|undefined} wikitext wikitext
|
|
15
|
+
* @param {accum} accum
|
|
16
|
+
*/
|
|
17
|
+
constructor(wikitext, config = Parser.getConfig(), accum = []) {
|
|
18
|
+
super(wikitext, /<(ref)(\s[^>]*)?>(.*?)<\/(ref\s*)>/gisu, ['ref'], config, accum);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Parser.classes.ReferencesToken = __filename;
|
|
23
|
+
module.exports = ReferencesToken;
|
package/src/nowiki/comment.js
CHANGED
|
@@ -30,8 +30,21 @@ class CommentToken extends hidden(NowikiToken) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/** @override */
|
|
33
|
-
|
|
34
|
-
return
|
|
33
|
+
getPadding() {
|
|
34
|
+
return 4;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** @override */
|
|
38
|
+
print() {
|
|
39
|
+
return super.print({pre: '<!--', post: this.closed ? '-->' : ''});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @override
|
|
44
|
+
* @param {number} start 起始位置
|
|
45
|
+
*/
|
|
46
|
+
lint(start = 0) {
|
|
47
|
+
return this.closed ? [] : [generateForSelf(this, this.getRootNode().posFromIndex(start), '未闭合的HTML注释')];
|
|
35
48
|
}
|
|
36
49
|
|
|
37
50
|
/**
|
|
@@ -49,21 +62,8 @@ class CommentToken extends hidden(NowikiToken) {
|
|
|
49
62
|
}
|
|
50
63
|
|
|
51
64
|
/** @override */
|
|
52
|
-
|
|
53
|
-
return
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** @override */
|
|
57
|
-
print() {
|
|
58
|
-
return super.print({pre: '<!--', post: this.closed ? '-->' : ''});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @override
|
|
63
|
-
* @param {number} start 起始位置
|
|
64
|
-
*/
|
|
65
|
-
lint(start = 0) {
|
|
66
|
-
return this.closed ? [] : [generateForSelf(this, this.getRootNode().posFromIndex(start), '未闭合的HTML注释')];
|
|
65
|
+
cloneNode() {
|
|
66
|
+
return Parser.run(() => new CommentToken(String(this.firstChild), this.closed, this.getAttribute('config')));
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
package/src/nowiki/dd.js
CHANGED
|
@@ -32,9 +32,9 @@ class DdToken extends NowikiToken {
|
|
|
32
32
|
|
|
33
33
|
set indent(indent) {
|
|
34
34
|
if (this.type === 'dd') {
|
|
35
|
-
if (
|
|
35
|
+
if (!Number.isInteger(indent)) {
|
|
36
36
|
this.typeError('set indent', 'Number');
|
|
37
|
-
} else if (
|
|
37
|
+
} else if (indent < 0) {
|
|
38
38
|
throw new RangeError(`indent 应为自然数!${indent}`);
|
|
39
39
|
}
|
|
40
40
|
this.setText(':'.repeat(indent));
|
|
@@ -11,18 +11,14 @@ const hidden = require('../../mixin/hidden'),
|
|
|
11
11
|
class DoubleUnderscoreToken extends hidden(NowikiToken) {
|
|
12
12
|
type = 'double-underscore';
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*/
|
|
18
|
-
constructor(word, config = Parser.getConfig(), accum = []) {
|
|
19
|
-
super(word, config, accum);
|
|
20
|
-
this.setAttribute('name', word.toLowerCase());
|
|
14
|
+
/** @override */
|
|
15
|
+
getPadding() {
|
|
16
|
+
return 2;
|
|
21
17
|
}
|
|
22
18
|
|
|
23
19
|
/** @override */
|
|
24
|
-
|
|
25
|
-
return
|
|
20
|
+
print() {
|
|
21
|
+
return super.print({pre: '__', post: '__'});
|
|
26
22
|
}
|
|
27
23
|
|
|
28
24
|
/**
|
|
@@ -33,14 +29,18 @@ class DoubleUnderscoreToken extends hidden(NowikiToken) {
|
|
|
33
29
|
return selector && this.matches(selector) ? '' : `__${String(this.firstChild)}__`;
|
|
34
30
|
}
|
|
35
31
|
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
/**
|
|
33
|
+
* @param {string} word 状态开关名
|
|
34
|
+
* @param {accum} accum
|
|
35
|
+
*/
|
|
36
|
+
constructor(word, config = Parser.getConfig(), accum = []) {
|
|
37
|
+
super(word, config, accum);
|
|
38
|
+
this.setAttribute('name', word.toLowerCase());
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/** @override */
|
|
42
|
-
|
|
43
|
-
return
|
|
42
|
+
cloneNode() {
|
|
43
|
+
return Parser.run(() => new DoubleUnderscoreToken(String(this.firstChild), this.getAttribute('config')));
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
package/src/nowiki/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const fixedToken = require('../../mixin/fixedToken'),
|
|
4
|
+
{generateForSelf} = require('../../util/lint'),
|
|
4
5
|
Parser = require('../..'),
|
|
5
6
|
Token = require('..'),
|
|
6
7
|
AstText = require('../../lib/text');
|
|
@@ -20,6 +21,17 @@ class NowikiToken extends fixedToken(Token) {
|
|
|
20
21
|
super(wikitext, config, true, accum);
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
/**
|
|
25
|
+
* @override
|
|
26
|
+
* @param {number} start 起始位置
|
|
27
|
+
*/
|
|
28
|
+
lint(start = 0) {
|
|
29
|
+
const {type, name} = this;
|
|
30
|
+
return type === 'ext-inner' && (name === 'templatestyles' || name === 'section') && String(this)
|
|
31
|
+
? [generateForSelf(this, this.getRootNode().posFromIndex(start), `<${name}>标签内不应有任何内容`)]
|
|
32
|
+
: super.lint(start);
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
/**
|
|
24
36
|
* @override
|
|
25
37
|
* @this {NowikiToken & {firstChild: AstText, constructor: typeof NowikiToken}}
|
package/src/onlyinclude.js
CHANGED
|
@@ -23,14 +23,6 @@ class OnlyincludeToken extends Token {
|
|
|
23
23
|
super(inner, config, true, accum);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
/** @override */
|
|
27
|
-
cloneNode() {
|
|
28
|
-
const cloned = this.cloneChildNodes(),
|
|
29
|
-
token = Parser.run(() => new OnlyincludeToken(undefined, this.getAttribute('config')));
|
|
30
|
-
token.append(...cloned);
|
|
31
|
-
return token;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
26
|
/**
|
|
35
27
|
* @override
|
|
36
28
|
* @param {string} selector
|
|
@@ -53,6 +45,16 @@ class OnlyincludeToken extends Token {
|
|
|
53
45
|
isPlain() {
|
|
54
46
|
return true;
|
|
55
47
|
}
|
|
48
|
+
|
|
49
|
+
/** @override */
|
|
50
|
+
cloneNode() {
|
|
51
|
+
const cloned = this.cloneChildNodes();
|
|
52
|
+
return Parser.run(() => {
|
|
53
|
+
const token = new OnlyincludeToken(undefined, this.getAttribute('config'));
|
|
54
|
+
token.append(...cloned);
|
|
55
|
+
return token;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
Parser.classes.OnlyincludeToken = __filename;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {generateForChild} = require('../../util/lint'),
|
|
4
|
+
Parser = require('../..'),
|
|
5
|
+
Token = require('..'),
|
|
6
|
+
AtomToken = require('../atom');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `<inputbox>`
|
|
10
|
+
* @classdesc `{childNodes: ...AtomToken}`
|
|
11
|
+
*/
|
|
12
|
+
class ParamTagToken extends Token {
|
|
13
|
+
type = 'ext-inner';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} wikitext wikitext
|
|
17
|
+
* @param {accum} accum
|
|
18
|
+
*/
|
|
19
|
+
constructor(wikitext, config = Parser.getConfig(), accum = []) {
|
|
20
|
+
super(undefined, config, true, accum, {AtomToken: ':'});
|
|
21
|
+
if (wikitext) {
|
|
22
|
+
this.append(
|
|
23
|
+
...wikitext.split('\n').map(line => new AtomToken(line, 'param-line', config, accum, {AstText: ':'})),
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @override
|
|
30
|
+
* @param {string} selector
|
|
31
|
+
*/
|
|
32
|
+
toString(selector) {
|
|
33
|
+
return super.toString(selector, '\n');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** @override */
|
|
37
|
+
getGaps() {
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** @override */
|
|
42
|
+
print() {
|
|
43
|
+
return super.print({sep: '\n'});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @override
|
|
48
|
+
* @param {number} start 起始位置
|
|
49
|
+
*/
|
|
50
|
+
lint(start = 0) {
|
|
51
|
+
let /** @type {{top: number, left: number}} */ rect;
|
|
52
|
+
return this.childNodes.filter(child => {
|
|
53
|
+
const {childNodes} = child,
|
|
54
|
+
i = childNodes.findIndex(({type}) => type !== 'text'),
|
|
55
|
+
str = (i >= 0 ? childNodes.slice(0, i).map(String).join('') : String(child)).trim();
|
|
56
|
+
return str && !(i >= 0 ? /^[a-z]+\s*(?:=|$)/iu : /^[a-z]+\s*=/iu).test(str);
|
|
57
|
+
}).map(child => {
|
|
58
|
+
rect ||= this.getRootNode().posFromIndex(start);
|
|
59
|
+
return generateForChild(child, rect, `${this.name}的无效参数`);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @override */
|
|
64
|
+
text() {
|
|
65
|
+
return super.text('\n');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @override
|
|
70
|
+
* @this {ParamTagToken & {constructor: typeof ParamTagToken}}
|
|
71
|
+
*/
|
|
72
|
+
cloneNode() {
|
|
73
|
+
const cloned = this.cloneChildNodes();
|
|
74
|
+
return Parser.run(() => {
|
|
75
|
+
const token = new this.constructor(undefined, this.getAttribute('config'));
|
|
76
|
+
token.append(...cloned);
|
|
77
|
+
return token;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Parser.classes.ParamTagToken = __filename;
|
|
83
|
+
module.exports = ParamTagToken;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const parseBrackets = require('../../parser/brackets'),
|
|
4
|
+
Parser = require('../..'),
|
|
5
|
+
ParamTagToken = require('.'),
|
|
6
|
+
AtomToken = require('../atom');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `<inputbox>`
|
|
10
|
+
* @classdesc `{childNodes: ...AtomToken}`
|
|
11
|
+
*/
|
|
12
|
+
class InputboxToken extends ParamTagToken {
|
|
13
|
+
name = 'inputbox';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} wikitext wikitext
|
|
17
|
+
* @param {accum} accum
|
|
18
|
+
*/
|
|
19
|
+
constructor(wikitext, config = Parser.getConfig(), accum = []) {
|
|
20
|
+
super(undefined, config, accum);
|
|
21
|
+
wikitext = parseBrackets(wikitext, config, accum);
|
|
22
|
+
accum.splice(accum.indexOf(this), 1);
|
|
23
|
+
accum.push(this);
|
|
24
|
+
if (wikitext) {
|
|
25
|
+
this.append(...wikitext.split('\n').map(line => new AtomToken(
|
|
26
|
+
line, 'param-line', config, accum, {AstText: ':', ArgToken: ':', TranscludeToken: ':'},
|
|
27
|
+
)));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** @override */
|
|
32
|
+
afterBuild() {
|
|
33
|
+
for (const heading of this.querySelectorAll('heading')) {
|
|
34
|
+
const {firstChild, lastChild, name} = heading,
|
|
35
|
+
syntax = '='.repeat(name);
|
|
36
|
+
heading.replaceWith(syntax, ...firstChild.cloneChildNodes(), `${syntax}${String(lastChild)}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
Parser.classes.InputboxToken = __filename;
|
|
42
|
+
module.exports = InputboxToken;
|
package/src/parameter.js
CHANGED
|
@@ -26,6 +26,19 @@ class ParameterToken extends fixedToken(Token) {
|
|
|
26
26
|
this.setValue(value);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* 是否是重复参数
|
|
31
|
+
* @this {ParameterToken & {parentNode: TranscludeToken}}
|
|
32
|
+
*/
|
|
33
|
+
get duplicated() {
|
|
34
|
+
const TranscludeToken = require('./transclude');
|
|
35
|
+
try {
|
|
36
|
+
return Boolean(this.parentNode?.getDuplicatedArgs()?.some(([key]) => key === this.name));
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
29
42
|
/**
|
|
30
43
|
* @param {string|number} key 参数名
|
|
31
44
|
* @param {string} value 参数值
|
|
@@ -42,25 +55,14 @@ class ParameterToken extends fixedToken(Token) {
|
|
|
42
55
|
this.append(keyToken, token.setAttribute('stage', 2));
|
|
43
56
|
}
|
|
44
57
|
|
|
45
|
-
/** @override */
|
|
46
|
-
cloneNode() {
|
|
47
|
-
const [key, value] = this.cloneChildNodes(),
|
|
48
|
-
config = this.getAttribute('config');
|
|
49
|
-
return Parser.run(() => {
|
|
50
|
-
const token = new ParameterToken(this.anon ? Number(this.name) : undefined, undefined, config);
|
|
51
|
-
token.firstChild.safeReplaceWith(key);
|
|
52
|
-
token.lastChild.safeReplaceWith(value);
|
|
53
|
-
return token.afterBuild();
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
58
|
/** @override */
|
|
58
59
|
afterBuild() {
|
|
59
60
|
if (!this.anon) {
|
|
61
|
+
const TranscludeToken = require('./transclude');
|
|
60
62
|
const name = this.firstChild.text().trim(),
|
|
61
63
|
{parentNode} = this;
|
|
62
64
|
this.setAttribute('name', name);
|
|
63
|
-
if (parentNode && parentNode instanceof
|
|
65
|
+
if (parentNode && parentNode instanceof TranscludeToken) {
|
|
64
66
|
parentNode.getAttribute('keys').add(name);
|
|
65
67
|
parentNode.getArgs(name, false, false).add(this);
|
|
66
68
|
}
|
|
@@ -101,6 +103,18 @@ class ParameterToken extends fixedToken(Token) {
|
|
|
101
103
|
return super.print({sep: this.anon ? '' : '='});
|
|
102
104
|
}
|
|
103
105
|
|
|
106
|
+
/** @override */
|
|
107
|
+
cloneNode() {
|
|
108
|
+
const [key, value] = this.cloneChildNodes(),
|
|
109
|
+
config = this.getAttribute('config');
|
|
110
|
+
return Parser.run(() => {
|
|
111
|
+
const token = new ParameterToken(this.anon ? Number(this.name) : undefined, undefined, config);
|
|
112
|
+
token.firstChild.safeReplaceWith(key);
|
|
113
|
+
token.lastChild.safeReplaceWith(value);
|
|
114
|
+
return token.afterBuild();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
104
118
|
/**
|
|
105
119
|
* @override
|
|
106
120
|
* @returns {string}
|
|
@@ -141,9 +155,9 @@ class ParameterToken extends fixedToken(Token) {
|
|
|
141
155
|
const templateLike = this.parentNode?.isTemplate(),
|
|
142
156
|
wikitext = `{{${templateLike ? ':T|' : 'lc:'}${this.anon ? '' : '1='}${value}}}`,
|
|
143
157
|
root = Parser.parse(wikitext, this.getAttribute('include'), 2, this.getAttribute('config')),
|
|
144
|
-
{
|
|
158
|
+
{length, firstChild: transclude} = root,
|
|
145
159
|
/** @type {Token & {lastChild: ParameterToken}} */
|
|
146
|
-
{lastChild: parameter, type, name,
|
|
160
|
+
{lastChild: parameter, type, name, length: transcludeLength} = transclude,
|
|
147
161
|
targetType = templateLike ? 'template' : 'magic-word',
|
|
148
162
|
targetName = templateLike ? 'T' : 'lc';
|
|
149
163
|
if (length !== 1 || type !== targetType || name !== targetName || transcludeLength !== 2
|
|
@@ -172,12 +186,12 @@ class ParameterToken extends fixedToken(Token) {
|
|
|
172
186
|
const TranscludeToken = require('./transclude');
|
|
173
187
|
const {parentNode} = this;
|
|
174
188
|
// 必须检测是否是TranscludeToken
|
|
175
|
-
if (!parentNode?.isTemplate() || !(parentNode instanceof
|
|
189
|
+
if (!parentNode?.isTemplate() || !(parentNode instanceof TranscludeToken)) {
|
|
176
190
|
throw new Error(`${this.constructor.name}.rename 方法仅用于模板参数!`);
|
|
177
191
|
}
|
|
178
192
|
const root = Parser.parse(`{{:T|${key}=}}`, this.getAttribute('include'), 2, this.getAttribute('config')),
|
|
179
|
-
{
|
|
180
|
-
{type, name, lastChild: parameter,
|
|
193
|
+
{length, firstChild: template} = root,
|
|
194
|
+
{type, name, lastChild: parameter, length: templateLength} = template;
|
|
181
195
|
if (length !== 1 || type !== 'template' || name !== 'T' || templateLength !== 2) {
|
|
182
196
|
throw new SyntaxError(`非法的模板参数名:${key}`);
|
|
183
197
|
}
|
package/src/syntax.js
CHANGED
|
@@ -7,7 +7,7 @@ const {undo} = require('../util/debug'),
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* 满足特定语法格式的plain Token
|
|
10
|
-
* @classdesc `{childNodes:
|
|
10
|
+
* @classdesc `{childNodes: ...AstText|Token}`
|
|
11
11
|
*/
|
|
12
12
|
class SyntaxToken extends Token {
|
|
13
13
|
#pattern;
|
|
@@ -65,6 +65,14 @@ class SyntaxToken extends Token {
|
|
|
65
65
|
return key === 'pattern' ? this.#pattern : super.getAttribute(key);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @override
|
|
70
|
+
* @param {PropertyKey} key 属性键
|
|
71
|
+
*/
|
|
72
|
+
hasAttribute(key) {
|
|
73
|
+
return key === 'pattern' || super.hasAttribute(key);
|
|
74
|
+
}
|
|
75
|
+
|
|
68
76
|
/**
|
|
69
77
|
* @override
|
|
70
78
|
* @param {...Token} elements 待替换的子节点
|