wikilint 2.3.3 → 2.3.5
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/dist/lib/element.js +3 -5
- package/dist/parser/braces.js +9 -2
- package/dist/parser/commentAndExt.js +18 -10
- package/dist/parser/list.js +11 -4
- package/dist/parser/table.js +28 -20
- package/dist/src/attributes.js +9 -3
- package/dist/src/imageParameter.js +0 -1
- package/dist/src/imagemap.js +2 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +4 -1
- package/dist/src/magicLink.js +1 -1
- package/dist/src/table/trBase.js +2 -5
- package/dist/src/transclude.d.ts +0 -1
- package/dist/src/transclude.js +13 -5
- package/dist/util/debug.js +22 -1
- package/dist/util/lint.js +12 -28
- package/dist/util/string.js +12 -22
- package/package.json +1 -1
package/dist/lib/element.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AstElement = void 0;
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
|
+
const debug_1 = require("../util/debug");
|
|
5
6
|
const node_1 = require("./node");
|
|
6
7
|
/** 类似HTMLElement */
|
|
7
8
|
class AstElement extends node_1.AstNode {
|
|
@@ -38,8 +39,7 @@ class AstElement extends node_1.AstNode {
|
|
|
38
39
|
* @param i 移除位置
|
|
39
40
|
*/
|
|
40
41
|
removeAt(i) {
|
|
41
|
-
|
|
42
|
-
return node;
|
|
42
|
+
return (0, debug_1.setChildNodes)(this, i, 1)[0];
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
45
|
* 插入子节点
|
|
@@ -47,9 +47,7 @@ class AstElement extends node_1.AstNode {
|
|
|
47
47
|
* @param i 插入位置
|
|
48
48
|
*/
|
|
49
49
|
insertAt(node, i = this.length) {
|
|
50
|
-
|
|
51
|
-
node.setAttribute('parentNode', this);
|
|
52
|
-
childNodes.splice(i, 0, node);
|
|
50
|
+
(0, debug_1.setChildNodes)(this, i, 0, [node]);
|
|
53
51
|
return node;
|
|
54
52
|
}
|
|
55
53
|
/**
|
package/dist/parser/braces.js
CHANGED
|
@@ -24,6 +24,13 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
|
24
24
|
mt.index += length;
|
|
25
25
|
}
|
|
26
26
|
const { 0: syntax, index: curIndex } = mt ?? { 0: '\n', index: wikitext.length }, top = stack.pop() ?? {}, { 0: open, index, parts, findEqual: topFindEqual, pos: topPos } = top, innerEqual = syntax === '=' && topFindEqual;
|
|
27
|
+
/**
|
|
28
|
+
* 填入模板内容
|
|
29
|
+
* @param text wikitext全文
|
|
30
|
+
*/
|
|
31
|
+
const push = (text) => {
|
|
32
|
+
parts.at(-1).push(text.slice(topPos, curIndex));
|
|
33
|
+
};
|
|
27
34
|
if (syntax === ']]' || syntax === '}-') { // 情形1:闭合内链或转换
|
|
28
35
|
lastIndex = curIndex + 2;
|
|
29
36
|
}
|
|
@@ -42,7 +49,7 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
|
42
49
|
}
|
|
43
50
|
else if (syntax === '|' || innerEqual) { // 情形3:模板内部,含行首单个'='
|
|
44
51
|
lastIndex = curIndex + 1;
|
|
45
|
-
|
|
52
|
+
push(wikitext);
|
|
46
53
|
if (syntax === '|') {
|
|
47
54
|
parts.push([]);
|
|
48
55
|
}
|
|
@@ -53,7 +60,7 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
|
53
60
|
else if (syntax.startsWith('}}')) { // 情形4:闭合模板
|
|
54
61
|
const close = syntax.slice(0, Math.min(open.length, 3)), rest = open.length - close.length, { length } = accum;
|
|
55
62
|
lastIndex = curIndex + close.length; // 这不是最终的lastIndex
|
|
56
|
-
|
|
63
|
+
push(wikitext);
|
|
57
64
|
let skip = false, ch = 't';
|
|
58
65
|
if (close.length === 3) {
|
|
59
66
|
const argParts = parts.map(part => part.join('=')), str = argParts.length > 1 && (0, string_1.removeComment)(argParts[1]).trim();
|
|
@@ -16,27 +16,35 @@ const comment_1 = require("../src/nowiki/comment");
|
|
|
16
16
|
*/
|
|
17
17
|
const parseCommentAndExt = (wikitext, config = Parser.getConfig(), accum = [], includeOnly = false) => {
|
|
18
18
|
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft;
|
|
19
|
+
/** 更新`<onlyinclude>`和`</onlyinclude>`的位置 */
|
|
20
|
+
const update = () => {
|
|
21
|
+
const i = wikitext.indexOf(onlyincludeLeft);
|
|
22
|
+
return { i, j: wikitext.indexOf(onlyincludeRight, i + length) };
|
|
23
|
+
};
|
|
19
24
|
if (includeOnly) {
|
|
20
|
-
let i
|
|
25
|
+
let { i, j } = update();
|
|
21
26
|
if (i !== -1 && j !== -1) { // `<onlyinclude>`拥有最高优先级
|
|
22
27
|
let str = '';
|
|
28
|
+
/**
|
|
29
|
+
* 忽略未被`<onlyinclude>`和`</onlyinclude>`包裹的内容
|
|
30
|
+
* @param text 未被包裹的内容
|
|
31
|
+
*/
|
|
32
|
+
const noinclude = (text) => {
|
|
33
|
+
new noinclude_1.NoincludeToken(text, config, accum);
|
|
34
|
+
str += `\0${accum.length - 1}c\x7F`;
|
|
35
|
+
};
|
|
23
36
|
while (i !== -1 && j !== -1) {
|
|
24
37
|
const token = `\0${accum.length}e\x7F`;
|
|
25
38
|
new onlyinclude_1.OnlyincludeToken(wikitext.slice(i + length, j), config, accum);
|
|
26
39
|
if (i > 0) {
|
|
27
|
-
|
|
28
|
-
str += `\0${accum.length - 1}c\x7F${token}`;
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
str += token;
|
|
40
|
+
noinclude(wikitext.slice(0, i));
|
|
32
41
|
}
|
|
42
|
+
str += token;
|
|
33
43
|
wikitext = wikitext.slice(j + length + 1);
|
|
34
|
-
i =
|
|
35
|
-
j = wikitext.indexOf(onlyincludeRight, i + length);
|
|
44
|
+
({ i, j } = update());
|
|
36
45
|
}
|
|
37
46
|
if (wikitext) {
|
|
38
|
-
|
|
39
|
-
str += `\0${accum.length - 1}c\x7F`;
|
|
47
|
+
noinclude(wikitext);
|
|
40
48
|
}
|
|
41
49
|
return str;
|
|
42
50
|
}
|
package/dist/parser/list.js
CHANGED
|
@@ -22,17 +22,24 @@ const parseList = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
|
22
22
|
return text;
|
|
23
23
|
}
|
|
24
24
|
let regex = /:+|-\{/gu, ex = regex.exec(text), lc = 0;
|
|
25
|
+
/**
|
|
26
|
+
* 创建`DdToken`
|
|
27
|
+
* @param syntax `:`
|
|
28
|
+
* @param index 起点
|
|
29
|
+
*/
|
|
30
|
+
const dd = (syntax, index) => {
|
|
31
|
+
new dd_1.DdToken(syntax, config, accum);
|
|
32
|
+
return `${text.slice(0, index)}\0${accum.length - 1}d\x7F${text.slice(index + syntax.length)}`;
|
|
33
|
+
};
|
|
25
34
|
while (ex && dt) {
|
|
26
35
|
const { 0: syntax, index } = ex;
|
|
27
36
|
if (syntax.startsWith(':')) {
|
|
28
37
|
if (syntax.length >= dt) {
|
|
29
|
-
|
|
30
|
-
return `${text.slice(0, index)}\0${accum.length - 1}d\x7F${text.slice(index + dt)}`;
|
|
38
|
+
return dd(syntax.slice(0, dt), index);
|
|
31
39
|
}
|
|
32
|
-
text = `${text.slice(0, index)}\0${accum.length}d\x7F${text.slice(regex.lastIndex)}`;
|
|
33
40
|
dt -= syntax.length;
|
|
34
41
|
regex.lastIndex = index + 4 + String(accum.length).length;
|
|
35
|
-
|
|
42
|
+
text = dd(syntax, index);
|
|
36
43
|
}
|
|
37
44
|
else if (syntax === '-{') {
|
|
38
45
|
if (!lc) {
|
package/dist/parser/table.js
CHANGED
|
@@ -7,7 +7,10 @@ const index_2 = require("../src/table/index");
|
|
|
7
7
|
const tr_1 = require("../src/table/tr");
|
|
8
8
|
const td_1 = require("../src/table/td");
|
|
9
9
|
const dd_1 = require("../src/nowiki/dd");
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* 判断是否为表格行或表格
|
|
12
|
+
* @param token 表格节点
|
|
13
|
+
*/
|
|
11
14
|
const isTr = (token) => token.lastChild.constructor !== index_1.Token;
|
|
12
15
|
/**
|
|
13
16
|
* 解析表格,注意`tr`和`td`包含开头的换行
|
|
@@ -19,30 +22,32 @@ const parseTable = ({ firstChild: { data }, type, name }, config = Parser.getCon
|
|
|
19
22
|
const stack = [], lines = data.split('\n');
|
|
20
23
|
let out = type === 'root' || type === 'parameter-value' || type === 'ext-inner' && name === 'poem'
|
|
21
24
|
? ''
|
|
22
|
-
: `\n${lines.shift()}
|
|
25
|
+
: `\n${lines.shift()}`, top;
|
|
23
26
|
/**
|
|
24
27
|
* 向表格中插入纯文本
|
|
25
28
|
* @param str 待插入的文本
|
|
26
|
-
* @param
|
|
29
|
+
* @param topToken 当前解析的表格或表格行
|
|
27
30
|
*/
|
|
28
|
-
const push = (str,
|
|
29
|
-
if (!
|
|
31
|
+
const push = (str, topToken) => {
|
|
32
|
+
if (!topToken) {
|
|
30
33
|
out += str;
|
|
31
34
|
return;
|
|
32
35
|
}
|
|
33
|
-
const { lastChild } =
|
|
34
|
-
if (isTr(
|
|
36
|
+
const { lastChild } = topToken;
|
|
37
|
+
if (isTr(topToken)) {
|
|
35
38
|
const token = new index_1.Token(str, config, accum);
|
|
36
39
|
token.type = 'table-inter';
|
|
37
40
|
token.setAttribute('stage', 3);
|
|
38
|
-
|
|
41
|
+
topToken.insertAt(token);
|
|
39
42
|
}
|
|
40
43
|
else {
|
|
41
44
|
lastChild.setText(String(lastChild) + str);
|
|
42
45
|
}
|
|
43
|
-
}
|
|
46
|
+
},
|
|
47
|
+
/** 取出最近的表格行 */
|
|
48
|
+
pop = () => top.type === 'td' ? stack.pop() : top;
|
|
44
49
|
for (const outLine of lines) {
|
|
45
|
-
|
|
50
|
+
top = stack.pop();
|
|
46
51
|
const [spaces] = /^(?:\s|\0\d+c\x7F)*/u.exec(outLine), line = outLine.slice(spaces.length), matchesStart = /^(:*)((?:\s|\0\d+c\x7F)*)(\{\||\{(?:\0\d+c\x7F)*\0\d+!\x7F|\0\d+\{\x7F)(.*)$/u
|
|
47
52
|
.exec(line);
|
|
48
53
|
if (matchesStart) {
|
|
@@ -78,9 +83,7 @@ const parseTable = ({ firstChild: { data }, type, name }, config = Parser.getCon
|
|
|
78
83
|
push(attr, stack.at(-1));
|
|
79
84
|
}
|
|
80
85
|
else if (row) {
|
|
81
|
-
|
|
82
|
-
top = stack.pop();
|
|
83
|
-
}
|
|
86
|
+
top = pop();
|
|
84
87
|
if (top.type === 'tr') {
|
|
85
88
|
top = stack.pop();
|
|
86
89
|
}
|
|
@@ -89,20 +92,25 @@ const parseTable = ({ firstChild: { data }, type, name }, config = Parser.getCon
|
|
|
89
92
|
top.insertAt(tr);
|
|
90
93
|
}
|
|
91
94
|
else {
|
|
92
|
-
|
|
93
|
-
top = stack.pop();
|
|
94
|
-
}
|
|
95
|
+
top = pop();
|
|
95
96
|
const regex = cell === '!' ? /!!|(?:\||\0\d+!\x7F){2}|\0\d+\+\x7F/gu : /(?:\||\0\d+!\x7F){2}|\0\d+\+\x7F/gu;
|
|
96
97
|
let mt = regex.exec(attr), lastIndex = 0, lastSyntax = `\n${spaces}${cell}`;
|
|
98
|
+
/**
|
|
99
|
+
* 创建表格单元格
|
|
100
|
+
* @param tr 当前表格行
|
|
101
|
+
*/
|
|
102
|
+
const createTd = (tr) => {
|
|
103
|
+
const td = new td_1.TdToken(lastSyntax, attr.slice(lastIndex, mt?.index), config, accum);
|
|
104
|
+
tr.insertAt(td);
|
|
105
|
+
return td;
|
|
106
|
+
};
|
|
97
107
|
while (mt) {
|
|
98
|
-
top
|
|
108
|
+
createTd(top);
|
|
99
109
|
({ lastIndex } = regex);
|
|
100
110
|
[lastSyntax] = mt;
|
|
101
111
|
mt = regex.exec(attr);
|
|
102
112
|
}
|
|
103
|
-
|
|
104
|
-
stack.push(top, td);
|
|
105
|
-
top.insertAt(td);
|
|
113
|
+
stack.push(top, createTd(top));
|
|
106
114
|
}
|
|
107
115
|
}
|
|
108
116
|
return out.slice(1);
|
package/dist/src/attributes.js
CHANGED
|
@@ -7,9 +7,15 @@ const Parser = require("../index");
|
|
|
7
7
|
const index_1 = require("./index");
|
|
8
8
|
const atom_1 = require("./atom");
|
|
9
9
|
const attribute_1 = require("./attribute");
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* 将属性类型转换为单属性类型
|
|
12
|
+
* @param type 属性类型
|
|
13
|
+
*/
|
|
11
14
|
const toAttributeType = (type) => type.slice(0, -1);
|
|
12
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* 将属性类型转换为无效属性类型
|
|
17
|
+
* @param type 属性类型
|
|
18
|
+
*/
|
|
13
19
|
const toDirty = (type) => `${toAttributeType(type)}-dirty`;
|
|
14
20
|
/**
|
|
15
21
|
* 扩展和HTML标签属性
|
|
@@ -26,7 +32,7 @@ class AttributesToken extends index_1.Token {
|
|
|
26
32
|
this.type = type;
|
|
27
33
|
this.setAttribute('name', name);
|
|
28
34
|
if (attr) {
|
|
29
|
-
const regex = new RegExp(
|
|
35
|
+
const regex = new RegExp('([^\\s/](?:(?!\0\\d+~\x7F)[^\\s/=])*)' // 属性名
|
|
30
36
|
+ '(?:'
|
|
31
37
|
+ '((?:\\s|\0\\d+c\x7F)*' // `=`前的空白字符
|
|
32
38
|
+ '(?:=|\0\\d+~\x7F)' // `=`
|
|
@@ -6,7 +6,6 @@ const lint_1 = require("../util/lint");
|
|
|
6
6
|
const Parser = require("../index");
|
|
7
7
|
const index_1 = require("./index");
|
|
8
8
|
exports.galleryParams = new Set(['alt', 'link', 'lang', 'page', 'caption']);
|
|
9
|
-
/** @ignore */
|
|
10
9
|
function validate(key, val, config = Parser.getConfig(), halfParsed = false) {
|
|
11
10
|
val = val.trim();
|
|
12
11
|
let value = val.replace(/\0\d+t\x7F/gu, '').trim();
|
package/dist/src/imagemap.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ImagemapToken = void 0;
|
|
4
4
|
const lint_1 = require("../util/lint");
|
|
5
|
+
const debug_1 = require("../util/debug");
|
|
5
6
|
const Parser = require("../index");
|
|
6
7
|
const index_1 = require("./index");
|
|
7
8
|
const noinclude_1 = require("./nowiki/noinclude");
|
|
@@ -15,7 +16,7 @@ class ImagemapToken extends index_1.Token {
|
|
|
15
16
|
type = 'ext-inner';
|
|
16
17
|
/** 图片 */
|
|
17
18
|
get image() {
|
|
18
|
-
return this.childNodes.find((
|
|
19
|
+
return this.childNodes.find((0, debug_1.isToken)('imagemap-image'));
|
|
19
20
|
}
|
|
20
21
|
/** @param inner 标签内部wikitext */
|
|
21
22
|
constructor(inner, config = Parser.getConfig(), accum = []) {
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -71,6 +71,9 @@ class Token extends element_1.AstElement {
|
|
|
71
71
|
if (n < this.#stage || !this.getAttribute('plain') || this.length === 0) {
|
|
72
72
|
return this;
|
|
73
73
|
}
|
|
74
|
+
else if (this.#stage >= constants_1.MAX_STAGE) {
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
74
77
|
switch (n) {
|
|
75
78
|
case 0:
|
|
76
79
|
if (this.type === 'root') {
|
|
@@ -161,6 +164,7 @@ class Token extends element_1.AstElement {
|
|
|
161
164
|
}
|
|
162
165
|
/** @private */
|
|
163
166
|
parse(n = constants_1.MAX_STAGE, include = false) {
|
|
167
|
+
n = Math.min(n, constants_1.MAX_STAGE);
|
|
164
168
|
while (this.#stage < n) {
|
|
165
169
|
this.parseOnce(this.#stage, include);
|
|
166
170
|
}
|
|
@@ -297,7 +301,6 @@ class Token extends element_1.AstElement {
|
|
|
297
301
|
super.setAttribute(key, value);
|
|
298
302
|
}
|
|
299
303
|
}
|
|
300
|
-
/** @ignore */
|
|
301
304
|
insertAt(child, i = this.length) {
|
|
302
305
|
const token = typeof child === 'string' ? new text_1.AstText(child) : child;
|
|
303
306
|
super.insertAt(token, i);
|
package/dist/src/magicLink.js
CHANGED
|
@@ -29,7 +29,7 @@ class MagicLinkToken extends index_1.Token {
|
|
|
29
29
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
30
30
|
const refError = (0, lint_1.generateForChild)(child, rect, '', 'warning');
|
|
31
31
|
errors.push(...[...data.matchAll(regexGlobal)].map(({ index, 0: s }) => {
|
|
32
|
-
const lines = data.slice(0, index).split('\n'), { length: top } = lines, { length: left } = lines.at(-1), startIndex =
|
|
32
|
+
const lines = data.slice(0, index).split('\n'), { length: top } = lines, { length: left } = lines.at(-1), startIndex = refError.startIndex + index, startLine = refError.startLine + top - 1, startCol = top === 1 ? refError.startCol + left : left;
|
|
33
33
|
return {
|
|
34
34
|
...refError,
|
|
35
35
|
message: Parser.msg('$1 in URL', s.startsWith('|') ? '"|"' : Parser.msg('full-width punctuation')),
|
package/dist/src/table/trBase.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TrBaseToken = void 0;
|
|
4
4
|
const lint_1 = require("../../util/lint");
|
|
5
|
+
const debug_1 = require("../../util/debug");
|
|
5
6
|
const base_1 = require("./base");
|
|
6
7
|
/** 表格行或表格 */
|
|
7
8
|
class TrBaseToken extends base_1.TableBaseToken {
|
|
@@ -11,11 +12,7 @@ class TrBaseToken extends base_1.TableBaseToken {
|
|
|
11
12
|
if (!inter) {
|
|
12
13
|
return errors;
|
|
13
14
|
}
|
|
14
|
-
const first = inter.childNodes.find(child => child.text().trim()), tdPattern = /^\s*(?:!|\{\{\s*![!-]?\s*\}\})/u,
|
|
15
|
-
/** @ignore */
|
|
16
|
-
isArg = (token) => token.type === 'arg',
|
|
17
|
-
/** @ignore */
|
|
18
|
-
isTransclude = (token) => token.type === 'magic-word';
|
|
15
|
+
const first = inter.childNodes.find(child => child.text().trim()), tdPattern = /^\s*(?:!|\{\{\s*![!-]?\s*\}\})/u, isArg = (0, debug_1.isToken)('arg'), isTransclude = (0, debug_1.isToken)('magic-word');
|
|
19
16
|
if (!first
|
|
20
17
|
|| tdPattern.test(String(first))
|
|
21
18
|
|| isArg(first) && tdPattern.test(first.default || '')) {
|
package/dist/src/transclude.d.ts
CHANGED
|
@@ -51,7 +51,6 @@ export declare class TranscludeToken extends Token {
|
|
|
51
51
|
getArgs(key: string | number, exact?: boolean, copy?: boolean): Set<ParameterToken>;
|
|
52
52
|
/**
|
|
53
53
|
* 获取重名参数
|
|
54
|
-
* @throws `Error` 仅用于模板
|
|
55
54
|
*/
|
|
56
55
|
getDuplicatedArgs(): readonly [string, ParameterToken[]][];
|
|
57
56
|
/**
|
package/dist/src/transclude.js
CHANGED
|
@@ -3,11 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TranscludeToken = void 0;
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
5
|
const lint_1 = require("../util/lint");
|
|
6
|
+
const debug_1 = require("../util/debug");
|
|
6
7
|
const Parser = require("../index");
|
|
7
8
|
const index_1 = require("./index");
|
|
8
9
|
const parameter_1 = require("./parameter");
|
|
9
10
|
const atom_1 = require("./atom");
|
|
10
11
|
const syntax_1 = require("./syntax");
|
|
12
|
+
const insensitiveVars = new Set([
|
|
13
|
+
'pageid',
|
|
14
|
+
'articlepath',
|
|
15
|
+
'server',
|
|
16
|
+
'servername',
|
|
17
|
+
'scriptpath',
|
|
18
|
+
'stylepath',
|
|
19
|
+
]);
|
|
11
20
|
/**
|
|
12
21
|
* 模板或魔术字
|
|
13
22
|
* @classdesc `{childNodes: [AtomToken|SyntaxToken, ...AtomToken, ...ParameterToken]}`
|
|
@@ -37,9 +46,9 @@ class TranscludeToken extends index_1.Token {
|
|
|
37
46
|
}
|
|
38
47
|
const isFunction = title.includes(':');
|
|
39
48
|
if (isFunction || parts.length === 0 && !this.#raw) {
|
|
40
|
-
const [magicWord, ...arg] = title.split(':'), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg.length > 0 ? 'trimStart' : 'trim'](), isSensitive = sensitive.includes(name),
|
|
41
|
-
if (
|
|
42
|
-
this.setAttribute('name',
|
|
49
|
+
const [magicWord, ...arg] = title.split(':'), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg.length > 0 ? 'trimStart' : 'trim'](), lcName = name.toLowerCase(), canonicalName = insensitive[lcName], isSensitive = sensitive.includes(name), isVar = isSensitive || insensitiveVars.has(canonicalName);
|
|
50
|
+
if (isVar || isFunction && canonicalName) {
|
|
51
|
+
this.setAttribute('name', canonicalName ?? lcName);
|
|
43
52
|
this.type = 'magic-word';
|
|
44
53
|
const pattern = new RegExp(`^\\s*${name}\\s*$`, isSensitive ? 'u' : 'iu'), token = new syntax_1.SyntaxToken(magicWord, pattern, 'magic-word-name', config, accum, {});
|
|
45
54
|
super.insertAt(token);
|
|
@@ -208,7 +217,7 @@ class TranscludeToken extends index_1.Token {
|
|
|
208
217
|
}
|
|
209
218
|
/** 获取所有参数 */
|
|
210
219
|
getAllArgs() {
|
|
211
|
-
return this.childNodes.filter((
|
|
220
|
+
return this.childNodes.filter((0, debug_1.isToken)('parameter'));
|
|
212
221
|
}
|
|
213
222
|
/** 获取所有匿名参数 */
|
|
214
223
|
getAnonArgs() {
|
|
@@ -234,7 +243,6 @@ class TranscludeToken extends index_1.Token {
|
|
|
234
243
|
}
|
|
235
244
|
/**
|
|
236
245
|
* 获取重名参数
|
|
237
|
-
* @throws `Error` 仅用于模板
|
|
238
246
|
*/
|
|
239
247
|
getDuplicatedArgs() {
|
|
240
248
|
if (this.isTemplate()) {
|
package/dist/util/debug.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Shadow = void 0;
|
|
3
|
+
exports.setChildNodes = exports.isToken = exports.Shadow = void 0;
|
|
4
4
|
exports.Shadow = {
|
|
5
5
|
/** @private */
|
|
6
6
|
run(callback) {
|
|
@@ -8,3 +8,24 @@ exports.Shadow = {
|
|
|
8
8
|
return result;
|
|
9
9
|
},
|
|
10
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* 是否是某一特定类型的节点
|
|
13
|
+
* @param type 节点类型
|
|
14
|
+
*/
|
|
15
|
+
const isToken = (type) => (node) => node.type === type;
|
|
16
|
+
exports.isToken = isToken;
|
|
17
|
+
/**
|
|
18
|
+
* 更新chldNodes
|
|
19
|
+
* @param parent 父节点
|
|
20
|
+
* @param position 子节点位置
|
|
21
|
+
* @param deleteCount 移除的子节点数量
|
|
22
|
+
* @param inserted 插入的子节点
|
|
23
|
+
*/
|
|
24
|
+
const setChildNodes = (parent, position, deleteCount, inserted = []) => {
|
|
25
|
+
const { childNodes } = parent, removed = childNodes.splice(position, deleteCount, ...inserted);
|
|
26
|
+
for (const node of inserted) {
|
|
27
|
+
node.setAttribute('parentNode', parent);
|
|
28
|
+
}
|
|
29
|
+
return removed;
|
|
30
|
+
};
|
|
31
|
+
exports.setChildNodes = setChildNodes;
|
package/dist/util/lint.js
CHANGED
|
@@ -3,44 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateForSelf = exports.generateForChild = void 0;
|
|
4
4
|
const Parser = require("../index");
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* @param
|
|
8
|
-
* @param boundingRect 父节点的绝对定位
|
|
9
|
-
* @param msg 错误信息
|
|
10
|
-
* @param severity 严重程度
|
|
6
|
+
* 生成lint函数
|
|
7
|
+
* @param func lint函数
|
|
11
8
|
*/
|
|
12
|
-
const
|
|
13
|
-
const
|
|
9
|
+
const factory = (func) => (token, boundingRect, msg, severity = 'error') => {
|
|
10
|
+
const { start } = boundingRect, { top, left } = 'top' in boundingRect ? boundingRect : token.getRootNode().posFromIndex(start), { offsetHeight, offsetWidth } = token, { startIndex, startLine, startCol } = func(token, start, top, left);
|
|
14
11
|
return {
|
|
15
12
|
message: Parser.msg(msg),
|
|
16
13
|
severity,
|
|
17
14
|
startIndex,
|
|
18
|
-
endIndex: startIndex + String(
|
|
15
|
+
endIndex: startIndex + String(token).length,
|
|
19
16
|
startLine,
|
|
20
17
|
endLine: startLine + offsetHeight - 1,
|
|
21
18
|
startCol,
|
|
22
19
|
endCol: offsetHeight === 1 ? startCol + offsetWidth : offsetWidth,
|
|
23
20
|
};
|
|
24
21
|
};
|
|
25
|
-
exports.generateForChild =
|
|
26
|
-
|
|
27
|
-
* 生成对于自己的LintError对象
|
|
28
|
-
* @param token 节点
|
|
29
|
-
* @param boundingRect 绝对定位
|
|
30
|
-
* @param msg 错误信息
|
|
31
|
-
* @param severity 严重程度
|
|
32
|
-
*/
|
|
33
|
-
const generateForSelf = (token, boundingRect, msg, severity = 'error') => {
|
|
34
|
-
const { start } = boundingRect, { offsetHeight, offsetWidth } = token, { top, left } = 'top' in boundingRect ? boundingRect : token.getRootNode().posFromIndex(start);
|
|
22
|
+
exports.generateForChild = factory((child, start, line, col) => {
|
|
23
|
+
const index = child.getRelativeIndex(), { top, left } = child.parentNode.posFromIndex(index);
|
|
35
24
|
return {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
endIndex: start + String(token).length,
|
|
40
|
-
startLine: top,
|
|
41
|
-
endLine: top + offsetHeight - 1,
|
|
42
|
-
startCol: left,
|
|
43
|
-
endCol: offsetHeight === 1 ? left + offsetWidth : offsetWidth,
|
|
25
|
+
startIndex: start + index,
|
|
26
|
+
startLine: line + top,
|
|
27
|
+
startCol: top ? left : col + left,
|
|
44
28
|
};
|
|
45
|
-
};
|
|
46
|
-
exports.generateForSelf =
|
|
29
|
+
});
|
|
30
|
+
exports.generateForSelf = factory((_, startIndex, startLine, startCol) => ({ startIndex, startLine, startCol }));
|
package/dist/util/string.js
CHANGED
|
@@ -4,17 +4,15 @@ exports.noWrap = exports.decodeHtml = exports.text = exports.escapeRegExp = expo
|
|
|
4
4
|
exports.extUrlCharFirst = '(?:\\[[\\da-f:.]+\\]|[^[\\]<>"\\0-\\x1F\\x7F\\p{Zs}\\uFFFD])';
|
|
5
5
|
exports.extUrlChar = '(?:[^[\\]<>"\\0-\\x1F\\x7F\\p{Zs}\\uFFFD]|\\0\\d+[c!~]\\x7F)*';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @param
|
|
7
|
+
* 生成正则替换函数
|
|
8
|
+
* @param regex 正则表达式
|
|
9
|
+
* @param replace 替换字符串或函数
|
|
9
10
|
*/
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
const escapeRegExp = (str) => str.replace(/[\\{}()|.?*+^$[\]]/gu, '\\$&');
|
|
17
|
-
exports.escapeRegExp = escapeRegExp;
|
|
11
|
+
const factory = (regex, replace) => (str) => str.replace(regex, replace);
|
|
12
|
+
/** remove half-parsed comment-like tokens */
|
|
13
|
+
exports.removeComment = factory(/\0\d+c\x7F/gu, '');
|
|
14
|
+
/** escape special chars for RegExp constructor */
|
|
15
|
+
exports.escapeRegExp = factory(/[\\{}()|.?*+^$[\]]/gu, '\\$&');
|
|
18
16
|
/**
|
|
19
17
|
* extract effective wikitext
|
|
20
18
|
* @param childNodes a Token's contents
|
|
@@ -22,15 +20,7 @@ exports.escapeRegExp = escapeRegExp;
|
|
|
22
20
|
*/
|
|
23
21
|
const text = (childNodes, separator = '') => childNodes.map(child => typeof child === 'string' ? child : child.text()).join(separator);
|
|
24
22
|
exports.text = text;
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const decodeHtml = (str) => str.replace(/&#(\d+|x[\da-f]+);/giu, (_, code) => String.fromCodePoint(Number(`${code.toLowerCase().startsWith('x') ? '0' : ''}${code}`)));
|
|
30
|
-
exports.decodeHtml = decodeHtml;
|
|
31
|
-
/**
|
|
32
|
-
* escape newlines
|
|
33
|
-
* @param str 原字符串
|
|
34
|
-
*/
|
|
35
|
-
const noWrap = (str) => str.replaceAll('\n', '\\n');
|
|
36
|
-
exports.noWrap = noWrap;
|
|
23
|
+
/** decode HTML entities */
|
|
24
|
+
exports.decodeHtml = factory(/&#(\d+|x[\da-f]+);/giu, (_, code) => String.fromCodePoint(Number(`${code.toLowerCase().startsWith('x') ? '0' : ''}${code}`)));
|
|
25
|
+
/** escape newlines */
|
|
26
|
+
exports.noWrap = factory(/\n/gu, '\\n');
|