wikiparser-node 0.2.2 → 0.3.0
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/.eslintrc.json +53 -6
- package/config/default.json +8 -45
- package/config/moegirl.json +11 -52
- package/lib/element.js +10 -12
- package/lib/node.js +2 -2
- package/lib/title.js +7 -3
- package/mixin/attributeParent.js +2 -2
- package/mixin/fixedToken.js +1 -1
- package/mixin/hidden.js +1 -6
- package/mixin/sol.js +2 -2
- package/package.json +3 -3
- package/parser/hrAndDoubleUnderscore.js +1 -1
- package/parser/links.js +2 -2
- package/parser/list.js +3 -3
- package/parser/quotes.js +2 -2
- package/parser/table.js +3 -0
- package/src/arg.js +0 -5
- package/src/attribute.js +1 -6
- package/src/converter.js +1 -6
- package/src/converterFlags.js +1 -6
- package/src/converterRule.js +1 -10
- package/src/extLink.js +1 -8
- package/src/gallery.js +64 -0
- package/src/heading.js +0 -5
- package/src/html.js +0 -5
- package/src/link/category.js +2 -6
- package/src/link/file.js +2 -1
- package/src/link/galleryImage.js +47 -0
- package/src/link/index.js +34 -10
- package/src/magicLink.js +11 -1
- package/src/nowiki/dd.js +0 -5
- package/src/nowiki/hr.js +0 -5
- package/src/nowiki/index.js +1 -1
- package/src/nowiki/quote.js +0 -5
- package/src/onlyinclude.js +1 -1
- package/src/parameter.js +0 -5
- package/src/syntax.js +0 -5
- package/src/table/index.js +5 -5
- package/src/table/td.js +13 -11
- package/src/table/tr.js +3 -3
- package/src/tagPair/ext.js +15 -3
- package/src/tagPair/index.js +1 -10
- package/src/transclude.js +0 -4
- package/util/string.js +2 -2
package/.eslintrc.json
CHANGED
|
@@ -5,10 +5,7 @@
|
|
|
5
5
|
},
|
|
6
6
|
"extends": "eslint:recommended",
|
|
7
7
|
"parserOptions": {
|
|
8
|
-
"ecmaVersion": 13
|
|
9
|
-
"ecmaFeatures": {
|
|
10
|
-
"impliedStrict": true
|
|
11
|
-
}
|
|
8
|
+
"ecmaVersion": 13
|
|
12
9
|
},
|
|
13
10
|
"rules": {
|
|
14
11
|
"array-callback-return": [
|
|
@@ -18,13 +15,39 @@
|
|
|
18
15
|
}
|
|
19
16
|
],
|
|
20
17
|
"no-await-in-loop": 2,
|
|
18
|
+
"no-constant-binary-expression": 2,
|
|
21
19
|
"no-constructor-return": 2,
|
|
22
20
|
"no-fallthrough": 1,
|
|
23
21
|
"no-promise-executor-return": 2,
|
|
24
22
|
"no-self-compare": 2,
|
|
25
23
|
"no-template-curly-in-string": 2,
|
|
24
|
+
"no-undef": [
|
|
25
|
+
2,
|
|
26
|
+
{
|
|
27
|
+
"typeof": true
|
|
28
|
+
}
|
|
29
|
+
],
|
|
26
30
|
"no-unmodified-loop-condition": 2,
|
|
27
31
|
"no-unreachable-loop": 2,
|
|
32
|
+
"no-unsafe-negation": [
|
|
33
|
+
2,
|
|
34
|
+
{
|
|
35
|
+
"enforceForOrderingRelations": true
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"no-unsafe-optional-chaining": [
|
|
39
|
+
2,
|
|
40
|
+
{
|
|
41
|
+
"disallowArithmeticOperators": true
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"no-unused-vars": [
|
|
45
|
+
2,
|
|
46
|
+
{
|
|
47
|
+
"varsIgnorePattern": "AstNode|AstElement|[a-zA-Z]*Token",
|
|
48
|
+
"ignoreRestSiblings": true
|
|
49
|
+
}
|
|
50
|
+
],
|
|
28
51
|
"no-use-before-define": [
|
|
29
52
|
2,
|
|
30
53
|
{
|
|
@@ -33,7 +56,12 @@
|
|
|
33
56
|
"variables": false
|
|
34
57
|
}
|
|
35
58
|
],
|
|
36
|
-
"require-atomic-updates":
|
|
59
|
+
"require-atomic-updates": [
|
|
60
|
+
2,
|
|
61
|
+
{
|
|
62
|
+
"allowProperties": true
|
|
63
|
+
}
|
|
64
|
+
],
|
|
37
65
|
"block-scoped-var": 2,
|
|
38
66
|
"class-methods-use-this": 0,
|
|
39
67
|
"consistent-this": 2,
|
|
@@ -47,6 +75,13 @@
|
|
|
47
75
|
2,
|
|
48
76
|
"never"
|
|
49
77
|
],
|
|
78
|
+
"logical-assignment-operators": [
|
|
79
|
+
2,
|
|
80
|
+
"always",
|
|
81
|
+
{
|
|
82
|
+
"enforceForIfStatements": true
|
|
83
|
+
}
|
|
84
|
+
],
|
|
50
85
|
"multiline-comment-style": 2,
|
|
51
86
|
"new-cap": [
|
|
52
87
|
1,
|
|
@@ -67,6 +102,12 @@
|
|
|
67
102
|
],
|
|
68
103
|
"no-eval": 2,
|
|
69
104
|
"no-extend-native": 2,
|
|
105
|
+
"no-extra-boolean-cast": [
|
|
106
|
+
2,
|
|
107
|
+
{
|
|
108
|
+
"enforceForLogicalOperands": true
|
|
109
|
+
}
|
|
110
|
+
],
|
|
70
111
|
"no-floating-decimal": 2,
|
|
71
112
|
"no-implied-eval": 2,
|
|
72
113
|
"no-invalid-this": [
|
|
@@ -91,7 +132,12 @@
|
|
|
91
132
|
"no-return-await": 2,
|
|
92
133
|
"no-script-url": 2,
|
|
93
134
|
"no-sequences": 2,
|
|
94
|
-
"no-shadow":
|
|
135
|
+
"no-shadow": [
|
|
136
|
+
2,
|
|
137
|
+
{
|
|
138
|
+
"builtinGlobals": true
|
|
139
|
+
}
|
|
140
|
+
],
|
|
95
141
|
"no-undef-init": 2,
|
|
96
142
|
"no-unneeded-ternary": [
|
|
97
143
|
2,
|
|
@@ -139,6 +185,7 @@
|
|
|
139
185
|
],
|
|
140
186
|
"require-await": 2,
|
|
141
187
|
"spaced-comment": 2,
|
|
188
|
+
"strict": 2,
|
|
142
189
|
"symbol-description": 2,
|
|
143
190
|
"yoda": 2,
|
|
144
191
|
"array-bracket-spacing": 2,
|
package/config/default.json
CHANGED
|
@@ -646,65 +646,28 @@
|
|
|
646
646
|
"wikt",
|
|
647
647
|
"wiktionary",
|
|
648
648
|
"zhwiki",
|
|
649
|
-
"
|
|
650
|
-
"c2find",
|
|
649
|
+
"cc",
|
|
651
650
|
"cm",
|
|
652
|
-
"dictionary",
|
|
653
|
-
"drumcorpswiki",
|
|
654
|
-
"dwjwiki",
|
|
655
|
-
"elibre",
|
|
656
|
-
"emacswiki",
|
|
657
651
|
"enmoe",
|
|
658
|
-
"
|
|
659
|
-
"
|
|
660
|
-
"
|
|
661
|
-
"
|
|
662
|
-
"gentoo-wiki",
|
|
663
|
-
"hammondwiki",
|
|
664
|
-
"hrwiki",
|
|
652
|
+
"enwp",
|
|
653
|
+
"fandom",
|
|
654
|
+
"ghia",
|
|
655
|
+
"huiji",
|
|
665
656
|
"jamoe",
|
|
666
|
-
"
|
|
657
|
+
"jawp",
|
|
667
658
|
"library",
|
|
668
|
-
"linuxwiki",
|
|
669
|
-
"lojban",
|
|
670
|
-
"lqwiki",
|
|
671
|
-
"mcwiki",
|
|
672
|
-
"meatball",
|
|
673
|
-
"memoryalpha",
|
|
674
659
|
"meta",
|
|
675
|
-
"metawiki",
|
|
676
|
-
"mozillawiki",
|
|
677
|
-
"oeis",
|
|
678
|
-
"openwiki",
|
|
679
660
|
"phab",
|
|
680
661
|
"pmid",
|
|
681
|
-
"pythoninfo",
|
|
682
|
-
"rfc",
|
|
683
|
-
"s23wiki",
|
|
684
|
-
"seattlewireless",
|
|
685
|
-
"senseislibrary",
|
|
686
662
|
"shoutwiki",
|
|
687
|
-
"sourceforge",
|
|
688
|
-
"squeak",
|
|
689
|
-
"theopedia",
|
|
690
|
-
"tmbw",
|
|
691
|
-
"tmnet",
|
|
692
663
|
"translatewiki",
|
|
693
|
-
"twiki",
|
|
694
|
-
"uncyclopedia",
|
|
695
|
-
"unreal",
|
|
696
|
-
"usemod",
|
|
697
|
-
"wiki",
|
|
698
|
-
"wikif1",
|
|
699
|
-
"wikihow",
|
|
700
664
|
"zhmoe",
|
|
701
665
|
"zhmoegirl",
|
|
702
666
|
"zhtest",
|
|
667
|
+
"zhwp",
|
|
703
668
|
"文库",
|
|
704
|
-
"维基中文",
|
|
705
|
-
"维基日文",
|
|
706
|
-
"维基英文",
|
|
707
669
|
"萌娘共享",
|
|
670
|
+
"萌娘文库",
|
|
708
671
|
"萌百"
|
|
709
672
|
],
|
|
710
673
|
"img": {
|
package/config/moegirl.json
CHANGED
|
@@ -578,20 +578,14 @@
|
|
|
578
578
|
],
|
|
579
579
|
"protocol": "bitcoin:|ftp://|ftps://|geo:|git://|gopher://|http://|https://|irc://|ircs://|magnet:|mailto:|mms://|news:|nntp://|redis://|sftp://|sip:|sips:|sms:|ssh://|svn://|tel:|telnet://|urn:|worldwind://|xmpp:",
|
|
580
580
|
"interwiki": [
|
|
581
|
-
"arxiv",
|
|
582
581
|
"commons",
|
|
583
|
-
"doi",
|
|
584
|
-
"imdb",
|
|
585
|
-
"jawiki",
|
|
586
582
|
"mediawikiwiki",
|
|
587
583
|
"metawikimedia",
|
|
588
584
|
"mw",
|
|
589
|
-
"wikia",
|
|
590
585
|
"wikibooks",
|
|
591
586
|
"wikidata",
|
|
592
587
|
"wikimedia",
|
|
593
588
|
"wikinews",
|
|
594
|
-
"wikiinfo",
|
|
595
589
|
"wikipedia",
|
|
596
590
|
"wikiquote",
|
|
597
591
|
"wikisource",
|
|
@@ -600,66 +594,31 @@
|
|
|
600
594
|
"wikivoyage",
|
|
601
595
|
"wikt",
|
|
602
596
|
"wiktionary",
|
|
603
|
-
"
|
|
604
|
-
"acronym",
|
|
605
|
-
"c2find",
|
|
597
|
+
"cc",
|
|
606
598
|
"cm",
|
|
607
|
-
"
|
|
608
|
-
"drumcorpswiki",
|
|
609
|
-
"dwjwiki",
|
|
610
|
-
"elibre",
|
|
611
|
-
"emacswiki",
|
|
599
|
+
"en",
|
|
612
600
|
"enmoe",
|
|
613
|
-
"
|
|
614
|
-
"
|
|
615
|
-
"
|
|
616
|
-
"
|
|
617
|
-
"
|
|
618
|
-
"hammondwiki",
|
|
619
|
-
"hrwiki",
|
|
601
|
+
"enwp",
|
|
602
|
+
"fandom",
|
|
603
|
+
"ghia",
|
|
604
|
+
"huiji",
|
|
605
|
+
"ja",
|
|
620
606
|
"jamoe",
|
|
621
|
-
"
|
|
607
|
+
"jawp",
|
|
622
608
|
"library",
|
|
623
|
-
"linuxwiki",
|
|
624
|
-
"lojban",
|
|
625
|
-
"lqwiki",
|
|
626
|
-
"mcwiki",
|
|
627
|
-
"meatball",
|
|
628
|
-
"memoryalpha",
|
|
629
609
|
"meta",
|
|
630
|
-
"metawiki",
|
|
631
|
-
"mozillawiki",
|
|
632
|
-
"oeis",
|
|
633
|
-
"openwiki",
|
|
634
610
|
"phab",
|
|
635
611
|
"pmid",
|
|
636
|
-
"pythoninfo",
|
|
637
|
-
"rfc",
|
|
638
|
-
"s23wiki",
|
|
639
|
-
"seattlewireless",
|
|
640
|
-
"senseislibrary",
|
|
641
612
|
"shoutwiki",
|
|
642
|
-
"sourceforge",
|
|
643
|
-
"squeak",
|
|
644
|
-
"theopedia",
|
|
645
|
-
"tmbw",
|
|
646
|
-
"tmnet",
|
|
647
613
|
"translatewiki",
|
|
648
|
-
"
|
|
649
|
-
"uncyclopedia",
|
|
650
|
-
"unreal",
|
|
651
|
-
"usemod",
|
|
652
|
-
"wiki",
|
|
653
|
-
"wikif1",
|
|
654
|
-
"wikihow",
|
|
614
|
+
"zh",
|
|
655
615
|
"zhmoe",
|
|
656
616
|
"zhmoegirl",
|
|
657
617
|
"zhtest",
|
|
618
|
+
"zhwp",
|
|
658
619
|
"文库",
|
|
659
|
-
"维基中文",
|
|
660
|
-
"维基日文",
|
|
661
|
-
"维基英文",
|
|
662
620
|
"萌娘共享",
|
|
621
|
+
"萌娘文库",
|
|
663
622
|
"萌百"
|
|
664
623
|
],
|
|
665
624
|
"img": {
|
package/lib/element.js
CHANGED
|
@@ -39,12 +39,12 @@ class AstElement extends AstNode {
|
|
|
39
39
|
/** @complexity `n` */
|
|
40
40
|
get nextElementSibling() {
|
|
41
41
|
const children = this.parentElement?.children;
|
|
42
|
-
return children
|
|
42
|
+
return children && children[children.indexOf(this) + 1];
|
|
43
43
|
}
|
|
44
44
|
/** @complexity `n` */
|
|
45
45
|
get previousElementSibling() {
|
|
46
46
|
const children = this.parentElement?.children;
|
|
47
|
-
return children
|
|
47
|
+
return children && children[children.indexOf(this) - 1];
|
|
48
48
|
}
|
|
49
49
|
/** @complexity `n` */
|
|
50
50
|
get hidden() {
|
|
@@ -673,18 +673,11 @@ class AstElement extends AstNode {
|
|
|
673
673
|
}
|
|
674
674
|
|
|
675
675
|
/**
|
|
676
|
-
*
|
|
677
|
-
* @returns {[number, string][]}
|
|
676
|
+
* @returns {boolean}
|
|
678
677
|
* @complexity `n`
|
|
679
678
|
*/
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
return this.childNodes.flatMap((node, i) => {
|
|
683
|
-
if (node instanceof AstElement) {
|
|
684
|
-
return node.plain();
|
|
685
|
-
}
|
|
686
|
-
return node ? [[index + this.getRelativeIndex(i), node]] : [];
|
|
687
|
-
});
|
|
679
|
+
get eof() {
|
|
680
|
+
return this.type === 'root' || !this.nextSibling && this.parentElement.eof;
|
|
688
681
|
}
|
|
689
682
|
|
|
690
683
|
/**
|
|
@@ -743,6 +736,11 @@ class AstElement extends AstNode {
|
|
|
743
736
|
}
|
|
744
737
|
Parser.info(`${indent}</${type}>`);
|
|
745
738
|
}
|
|
739
|
+
|
|
740
|
+
/** @param {number} n */
|
|
741
|
+
getLine(n) {
|
|
742
|
+
return this.toString().split('\n', n + 1).at(-1);
|
|
743
|
+
}
|
|
746
744
|
}
|
|
747
745
|
|
|
748
746
|
Parser.classes.AstElement = __filename;
|
package/lib/node.js
CHANGED
|
@@ -22,12 +22,12 @@ class AstNode {
|
|
|
22
22
|
/** @complexity `n` */
|
|
23
23
|
get nextSibling() {
|
|
24
24
|
const childNodes = this.#parentNode?.childNodes;
|
|
25
|
-
return childNodes
|
|
25
|
+
return childNodes && childNodes[childNodes.indexOf(this) + 1];
|
|
26
26
|
}
|
|
27
27
|
/** @complexity `n` */
|
|
28
28
|
get previousSibling() {
|
|
29
29
|
const childNodes = this.#parentNode?.childNodes;
|
|
30
|
-
return childNodes
|
|
30
|
+
return childNodes && childNodes[childNodes.indexOf(this) - 1];
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
debugOnly(method = 'debugOnly') {
|
package/lib/title.js
CHANGED
|
@@ -5,6 +5,8 @@ const {ucfirst} = require('../util/string'),
|
|
|
5
5
|
|
|
6
6
|
class Title {
|
|
7
7
|
title = '';
|
|
8
|
+
main = '';
|
|
9
|
+
prefix = '';
|
|
8
10
|
ns = 0;
|
|
9
11
|
interwiki = '';
|
|
10
12
|
fragment = '';
|
|
@@ -19,7 +21,7 @@ class Title {
|
|
|
19
21
|
namespace = '';
|
|
20
22
|
title = title.slice(1).trim();
|
|
21
23
|
}
|
|
22
|
-
const iw = Parser.isInterwiki(title, config);
|
|
24
|
+
const iw = defaultNs ? null : Parser.isInterwiki(title, config);
|
|
23
25
|
if (iw) {
|
|
24
26
|
this.interwiki = iw[1].toLowerCase();
|
|
25
27
|
title = title.slice(iw[0].length);
|
|
@@ -48,8 +50,10 @@ class Title {
|
|
|
48
50
|
this.fragment ||= fragment;
|
|
49
51
|
title = title.slice(0, i).trim();
|
|
50
52
|
}
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
53
|
+
this.main = ucfirst(title);
|
|
54
|
+
this.prefix = `${namespace}${namespace && ':'}`;
|
|
55
|
+
this.title = `${iw ? `${this.interwiki}:` : ''}${this.prefix}${this.main}`;
|
|
56
|
+
this.valid = Boolean(this.main) && !/\x00\d+[eh!+-]\x7f|[<>[\]{}|]/.test(this.title);
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
59
|
|
package/mixin/attributeParent.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const /** @type {Parser} */ Parser = require('..'),
|
|
4
|
-
AttributeToken = require('../src/attribute');
|
|
4
|
+
AttributeToken = require('../src/attribute');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @template T
|
|
8
8
|
* @param {T} constructor
|
|
9
9
|
* @returns {T}
|
|
10
10
|
*/
|
|
11
|
-
const attributeParent = (
|
|
11
|
+
const attributeParent = (ct, i = 0) => class extends ct {
|
|
12
12
|
/**
|
|
13
13
|
* @this {{children: AttributeToken[]}}
|
|
14
14
|
* @param {string} key
|
package/mixin/fixedToken.js
CHANGED
package/mixin/hidden.js
CHANGED
|
@@ -7,15 +7,10 @@ const /** @type {Parser} */ Parser = require('..');
|
|
|
7
7
|
* @param {T} constructor
|
|
8
8
|
* @returns {T}
|
|
9
9
|
*/
|
|
10
|
-
const hidden =
|
|
10
|
+
const hidden = ct => class extends ct {
|
|
11
11
|
text() {
|
|
12
12
|
return '';
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
/** @returns {[number, string][]} */
|
|
16
|
-
plain() {
|
|
17
|
-
return [];
|
|
18
|
-
}
|
|
19
14
|
};
|
|
20
15
|
|
|
21
16
|
Parser.mixins.hidden = __filename;
|
package/mixin/sol.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const /** @type {Parser} */ Parser = require('..'),
|
|
4
|
-
Token = require('../src');
|
|
4
|
+
Token = require('../src');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @template T
|
|
8
8
|
* @param {T} constructor
|
|
9
9
|
* @returns {T}
|
|
10
10
|
*/
|
|
11
|
-
const sol =
|
|
11
|
+
const sol = ct => class extends ct {
|
|
12
12
|
/** @this {Token} */
|
|
13
13
|
prependNewLine() {
|
|
14
14
|
const {previousVisibleSibling = '', parentNode} = this;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikiparser-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A Node.js parser for MediaWiki markup with AST",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"test": "echo 'Error: no test specified' && exit 1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"@types/node": "^17.0.23",
|
|
25
|
+
"eslint": "^8.30.0"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
28
28
|
"node": "^18.4.0"
|
|
@@ -10,7 +10,7 @@ const parseHrAndDoubleUnderscore = (firstChild, config = Parser.getConfig(), acc
|
|
|
10
10
|
const HrToken = require('../src/nowiki/hr'),
|
|
11
11
|
DoubleUnderscoreToken = require('../src/nowiki/doubleUnderscore'),
|
|
12
12
|
{doubleUnderscore} = config;
|
|
13
|
-
return firstChild.replace(
|
|
13
|
+
return firstChild.replace(/(?<=^(?:\x00\d+c\x7f)*)-{4,}/mg, m => {
|
|
14
14
|
new HrToken(m.length, config, accum);
|
|
15
15
|
return `\x00${accum.length - 1}r\x7f`;
|
|
16
16
|
}).replace(new RegExp(`__(${doubleUnderscore.flat().join('|')})__`, 'ig'), /** @param {string} p1 */(m, p1) => {
|
package/parser/links.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const /** @type {Parser} */ Parser = require('..'),
|
|
4
|
-
Token = require('../src');
|
|
4
|
+
Token = require('../src');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {string} firstChild
|
|
@@ -78,7 +78,7 @@ const parseLinks = (firstChild, config = Parser.getConfig(), accum = []) => {
|
|
|
78
78
|
continue;
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
text
|
|
81
|
+
text &&= parseQuotes(text, config, accum);
|
|
82
82
|
s += `\x00${accum.length}l\x7f${after}`;
|
|
83
83
|
let LinkToken = require('../src/link');
|
|
84
84
|
if (!force) {
|
package/parser/list.js
CHANGED
|
@@ -7,13 +7,13 @@ const /** @type {Parser} */ Parser = require('..');
|
|
|
7
7
|
* @param {accum} accum
|
|
8
8
|
*/
|
|
9
9
|
const parseList = (text, config = Parser.getConfig(), accum = []) => {
|
|
10
|
-
const mt = text.match(/^(
|
|
10
|
+
const mt = text.match(/^((?:\x00\d+c\x7f)*)([;:*#]+)/);
|
|
11
11
|
if (!mt) {
|
|
12
12
|
return text;
|
|
13
13
|
}
|
|
14
14
|
const ListToken = require('../src/nowiki/list'),
|
|
15
|
-
[prefix] = mt;
|
|
16
|
-
text =
|
|
15
|
+
[total, comment, prefix] = mt;
|
|
16
|
+
text = `${comment}\x00${accum.length}d\x7f${text.slice(total.length)}`;
|
|
17
17
|
new ListToken(prefix, config, accum);
|
|
18
18
|
let dt = prefix.split(';').length - 1;
|
|
19
19
|
if (!dt) {
|
package/parser/quotes.js
CHANGED
package/parser/table.js
CHANGED
|
@@ -36,6 +36,9 @@ const parseTable = ({firstChild, type}, config = Parser.getConfig(), accum = [])
|
|
|
36
36
|
const line = outLine.slice(spaces.length),
|
|
37
37
|
matchesStart = line.match(/^(:*)((?:\s|\x00\d+c\x7f)*)({\||{\x00\d+!\x7f|\x00\d+{\x7f)(.*)/);
|
|
38
38
|
if (matchesStart) {
|
|
39
|
+
while (top && top.type !== 'td') {
|
|
40
|
+
top = stack.pop();
|
|
41
|
+
}
|
|
39
42
|
const [, indent, moreSpaces, tableSyntax, attr] = matchesStart;
|
|
40
43
|
if (indent) {
|
|
41
44
|
new DdToken(indent, config, accum);
|
package/src/arg.js
CHANGED
|
@@ -73,11 +73,6 @@ class ArgToken extends Token {
|
|
|
73
73
|
return `{{{${text(this.children.slice(0, 2), '|')}}}}`;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
/** @returns {[number, string][]} */
|
|
77
|
-
plain() {
|
|
78
|
-
return this.childNodes.length > 1 ? this.children[1].plain() : [];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
76
|
/** @complexity `n` */
|
|
82
77
|
removeRedundant() {
|
|
83
78
|
Parser.run(() => {
|
package/src/attribute.js
CHANGED
|
@@ -82,7 +82,7 @@ class AttributeToken extends Token {
|
|
|
82
82
|
* @param {accum} accum
|
|
83
83
|
*/
|
|
84
84
|
constructor(attr, type, name, config = Parser.getConfig(), accum = []) {
|
|
85
|
-
super(attr, config,
|
|
85
|
+
super(attr, config, true, accum, {[`Stage-${stages[type]}`]: ':'});
|
|
86
86
|
this.type = type;
|
|
87
87
|
this.setAttribute('name', name).#parseAttr();
|
|
88
88
|
}
|
|
@@ -253,11 +253,6 @@ class AttributeToken extends Token {
|
|
|
253
253
|
return this.type === 'table-attr' ? normalizeSpace(str) : str;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
/** @returns {[number, string][]} */
|
|
257
|
-
plain() {
|
|
258
|
-
return [];
|
|
259
|
-
}
|
|
260
|
-
|
|
261
256
|
/**
|
|
262
257
|
* @param {number} i
|
|
263
258
|
* @complexity `n`
|
package/src/converter.js
CHANGED
|
@@ -19,7 +19,7 @@ class ConverterToken extends Token {
|
|
|
19
19
|
* @param {accum} accum
|
|
20
20
|
*/
|
|
21
21
|
constructor(flags, rules, config = Parser.getConfig(), accum = []) {
|
|
22
|
-
super(undefined, config,
|
|
22
|
+
super(undefined, config, true, accum);
|
|
23
23
|
this.append(new ConverterFlagsToken(flags, config, accum));
|
|
24
24
|
if (rules.length) {
|
|
25
25
|
const [firstRule] = rules,
|
|
@@ -65,11 +65,6 @@ class ConverterToken extends Token {
|
|
|
65
65
|
return `-{${flags.text()}|${text(rules, ';')}}-`;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
/** @returns {[number, string][]} */
|
|
69
|
-
plain() {
|
|
70
|
-
return this.children.slice(1).flatMap(child => child.plain());
|
|
71
|
-
}
|
|
72
|
-
|
|
73
68
|
/** @this {ConverterToken & {firstChild: ConverterFlagsToken}} */
|
|
74
69
|
getAllFlags() {
|
|
75
70
|
return this.firstChild.getAllFlags();
|
package/src/converterFlags.js
CHANGED
|
@@ -17,7 +17,7 @@ class ConverterFlagsToken extends Token {
|
|
|
17
17
|
* @param {accum} accum
|
|
18
18
|
*/
|
|
19
19
|
constructor(flags, config = Parser.getConfig(), accum = []) {
|
|
20
|
-
super(undefined, config,
|
|
20
|
+
super(undefined, config, true, accum, {AtomToken: ':'});
|
|
21
21
|
this.append(...flags.map(flag => new AtomToken(flag, 'converter-flag', config, accum)));
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -86,11 +86,6 @@ class ConverterFlagsToken extends Token {
|
|
|
86
86
|
return super.text(';');
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
/** @returns {[number, string][]} */
|
|
90
|
-
plain() {
|
|
91
|
-
return [];
|
|
92
|
-
}
|
|
93
|
-
|
|
94
89
|
/**
|
|
95
90
|
* @param {string} flag
|
|
96
91
|
* @returns {AtomToken[]}
|
package/src/converterRule.js
CHANGED
|
@@ -47,7 +47,7 @@ class ConverterRuleToken extends Token {
|
|
|
47
47
|
|
|
48
48
|
cloneNode() {
|
|
49
49
|
const cloned = this.cloneChildren(),
|
|
50
|
-
placeholders = ['', ':', '
|
|
50
|
+
placeholders = ['', 'zh:', '=>zh:'],
|
|
51
51
|
placeholder = placeholders[cloned.length - 1],
|
|
52
52
|
token = Parser.run(() => new ConverterRuleToken(placeholder, placeholder, this.getAttribute('config')));
|
|
53
53
|
for (let i = 0; i < cloned.length; i++) {
|
|
@@ -120,15 +120,6 @@ class ConverterRuleToken extends Token {
|
|
|
120
120
|
return super.text(':');
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
/** @returns {[number, string][]} */
|
|
124
|
-
plain() {
|
|
125
|
-
const {firstElementChild, lastElementChild, unidirectional} = this;
|
|
126
|
-
if (unidirectional) {
|
|
127
|
-
return [...firstElementChild.plain(), ...lastElementChild.plain()];
|
|
128
|
-
}
|
|
129
|
-
return lastElementChild.plain();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
123
|
noConvert() {
|
|
133
124
|
for (let i = this.childNodes.length - 2; i >= 0; i--) {
|
|
134
125
|
super.removeAt(i);
|
package/src/extLink.js
CHANGED
|
@@ -47,6 +47,7 @@ class ExtLinkToken extends Token {
|
|
|
47
47
|
if (text) {
|
|
48
48
|
token.appendChild(text);
|
|
49
49
|
}
|
|
50
|
+
return token;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
#correct() {
|
|
@@ -77,14 +78,6 @@ class ExtLinkToken extends Token {
|
|
|
77
78
|
return `[${super.text(' ').replaceAll('\n', ' ')}]`;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
/**
|
|
81
|
-
* @returns {[number, string][]}
|
|
82
|
-
* @complexity `n`
|
|
83
|
-
*/
|
|
84
|
-
plain() {
|
|
85
|
-
return this.childNodes.length === 1 ? [] : this.lastElementChild.plain();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
81
|
/** @this {ExtLinkToken & {firstElementChild: MagicLinkToken}} */
|
|
89
82
|
getUrl() {
|
|
90
83
|
return this.firstElementChild.getUrl();
|
package/src/gallery.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {text} = require('../util/string'),
|
|
4
|
+
/** @type {Parser} */ Parser = require('..'),
|
|
5
|
+
Token = require('.'),
|
|
6
|
+
GalleryImageToken = require('./link/galleryImage');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* gallery标签
|
|
10
|
+
* @classdesc `{childNodes: (string|FileToken)[]]}`
|
|
11
|
+
*/
|
|
12
|
+
class GalleryToken extends Token {
|
|
13
|
+
type = 'ext-inner';
|
|
14
|
+
name = 'gallery';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {string} inner
|
|
18
|
+
* @param {accum} accum
|
|
19
|
+
*/
|
|
20
|
+
constructor(inner, config = Parser.getConfig(), accum = []) {
|
|
21
|
+
super(undefined, config, true, accum, {String: ':', GalleryImageToken: ':'});
|
|
22
|
+
for (const line of inner?.split('\n') ?? []) {
|
|
23
|
+
const matches = line.match(/^([^|]+)(?:\|(.*))?/);
|
|
24
|
+
if (!matches) {
|
|
25
|
+
this.appendChild(line);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const [, file, alt] = matches;
|
|
29
|
+
let title;
|
|
30
|
+
try {
|
|
31
|
+
title = this.normalizeTitle(decodeURIComponent(file), 6, true);
|
|
32
|
+
} catch {
|
|
33
|
+
title = this.normalizeTitle(file, 6, true);
|
|
34
|
+
}
|
|
35
|
+
if (!title.valid) {
|
|
36
|
+
this.appendChild(line);
|
|
37
|
+
} else {
|
|
38
|
+
this.appendChild(new GalleryImageToken(file, alt, title, config, accum));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
cloneNode() {
|
|
44
|
+
const cloned = this.cloneChildren(),
|
|
45
|
+
token = Parser.run(() => new GalleryToken(undefined, this.getAttribute('config')));
|
|
46
|
+
token.append(...cloned);
|
|
47
|
+
return token;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
toString() {
|
|
51
|
+
return super.toString('\n');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
getGaps() {
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
text() {
|
|
59
|
+
return text(this.children, '\n');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Parser.classes.GalleryToken = __filename;
|
|
64
|
+
module.exports = GalleryToken;
|
package/src/heading.js
CHANGED
|
@@ -63,11 +63,6 @@ class HeadingToken extends fixedToken(sol(Token)) {
|
|
|
63
63
|
return `${this.prependNewLine()}${equals}${this.firstElementChild.text()}${equals}${this.appendNewLine()}`;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
/** @returns {[number, string][]} */
|
|
67
|
-
plain() {
|
|
68
|
-
return this.firstElementChild.plain();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
66
|
/** @param {number} n */
|
|
72
67
|
setLevel(n) {
|
|
73
68
|
if (typeof n !== 'number') {
|
package/src/html.js
CHANGED
|
@@ -62,11 +62,6 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
|
|
|
62
62
|
return `<${this.closing ? '/' : ''}${this.#tag}${super.text()}${this.selfClosing ? '/' : ''}>`;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
/** @returns {[number, string][]} */
|
|
66
|
-
plain() {
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
65
|
/** @param {string} tag */
|
|
71
66
|
replaceTag(tag) {
|
|
72
67
|
const name = tag.toLowerCase();
|
package/src/link/category.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const /** @type {Parser} */ Parser = require('../..'),
|
|
4
4
|
LinkToken = require('.'),
|
|
5
|
-
Token = require('..');
|
|
5
|
+
Token = require('..');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* 分类
|
|
@@ -12,6 +12,7 @@ class CategoryToken extends LinkToken {
|
|
|
12
12
|
type = 'category';
|
|
13
13
|
sortkey = '';
|
|
14
14
|
|
|
15
|
+
setLangLink = undefined;
|
|
15
16
|
setFragment = undefined;
|
|
16
17
|
asSelfLink = undefined;
|
|
17
18
|
pipeTrick = undefined;
|
|
@@ -74,11 +75,6 @@ class CategoryToken extends LinkToken {
|
|
|
74
75
|
return `[[${this.firstElementChild.text()}]]`;
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
/** @returns {[number, string][]} */
|
|
78
|
-
plain() {
|
|
79
|
-
return [];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
78
|
/** @param {string} text */
|
|
83
79
|
setSortkey(text) {
|
|
84
80
|
this.setLinkText(text);
|
package/src/link/file.js
CHANGED
|
@@ -15,6 +15,7 @@ class FileToken extends LinkToken {
|
|
|
15
15
|
/** @type {Set<string>} */ #keys = new Set();
|
|
16
16
|
/** @type {Record<string, Set<ImageParameterToken>>} */ #args = {};
|
|
17
17
|
|
|
18
|
+
setLangLink = undefined;
|
|
18
19
|
setFragment = undefined;
|
|
19
20
|
asSelfLink = undefined;
|
|
20
21
|
setLinkText = undefined;
|
|
@@ -63,7 +64,7 @@ class FileToken extends LinkToken {
|
|
|
63
64
|
super(link, undefined, title, config, accum);
|
|
64
65
|
this.setAttribute('acceptable', {AtomToken: 0, ImageParameterToken: '1:'});
|
|
65
66
|
this.append(...explode('-{', '}-', '|', text).map(part => new ImageParameterToken(part, config, accum)));
|
|
66
|
-
this.seal(['setFragment', 'asSelfLink', 'setLinkText', 'pipeTrick']);
|
|
67
|
+
this.seal(['setLangLink', 'setFragment', 'asSelfLink', 'setLinkText', 'pipeTrick']);
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
/**
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const /** @type {Parser} */ Parser = require('../..'),
|
|
4
|
+
Token = require('..'),
|
|
5
|
+
FileToken = require('./file');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 图片
|
|
9
|
+
* @classdesc `{childNodes: [AtomToken, ...ImageParameterToken]}`
|
|
10
|
+
*/
|
|
11
|
+
class GalleryImageToken extends FileToken {
|
|
12
|
+
type = 'gallery-image';
|
|
13
|
+
|
|
14
|
+
size = undefined;
|
|
15
|
+
width = undefined;
|
|
16
|
+
height = undefined;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {string} link
|
|
20
|
+
* @param {string|undefined} text
|
|
21
|
+
* @param {Title} title
|
|
22
|
+
* @param {accum} accum
|
|
23
|
+
*/
|
|
24
|
+
constructor(link, text, title, config = Parser.getConfig(), accum = []) {
|
|
25
|
+
let token;
|
|
26
|
+
if (text !== undefined) {
|
|
27
|
+
token = new Token(text, config, true, accum);
|
|
28
|
+
token.type = 'temp';
|
|
29
|
+
token.setAttribute('stage', 1);
|
|
30
|
+
for (let n = 1; n < Parser.MAX_STAGE; n++) {
|
|
31
|
+
token.parseOnce();
|
|
32
|
+
}
|
|
33
|
+
accum.splice(accum.indexOf(token), 1);
|
|
34
|
+
}
|
|
35
|
+
const newConfig = structuredClone(config);
|
|
36
|
+
newConfig.img = Object.fromEntries(Object.entries(config.img).filter(([, param]) => param !== 'width'));
|
|
37
|
+
super(link, token?.toString(), title, newConfig, accum);
|
|
38
|
+
this.seal(['size', 'width', 'height']);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getPadding() {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Parser.classes.GalleryImageToken = __filename;
|
|
47
|
+
module.exports = GalleryImageToken;
|
package/src/link/index.js
CHANGED
|
@@ -47,7 +47,7 @@ class LinkToken extends Token {
|
|
|
47
47
|
title: this.name, interwiki: this.interwiki, fragment: this.fragment,
|
|
48
48
|
}, this.getAttribute('config'));
|
|
49
49
|
token.firstElementChild.safeReplaceWith(link);
|
|
50
|
-
token.
|
|
50
|
+
token.append(...linkText);
|
|
51
51
|
return token.afterBuild();
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -90,7 +90,8 @@ class LinkToken extends Token {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
toString() {
|
|
93
|
-
|
|
93
|
+
const str = super.toString('|');
|
|
94
|
+
return this.type === 'gallery-image' ? str : `[[${str}]]`;
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
getPadding() {
|
|
@@ -102,24 +103,20 @@ class LinkToken extends Token {
|
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
text() {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
/** @returns {[number, string][]} */
|
|
109
|
-
plain() {
|
|
110
|
-
return this.childNodes.length === 1 ? [] : this.lastElementChild.plain();
|
|
106
|
+
const str = super.text('|');
|
|
107
|
+
return this.type === 'gallery-image' ? str : `[[${str}]]`;
|
|
111
108
|
}
|
|
112
109
|
|
|
113
110
|
/** @param {string} link */
|
|
114
111
|
setTarget(link) {
|
|
115
112
|
link = String(link);
|
|
116
|
-
if (!/^\s*[:#]/.test(link)) {
|
|
113
|
+
if (link.type === 'link' && !/^\s*[:#]/.test(link)) {
|
|
117
114
|
link = `:${link}`;
|
|
118
115
|
}
|
|
119
116
|
const root = Parser.parse(`[[${link}]]`, this.getAttribute('include'), 6, this.getAttribute('config')),
|
|
120
117
|
{childNodes: {length}, firstElementChild} = root;
|
|
121
118
|
if (length !== 1 || firstElementChild?.type !== this.type || firstElementChild.childNodes.length !== 1) {
|
|
122
|
-
const msgs = {link: '内链', file: '文件链接', category: '分类'};
|
|
119
|
+
const msgs = {link: '内链', file: '文件链接', category: '分类', 'gallery-image': '文件链接'};
|
|
123
120
|
throw new SyntaxError(`非法的${msgs[this.type]}目标:${link}`);
|
|
124
121
|
}
|
|
125
122
|
const {firstChild} = firstElementChild;
|
|
@@ -128,6 +125,33 @@ class LinkToken extends Token {
|
|
|
128
125
|
this.firstElementChild.safeReplaceWith(firstChild);
|
|
129
126
|
}
|
|
130
127
|
|
|
128
|
+
/**
|
|
129
|
+
* @param {string} lang
|
|
130
|
+
* @param {string} link
|
|
131
|
+
*/
|
|
132
|
+
setLangLink(lang, link) {
|
|
133
|
+
if (typeof lang !== 'string') {
|
|
134
|
+
this.typeError('setLangLink', 'String');
|
|
135
|
+
}
|
|
136
|
+
link = String(link).trim();
|
|
137
|
+
if (link.startsWith('#')) {
|
|
138
|
+
throw new SyntaxError(`跨语言链接不能仅为fragment!`);
|
|
139
|
+
} else if (link.startsWith(':')) {
|
|
140
|
+
link = link.slice(1);
|
|
141
|
+
}
|
|
142
|
+
const root = Parser.parse(`[[${lang}:${link}]]`, this.getAttribute('include'), 6, this.getAttribute('config')),
|
|
143
|
+
/** @type {Token & {firstElementChild: LinkToken}} */ {childNodes: {length}, firstElementChild} = root;
|
|
144
|
+
if (length !== 1 || firstElementChild?.type !== 'link' || firstElementChild.childNodes.length !== 1
|
|
145
|
+
|| firstElementChild.interwiki !== lang.toLowerCase()
|
|
146
|
+
) {
|
|
147
|
+
throw new SyntaxError(`非法的跨语言链接目标:${lang}:${link}`);
|
|
148
|
+
}
|
|
149
|
+
const {firstChild} = firstElementChild;
|
|
150
|
+
root.destroy();
|
|
151
|
+
firstElementChild.destroy();
|
|
152
|
+
this.firstElementChild.safeReplaceWith(firstChild);
|
|
153
|
+
}
|
|
154
|
+
|
|
131
155
|
/** @param {string} fragment */
|
|
132
156
|
#setFragment(fragment, page = true) {
|
|
133
157
|
fragment = String(fragment).replace(/[<>[]#|=!]/g, p => encodeURIComponent(p));
|
package/src/magicLink.js
CHANGED
|
@@ -37,7 +37,7 @@ class MagicLinkToken extends Token {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
afterBuild() {
|
|
40
|
-
const ParameterToken = require('./parameter'),
|
|
40
|
+
const ParameterToken = require('./parameter'),
|
|
41
41
|
/** @type {ParameterToken} */ parameter = this.closest('parameter');
|
|
42
42
|
if (parameter?.getValue() === this.text()) {
|
|
43
43
|
this.replaceWith(this.toString());
|
|
@@ -45,6 +45,16 @@ class MagicLinkToken extends Token {
|
|
|
45
45
|
return this;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
cloneNode() {
|
|
49
|
+
const cloned = this.cloneChildren(),
|
|
50
|
+
token = Parser.run(() => new MagicLinkToken(
|
|
51
|
+
undefined, this.type === 'ext-link-url', this.getAttribute('config'),
|
|
52
|
+
));
|
|
53
|
+
token.append(...cloned);
|
|
54
|
+
token.afterBuild();
|
|
55
|
+
return token;
|
|
56
|
+
}
|
|
57
|
+
|
|
48
58
|
getUrl() {
|
|
49
59
|
let url = this.text();
|
|
50
60
|
if (url.startsWith('//')) {
|
package/src/nowiki/dd.js
CHANGED
|
@@ -29,11 +29,6 @@ class DdToken extends NowikiToken {
|
|
|
29
29
|
this.seal(['dt', 'ul', 'ol', 'indent']).#update(str);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
/** @returns {[number, string][]} */
|
|
33
|
-
plain() {
|
|
34
|
-
return [];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
32
|
/** @param {string} str */
|
|
38
33
|
setText(str) {
|
|
39
34
|
const src = this.type === 'dd' ? ':' : ';:*#';
|
package/src/nowiki/hr.js
CHANGED
|
@@ -24,11 +24,6 @@ class HrToken extends sol(NowikiToken) {
|
|
|
24
24
|
return Parser.run(() => new HrToken(this.firstChild.length, this.getAttribute('config')));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/** @returns {[number, string][]} */
|
|
28
|
-
plain() {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
27
|
/** @param {string} str */
|
|
33
28
|
setText(str) {
|
|
34
29
|
if (!/^-{4,}$/.test(str)) {
|
package/src/nowiki/index.js
CHANGED
|
@@ -16,7 +16,7 @@ class NowikiToken extends fixedToken(Token) {
|
|
|
16
16
|
* @param {accum} accum
|
|
17
17
|
*/
|
|
18
18
|
constructor(wikitext, config = Parser.getConfig(), accum = []) {
|
|
19
|
-
super(wikitext, config,
|
|
19
|
+
super(wikitext, config, true, accum);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/** @this {NowikiToken & {firstChild: string}} */
|
package/src/nowiki/quote.js
CHANGED
package/src/onlyinclude.js
CHANGED
package/src/parameter.js
CHANGED
|
@@ -85,11 +85,6 @@ class ParameterToken extends fixedToken(Token) {
|
|
|
85
85
|
return this.anon ? this.lastElementChild.text() : super.text('=');
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
/** @returns {[number, string][]} */
|
|
89
|
-
plain() {
|
|
90
|
-
return this.lastElementChild.plain();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
88
|
/**
|
|
94
89
|
* @param {ParameterToken} token
|
|
95
90
|
* @complexity `n`
|
package/src/syntax.js
CHANGED
package/src/table/index.js
CHANGED
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
const assert = require('assert/strict'),
|
|
4
4
|
{noWrap} = require('../../util/string'),
|
|
5
5
|
/** @type {Parser} */ Parser = require('../..'),
|
|
6
|
-
Token = require('..'),
|
|
6
|
+
Token = require('..'),
|
|
7
7
|
TrToken = require('./tr'),
|
|
8
8
|
TdToken = require('./td'),
|
|
9
9
|
SyntaxToken = require('../syntax'),
|
|
10
|
-
AttributeToken = require('../attribute');
|
|
10
|
+
AttributeToken = require('../attribute');
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @param {TableCoords} coords1
|
|
14
14
|
* @param {TableCoords} coords2
|
|
15
15
|
*/
|
|
16
16
|
const cmpCoords = (coords1, coords2) => {
|
|
17
|
-
const diff = coords1
|
|
18
|
-
return diff === 0 ? coords1
|
|
17
|
+
const diff = coords1.row - coords2.row;
|
|
18
|
+
return diff === 0 ? coords1.column - coords2.column : diff;
|
|
19
19
|
};
|
|
20
20
|
const isRowEnd = /** @param {Token} */ ({type}) => ['tr', 'table-syntax'].includes(type);
|
|
21
21
|
|
|
@@ -192,7 +192,7 @@ class TableToken extends TrToken {
|
|
|
192
192
|
{length} = rows,
|
|
193
193
|
/** @type {Layout} */ layout = new Layout(length).fill().map(() => []);
|
|
194
194
|
for (const [i, rowToken] of rows.entries()) {
|
|
195
|
-
if (i > stop.row ?? stop.y) {
|
|
195
|
+
if (i > (stop.row ?? stop.y)) {
|
|
196
196
|
break;
|
|
197
197
|
}
|
|
198
198
|
const rowLayout = layout[i];
|
package/src/table/td.js
CHANGED
|
@@ -45,7 +45,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
45
45
|
*/
|
|
46
46
|
getSyntax() {
|
|
47
47
|
const syntax = this.firstElementChild.text(),
|
|
48
|
-
|
|
48
|
+
esc = syntax.includes('{{');
|
|
49
49
|
let subtype = 'td';
|
|
50
50
|
if (syntax.endsWith('!')) {
|
|
51
51
|
subtype = 'th';
|
|
@@ -53,14 +53,14 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
53
53
|
subtype = 'caption';
|
|
54
54
|
}
|
|
55
55
|
if (this.isIndependent()) {
|
|
56
|
-
return {subtype, escape, correction: false};
|
|
56
|
+
return {subtype, escape: esc, correction: false};
|
|
57
57
|
}
|
|
58
58
|
const {previousElementSibling} = this;
|
|
59
59
|
if (previousElementSibling?.type !== 'td') {
|
|
60
|
-
return {subtype, escape, correction: true};
|
|
60
|
+
return {subtype, escape: esc, correction: true};
|
|
61
61
|
}
|
|
62
62
|
const result = previousElementSibling.getSyntax();
|
|
63
|
-
result.escape ||=
|
|
63
|
+
result.escape ||= esc;
|
|
64
64
|
result.correction = previousElementSibling.lastElementChild.offsetHeight > 1;
|
|
65
65
|
if (subtype === 'th' && result.subtype !== 'th') {
|
|
66
66
|
result.subtype = 'th';
|
|
@@ -91,6 +91,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
91
91
|
if (innerSyntax) {
|
|
92
92
|
[this.#innerSyntax] = innerSyntax;
|
|
93
93
|
}
|
|
94
|
+
// eslint-disable-next-line no-unsafe-optional-chaining
|
|
94
95
|
const innerToken = new Token(inner?.slice(innerSyntax?.index + this.#innerSyntax.length), config, true, accum);
|
|
95
96
|
innerToken.type = 'td-inner';
|
|
96
97
|
this.setAttribute('acceptable', {SyntaxToken: 0, AttributeToken: 1, Token: 2})
|
|
@@ -98,7 +99,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
cloneNode() {
|
|
101
|
-
const token = super.cloneNode();
|
|
102
|
+
const /** @type {TdToken} */ token = super.cloneNode();
|
|
102
103
|
token.setAttribute('innerSyntax', this.#innerSyntax);
|
|
103
104
|
return token;
|
|
104
105
|
}
|
|
@@ -141,6 +142,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
141
142
|
* @template {string} T
|
|
142
143
|
* @param {T} key
|
|
143
144
|
* @param {TokenAttribute<T>} value
|
|
145
|
+
* @return {this}
|
|
144
146
|
*/
|
|
145
147
|
setAttribute(key, value) {
|
|
146
148
|
if (key !== 'innerSyntax') {
|
|
@@ -162,8 +164,8 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
162
164
|
static #aliases = {td: '\n|', th: '\n!', caption: '\n|+'};
|
|
163
165
|
|
|
164
166
|
/** @param {string} syntax */
|
|
165
|
-
setSyntax(syntax,
|
|
166
|
-
super.setSyntax(TdToken.#aliases[syntax] ?? syntax,
|
|
167
|
+
setSyntax(syntax, esc = false) {
|
|
168
|
+
super.setSyntax(TdToken.#aliases[syntax] ?? syntax, esc);
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
/** @complexity `n` */
|
|
@@ -171,17 +173,17 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
171
173
|
if (this.children[1].toString()) {
|
|
172
174
|
this.#innerSyntax ||= '|';
|
|
173
175
|
}
|
|
174
|
-
const {subtype, escape, correction} = this.getSyntax();
|
|
176
|
+
const {subtype, escape: esc, correction} = this.getSyntax();
|
|
175
177
|
if (correction) {
|
|
176
|
-
this.setSyntax(subtype,
|
|
178
|
+
this.setSyntax(subtype, esc);
|
|
177
179
|
}
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
/** @complexity `n` */
|
|
181
183
|
independence() {
|
|
182
184
|
if (!this.isIndependent()) {
|
|
183
|
-
const {subtype, escape} = this.getSyntax();
|
|
184
|
-
this.setSyntax(subtype,
|
|
185
|
+
const {subtype, escape: esc} = this.getSyntax();
|
|
186
|
+
this.setSyntax(subtype, esc);
|
|
185
187
|
}
|
|
186
188
|
}
|
|
187
189
|
|
package/src/table/tr.js
CHANGED
|
@@ -93,10 +93,10 @@ class TrToken extends attributeParent(Token, 1) {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/** @param {string} syntax */
|
|
96
|
-
setSyntax(syntax,
|
|
96
|
+
setSyntax(syntax, esc = false) {
|
|
97
97
|
const {firstElementChild} = this;
|
|
98
98
|
firstElementChild.replaceChildren(syntax);
|
|
99
|
-
if (
|
|
99
|
+
if (esc) {
|
|
100
100
|
TrToken.escape(firstElementChild);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -202,7 +202,7 @@ class TrToken extends attributeParent(Token, 1) {
|
|
|
202
202
|
if (n < 0 || n > nCols || n === nCols && !insert) {
|
|
203
203
|
throw new RangeError(`不存在第 ${n} 个单元格!`);
|
|
204
204
|
}
|
|
205
|
-
const TdToken = require('./td');
|
|
205
|
+
const TdToken = require('./td');
|
|
206
206
|
let last = 0;
|
|
207
207
|
for (const child of this.children.slice(2)) {
|
|
208
208
|
if (child instanceof TdToken) {
|
package/src/tagPair/ext.js
CHANGED
|
@@ -23,7 +23,7 @@ class ExtToken extends attributeParent(TagPairToken) {
|
|
|
23
23
|
attrToken = new AttributeToken(attr, 'ext-attr', lcName, config, accum),
|
|
24
24
|
newConfig = structuredClone(config),
|
|
25
25
|
ext = new Set(newConfig.ext);
|
|
26
|
-
let /** @type {acceptable} */ acceptable, innerToken;
|
|
26
|
+
let /** @type {acceptable} */ acceptable, /** @type {Token} */ innerToken;
|
|
27
27
|
switch (lcName) {
|
|
28
28
|
case 'choose':
|
|
29
29
|
ext.add('option');
|
|
@@ -42,15 +42,23 @@ class ExtToken extends attributeParent(TagPairToken) {
|
|
|
42
42
|
innerToken = new Token(inner, newConfig, false, accum);
|
|
43
43
|
break;
|
|
44
44
|
}
|
|
45
|
+
case 'gallery': {
|
|
46
|
+
ext.delete(lcName);
|
|
47
|
+
newConfig.ext = [...ext];
|
|
48
|
+
const GalleryToken = require('../gallery');
|
|
49
|
+
acceptable = {AttributeToken: 0, GalleryToken: 1};
|
|
50
|
+
innerToken = new GalleryToken(inner, newConfig, accum);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
45
53
|
/*
|
|
46
54
|
* 更多定制扩展的代码示例:
|
|
47
55
|
* ```
|
|
48
56
|
* case 'extensionName': {
|
|
49
|
-
* ext.delete(
|
|
57
|
+
* ext.delete(lcName);
|
|
50
58
|
* newConfig.ext = [...ext];
|
|
51
59
|
* const ExtensionToken = require('../extension');
|
|
52
60
|
* acceptable = {AttributeToken: 0, ExtensionToken: 1};
|
|
53
|
-
* innerToken = new ExtensionToken(
|
|
61
|
+
* innerToken = new ExtensionToken(inner, newConfig, accum);
|
|
54
62
|
* break;
|
|
55
63
|
* }
|
|
56
64
|
* ```
|
|
@@ -79,6 +87,10 @@ class ExtToken extends attributeParent(TagPairToken) {
|
|
|
79
87
|
token.lastElementChild.safeReplaceWith(inner);
|
|
80
88
|
return token;
|
|
81
89
|
}
|
|
90
|
+
|
|
91
|
+
get innerText() {
|
|
92
|
+
return this.selfClosing ? '' : this.lastElementChild.text();
|
|
93
|
+
}
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
Parser.classes.ExtToken = __filename;
|
package/src/tagPair/index.js
CHANGED
|
@@ -21,7 +21,7 @@ class TagPairToken extends fixedToken(Token) {
|
|
|
21
21
|
* @param {accum} accum
|
|
22
22
|
*/
|
|
23
23
|
constructor(name, attr, inner, closing, config = Parser.getConfig(), accum = []) {
|
|
24
|
-
super(undefined, config);
|
|
24
|
+
super(undefined, config, true);
|
|
25
25
|
this.setAttribute('name', name.toLowerCase()).#tags = [name, closing || name];
|
|
26
26
|
this.selfClosing = closing === undefined;
|
|
27
27
|
this.closed = closing !== '';
|
|
@@ -76,15 +76,6 @@ class TagPairToken extends fixedToken(Token) {
|
|
|
76
76
|
? `<${opening}${typeof firstChild === 'string' ? firstChild : firstChild.text()}/>`
|
|
77
77
|
: `<${opening}${super.text('>')}${closed ? `</${closing}>` : ''}`;
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
/** @returns {[number, string][]} */
|
|
81
|
-
plain() {
|
|
82
|
-
const {lastChild} = this;
|
|
83
|
-
if (typeof lastChild === 'string') {
|
|
84
|
-
return lastChild ? [[this.getAbsoluteIndex() + this.getRelativeIndex(1), lastChild]] : [];
|
|
85
|
-
}
|
|
86
|
-
return lastChild.plain();
|
|
87
|
-
}
|
|
88
79
|
}
|
|
89
80
|
|
|
90
81
|
Parser.classes.TagPairToken = __filename;
|
package/src/transclude.js
CHANGED
package/util/string.js
CHANGED
|
@@ -21,7 +21,7 @@ const escapeRegExp = str => str.replace(/[\\{}()|.?*+\-^$[\]]/g, '\\$&');
|
|
|
21
21
|
|
|
22
22
|
/** @param {(string|AstNode)[]} childNodes */
|
|
23
23
|
const text = (childNodes, separator = '') => {
|
|
24
|
-
const AstNode = require('../lib/node');
|
|
24
|
+
const AstNode = require('../lib/node');
|
|
25
25
|
return childNodes.map(child => typeof child === 'string' ? child : child.text()).join(separator);
|
|
26
26
|
};
|
|
27
27
|
|
|
@@ -62,7 +62,7 @@ const noWrap = str => str.replaceAll('\n', '\\n');
|
|
|
62
62
|
* @returns {string}
|
|
63
63
|
*/
|
|
64
64
|
const normalizeSpace = (token = '', separator = '') => {
|
|
65
|
-
const Token = require('../src');
|
|
65
|
+
const Token = require('../src');
|
|
66
66
|
return typeof token === 'string'
|
|
67
67
|
? token.replaceAll('\n', ' ')
|
|
68
68
|
: token.childNodes.map(child => typeof child === 'string' ? normalizeSpace(child) : child.toString())
|