wikiparser-node 1.13.7 → 1.13.9
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/bundle/bundle.min.js +29 -29
- package/config/default.json +63 -2
- package/config/enwiki.json +2 -0
- package/config/minimum.json +37 -3
- package/config/moegirl.json +0 -1
- package/config/zhwiki.json +2 -0
- package/dist/base.d.ts +1 -0
- package/dist/lib/text.js +17 -13
- package/dist/parser/braces.js +2 -2
- package/dist/parser/commentAndExt.js +14 -9
- package/dist/parser/hrAndDoubleUnderscore.js +5 -3
- package/dist/parser/html.js +4 -2
- package/dist/parser/table.js +9 -5
- package/dist/src/arg.js +1 -1
- package/dist/src/attribute.js +2 -7
- package/dist/src/attributes.js +1 -1
- package/dist/src/converterFlags.js +1 -1
- package/dist/src/html.js +1 -1
- package/dist/src/imageParameter.js +1 -1
- package/dist/src/link/base.js +1 -0
- package/dist/src/link/file.js +1 -1
- package/dist/src/link/redirectTarget.js +1 -1
- package/dist/src/nowiki/comment.js +1 -1
- package/dist/src/nowiki/index.js +1 -1
- package/dist/src/parameter.js +1 -1
- package/dist/src/table/td.js +1 -0
- package/dist/src/transclude.js +1 -0
- package/extensions/dist/base.js +1 -1
- package/extensions/dist/codejar.js +1 -1
- package/extensions/dist/lint.js +2 -2
- package/package.json +3 -3
package/config/default.json
CHANGED
|
@@ -134,6 +134,8 @@
|
|
|
134
134
|
"103": "WikiProject talk",
|
|
135
135
|
"118": "Draft",
|
|
136
136
|
"119": "Draft talk",
|
|
137
|
+
"126": "MOS",
|
|
138
|
+
"127": "MOS talk",
|
|
137
139
|
"274": "Widget",
|
|
138
140
|
"275": "Widget talk",
|
|
139
141
|
"710": "TimedText",
|
|
@@ -279,6 +281,42 @@
|
|
|
279
281
|
"分類討論": 15,
|
|
280
282
|
"category‐ノート": 15,
|
|
281
283
|
"カテゴリ・トーク": 15,
|
|
284
|
+
"p": 100,
|
|
285
|
+
"portal": 100,
|
|
286
|
+
"主题": 100,
|
|
287
|
+
"主題": 100,
|
|
288
|
+
"portal talk": 101,
|
|
289
|
+
"主题对话": 101,
|
|
290
|
+
"主题讨论": 101,
|
|
291
|
+
"主題對話": 101,
|
|
292
|
+
"主題討論": 101,
|
|
293
|
+
"pj": 102,
|
|
294
|
+
"wpj": 102,
|
|
295
|
+
"wikiproject": 102,
|
|
296
|
+
"专题": 102,
|
|
297
|
+
"專題": 102,
|
|
298
|
+
"維基專題": 102,
|
|
299
|
+
"维基专题": 102,
|
|
300
|
+
"pjt": 103,
|
|
301
|
+
"wpjt": 103,
|
|
302
|
+
"wikiproject talk": 103,
|
|
303
|
+
"专题对话": 103,
|
|
304
|
+
"专题讨论": 103,
|
|
305
|
+
"專題對話": 103,
|
|
306
|
+
"專題討論": 103,
|
|
307
|
+
"維基專題對話": 103,
|
|
308
|
+
"維基專題討論": 103,
|
|
309
|
+
"维基专题对话": 103,
|
|
310
|
+
"维基专题讨论": 103,
|
|
311
|
+
"draft": 118,
|
|
312
|
+
"草稿": 118,
|
|
313
|
+
"draft talk": 119,
|
|
314
|
+
"草稿讨论": 119,
|
|
315
|
+
"草稿討論": 119,
|
|
316
|
+
"mos": 126,
|
|
317
|
+
"mos talk": 127,
|
|
318
|
+
"timedtext": 710,
|
|
319
|
+
"timedtext talk": 711,
|
|
282
320
|
"widget": 274,
|
|
283
321
|
"widget talk": 275,
|
|
284
322
|
"module": 828,
|
|
@@ -296,7 +334,10 @@
|
|
|
296
334
|
"模組討論": 829,
|
|
297
335
|
"模组对话": 829,
|
|
298
336
|
"模组讨论": 829,
|
|
299
|
-
"モジュール・トーク": 829
|
|
337
|
+
"モジュール・トーク": 829,
|
|
338
|
+
"topic": 2600,
|
|
339
|
+
"話題": 2600,
|
|
340
|
+
"话题": 2600
|
|
300
341
|
},
|
|
301
342
|
"parserFunction": [
|
|
302
343
|
{
|
|
@@ -698,6 +739,8 @@
|
|
|
698
739
|
"#FORMAL",
|
|
699
740
|
"#bcp47",
|
|
700
741
|
"#dir",
|
|
742
|
+
"#interwikilink",
|
|
743
|
+
"#interlanguagelink",
|
|
701
744
|
"#timef",
|
|
702
745
|
"#timefl"
|
|
703
746
|
],
|
|
@@ -775,26 +818,31 @@
|
|
|
775
818
|
"thumbnail": "thumbnail",
|
|
776
819
|
"thumb": "thumbnail",
|
|
777
820
|
"缩略图": "thumbnail",
|
|
821
|
+
"縮圖": "thumbnail",
|
|
778
822
|
"thumbnail=$1": "manualthumb",
|
|
779
823
|
"thumb=$1": "manualthumb",
|
|
780
824
|
"缩略图=$1": "manualthumb",
|
|
825
|
+
"縮圖=$1": "manualthumb",
|
|
781
826
|
"left": "left",
|
|
782
827
|
"左": "left",
|
|
783
828
|
"right": "right",
|
|
784
829
|
"右": "right",
|
|
785
830
|
"none": "none",
|
|
786
831
|
"无": "none",
|
|
832
|
+
"無": "none",
|
|
787
833
|
"$1px": "width",
|
|
788
834
|
"$1像素": "width",
|
|
789
835
|
"center": "center",
|
|
790
836
|
"centre": "center",
|
|
791
837
|
"居中": "center",
|
|
838
|
+
"置中": "center",
|
|
792
839
|
"framed": "framed",
|
|
793
840
|
"enframed": "framed",
|
|
794
841
|
"frame": "framed",
|
|
795
842
|
"有框": "framed",
|
|
796
843
|
"frameless": "frameless",
|
|
797
844
|
"无框": "frameless",
|
|
845
|
+
"無框": "frameless",
|
|
798
846
|
"upright": "upright",
|
|
799
847
|
"右上": "upright",
|
|
800
848
|
"upright=$1": "manual-upright",
|
|
@@ -803,36 +851,49 @@
|
|
|
803
851
|
"右上$1": "manual-upright",
|
|
804
852
|
"border": "border",
|
|
805
853
|
"边框": "border",
|
|
854
|
+
"邊框": "border",
|
|
806
855
|
"alt=$1": "alt",
|
|
807
856
|
"替代=$1": "alt",
|
|
808
857
|
"替代文本=$1": "alt",
|
|
809
858
|
"class=$1": "class",
|
|
810
859
|
"类=$1": "class",
|
|
860
|
+
"類別=$1": "class",
|
|
811
861
|
"link=$1": "link",
|
|
812
862
|
"链接=$1": "link",
|
|
863
|
+
"連結=$1": "link",
|
|
813
864
|
"baseline": "baseline",
|
|
814
865
|
"基线": "baseline",
|
|
815
866
|
"sub": "sub",
|
|
816
867
|
"子": "sub",
|
|
868
|
+
"下標": "sub",
|
|
817
869
|
"super": "super",
|
|
818
870
|
"sup": "super",
|
|
819
871
|
"超": "super",
|
|
872
|
+
"上標": "super",
|
|
820
873
|
"top": "top",
|
|
821
874
|
"顶部": "top",
|
|
875
|
+
"垂直置頂": "top",
|
|
822
876
|
"text-top": "text-top",
|
|
823
877
|
"文字顶部": "text-top",
|
|
878
|
+
"文字置頂": "text-top",
|
|
824
879
|
"middle": "middle",
|
|
825
880
|
"中间": "middle",
|
|
881
|
+
"垂直置中": "middle",
|
|
826
882
|
"bottom": "bottom",
|
|
827
883
|
"底部": "bottom",
|
|
884
|
+
"垂直置底": "bottom",
|
|
828
885
|
"text-bottom": "text-bottom",
|
|
829
886
|
"文字底部": "text-bottom",
|
|
887
|
+
"文字置底": "text-bottom",
|
|
830
888
|
"lang=$1": "lang",
|
|
831
889
|
"语言=$1": "lang",
|
|
890
|
+
"語言=$1": "lang",
|
|
832
891
|
"page=$1": "page",
|
|
833
892
|
"page $1": "page",
|
|
834
893
|
"页数=$1": "page",
|
|
835
|
-
"$1页": "page"
|
|
894
|
+
"$1页": "page",
|
|
895
|
+
"頁=$1": "page",
|
|
896
|
+
"$1頁": "page"
|
|
836
897
|
},
|
|
837
898
|
"redirection": [
|
|
838
899
|
"#redirect",
|
package/config/enwiki.json
CHANGED
package/config/minimum.json
CHANGED
|
@@ -73,11 +73,15 @@
|
|
|
73
73
|
"0": "",
|
|
74
74
|
"6": "File",
|
|
75
75
|
"10": "Template",
|
|
76
|
+
"14": "Category",
|
|
76
77
|
"828": "Module"
|
|
77
78
|
},
|
|
78
79
|
"nsid": {
|
|
80
|
+
"": 0,
|
|
79
81
|
"file": 6,
|
|
80
|
-
"
|
|
82
|
+
"template": 10,
|
|
83
|
+
"category": 14,
|
|
84
|
+
"module": 828
|
|
81
85
|
},
|
|
82
86
|
"parserFunction": [
|
|
83
87
|
{
|
|
@@ -113,14 +117,44 @@
|
|
|
113
117
|
"#vardefine": "vardefine",
|
|
114
118
|
"#vardefineecho": "vardefineecho",
|
|
115
119
|
"#widget": "widget",
|
|
116
|
-
"#regex": "regex",
|
|
117
120
|
"#related": "related",
|
|
118
|
-
"#cscore": "cscore"
|
|
121
|
+
"#cscore": "cscore",
|
|
122
|
+
"#regex": "regex",
|
|
123
|
+
"#regex_var": "regex_var",
|
|
124
|
+
"#regexquote": "regexquote",
|
|
125
|
+
"#regexall": "regexall",
|
|
126
|
+
"#len": "len",
|
|
127
|
+
"#pos": "pos",
|
|
128
|
+
"#rpos": "rpos",
|
|
129
|
+
"#sub": "sub",
|
|
130
|
+
"#count": "count",
|
|
131
|
+
"#replace": "replace",
|
|
132
|
+
"#explode": "explode",
|
|
133
|
+
"#tab": "tab",
|
|
134
|
+
"#seo": "seo",
|
|
135
|
+
"#babel": "babel",
|
|
136
|
+
"#commaseparatedlist": "commaseparatedlist",
|
|
137
|
+
"#coordinates": "coordinates",
|
|
138
|
+
"#lst": "lst",
|
|
139
|
+
"#lsth": "lsth",
|
|
140
|
+
"#lstx": "lstx",
|
|
141
|
+
"#assessment": "assessment",
|
|
142
|
+
"#mentor": "mentor",
|
|
143
|
+
"#property": "property",
|
|
144
|
+
"#target": "target",
|
|
145
|
+
"#section": "section",
|
|
146
|
+
"#section-x": "section-x",
|
|
147
|
+
"#section-h": "section-h",
|
|
148
|
+
"#statements": "statements"
|
|
119
149
|
},
|
|
120
150
|
[
|
|
121
151
|
"!",
|
|
122
152
|
"=",
|
|
123
153
|
"#FORMAL",
|
|
154
|
+
"#bcp47",
|
|
155
|
+
"#dir",
|
|
156
|
+
"#interwikilink",
|
|
157
|
+
"#interlanguagelink",
|
|
124
158
|
"#timef",
|
|
125
159
|
"#timefl"
|
|
126
160
|
],
|
package/config/moegirl.json
CHANGED
package/config/zhwiki.json
CHANGED
package/dist/base.d.ts
CHANGED
package/dist/lib/text.js
CHANGED
|
@@ -13,7 +13,7 @@ const html_1 = require("../util/html");
|
|
|
13
13
|
/<\s*(?:\/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])|((?:^|\])[^[]*?)\]+|https?[:/]\/+/giu;
|
|
14
14
|
/^https?:\/\/(?:\[[\da-f:.]+\]|[^[\]<>"\t\n\p{Zs}])[^[\]<>"\t\n\p{Zs}]*\.(?:gif|png|jpg|jpeg)$/iu;
|
|
15
15
|
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
16
|
-
const source = String.raw `<\s*(?:/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])|((?:^|\])[^[]*?)\]
|
|
16
|
+
const sp = String.raw `[\p{Zs}\t]*`, source = String.raw `<\s*(?:/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])|((?:^|\])[^[]*?)\]+|(?:rfc|pmid)(?=[-::]?${sp}\d)|isbn(?=[-::]?${sp}(?:\d(?:${sp}|-)){6})`, errorSyntax = new RegExp(String.raw `${source}|https?[:/]/+`, 'giu'), errorSyntaxUrl = new RegExp(source, 'giu'), extImage = new RegExp(String.raw `^https?://${string_1.extUrlCharFirst}${string_1.extUrlChar}\.(?:gif|png|jpg|jpeg)$`, 'iu'), noLinkTypes = new Set(['attr-value', 'ext-link-text', 'link-text']), regexes = {
|
|
17
17
|
'[': /[[\]]/u,
|
|
18
18
|
'{': /[{}]/u,
|
|
19
19
|
']': /[[\]](?=[^[\]]*$)/u,
|
|
@@ -25,6 +25,9 @@ const source = String.raw `<\s*(?:/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])
|
|
|
25
25
|
']': 'lonely-bracket',
|
|
26
26
|
'}': 'lonely-bracket',
|
|
27
27
|
h: 'lonely-http',
|
|
28
|
+
r: 'lonely-http',
|
|
29
|
+
p: 'lonely-http',
|
|
30
|
+
i: 'lonely-http',
|
|
28
31
|
}, disallowedTags = [
|
|
29
32
|
'html',
|
|
30
33
|
'base',
|
|
@@ -148,28 +151,26 @@ class AstText extends node_1.AstNode {
|
|
|
148
151
|
const errors = [], nextType = nextSibling?.type, nextName = nextSibling?.name, previousType = previousSibling?.type, root = this.getRootNode(), { ext, html } = root.getAttribute('config'), { top, left } = root.posFromIndex(start), tags = new Set(['onlyinclude', 'noinclude', 'includeonly', ext, html, disallowedTags].flat(2));
|
|
149
152
|
for (let mt = errorRegex.exec(data); mt; mt = errorRegex.exec(data)) {
|
|
150
153
|
const [, tag, prefix] = mt;
|
|
151
|
-
let {
|
|
154
|
+
let { index } = mt, error = mt[0].toLowerCase();
|
|
152
155
|
if (prefix && prefix !== ']') {
|
|
153
156
|
const { length } = prefix;
|
|
154
157
|
index += length;
|
|
155
158
|
error = error.slice(length);
|
|
156
159
|
}
|
|
157
|
-
const { 0: char, length } = error;
|
|
160
|
+
const { 0: char, length } = error, magicLink = char === 'r' || char === 'p' || char === 'i';
|
|
158
161
|
if (char === '<' && !tags.has(tag.toLowerCase())
|
|
159
|
-
|| char === '['
|
|
160
|
-
&&
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
|| char === '[' && type === 'ext-link-text' && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
|
|
163
|
+
|| nextSibling?.is('ext') && nextName === 'nowiki' && nextSibling.innerText?.includes(']'))
|
|
164
|
+
|| char === 'h' && index === 0 && type === 'ext-link-text' && extImage.test(data)
|
|
165
|
+
|| magicLink && (!parentNode.getAttribute('plain') || noLinkTypes.has(type))) {
|
|
163
166
|
continue;
|
|
164
167
|
}
|
|
165
168
|
else if (char === ']' && (index || length > 1)) {
|
|
166
169
|
errorRegex.lastIndex--;
|
|
167
170
|
}
|
|
168
|
-
else if (char === 'h' && index === 0 && type === 'ext-link-text' && extImage.test(data)) {
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
171
|
const startIndex = start + index, endIndex = startIndex + length, rootStr = root.toString(), nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], severity = length > 1 && !(char === '<' && !/[\s/>]/u.test(nextChar ?? '')
|
|
172
|
-
|| isHtmlAttrVal && (char === '[' || char === ']')
|
|
172
|
+
|| isHtmlAttrVal && (char === '[' || char === ']')
|
|
173
|
+
|| magicLink && type === 'parameter-value')
|
|
173
174
|
|| char === '{' && (nextChar === char || previousChar === '-')
|
|
174
175
|
|| char === '}' && (previousChar === char || nextChar === '-')
|
|
175
176
|
|| char === '[' && (nextChar === char
|
|
@@ -197,9 +198,12 @@ class AstText extends node_1.AstNode {
|
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
200
|
}
|
|
201
|
+
if (magicLink) {
|
|
202
|
+
error = error.toUpperCase();
|
|
203
|
+
}
|
|
200
204
|
const lines = data.slice(0, index).split('\n'), startLine = lines.length + top - 1, line = lines[lines.length - 1], startCol = lines.length === 1 ? left + line.length : line.length, e = {
|
|
201
205
|
rule: ruleMap[char],
|
|
202
|
-
message: index_1.default.msg('lonely "$1"', char === 'h' ? error : char),
|
|
206
|
+
message: index_1.default.msg('lonely "$1"', magicLink || char === 'h' ? error : char),
|
|
203
207
|
severity,
|
|
204
208
|
startIndex,
|
|
205
209
|
endIndex,
|
|
@@ -240,7 +244,7 @@ class AstText extends node_1.AstNode {
|
|
|
240
244
|
}
|
|
241
245
|
else if (char === ']' && previousType === 'free-ext-link' && severity === 'error') {
|
|
242
246
|
const i = start - previousSibling.toString().length;
|
|
243
|
-
e.fix = { range: [i, i], text: '[' };
|
|
247
|
+
e.fix = { range: [i, i], text: '[', desc: 'left bracket' };
|
|
244
248
|
}
|
|
245
249
|
errors.push(e);
|
|
246
250
|
}
|
package/dist/parser/braces.js
CHANGED
|
@@ -15,7 +15,7 @@ const closes = {
|
|
|
15
15
|
'{': String.raw `\}{2,}|\|`,
|
|
16
16
|
'-': String.raw `\}-`,
|
|
17
17
|
'[': String.raw `\]\]`,
|
|
18
|
-
}, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~'], ['server', 'm']]), re = /\{\{\s*([^\s\0<>[\]{}|_#&%:.]+)\s*\}\}(?!\})/gu;
|
|
18
|
+
}, openBraces = String.raw `|\{{2,}`, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~'], ['server', 'm']]), re = /\{\{\s*([^\s\0<>[\]{}|_#&%:.]+)\s*\}\}(?!\})/gu;
|
|
19
19
|
/**
|
|
20
20
|
* 解析花括号
|
|
21
21
|
* @param wikitext
|
|
@@ -24,7 +24,7 @@ const closes = {
|
|
|
24
24
|
* @throws TranscludeToken.constructor()
|
|
25
25
|
*/
|
|
26
26
|
const parseBraces = (wikitext, config, accum) => {
|
|
27
|
-
const source = String.raw `${config.excludes?.includes('heading') ? '' : String.raw `^((?:\0\d+[cno]\x7F)*)={1,6}|`}\[\[|-\{(?!\{)`,
|
|
27
|
+
const source = String.raw `${config.excludes?.includes('heading') ? '' : String.raw `^((?:\0\d+[cno]\x7F)*)={1,6}|`}\[\[|-\{(?!\{)`, { parserFunction: [, , , subst] } = config, stack = [];
|
|
28
28
|
wikitext = wikitext.replace(re, (m, p1) => {
|
|
29
29
|
// @ts-expect-error abstract class
|
|
30
30
|
new transclude_1.TranscludeToken(m.slice(2, -2), [], config, accum);
|
|
@@ -9,6 +9,15 @@ const comment_1 = require("../src/nowiki/comment");
|
|
|
9
9
|
/* NOT FOR BROWSER */
|
|
10
10
|
const constants_1 = require("../util/constants");
|
|
11
11
|
/* NOT FOR BROWSER END */
|
|
12
|
+
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft;
|
|
13
|
+
/**
|
|
14
|
+
* 更新`<onlyinclude>`和`</onlyinclude>`的位置
|
|
15
|
+
* @param wikitext
|
|
16
|
+
*/
|
|
17
|
+
const update = (wikitext) => {
|
|
18
|
+
const i = wikitext.indexOf(onlyincludeLeft);
|
|
19
|
+
return { i, j: wikitext.indexOf(onlyincludeRight, i + length) };
|
|
20
|
+
};
|
|
12
21
|
/**
|
|
13
22
|
* 解析HTML注释和扩展标签
|
|
14
23
|
* @param wikitext
|
|
@@ -17,14 +26,8 @@ const constants_1 = require("../util/constants");
|
|
|
17
26
|
* @param includeOnly 是否嵌入
|
|
18
27
|
*/
|
|
19
28
|
const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
|
|
20
|
-
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft;
|
|
21
|
-
/** 更新`<onlyinclude>`和`</onlyinclude>`的位置 */
|
|
22
|
-
const update = () => {
|
|
23
|
-
const i = wikitext.indexOf(onlyincludeLeft);
|
|
24
|
-
return { i, j: wikitext.indexOf(onlyincludeRight, i + length) };
|
|
25
|
-
};
|
|
26
29
|
if (includeOnly) {
|
|
27
|
-
let { i, j } = update();
|
|
30
|
+
let { i, j } = update(wikitext);
|
|
28
31
|
if (i !== -1 && j !== -1) { // `<onlyinclude>`拥有最高优先级
|
|
29
32
|
let str = '';
|
|
30
33
|
/**
|
|
@@ -44,7 +47,7 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
|
|
|
44
47
|
}
|
|
45
48
|
str += token;
|
|
46
49
|
wikitext = wikitext.slice(j + length + 1);
|
|
47
|
-
({ i, j } = update());
|
|
50
|
+
({ i, j } = update(wikitext));
|
|
48
51
|
}
|
|
49
52
|
if (wikitext) {
|
|
50
53
|
noinclude(wikitext);
|
|
@@ -54,7 +57,9 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
|
|
|
54
57
|
}
|
|
55
58
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
56
59
|
/<!--.*?(?:-->|$)|<foo(?:\s[^>]*)?\/?>|<\/foo\s*>|<(bar)(\s[^>]*?)?(?:\/>|>(.*?)<\/(\1\s*)>)|<(baz)(\s[^>]*?)?(?:\/>|>(.*?)(?:<\/(baz\s*)>|$))/gisu;
|
|
57
|
-
const ext = config.ext.join('|'), noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly',
|
|
60
|
+
const ext = config.ext.join('|'), noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly',
|
|
61
|
+
/** Never cached due to the possibility of nested extension tags */
|
|
62
|
+
regex = new RegExp(String.raw `<!--.*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext})(\s[^>]*?)?(?:/>|>(.*?)</(\1\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>(.*?)(?:</(${includeRegex}\s*)>|$))`, 'gisu');
|
|
58
63
|
return wikitext.replace(regex, (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
|
|
59
64
|
const l = accum.length;
|
|
60
65
|
let ch = 'n';
|
|
@@ -14,7 +14,9 @@ const constants_1 = require("../util/constants");
|
|
|
14
14
|
* @param accum
|
|
15
15
|
*/
|
|
16
16
|
const parseHrAndDoubleUnderscore = ({ firstChild: { data }, type, name }, config, accum) => {
|
|
17
|
-
const { doubleUnderscore
|
|
17
|
+
const { doubleUnderscore: [insensitive, sensitive, aliases] } = config;
|
|
18
|
+
config.insensitiveDoubleUnderscore ??= new Set(insensitive);
|
|
19
|
+
config.sensitiveDoubleUnderscore ??= new Set(sensitive);
|
|
18
20
|
config.regexHrAndDoubleUnderscore ??= new RegExp(`__(${[...insensitive, ...sensitive].join('|')})__`, 'giu');
|
|
19
21
|
if (type !== 'root' && (type !== 'ext-inner' || name !== 'poem')) {
|
|
20
22
|
data = `\0${data}`;
|
|
@@ -26,11 +28,11 @@ const parseHrAndDoubleUnderscore = ({ firstChild: { data }, type, name }, config
|
|
|
26
28
|
new hr_1.HrToken(m, config, accum);
|
|
27
29
|
return `${lead}\0${accum.length - 1}r\x7F`;
|
|
28
30
|
}).replace(config.regexHrAndDoubleUnderscore, (m, p1) => {
|
|
29
|
-
const caseSensitive =
|
|
31
|
+
const caseSensitive = config.sensitiveDoubleUnderscore.has(p1), lc = p1.toLowerCase(), caseInsensitive = config.insensitiveDoubleUnderscore.has(lc);
|
|
30
32
|
if (caseSensitive || caseInsensitive) {
|
|
31
33
|
// @ts-expect-error abstract class
|
|
32
34
|
new doubleUnderscore_1.DoubleUnderscoreToken(p1, caseSensitive, config, accum);
|
|
33
|
-
return `\0${accum.length - 1}${caseInsensitive && (
|
|
35
|
+
return `\0${accum.length - 1}${caseInsensitive && (aliases?.[lc] ?? lc) === 'toc' ? 'u' : 'n'}\x7F`;
|
|
34
36
|
}
|
|
35
37
|
return m;
|
|
36
38
|
}).replace(/^((?:\0\d+[cn]\x7F)*)(={1,6})(.+)\2((?:\s|\0\d+[cn]\x7F)*)$/gmu, (_, lead, equals, heading, trail) => {
|
package/dist/parser/html.js
CHANGED
|
@@ -6,6 +6,7 @@ const html_1 = require("../src/html");
|
|
|
6
6
|
/* NOT FOR BROWSER */
|
|
7
7
|
const constants_1 = require("../util/constants");
|
|
8
8
|
/* NOT FOR BROWSER END */
|
|
9
|
+
const regex = /^(\/?)([a-z][^\s/>]*)((?:\s|\/(?!>))[^>]*?)?(\/?>)([^<]*)$/iu;
|
|
9
10
|
/**
|
|
10
11
|
* 解析HTML标签
|
|
11
12
|
* @param wikitext
|
|
@@ -13,11 +14,12 @@ const constants_1 = require("../util/constants");
|
|
|
13
14
|
* @param accum
|
|
14
15
|
*/
|
|
15
16
|
const parseHtml = (wikitext, config, accum) => {
|
|
16
|
-
|
|
17
|
+
config.htmlElements ??= new Set(config.html.flat());
|
|
18
|
+
const bits = wikitext.split('<');
|
|
17
19
|
let text = bits.shift();
|
|
18
20
|
for (const x of bits) {
|
|
19
21
|
const mt = regex.exec(x), t = mt?.[2], name = t?.toLowerCase();
|
|
20
|
-
if (!mt || !
|
|
22
|
+
if (!mt || !config.htmlElements.has(name)) {
|
|
21
23
|
text += `<${x}`;
|
|
22
24
|
continue;
|
|
23
25
|
}
|
package/dist/parser/table.js
CHANGED
|
@@ -14,6 +14,12 @@ const constants_1 = require("../util/constants");
|
|
|
14
14
|
* @param token 表格节点
|
|
15
15
|
*/
|
|
16
16
|
const isTr = (token) => token.lastChild.constructor !== index_1.Token;
|
|
17
|
+
/**
|
|
18
|
+
* 取出最近的表格行
|
|
19
|
+
* @param top 当前解析的表格或表格行
|
|
20
|
+
* @param stack 表格栈
|
|
21
|
+
*/
|
|
22
|
+
const pop = (top, stack) => top.type === 'td' ? stack.pop() : top;
|
|
17
23
|
/**
|
|
18
24
|
* 解析表格,注意`tr`和`td`包含开头的换行
|
|
19
25
|
* @param {Token & {firstChild: AstText}} root 根节点
|
|
@@ -45,9 +51,7 @@ const parseTable = ({ firstChild: { data }, type, name }, config, accum) => {
|
|
|
45
51
|
else {
|
|
46
52
|
lastChild.setText(lastChild.toString() + str);
|
|
47
53
|
}
|
|
48
|
-
}
|
|
49
|
-
/** 取出最近的表格行 */
|
|
50
|
-
pop = () => top.type === 'td' ? stack.pop() : top;
|
|
54
|
+
};
|
|
51
55
|
for (const outLine of lines) {
|
|
52
56
|
top = stack.pop();
|
|
53
57
|
const [spaces] = /^(?:\s|\0\d+[cno]\x7F)*/u.exec(outLine), line = outLine.slice(spaces.length), matchesStart = /^(:*)((?:\s|\0\d+[cn]\x7F)*)(\{\||\{(?:\0\d+[cn]\x7F)*\0\d+!\x7F|\0\d+\{\x7F)(.*)$/u
|
|
@@ -87,7 +91,7 @@ const parseTable = ({ firstChild: { data }, type, name }, config, accum) => {
|
|
|
87
91
|
push(attr, stack[stack.length - 1]);
|
|
88
92
|
}
|
|
89
93
|
else if (row) {
|
|
90
|
-
top = pop();
|
|
94
|
+
top = pop(top, stack);
|
|
91
95
|
if (top.type === 'tr') {
|
|
92
96
|
top = stack.pop();
|
|
93
97
|
}
|
|
@@ -97,7 +101,7 @@ const parseTable = ({ firstChild: { data }, type, name }, config, accum) => {
|
|
|
97
101
|
top.insertAt(tr);
|
|
98
102
|
}
|
|
99
103
|
else {
|
|
100
|
-
top = pop();
|
|
104
|
+
top = pop(top, stack);
|
|
101
105
|
const regex = cell === '!' ? /!!|(?:\||\0\d+!\x7F){2}|\0\d+\+\x7F/gu : /(?:\||\0\d+!\x7F){2}|\0\d+\+\x7F/gu;
|
|
102
106
|
let mt = regex.exec(attr), lastIndex = 0, lastSyntax = `\n${spaces}${cell}`;
|
|
103
107
|
/**
|
package/dist/src/arg.js
CHANGED
|
@@ -95,7 +95,7 @@ class ArgToken extends index_2.Token {
|
|
|
95
95
|
if (!this.getAttribute('include')) {
|
|
96
96
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'no-arg', 'unexpected template argument');
|
|
97
97
|
if (argDefault) {
|
|
98
|
-
e.fix = { range: [start, e.endIndex], text: argDefault.text() };
|
|
98
|
+
e.fix = { range: [start, e.endIndex], text: argDefault.text(), desc: 'expand' };
|
|
99
99
|
}
|
|
100
100
|
return [e];
|
|
101
101
|
}
|
package/dist/src/attribute.js
CHANGED
|
@@ -180,14 +180,9 @@ let AttributeToken = (() => {
|
|
|
180
180
|
const e = (0, lint_1.generateForChild)(lastChild, rect, 'unclosed-quote', index_1.default.msg('unclosed $1', 'quotes'), 'warning');
|
|
181
181
|
e.startIndex--;
|
|
182
182
|
e.startCol--;
|
|
183
|
-
const fix = { range: [e.endIndex, e.endIndex], text: this.#quotes[0] };
|
|
183
|
+
const fix = { range: [e.endIndex, e.endIndex], text: this.#quotes[0], desc: 'close' };
|
|
184
184
|
if (lastChild.childNodes.some(({ type: t, data }) => t === 'text' && /\s/u.test(data))) {
|
|
185
|
-
e.suggestions = [
|
|
186
|
-
{
|
|
187
|
-
desc: 'close',
|
|
188
|
-
...fix,
|
|
189
|
-
},
|
|
190
|
-
];
|
|
185
|
+
e.suggestions = [fix];
|
|
191
186
|
}
|
|
192
187
|
else {
|
|
193
188
|
e.fix = fix;
|
package/dist/src/attributes.js
CHANGED
|
@@ -169,7 +169,7 @@ class AttributesToken extends index_2.Token {
|
|
|
169
169
|
const errors = super.lint(start, re), { parentNode, childNodes } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start);
|
|
170
170
|
if (parentNode?.type === 'html' && parentNode.closing && this.text().trim()) {
|
|
171
171
|
const e = (0, lint_1.generateForSelf)(this, rect, 'no-ignored', 'attributes of a closing tag');
|
|
172
|
-
e.fix = { range: [start, e.endIndex], text: '' };
|
|
172
|
+
e.fix = { range: [start, e.endIndex], text: '', desc: 'remove' };
|
|
173
173
|
errors.push(e);
|
|
174
174
|
}
|
|
175
175
|
for (const attr of childNodes) {
|
|
@@ -88,7 +88,7 @@ class ConverterFlagsToken extends index_2.Token {
|
|
|
88
88
|
&& (variantFlags.size > 0 || !validFlags.has(flag))) {
|
|
89
89
|
const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', 'invalid conversion flag');
|
|
90
90
|
if (variantFlags.size === 0 && definedFlags.has(flag.toUpperCase())) {
|
|
91
|
-
e.fix = { range: [e.startIndex, e.endIndex], text: flag.toUpperCase() };
|
|
91
|
+
e.fix = { range: [e.startIndex, e.endIndex], text: flag.toUpperCase(), desc: 'uppercase' };
|
|
92
92
|
}
|
|
93
93
|
else {
|
|
94
94
|
e.suggestions = [
|
package/dist/src/html.js
CHANGED
|
@@ -223,7 +223,7 @@ let HtmlToken = (() => {
|
|
|
223
223
|
else if (msg === 'tag that is both closing and self-closing') {
|
|
224
224
|
const { html: [, , voidTags] } = this.getAttribute('config');
|
|
225
225
|
if (voidTags.includes(this.name)) {
|
|
226
|
-
error.fix = { range: [start + 1, start + 2], text: '' };
|
|
226
|
+
error.fix = { range: [start + 1, start + 2], text: '', desc: 'open' };
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
errors.push(error);
|
|
@@ -181,7 +181,7 @@ class ImageParameterToken extends index_2.Token {
|
|
|
181
181
|
const errors = super.lint(start, re), { link, name } = this;
|
|
182
182
|
if (name === 'invalid') {
|
|
183
183
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'invalid-gallery', 'invalid image parameter');
|
|
184
|
-
e.fix = { range: [start - 1, e.endIndex], text: '' };
|
|
184
|
+
e.fix = { range: [start - 1, e.endIndex], text: '', desc: 'remove' };
|
|
185
185
|
errors.push(e);
|
|
186
186
|
}
|
|
187
187
|
else if (typeof link === 'object' && link.encoded) {
|
package/dist/src/link/base.js
CHANGED
package/dist/src/link/file.js
CHANGED
|
@@ -135,7 +135,7 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
135
135
|
if (unscaled) {
|
|
136
136
|
for (const arg of args.filter(({ name }) => name === 'width')) {
|
|
137
137
|
const e = (0, lint_1.generateForChild)(arg, rect, 'invalid-gallery', 'invalid image parameter');
|
|
138
|
-
e.fix = { range: [e.startIndex - 1, e.endIndex], text: '' };
|
|
138
|
+
e.fix = { range: [e.startIndex - 1, e.endIndex], text: '', desc: 'remove' };
|
|
139
139
|
errors.push(e);
|
|
140
140
|
}
|
|
141
141
|
}
|
|
@@ -50,7 +50,7 @@ class RedirectTargetToken extends base_1.LinkBaseToken {
|
|
|
50
50
|
const e = (0, lint_1.generateForChild)(this.lastChild, { start }, 'no-ignored', 'useless link text');
|
|
51
51
|
e.startIndex--;
|
|
52
52
|
e.startCol--;
|
|
53
|
-
e.fix = { range: [e.startIndex, e.endIndex], text: '' };
|
|
53
|
+
e.fix = { range: [e.startIndex, e.endIndex], text: '', desc: 'remove' };
|
|
54
54
|
errors.push(e);
|
|
55
55
|
}
|
|
56
56
|
return errors;
|
|
@@ -87,7 +87,7 @@ let CommentToken = (() => {
|
|
|
87
87
|
return [];
|
|
88
88
|
}
|
|
89
89
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'unclosed-comment', index_1.default.msg('unclosed $1', 'HTML comment'));
|
|
90
|
-
e.fix = { range: [e.endIndex, e.endIndex], text: '-->' };
|
|
90
|
+
e.fix = { range: [e.endIndex, e.endIndex], text: '-->', desc: 'close' };
|
|
91
91
|
return [e];
|
|
92
92
|
}
|
|
93
93
|
/** @private */
|
package/dist/src/nowiki/index.js
CHANGED
|
@@ -18,7 +18,7 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
18
18
|
const { name, firstChild: { data } } = this;
|
|
19
19
|
if ((name === 'templatestyles' || name === 'section') && data) {
|
|
20
20
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'void-ext', index_1.default.msg('nothing should be in <$1>', name));
|
|
21
|
-
e.fix = { range: [start, e.endIndex], text: '' };
|
|
21
|
+
e.fix = { range: [start, e.endIndex], text: '', desc: 'empty' };
|
|
22
22
|
return [e];
|
|
23
23
|
}
|
|
24
24
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
package/dist/src/parameter.js
CHANGED
|
@@ -176,7 +176,7 @@ let ParameterToken = (() => {
|
|
|
176
176
|
e.startCol = e.endCol;
|
|
177
177
|
e.endIndex++;
|
|
178
178
|
e.endCol++;
|
|
179
|
-
e.fix = { range: [e.startIndex, e.endIndex], text: '{{=}}' };
|
|
179
|
+
e.fix = { range: [e.startIndex, e.endIndex], text: '{{=}}', desc: 'escape' };
|
|
180
180
|
errors.push(e);
|
|
181
181
|
}
|
|
182
182
|
return errors;
|
package/dist/src/table/td.js
CHANGED
package/dist/src/transclude.js
CHANGED