wikilint 2.3.5 → 2.3.8
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 +7 -3
- package/dist/lib/node.js +5 -11
- package/dist/lib/text.js +28 -19
- package/dist/lib/title.js +1 -1
- package/dist/mixin/hidden.js +0 -1
- package/dist/parser/braces.js +5 -5
- package/dist/parser/commentAndExt.js +11 -3
- package/dist/parser/converter.js +4 -4
- package/dist/parser/externalLinks.js +4 -1
- package/dist/parser/magicLinks.js +6 -4
- package/dist/parser/quotes.js +1 -1
- package/dist/parser/table.js +1 -1
- package/dist/src/attribute.js +10 -3
- package/dist/src/attributes.js +6 -7
- package/dist/src/html.d.ts +1 -1
- package/dist/src/html.js +1 -1
- package/dist/src/imageParameter.js +2 -0
- package/dist/src/imagemap.js +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +4 -7
- package/dist/src/link/base.js +1 -1
- package/dist/src/magicLink.js +6 -5
- package/dist/src/nested.js +2 -2
- package/dist/src/nowiki/quote.js +1 -1
- package/dist/src/parameter.js +3 -1
- package/dist/src/table/td.js +8 -4
- package/dist/src/tagPair/ext.d.ts +1 -0
- package/dist/src/tagPair/ext.js +1 -3
- package/dist/src/tagPair/index.d.ts +2 -2
- package/dist/src/tagPair/index.js +7 -11
- package/dist/src/transclude.d.ts +1 -1
- package/dist/src/transclude.js +5 -9
- package/dist/util/constants.js +6 -1
- package/dist/util/debug.js +2 -1
- package/dist/util/string.js +2 -2
- package/package.json +7 -5
package/dist/lib/element.js
CHANGED
|
@@ -19,7 +19,7 @@ class AstElement extends node_1.AstNode {
|
|
|
19
19
|
}
|
|
20
20
|
/** 合并相邻的文本子节点 */
|
|
21
21
|
normalize() {
|
|
22
|
-
const
|
|
22
|
+
const childNodes = [...this.childNodes];
|
|
23
23
|
for (let i = childNodes.length - 1; i >= 0; i--) {
|
|
24
24
|
const { type, data } = childNodes[i], prev = childNodes[i - 1];
|
|
25
25
|
if (type !== 'text' || this.getGaps(i - 1)) {
|
|
@@ -33,6 +33,7 @@ class AstElement extends node_1.AstNode {
|
|
|
33
33
|
childNodes.splice(i, 1);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
this.setAttribute('childNodes', childNodes);
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
39
|
* 移除子节点
|
|
@@ -81,7 +82,9 @@ class AstElement extends node_1.AstNode {
|
|
|
81
82
|
* @param elements 新的子节点
|
|
82
83
|
*/
|
|
83
84
|
replaceChildren(...elements) {
|
|
84
|
-
this.
|
|
85
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
86
|
+
this.removeAt(i);
|
|
87
|
+
}
|
|
85
88
|
this.append(...elements);
|
|
86
89
|
}
|
|
87
90
|
/**
|
|
@@ -90,7 +93,8 @@ class AstElement extends node_1.AstNode {
|
|
|
90
93
|
* @param i 子节点位置
|
|
91
94
|
*/
|
|
92
95
|
setText(str, i = 0) {
|
|
93
|
-
|
|
96
|
+
i += i < 0 ? this.length : 0;
|
|
97
|
+
const oldText = this.childNodes[i];
|
|
94
98
|
const { data } = oldText;
|
|
95
99
|
oldText.replaceData(str);
|
|
96
100
|
return data;
|
package/dist/lib/node.js
CHANGED
|
@@ -11,7 +11,7 @@ class AstNode {
|
|
|
11
11
|
}
|
|
12
12
|
/** 末位子节点 */
|
|
13
13
|
get lastChild() {
|
|
14
|
-
return this.childNodes.
|
|
14
|
+
return this.childNodes[this.childNodes.length - 1];
|
|
15
15
|
}
|
|
16
16
|
/** 父节点 */
|
|
17
17
|
get parentNode() {
|
|
@@ -68,21 +68,15 @@ class AstNode {
|
|
|
68
68
|
posFromIndex(index) {
|
|
69
69
|
const str = String(this);
|
|
70
70
|
if (index >= -str.length && index <= str.length) {
|
|
71
|
-
const lines = str.slice(0, index).split('\n');
|
|
72
|
-
return {
|
|
73
|
-
top: lines.length - 1,
|
|
74
|
-
left: lines.at(-1).length,
|
|
75
|
-
};
|
|
71
|
+
const lines = str.slice(0, index).split('\n'), top = lines.length - 1;
|
|
72
|
+
return { top, left: lines[top].length };
|
|
76
73
|
}
|
|
77
74
|
return undefined;
|
|
78
75
|
}
|
|
79
76
|
/** 获取行数和最后一行的列数 */
|
|
80
77
|
#getDimension() {
|
|
81
|
-
const lines = String(this).split('\n');
|
|
82
|
-
return {
|
|
83
|
-
height: lines.length,
|
|
84
|
-
width: lines.at(-1).length,
|
|
85
|
-
};
|
|
78
|
+
const lines = String(this).split('\n'), height = lines.length;
|
|
79
|
+
return { height, width: lines[height - 1].length };
|
|
86
80
|
}
|
|
87
81
|
/** @private */
|
|
88
82
|
getGaps(i) {
|
package/dist/lib/text.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AstText = void 0;
|
|
4
4
|
const Parser = require("../index");
|
|
5
5
|
const node_1 = require("./node");
|
|
6
|
-
const errorSyntax = /<\s*\/?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*\])|(
|
|
6
|
+
const errorSyntax = /<\s*\/?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*\])|((?:^|\])[^[]*?)\]+|https?[:/]\/+/giu, errorSyntaxUrl = /<\s*\/?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*\])|((?:^|\])[^[]*?)\]+/giu, disallowedTags = [
|
|
7
7
|
'html',
|
|
8
8
|
'head',
|
|
9
9
|
'style',
|
|
@@ -37,7 +37,11 @@ class AstText extends node_1.AstNode {
|
|
|
37
37
|
/** @param text 包含文本 */
|
|
38
38
|
constructor(text) {
|
|
39
39
|
super();
|
|
40
|
-
this
|
|
40
|
+
Object.defineProperties(this, {
|
|
41
|
+
data: {
|
|
42
|
+
value: text,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
41
45
|
}
|
|
42
46
|
/** @private */
|
|
43
47
|
toString() {
|
|
@@ -68,17 +72,19 @@ class AstText extends node_1.AstNode {
|
|
|
68
72
|
else {
|
|
69
73
|
errorRegex = errorSyntax;
|
|
70
74
|
}
|
|
71
|
-
const errors = [
|
|
72
|
-
if (
|
|
75
|
+
const errors = [], { ext, html } = this.getRootNode().getAttribute('config');
|
|
76
|
+
if (data.search(errorRegex) !== -1) {
|
|
77
|
+
errorRegex.lastIndex = 0;
|
|
73
78
|
const root = this.getRootNode(), { top, left } = root.posFromIndex(start), tags = new Set(['onlyinclude', 'noinclude', 'includeonly', ext, html, disallowedTags].flat(2));
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
for (let mt = errorRegex.exec(data); mt; mt = errorRegex.exec(data)) {
|
|
80
|
+
const [, tag, prefix] = mt;
|
|
81
|
+
let { 0: error, index } = mt;
|
|
82
|
+
if (prefix && prefix !== ']') {
|
|
77
83
|
const { length } = prefix;
|
|
78
84
|
index += length;
|
|
79
85
|
error = error.slice(length);
|
|
80
86
|
}
|
|
81
|
-
const startIndex = start + index, lines = data.slice(0, index).split('\n'), startLine = lines.length + top - 1, line = lines.
|
|
87
|
+
const startIndex = start + index, 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, { 0: char, length } = error, endIndex = startIndex + length, rootStr = String(root), nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], severity = length > 1 && (char !== '<' || /[\s/>]/u.test(nextChar ?? ''))
|
|
82
88
|
|| char === '{' && (nextChar === char || previousChar === '-')
|
|
83
89
|
|| char === '}' && (previousChar === char || nextChar === '-')
|
|
84
90
|
|| char === '[' && (nextChar === char
|
|
@@ -88,17 +94,20 @@ class AstText extends node_1.AstNode {
|
|
|
88
94
|
|| !data.slice(0, index).trim() && previousType === 'free-ext-link')
|
|
89
95
|
? 'error'
|
|
90
96
|
: 'warning';
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
if (char !== '<' || tags.has(tag.toLowerCase())) {
|
|
98
|
+
errors.push({
|
|
99
|
+
message: Parser.msg('lonely "$1"', char === 'h' ? error : char),
|
|
100
|
+
severity,
|
|
101
|
+
startIndex,
|
|
102
|
+
endIndex,
|
|
103
|
+
startLine,
|
|
104
|
+
endLine: startLine,
|
|
105
|
+
startCol,
|
|
106
|
+
endCol: startCol + length,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return errors;
|
|
102
111
|
}
|
|
103
112
|
return [];
|
|
104
113
|
}
|
package/dist/lib/title.js
CHANGED
package/dist/mixin/hidden.js
CHANGED
package/dist/parser/braces.js
CHANGED
|
@@ -17,7 +17,7 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
|
17
17
|
const source = `${config.excludes?.includes('heading') ? '' : '^(\0\\d+c\x7F)*={1,6}|'}\\[\\[|\\{{2,}|-\\{(?!\\{)`, { parserFunction: [, , , subst] } = config, stack = [], closes = { '=': '\n', '{': '\\}{2,}|\\|', '-': '\\}-', '[': '\\]\\]' }, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~']]);
|
|
18
18
|
let regex = new RegExp(source, 'gmu'), mt = regex.exec(wikitext), moreBraces = wikitext.includes('}}'), lastIndex;
|
|
19
19
|
while (mt
|
|
20
|
-
|| lastIndex !== undefined && lastIndex <= wikitext.length && stack.
|
|
20
|
+
|| lastIndex !== undefined && lastIndex <= wikitext.length && stack[stack.length - 1]?.[0]?.startsWith('=')) {
|
|
21
21
|
if (mt?.[1]) {
|
|
22
22
|
const [, { length }] = mt;
|
|
23
23
|
mt[0] = mt[0].slice(length);
|
|
@@ -29,14 +29,14 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
|
29
29
|
* @param text wikitext全文
|
|
30
30
|
*/
|
|
31
31
|
const push = (text) => {
|
|
32
|
-
parts.
|
|
32
|
+
parts[parts.length - 1].push(text.slice(topPos, curIndex));
|
|
33
33
|
};
|
|
34
34
|
if (syntax === ']]' || syntax === '}-') { // 情形1:闭合内链或转换
|
|
35
35
|
lastIndex = curIndex + 2;
|
|
36
36
|
}
|
|
37
37
|
else if (syntax === '\n') { // 情形2:闭合标题或文末
|
|
38
38
|
lastIndex = curIndex + 1;
|
|
39
|
-
const { pos, findEqual } = stack.
|
|
39
|
+
const { pos, findEqual } = stack[stack.length - 1] ?? {};
|
|
40
40
|
if (pos === undefined || findEqual || (0, string_1.removeComment)(wikitext.slice(pos, index)) !== '') {
|
|
41
41
|
const rmt = /^(={1,6})(.+)\1((?:\s|\0\d+c\x7F)*)$/u
|
|
42
42
|
.exec(wikitext.slice(index, curIndex));
|
|
@@ -112,10 +112,10 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
|
112
112
|
stack.push(...'0' in top ? [top] : [], mt);
|
|
113
113
|
}
|
|
114
114
|
moreBraces &&= wikitext.slice(lastIndex).includes('}}');
|
|
115
|
-
let curTop = stack.
|
|
115
|
+
let curTop = stack[stack.length - 1];
|
|
116
116
|
if (!moreBraces && curTop?.[0]?.startsWith('{')) {
|
|
117
117
|
stack.pop();
|
|
118
|
-
curTop = stack.
|
|
118
|
+
curTop = stack[stack.length - 1];
|
|
119
119
|
}
|
|
120
120
|
regex = new RegExp(source + (curTop ? `|${closes[curTop[0][0]]}${curTop.findEqual ? '|=' : ''}` : ''), 'gmu');
|
|
121
121
|
regex.lastIndex = lastIndex;
|
|
@@ -49,9 +49,17 @@ const parseCommentAndExt = (wikitext, config = Parser.getConfig(), accum = [], i
|
|
|
49
49
|
return str;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
53
|
+
/<foo(?:\s[^>]*)?>|<\/foo\s*>/giu;
|
|
54
|
+
/<(bar)(\s[^>]*?)?(?:\/>|>(.*?)<\/(\1\s*)>)/gisu;
|
|
55
|
+
/<(baz)(\s[^>]*?)?(?:\/>|>(.*?)(?:<\/(baz\s*)>|$))/gisu;
|
|
56
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
57
|
+
const ext = config.ext.join('|'), noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly', regex = new RegExp('<!--.*?(?:-->|$)' // comment
|
|
58
|
+
+ '|'
|
|
59
|
+
+ `<${noincludeRegex}(?:\\s[^>]*)?>|</${noincludeRegex}\\s*>` // <noinclude>
|
|
60
|
+
+ '|'
|
|
61
|
+
+ `<(${ext})(\\s[^>]*?)?(?:/>|>(.*?)</(\\1\\s*)>)` // 扩展标签
|
|
62
|
+
+ '|'
|
|
55
63
|
+ `<(${includeRegex})(\\s[^>]*?)?(?:/>|>(.*?)(?:</(${includeRegex}\\s*)>|$))`, // <includeonly>
|
|
56
64
|
'gisu');
|
|
57
65
|
return wikitext.replace(regex, (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
|
package/dist/parser/converter.js
CHANGED
|
@@ -15,10 +15,10 @@ const parseConverter = (text, config = Parser.getConfig(), accum = []) => {
|
|
|
15
15
|
while (mt) {
|
|
16
16
|
const { 0: syntax, index } = mt;
|
|
17
17
|
if (syntax === '}-') {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
temp = raw.replace(/(&[#a-z\d]+);/giu, '$1\x01'), variants = `(?:${config.variants.join('|')})`, rules = temp.split(new RegExp(`;(
|
|
21
|
-
.map(rule => rule.
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
19
|
+
/;(?=(?:[^;]*?=>)?\s*foo\s*:|(?:\s|\0\d+c\x7F)*$)/u;
|
|
20
|
+
const top = stack.pop(), { length } = accum, str = text.slice(top.index + 2, index), i = str.indexOf('|'), [flags, raw] = i === -1 ? [[], str] : [str.slice(0, i).split(';'), str.slice(i + 1)], temp = raw.replace(/(&[#a-z\d]+);/giu, '$1\x01'), variants = `(?:${config.variants.join('|')})`, rules = temp.split(new RegExp(`;(?=(?:[^;]*?=>)?\\s*${variants}\\s*:|(?:\\s|\0\\d+c\x7F)*$)`, 'u'))
|
|
21
|
+
.map(rule => rule.replace(/\x01/gu, ';'));
|
|
22
22
|
new converter_1.ConverterToken(flags, rules, config, accum);
|
|
23
23
|
text = `${text.slice(0, top.index)}\0${length}v\x7F${text.slice(index + 2)}`;
|
|
24
24
|
if (stack.length === 0) {
|
|
@@ -11,7 +11,10 @@ const extLink_1 = require("../src/extLink");
|
|
|
11
11
|
* @param accum
|
|
12
12
|
*/
|
|
13
13
|
const parseExternalLinks = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
14
|
-
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
15
|
+
/\[((?:\[[\da-f:.]+\]|[^[\]\t\n\p{Zs}])[^[\]\t\n\p{Zs}]*(?=[[\]\t\p{Zs}]|\0\d))(\p{Zs}*(?=\P{Zs}))([^\]\n]*)\]/giu;
|
|
16
|
+
const regex = new RegExp(`\\[((?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\\d+m\x7F)${string_1.extUrlChar}(?=[[\\]<>"\\t\\p{Zs}]|\0\\d))`
|
|
17
|
+
+ '(\\p{Zs}*(?=\\P{Zs}))([^\\]\x01-\x08\x0A-\x1F\uFFFD]*)\\]', 'giu');
|
|
15
18
|
return wikitext.replace(regex, (_, url, space, text) => {
|
|
16
19
|
const { length } = accum, mt = /&[lg]t;/u.exec(url);
|
|
17
20
|
if (mt) {
|
|
@@ -11,9 +11,11 @@ const magicLink_1 = require("../src/magicLink");
|
|
|
11
11
|
* @param accum
|
|
12
12
|
*/
|
|
13
13
|
const parseMagicLinks = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
15
|
+
/(^|[^\p{L}\d_])((?:\[[\da-f:.]+\]|[^[\]<>"\t\n\p{Zs}])(?:[^[\]<>"\0\t\n\p{Zs}]|\0\d+c\x7F)*)/giu;
|
|
16
|
+
const regex = new RegExp(`(^|[^\\p{L}\\d_])(?:${config.protocol})(${string_1.extUrlCharFirst}${string_1.extUrlChar})`, 'giu');
|
|
17
|
+
return wikitext.replace(regex, (m, lead, p1) => {
|
|
18
|
+
let trail = '', url = lead ? m.slice(1) : m;
|
|
17
19
|
const m2 = /&(?:lt|gt|nbsp|#x0*(?:3[ce]|a0)|#0*(?:6[02]|160));/iu.exec(url);
|
|
18
20
|
if (m2) {
|
|
19
21
|
trail = url.slice(m2.index);
|
|
@@ -32,7 +34,7 @@ const parseMagicLinks = (wikitext, config = Parser.getConfig(), accum = []) => {
|
|
|
32
34
|
return m;
|
|
33
35
|
}
|
|
34
36
|
new magicLink_1.MagicLinkToken(url, false, config, accum);
|
|
35
|
-
return
|
|
37
|
+
return `${lead}\0${accum.length - 1}w\x7F${trail}`;
|
|
36
38
|
});
|
|
37
39
|
};
|
|
38
40
|
exports.parseMagicLinks = parseMagicLinks;
|
package/dist/parser/quotes.js
CHANGED
package/dist/parser/table.js
CHANGED
|
@@ -80,7 +80,7 @@ const parseTable = ({ firstChild: { data }, type, name }, config = Parser.getCon
|
|
|
80
80
|
top = stack.pop();
|
|
81
81
|
}
|
|
82
82
|
top.close(`\n${spaces}${closing}`, true);
|
|
83
|
-
push(attr, stack.
|
|
83
|
+
push(attr, stack[stack.length - 1]);
|
|
84
84
|
}
|
|
85
85
|
else if (row) {
|
|
86
86
|
top = pop();
|
package/dist/src/attribute.js
CHANGED
|
@@ -112,12 +112,19 @@ const commonHtmlAttrs = new Set([
|
|
|
112
112
|
]),
|
|
113
113
|
tabs: new Set(['plain', 'class', 'container', 'id', 'title', 'style']),
|
|
114
114
|
combobox: new Set(['placeholder', 'value', 'id', 'class', 'text', 'dropdown', 'style']),
|
|
115
|
-
}, insecureStyle = new RegExp(
|
|
115
|
+
}, insecureStyle = new RegExp('expression'
|
|
116
|
+
+ '|'
|
|
117
|
+
+ '(?:filter|accelerator|-o-link(?:-source)?|-o-replace)\\s*:'
|
|
118
|
+
+ '|'
|
|
119
|
+
+ '(?:url|image(?:-set)?)\\s*\\('
|
|
120
|
+
+ '|'
|
|
121
|
+
+ 'attr\\s*\\([^)]+[\\s,]url', 'u');
|
|
116
122
|
/**
|
|
117
123
|
* 扩展和HTML标签属性
|
|
118
124
|
* @classdesc `{childNodes: [AtomToken, Token|AtomToken]}`
|
|
119
125
|
*/
|
|
120
126
|
class AttributeToken extends index_1.Token {
|
|
127
|
+
tag;
|
|
121
128
|
#equal;
|
|
122
129
|
#quotes;
|
|
123
130
|
/** 引号是否匹配 */
|
|
@@ -172,7 +179,7 @@ class AttributeToken extends index_1.Token {
|
|
|
172
179
|
/** @private */
|
|
173
180
|
afterBuild() {
|
|
174
181
|
if (this.#equal.includes('\0')) {
|
|
175
|
-
this.#equal = this.buildFromStr(this.#equal,
|
|
182
|
+
this.#equal = this.buildFromStr(this.#equal, constants_1.BuildMethod.String);
|
|
176
183
|
}
|
|
177
184
|
if (this.parentNode) {
|
|
178
185
|
this.setAttribute('tag', this.parentNode.name);
|
|
@@ -233,7 +240,7 @@ class AttributeToken extends index_1.Token {
|
|
|
233
240
|
if (this.#quotes[1]) {
|
|
234
241
|
return value;
|
|
235
242
|
}
|
|
236
|
-
return this.#quotes[0] ?
|
|
243
|
+
return value[this.#quotes[0] ? 'trimEnd' : 'trim']();
|
|
237
244
|
}
|
|
238
245
|
return this.type === 'ext-attr' || '';
|
|
239
246
|
}
|
package/dist/src/attributes.js
CHANGED
|
@@ -32,13 +32,12 @@ class AttributesToken extends index_1.Token {
|
|
|
32
32
|
this.type = type;
|
|
33
33
|
this.setAttribute('name', name);
|
|
34
34
|
if (attr) {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
36
|
+
/([^\s/](?:(?!\0\d+~\x7F)[^\s/=])*)(?:(\s*(?:=|\0\d+~\x7F)\s*)(?:(["'])(.*?)(\3|$)|(\S*)))?/gsu;
|
|
35
37
|
const regex = new RegExp('([^\\s/](?:(?!\0\\d+~\x7F)[^\\s/=])*)' // 属性名
|
|
36
|
-
+ '(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
+ '(?:\\s|\0\\d+c\x7F)*)' // `=`后的空白字符
|
|
40
|
-
+ `(?:(["'])(.*?)(\\3|$)|(\\S*))` // 属性值
|
|
41
|
-
+ ')?', 'gsu');
|
|
38
|
+
+ `(?:${'((?:\\s|\0\\d+c\x7F)*(?:=|\0\\d+~\x7F)(?:\\s|\0\\d+c\x7F)*)' // `=`和前后的空白字符
|
|
39
|
+
+ `(?:(["'])(.*?)(\\3|$)|(\\S*))` // 属性值
|
|
40
|
+
})?`, 'gsu');
|
|
42
41
|
let out = '', mt = regex.exec(attr), lastIndex = 0;
|
|
43
42
|
const insertDirty = /** 插入无效属性 */ () => {
|
|
44
43
|
if (out) {
|
|
@@ -84,7 +83,7 @@ class AttributesToken extends index_1.Token {
|
|
|
84
83
|
*/
|
|
85
84
|
getAttrToken(key) {
|
|
86
85
|
const tokens = this.getAttrTokens(key);
|
|
87
|
-
return tokens.
|
|
86
|
+
return tokens[tokens.length - 1];
|
|
88
87
|
}
|
|
89
88
|
/**
|
|
90
89
|
* 获取指定属性
|
package/dist/src/html.d.ts
CHANGED
package/dist/src/html.js
CHANGED
|
@@ -92,7 +92,7 @@ class HtmlToken extends index_1.Token {
|
|
|
92
92
|
* 搜索匹配的标签
|
|
93
93
|
* @throws `SyntaxError` 同时闭合和自封闭的标签
|
|
94
94
|
* @throws `SyntaxError` 无效自封闭标签
|
|
95
|
-
* @throws `SyntaxError`
|
|
95
|
+
* @throws `SyntaxError` 未匹配的标签
|
|
96
96
|
*/
|
|
97
97
|
findMatchingTag() {
|
|
98
98
|
const { html } = this.getAttribute('config'), { name: tagName, parentNode, closing } = this, string = (0, string_1.noWrap)(String(this));
|
|
@@ -16,6 +16,8 @@ function validate(key, val, config = Parser.getConfig(), halfParsed = false) {
|
|
|
16
16
|
if (!value) {
|
|
17
17
|
return val;
|
|
18
18
|
}
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
20
|
+
/^(?:\/\/(?:\[[\da-f:.]+\]|[^[\]<>"\t\n\p{Zs}])|\0\d+m\x7F)(?:[^[\]<>"\0\t\n\p{Zs}]|\0\d+c\x7F)*$/iu;
|
|
19
21
|
const regex = new RegExp(`^(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\\d+m\x7F)${string_1.extUrlChar}$`, 'iu');
|
|
20
22
|
if (regex.test(value)) {
|
|
21
23
|
return val;
|
package/dist/src/imagemap.js
CHANGED
|
@@ -59,7 +59,7 @@ class ImagemapToken extends index_1.Token {
|
|
|
59
59
|
}
|
|
60
60
|
else if (protocols.has(substr.slice(1, substr.indexOf(':') + 1))
|
|
61
61
|
|| protocols.has(substr.slice(1, substr.indexOf('//') + 2))) {
|
|
62
|
-
const mtEx = /^\[([^\]\s]+)(?:(\s+)(
|
|
62
|
+
const mtEx = /^\[([^\]\s]+)(?:(\s+(?=\S))([^\]]*))?\][\w\s]*$/u
|
|
63
63
|
.exec(substr);
|
|
64
64
|
if (mtEx) {
|
|
65
65
|
super.insertAt(new imagemapLink_1.ImagemapLinkToken(line.slice(0, i), mtEx.slice(1), substr.slice(substr.indexOf(']') + 1), config, accum));
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -127,15 +127,15 @@ class Token extends element_1.AstElement {
|
|
|
127
127
|
if (i % 2 === 0) {
|
|
128
128
|
return new text_1.AstText(s);
|
|
129
129
|
}
|
|
130
|
-
else if (Number.isNaN(Number(s.
|
|
130
|
+
else if (Number.isNaN(Number(s.slice(-1)))) {
|
|
131
131
|
return this.#accum[Number(s.slice(0, -1))];
|
|
132
132
|
}
|
|
133
133
|
throw new Error(`解析错误!未正确标记的 Token:${s}`);
|
|
134
134
|
});
|
|
135
|
-
if (type ===
|
|
135
|
+
if (type === constants_1.BuildMethod.String) {
|
|
136
136
|
return nodes.map(String).join('');
|
|
137
137
|
}
|
|
138
|
-
else if (type ===
|
|
138
|
+
else if (type === constants_1.BuildMethod.Text) {
|
|
139
139
|
return (0, string_1.text)(nodes);
|
|
140
140
|
}
|
|
141
141
|
return nodes;
|
|
@@ -279,10 +279,7 @@ class Token extends element_1.AstElement {
|
|
|
279
279
|
return this.#include;
|
|
280
280
|
}
|
|
281
281
|
const root = this.getRootNode();
|
|
282
|
-
|
|
283
|
-
return root.getAttribute('include');
|
|
284
|
-
}
|
|
285
|
-
return false;
|
|
282
|
+
return (root !== this && root.getAttribute('include'));
|
|
286
283
|
}
|
|
287
284
|
default:
|
|
288
285
|
return super.getAttribute(key);
|
package/dist/src/link/base.js
CHANGED
|
@@ -34,7 +34,7 @@ class LinkBaseToken extends index_1.Token {
|
|
|
34
34
|
afterBuild() {
|
|
35
35
|
this.#title = this.getTitle();
|
|
36
36
|
if (this.#delimiter.includes('\0')) {
|
|
37
|
-
this.#delimiter = this.buildFromStr(this.#delimiter,
|
|
37
|
+
this.#delimiter = this.buildFromStr(this.#delimiter, constants_1.BuildMethod.String);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
/** @private */
|
package/dist/src/magicLink.js
CHANGED
|
@@ -28,9 +28,10 @@ class MagicLinkToken extends index_1.Token {
|
|
|
28
28
|
}
|
|
29
29
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
30
30
|
const refError = (0, lint_1.generateForChild)(child, rect, '', 'warning');
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
regexGlobal.lastIndex = 0;
|
|
32
|
+
for (let mt = regexGlobal.exec(data); mt; mt = regexGlobal.exec(data)) {
|
|
33
|
+
const { index, 0: s } = mt, lines = data.slice(0, index).split('\n'), { length: top } = lines, { length: left } = lines[lines.length - 1], startIndex = refError.startIndex + index, startLine = refError.startLine + top - 1, startCol = top === 1 ? refError.startCol + left : left;
|
|
34
|
+
errors.push({
|
|
34
35
|
...refError,
|
|
35
36
|
message: Parser.msg('$1 in URL', s.startsWith('|') ? '"|"' : Parser.msg('full-width punctuation')),
|
|
36
37
|
startIndex,
|
|
@@ -39,8 +40,8 @@ class MagicLinkToken extends index_1.Token {
|
|
|
39
40
|
endLine: startLine,
|
|
40
41
|
startCol,
|
|
41
42
|
endCol: startCol + s.length,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
44
45
|
}
|
|
45
46
|
return errors;
|
|
46
47
|
}
|
package/dist/src/nested.js
CHANGED
|
@@ -28,9 +28,9 @@ class NestedToken extends index_1.Token {
|
|
|
28
28
|
new comment_1.CommentToken(comment.slice(4, closed ? -3 : undefined), closed, config, accum);
|
|
29
29
|
}
|
|
30
30
|
return str;
|
|
31
|
-
})?.replace(/(
|
|
31
|
+
})?.replace(/(^|\0\d+[ce]\x7F)([^\0]+)(?=$|\0\d+[ce]\x7F)/gu, (_, lead, substr) => {
|
|
32
32
|
new noinclude_1.NoincludeToken(substr, config, accum);
|
|
33
|
-
return
|
|
33
|
+
return `${lead}\0${accum.length}c\x7F`;
|
|
34
34
|
});
|
|
35
35
|
super(wikitext, config, accum, {});
|
|
36
36
|
}
|
package/dist/src/nowiki/quote.js
CHANGED
|
@@ -14,7 +14,7 @@ class QuoteToken extends base_1.NowikiBaseToken {
|
|
|
14
14
|
let refError;
|
|
15
15
|
if (previousSibling?.type === 'text' && previousSibling.data.endsWith(`'`)) {
|
|
16
16
|
refError = (0, lint_1.generateForSelf)(this, { start }, message);
|
|
17
|
-
const { startIndex: endIndex, startLine: endLine, startCol: endCol } = refError, [{ length }] = /(
|
|
17
|
+
const { startIndex: endIndex, startLine: endLine, startCol: endCol } = refError, [, { length }] = /(?:^|[^'])('+)$/u.exec(previousSibling.data), startIndex = start - length;
|
|
18
18
|
errors.push({
|
|
19
19
|
...refError,
|
|
20
20
|
startIndex,
|
package/dist/src/parameter.js
CHANGED
|
@@ -10,7 +10,7 @@ const index_1 = require("./index");
|
|
|
10
10
|
* @param name 预定的参数名
|
|
11
11
|
*/
|
|
12
12
|
const getName = (name) => name.toString(new Set(['comment', 'noinclude', 'include']))
|
|
13
|
-
.replace(/^[ \t\n\0\v]+|(
|
|
13
|
+
.replace(/^[ \t\n\0\v]+|([^ \t\n\0\v])[ \t\n\0\v]+$/gu, '$1');
|
|
14
14
|
/**
|
|
15
15
|
* 模板或魔术字参数
|
|
16
16
|
* @classdesc `{childNodes: [Token, Token]}`
|
|
@@ -59,6 +59,8 @@ class ParameterToken extends index_1.Token {
|
|
|
59
59
|
}
|
|
60
60
|
/** @override */
|
|
61
61
|
lint(start = this.getAbsoluteIndex()) {
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
63
|
+
/https?:\/\/(?:\[[\da-f:.]+\]|[^[\]<>"\t\n\p{Zs}])(?:[^[\]<>"\0\t\n\p{Zs}]|\0\d+c\x7F)*$/iu;
|
|
62
64
|
const errors = super.lint(start), { firstChild } = this, link = new RegExp(`https?://${string_1.extUrlCharFirst}${string_1.extUrlChar}$`, 'iu')
|
|
63
65
|
.exec(firstChild.toString(new Set(['comment', 'noinclude', 'include'])))?.[0];
|
|
64
66
|
if (link && new URL(link).search) {
|
package/dist/src/table/td.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TdToken = void 0;
|
|
4
4
|
const lint_1 = require("../../util/lint");
|
|
5
|
+
const constants_1 = require("../../util/constants");
|
|
5
6
|
const Parser = require("../../index");
|
|
6
7
|
const index_1 = require("../index");
|
|
7
8
|
const base_1 = require("./base");
|
|
@@ -38,7 +39,7 @@ class TdToken extends base_1.TableBaseToken {
|
|
|
38
39
|
}
|
|
39
40
|
/** 表格语法信息 */
|
|
40
41
|
#getSyntax() {
|
|
41
|
-
const syntax = this.firstChild.text(), char = syntax.
|
|
42
|
+
const syntax = this.firstChild.text(), char = syntax.slice(-1);
|
|
42
43
|
let subtype = 'td';
|
|
43
44
|
if (char === '!') {
|
|
44
45
|
subtype = 'th';
|
|
@@ -51,7 +52,7 @@ class TdToken extends base_1.TableBaseToken {
|
|
|
51
52
|
/** @private */
|
|
52
53
|
afterBuild() {
|
|
53
54
|
if (this.#innerSyntax.includes('\0')) {
|
|
54
|
-
this.#innerSyntax = this.buildFromStr(this.#innerSyntax,
|
|
55
|
+
this.#innerSyntax = this.buildFromStr(this.#innerSyntax, constants_1.BuildMethod.String);
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
/** @private */
|
|
@@ -76,8 +77,11 @@ class TdToken extends base_1.TableBaseToken {
|
|
|
76
77
|
const errors = super.lint(start);
|
|
77
78
|
start += this.getRelativeIndex(this.length - 1);
|
|
78
79
|
for (const child of this.lastChild.childNodes) {
|
|
79
|
-
if (child.type === 'text'
|
|
80
|
-
|
|
80
|
+
if (child.type === 'text') {
|
|
81
|
+
const { data } = child;
|
|
82
|
+
if (data.includes('|')) {
|
|
83
|
+
errors.push((0, lint_1.generateForChild)(child, { start }, 'additional "|" in a table cell', data.includes('||') ? 'error' : 'warning'));
|
|
84
|
+
}
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
return errors;
|
|
@@ -9,6 +9,7 @@ import type { LintError } from '../../base';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare class ExtToken extends TagPairToken {
|
|
11
11
|
readonly type = "ext";
|
|
12
|
+
closed: true;
|
|
12
13
|
readonly childNodes: [AttributesToken, Token];
|
|
13
14
|
abstract get firstChild(): AttributesToken;
|
|
14
15
|
abstract get lastChild(): Token;
|
package/dist/src/tagPair/ext.js
CHANGED
|
@@ -29,9 +29,7 @@ class ExtToken extends index_2.TagPairToken {
|
|
|
29
29
|
* @param closed 是否封闭
|
|
30
30
|
*/
|
|
31
31
|
constructor(name, attr, inner, closed, config = Parser.getConfig(), accum = []) {
|
|
32
|
-
const lcName = name.toLowerCase(), attrToken = new attributes_1.AttributesToken(!attr || attr.trimStart() !== attr
|
|
33
|
-
? attr
|
|
34
|
-
: ` ${attr}`, 'ext-attrs', lcName, config, accum), newConfig = { ...config, ext: del(config.ext, lcName), excludes: [...config.excludes ?? []] };
|
|
32
|
+
const lcName = name.toLowerCase(), attrToken = new attributes_1.AttributesToken(!attr || attr.trimStart() !== attr ? attr : ` ${attr}`, 'ext-attrs', lcName, config, accum), newConfig = { ...config, ext: del(config.ext, lcName), excludes: [...config.excludes ?? []] };
|
|
35
33
|
let innerToken;
|
|
36
34
|
switch (lcName) {
|
|
37
35
|
case 'tab':
|
|
@@ -6,11 +6,11 @@ export declare abstract class TagPairToken extends Token {
|
|
|
6
6
|
#private;
|
|
7
7
|
type: 'ext' | 'include';
|
|
8
8
|
readonly name: string;
|
|
9
|
+
closed: boolean;
|
|
10
|
+
selfClosing: boolean;
|
|
9
11
|
readonly childNodes: [AstNodes, AstNodes];
|
|
10
12
|
abstract get firstChild(): AstNodes;
|
|
11
13
|
abstract get lastChild(): AstNodes;
|
|
12
|
-
/** 是否闭合 */
|
|
13
|
-
get closed(): boolean;
|
|
14
14
|
/**
|
|
15
15
|
* @param name 标签名
|
|
16
16
|
* @param attr 标签属性
|
|
@@ -5,13 +5,9 @@ const Parser = require("../../index");
|
|
|
5
5
|
const index_1 = require("../index");
|
|
6
6
|
/** 成对标签 */
|
|
7
7
|
class TagPairToken extends index_1.Token {
|
|
8
|
-
#selfClosing;
|
|
9
|
-
#closed;
|
|
10
8
|
#tags;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return this.#closed;
|
|
14
|
-
}
|
|
9
|
+
closed;
|
|
10
|
+
selfClosing;
|
|
15
11
|
/**
|
|
16
12
|
* @param name 标签名
|
|
17
13
|
* @param attr 标签属性
|
|
@@ -22,23 +18,23 @@ class TagPairToken extends index_1.Token {
|
|
|
22
18
|
super(undefined, config);
|
|
23
19
|
this.setAttribute('name', name.toLowerCase());
|
|
24
20
|
this.#tags = [name, closed || name];
|
|
25
|
-
this
|
|
26
|
-
this
|
|
21
|
+
this.closed = closed !== '';
|
|
22
|
+
this.selfClosing = closed === undefined;
|
|
27
23
|
this.append(attr, inner);
|
|
28
24
|
const index = typeof attr === 'string' ? -1 : accum.indexOf(attr);
|
|
29
25
|
accum.splice(index === -1 ? Infinity : index, 0, this);
|
|
30
26
|
}
|
|
31
27
|
/** @private */
|
|
32
28
|
toString(omit) {
|
|
33
|
-
const { firstChild, lastChild, } = this, [opening, closing] = this.#tags;
|
|
34
|
-
return
|
|
29
|
+
const { selfClosing, firstChild, lastChild, } = this, [opening, closing] = this.#tags;
|
|
30
|
+
return selfClosing
|
|
35
31
|
? `<${opening}${firstChild.toString(omit)}/>`
|
|
36
32
|
: `<${opening}${firstChild.toString(omit)}>${lastChild.toString(omit)}${this.closed ? `</${closing}>` : ''}`;
|
|
37
33
|
}
|
|
38
34
|
/** @override */
|
|
39
35
|
text() {
|
|
40
36
|
const [opening, closing] = this.#tags;
|
|
41
|
-
return this
|
|
37
|
+
return this.selfClosing
|
|
42
38
|
? `<${opening}${this.firstChild.text()}/>`
|
|
43
39
|
: `<${opening}${super.text('>')}${this.closed ? `</${closing}>` : ''}`;
|
|
44
40
|
}
|
package/dist/src/transclude.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { LintError } from '../base';
|
|
|
11
11
|
export declare class TranscludeToken extends Token {
|
|
12
12
|
#private;
|
|
13
13
|
type: 'template' | 'magic-word';
|
|
14
|
-
readonly modifier
|
|
14
|
+
readonly modifier: string;
|
|
15
15
|
readonly childNodes: [AtomToken | SyntaxToken, ...ParameterToken[]] | [SyntaxToken, AtomToken, AtomToken, ...ParameterToken[]];
|
|
16
16
|
abstract get firstChild(): AtomToken | SyntaxToken;
|
|
17
17
|
abstract get lastChild(): AtomToken | SyntaxToken | ParameterToken;
|
package/dist/src/transclude.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.TranscludeToken = void 0;
|
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
5
|
const lint_1 = require("../util/lint");
|
|
6
6
|
const debug_1 = require("../util/debug");
|
|
7
|
+
const constants_1 = require("../util/constants");
|
|
7
8
|
const Parser = require("../index");
|
|
8
9
|
const index_1 = require("./index");
|
|
9
10
|
const parameter_1 = require("./parameter");
|
|
@@ -117,12 +118,12 @@ class TranscludeToken extends index_1.Token {
|
|
|
117
118
|
/** 获取模板或模块名 */
|
|
118
119
|
#getTitle() {
|
|
119
120
|
const isTemplate = this.type === 'template', child = this.childNodes[isTemplate ? 0 : 1];
|
|
120
|
-
return
|
|
121
|
+
return this.normalizeTitle(child.text(), isTemplate ? 10 : 828);
|
|
121
122
|
}
|
|
122
123
|
/** @private */
|
|
123
124
|
afterBuild() {
|
|
124
125
|
if (this.modifier.includes('\0')) {
|
|
125
|
-
this.setAttribute('modifier', this.buildFromStr(this.modifier,
|
|
126
|
+
this.setAttribute('modifier', this.buildFromStr(this.modifier, constants_1.BuildMethod.String));
|
|
126
127
|
}
|
|
127
128
|
}
|
|
128
129
|
/** @private */
|
|
@@ -161,12 +162,7 @@ class TranscludeToken extends index_1.Token {
|
|
|
161
162
|
return errors;
|
|
162
163
|
}
|
|
163
164
|
const title = this.#getTitle();
|
|
164
|
-
if (
|
|
165
|
-
rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
166
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, 'missing module name'));
|
|
167
|
-
return errors;
|
|
168
|
-
}
|
|
169
|
-
else if (title.fragment !== undefined) {
|
|
165
|
+
if (title.fragment !== undefined) {
|
|
170
166
|
rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
171
167
|
errors.push((0, lint_1.generateForChild)(childNodes[type === 'template' ? 0 : 1], rect, 'useless fragment'));
|
|
172
168
|
}
|
|
@@ -230,7 +226,7 @@ class TranscludeToken extends index_1.Token {
|
|
|
230
226
|
* @param copy 是否返回一个备份
|
|
231
227
|
*/
|
|
232
228
|
getArgs(key, exact = false, copy = true) {
|
|
233
|
-
const keyStr = String(key).replace(/^[ \t\n\0\v]+|(
|
|
229
|
+
const keyStr = String(key).replace(/^[ \t\n\0\v]+|([^ \t\n\0\v])[ \t\n\0\v]+$/gu, '$1');
|
|
234
230
|
let args;
|
|
235
231
|
if (this.#args.has(keyStr)) {
|
|
236
232
|
args = this.#args.get(keyStr);
|
package/dist/util/constants.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MAX_STAGE = void 0;
|
|
3
|
+
exports.BuildMethod = exports.MAX_STAGE = void 0;
|
|
4
4
|
exports.MAX_STAGE = 11;
|
|
5
|
+
var BuildMethod;
|
|
6
|
+
(function (BuildMethod) {
|
|
7
|
+
BuildMethod[BuildMethod["String"] = 0] = "String";
|
|
8
|
+
BuildMethod[BuildMethod["Text"] = 1] = "Text";
|
|
9
|
+
})(BuildMethod || (exports.BuildMethod = BuildMethod = {}));
|
package/dist/util/debug.js
CHANGED
|
@@ -22,7 +22,8 @@ exports.isToken = isToken;
|
|
|
22
22
|
* @param inserted 插入的子节点
|
|
23
23
|
*/
|
|
24
24
|
const setChildNodes = (parent, position, deleteCount, inserted = []) => {
|
|
25
|
-
const
|
|
25
|
+
const childNodes = [...parent.childNodes], removed = childNodes.splice(position, deleteCount, ...inserted);
|
|
26
|
+
parent.setAttribute('childNodes', childNodes);
|
|
26
27
|
for (const node of inserted) {
|
|
27
28
|
node.setAttribute('parentNode', parent);
|
|
28
29
|
}
|
package/dist/util/string.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.noWrap = exports.decodeHtml = exports.text = exports.escapeRegExp = exports.removeComment = exports.extUrlChar = exports.extUrlCharFirst = void 0;
|
|
4
|
-
exports.extUrlCharFirst = '(?:\\[[\\da-f:.]+\\]|[^[\\]<>"
|
|
5
|
-
exports.extUrlChar = '(?:[^[\\]<>"
|
|
4
|
+
exports.extUrlCharFirst = '(?:\\[[\\da-f:.]+\\]|[^[\\]<>"\0-\x1F\x7F\\p{Zs}\uFFFD])';
|
|
5
|
+
exports.extUrlChar = '(?:[^[\\]<>"\0-\x1F\x7F\\p{Zs}\uFFFD]|\0\\d+[c!~]\x7F)*';
|
|
6
6
|
/**
|
|
7
7
|
* 生成正则替换函数
|
|
8
8
|
* @param regex 正则表达式
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikilint",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.8",
|
|
4
4
|
"description": "A Node.js linter for MediaWiki markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"/config/",
|
|
20
20
|
"/i18n/",
|
|
21
21
|
"/bin/cli",
|
|
22
|
-
"/dist/"
|
|
22
|
+
"/dist/",
|
|
23
|
+
"!/dist/test/"
|
|
23
24
|
],
|
|
24
25
|
"bin": {
|
|
25
26
|
"wikilint": "./bin/cli.js"
|
|
@@ -30,15 +31,15 @@
|
|
|
30
31
|
"url": "git+https://github.com/bhsd-harry/wikiparser-node.git"
|
|
31
32
|
},
|
|
32
33
|
"scripts": {
|
|
33
|
-
"prepublishOnly": "npm run build
|
|
34
|
-
"build": "rm -rf dist/; tsc
|
|
34
|
+
"prepublishOnly": "npm run build && rm dist/internal.js dist/base.js dist/[bmpu]*/*.d.ts",
|
|
35
|
+
"build": "rm -rf dist/; tsc && grep -rl --include='*.d.ts' '@private' dist/ | xargs gsed -i '/@private/,+1d'",
|
|
35
36
|
"diff": "git diff --ignore-all-space --color-moved",
|
|
36
37
|
"lint:ts": "tsc --noEmit && eslint --cache .",
|
|
37
38
|
"lint:json": "ajv -s config/.schema.json -d 'config/*.json' --strict=true --strict-required=false",
|
|
38
39
|
"lint": "npm run lint:ts && npm run lint:json",
|
|
39
40
|
"test": "npx wikilint test/single-page.wiki",
|
|
40
41
|
"test:real": "node dist/test/real.js",
|
|
41
|
-
"test:single": "node dist/test/single.js
|
|
42
|
+
"test:single": "node dist/test/single.js && node --prof dist/test/single.js && node --prof-process isolate-0x*-v8.log > test/processed.txt && rm isolate-0x*-v8.log"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
45
|
"@cypress/request": "^3.0.1",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
"@typescript-eslint/parser": "^6.12.0",
|
|
50
51
|
"ajv-cli": "^5.0.0",
|
|
51
52
|
"eslint": "^8.56.0",
|
|
53
|
+
"eslint-plugin-es-x": "^7.3.0",
|
|
52
54
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
53
55
|
"eslint-plugin-jsdoc": "^47.0.2",
|
|
54
56
|
"eslint-plugin-json-es": "^1.5.7",
|