wikiparser-node 1.4.4 → 1.4.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/README.en.md +3 -3
- package/README.md +5 -5
- package/dist/base.d.ts +2 -0
- package/dist/lib/text.js +8 -0
- package/dist/src/arg.js +2 -2
- package/dist/src/attribute.js +5 -5
- package/dist/src/attributes.js +3 -3
- package/dist/src/converterFlags.js +1 -1
- package/dist/src/extLink.js +1 -1
- package/dist/src/gallery.js +1 -0
- package/dist/src/heading.js +5 -5
- package/dist/src/html.js +9 -6
- package/dist/src/imageParameter.js +2 -2
- package/dist/src/imagemap.js +2 -2
- package/dist/src/index.js +1 -1
- package/dist/src/link/base.js +4 -4
- package/dist/src/link/file.js +2 -2
- package/dist/src/link/galleryImage.js +1 -1
- package/dist/src/link/index.js +1 -1
- package/dist/src/magicLink.js +1 -1
- package/dist/src/nested.js +1 -1
- package/dist/src/nowiki/comment.js +3 -1
- package/dist/src/nowiki/index.js +1 -1
- package/dist/src/nowiki/quote.js +4 -3
- package/dist/src/paramTag/index.js +1 -1
- package/dist/src/parameter.js +1 -1
- package/dist/src/table/index.js +2 -2
- package/dist/src/table/td.js +1 -1
- package/dist/src/table/trBase.js +1 -1
- package/dist/src/tagPair/ext.js +2 -2
- package/dist/src/tagPair/include.js +3 -1
- package/dist/src/transclude.js +4 -4
- package/dist/util/lint.js +2 -1
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
# Introduction
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
WikiParser-Node is an offline [Wikitext](https://www.mediawiki.org/wiki/Wikitext) parser developed by Bhsd for the [Node.js](https://nodejs.org/) environment. It can parse almost all wiki syntax and generate an [Abstract Syntax Tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree) ([Try it online](https://bhsd-harry.github.io/wikiparser-node/#editor)). It also allows for easy querying and modification of the AST, and returns the modified wikitext.
|
|
12
12
|
|
|
13
13
|
# Other Versions
|
|
14
14
|
|
|
15
|
-
## Mini (also known as [
|
|
15
|
+
## Mini (also known as [WikiLint](https://www.npmjs.com/package/wikilint))
|
|
16
16
|
|
|
17
17
|
This version provides a [CLI](https://en.wikipedia.org/wiki/Command-line_interface), but only retains the parsing functionality and linting functionality. The parsed AST cannot be modified. It is used in the [eslint-plugin-wikitext](https://www.npmjs.com/package/eslint-plugin-wikitext) plugin.
|
|
18
18
|
|
|
@@ -24,7 +24,7 @@ A browser-compatible version, which can be used for code highlighting or as a li
|
|
|
24
24
|
|
|
25
25
|
## Node.js
|
|
26
26
|
|
|
27
|
-
Please install the corresponding version as needed (`
|
|
27
|
+
Please install the corresponding version as needed (`WikiParser-Node` or `WikiLint`), for example:
|
|
28
28
|
|
|
29
29
|
```sh
|
|
30
30
|
npm i wikiparser-node
|
package/README.md
CHANGED
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
# 简介
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
WikiParser-Node 是一款由 Bhsd 开发的基于 [Node.js](https://nodejs.org/) 环境的离线[维基文本](https://www.mediawiki.org/wiki/Wikitext)语法解析器,可以解析几乎全部的维基语法并生成[语法树](https://en.wikipedia.org/wiki/Abstract_syntax_tree)([在线解析](https://bhsd-harry.github.io/wikiparser-node/#editor)),还可以很方便地对语法树进行查询和修改,最后返回修改后的维基文本。
|
|
12
12
|
|
|
13
13
|
# 其他版本
|
|
14
14
|
|
|
15
|
-
## Mini (又名 [
|
|
15
|
+
## Mini (又名 [WikiLint](https://www.npmjs.com/package/wikilint))
|
|
16
16
|
|
|
17
17
|
提供了 [CLI](https://en.wikipedia.org/wiki/Command-line_interface),但仅保留了解析功能和语法错误分析功能,解析生成的语法树不能修改。这个版本被应用于 [eslint-plugin-wikitext](https://www.npmjs.com/package/eslint-plugin-wikitext) 插件。
|
|
18
18
|
|
|
@@ -24,7 +24,7 @@ wikiparser-node 是一款由 Bhsd 开发的基于 [Node.js](https://nodejs.org/)
|
|
|
24
24
|
|
|
25
25
|
## Node.js
|
|
26
26
|
|
|
27
|
-
请根据需要需要安装对应的版本(`
|
|
27
|
+
请根据需要需要安装对应的版本(`WikiParser-Node` 或 `WikiLint`),如:
|
|
28
28
|
|
|
29
29
|
```sh
|
|
30
30
|
npm i wikiparser-node
|
|
@@ -41,13 +41,13 @@ npm i wikilint
|
|
|
41
41
|
可以通过 CDN 下载代码,如:
|
|
42
42
|
|
|
43
43
|
```html
|
|
44
|
-
<script src="//cdn.jsdelivr.net/npm/wikiparser-node@browser
|
|
44
|
+
<script src="//cdn.jsdelivr.net/npm/wikiparser-node@browser"></script>
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
或
|
|
48
48
|
|
|
49
49
|
```html
|
|
50
|
-
<script src="//unpkg.com/wikiparser-node@browser
|
|
50
|
+
<script src="//unpkg.com/wikiparser-node@browser"></script>
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
更多浏览器端可用的插件请查阅对应[文档](https://github.com/bhsd-harry/wikiparser-node/wiki/Browser)。
|
package/dist/base.d.ts
CHANGED
|
@@ -14,7 +14,9 @@ export interface Config {
|
|
|
14
14
|
readonly redirects?: [string, string][];
|
|
15
15
|
}
|
|
16
16
|
export type Severity = 'error' | 'warning';
|
|
17
|
+
export type Rule = 'bold-header' | 'format-leakage' | 'fostered-content' | 'h1' | 'illegal-attr' | 'insecure-style' | 'invalid-gallery' | 'invalid-imagemap' | 'invalid-invoke' | 'lonely-apos' | 'lonely-bracket' | 'lonely-http' | 'nested-link' | 'no-arg' | 'no-duplicate' | 'no-ignored' | 'obsolete-attr' | 'obsolete-tag' | 'parsing-order' | 'pipe-like' | 'table-layout' | 'tag-like' | 'unbalanced-header' | 'unclosed-comment' | 'unclosed-quote' | 'unclosed-table' | 'unescaped' | 'unknown-page' | 'unmatched-tag' | 'unterminated-url' | 'url-encoding' | 'var-anchor' | 'void-ext';
|
|
17
18
|
export interface LintError {
|
|
19
|
+
readonly rule: Rule;
|
|
18
20
|
readonly message: string;
|
|
19
21
|
readonly severity: Severity;
|
|
20
22
|
readonly startIndex: number;
|
package/dist/lib/text.js
CHANGED
|
@@ -19,6 +19,13 @@ errorSyntax = new RegExp(`${source}|https?[:/]\\/+`, 'giu'), errorSyntaxUrl = ne
|
|
|
19
19
|
'{': /[{}]/u,
|
|
20
20
|
']': /[[\]](?=[^[\]]*$)/u,
|
|
21
21
|
'}': /[{}](?=[^{}]*$)/u,
|
|
22
|
+
}, ruleMap = {
|
|
23
|
+
'<': 'tag-like',
|
|
24
|
+
'[': 'lonely-bracket',
|
|
25
|
+
'{': 'lonely-bracket',
|
|
26
|
+
']': 'lonely-bracket',
|
|
27
|
+
'}': 'lonely-bracket',
|
|
28
|
+
h: 'lonely-http',
|
|
22
29
|
}, disallowedTags = [
|
|
23
30
|
'html',
|
|
24
31
|
'base',
|
|
@@ -186,6 +193,7 @@ class AstText extends node_1.AstNode {
|
|
|
186
193
|
}
|
|
187
194
|
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;
|
|
188
195
|
errors.push({
|
|
196
|
+
rule: ruleMap[char],
|
|
189
197
|
message: index_1.default.msg('lonely "$1"', char === 'h' ? error : char),
|
|
190
198
|
severity,
|
|
191
199
|
startIndex,
|
package/dist/src/arg.js
CHANGED
|
@@ -72,7 +72,7 @@ class ArgToken extends index_2.Token {
|
|
|
72
72
|
/** @override */
|
|
73
73
|
lint(start = this.getAbsoluteIndex()) {
|
|
74
74
|
if (!this.getAttribute('include')) {
|
|
75
|
-
return [(0, lint_1.generateForSelf)(this, { start }, 'unexpected template argument')];
|
|
75
|
+
return [(0, lint_1.generateForSelf)(this, { start }, 'no-arg', 'unexpected template argument')];
|
|
76
76
|
}
|
|
77
77
|
const { childNodes: [argName, argDefault, ...rest] } = this, errors = argName.lint(start + 3);
|
|
78
78
|
if (argDefault) {
|
|
@@ -81,7 +81,7 @@ class ArgToken extends index_2.Token {
|
|
|
81
81
|
if (rest.length > 0) {
|
|
82
82
|
const rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
83
83
|
errors.push(...rest.map(child => {
|
|
84
|
-
const error = (0, lint_1.generateForChild)(child, rect, 'invisible content inside triple braces');
|
|
84
|
+
const error = (0, lint_1.generateForChild)(child, rect, 'no-ignored', 'invisible content inside triple braces');
|
|
85
85
|
return {
|
|
86
86
|
...error,
|
|
87
87
|
startIndex: error.startIndex - 1,
|
package/dist/src/attribute.js
CHANGED
|
@@ -346,7 +346,7 @@ let AttributeToken = (() => {
|
|
|
346
346
|
if (!balanced) {
|
|
347
347
|
const root = this.getRootNode();
|
|
348
348
|
rect = { start, ...root.posFromIndex(start) };
|
|
349
|
-
const e = (0, lint_1.generateForChild)(lastChild, rect, index_1.default.msg('unclosed $1', 'quotes'), 'warning');
|
|
349
|
+
const e = (0, lint_1.generateForChild)(lastChild, rect, 'unclosed-quote', index_1.default.msg('unclosed $1', 'quotes'), 'warning');
|
|
350
350
|
errors.push({
|
|
351
351
|
...e,
|
|
352
352
|
startIndex: e.startIndex - 1,
|
|
@@ -360,19 +360,19 @@ let AttributeToken = (() => {
|
|
|
360
360
|
&& !/^(?:xmlns:[\w:.-]+|data-[^:]*)$/u.test(name)
|
|
361
361
|
&& (tag === 'meta' || tag === 'link' || !commonHtmlAttrs.has(name))) {
|
|
362
362
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
363
|
-
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'illegal attribute name'));
|
|
363
|
+
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'illegal-attr', 'illegal attribute name'));
|
|
364
364
|
}
|
|
365
365
|
else if (obsoleteAttrs[tag]?.has(name)) {
|
|
366
366
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
367
|
-
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'obsolete attribute', 'warning'));
|
|
367
|
+
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'obsolete-attr', 'obsolete attribute', 'warning'));
|
|
368
368
|
}
|
|
369
369
|
else if (name === 'style' && typeof value === 'string' && insecureStyle.test(value)) {
|
|
370
370
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
371
|
-
errors.push((0, lint_1.generateForChild)(lastChild, rect, 'insecure style'));
|
|
371
|
+
errors.push((0, lint_1.generateForChild)(lastChild, rect, 'insecure-style', 'insecure style'));
|
|
372
372
|
}
|
|
373
373
|
else if (name === 'tabindex' && typeof value === 'string' && value.trim() !== '0') {
|
|
374
374
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
375
|
-
errors.push((0, lint_1.generateForChild)(lastChild, rect, 'nonzero tabindex'));
|
|
375
|
+
errors.push((0, lint_1.generateForChild)(lastChild, rect, 'illegal-attr', 'nonzero tabindex'));
|
|
376
376
|
}
|
|
377
377
|
return errors;
|
|
378
378
|
}
|
package/dist/src/attributes.js
CHANGED
|
@@ -149,13 +149,13 @@ class AttributesToken extends index_2.Token {
|
|
|
149
149
|
let rect;
|
|
150
150
|
if (parentNode?.type === 'html' && parentNode.closing && this.text().trim()) {
|
|
151
151
|
rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
152
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, 'attributes of a closing tag'));
|
|
152
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, 'no-ignored', 'attributes of a closing tag'));
|
|
153
153
|
}
|
|
154
154
|
for (let i = 0; i < length; i++) {
|
|
155
155
|
const attr = childNodes[i];
|
|
156
156
|
if (attr instanceof atom_1.AtomToken && attr.text().trim()) {
|
|
157
157
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
158
|
-
errors.push((0, lint_1.generateForChild)(attr, rect, 'containing invalid attribute'));
|
|
158
|
+
errors.push((0, lint_1.generateForChild)(attr, rect, 'no-ignored', 'containing invalid attribute'));
|
|
159
159
|
}
|
|
160
160
|
else if (attr instanceof attribute_1.AttributeToken) {
|
|
161
161
|
const { name } = attr;
|
|
@@ -171,7 +171,7 @@ class AttributesToken extends index_2.Token {
|
|
|
171
171
|
if (duplicated.size > 0) {
|
|
172
172
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
173
173
|
for (const key of duplicated) {
|
|
174
|
-
errors.push(...attrs.get(key).map(attr => (0, lint_1.generateForChild)(attr, rect, index_1.default.msg('duplicated $1 attribute', key))));
|
|
174
|
+
errors.push(...attrs.get(key).map(attr => (0, lint_1.generateForChild)(attr, rect, 'no-duplicate', index_1.default.msg('duplicated $1 attribute', key))));
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
return errors;
|
|
@@ -78,7 +78,7 @@ class ConverterFlagsToken extends index_2.Token {
|
|
|
78
78
|
&& !variantFlags.has(flag)
|
|
79
79
|
&& !unknownFlags.has(flag)
|
|
80
80
|
&& (variantFlags.size > 0 || !validFlags.has(flag))) {
|
|
81
|
-
errors.push((0, lint_1.generateForChild)(child, rect, 'invalid conversion flag'));
|
|
81
|
+
errors.push((0, lint_1.generateForChild)(child, rect, 'no-ignored', 'invalid conversion flag'));
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
return errors;
|
package/dist/src/extLink.js
CHANGED
|
@@ -130,7 +130,7 @@ let ExtLinkToken = (() => {
|
|
|
130
130
|
lint(start = this.getAbsoluteIndex()) {
|
|
131
131
|
const errors = super.lint(start);
|
|
132
132
|
if (this.length === 1 && this.closest('heading-title')) {
|
|
133
|
-
errors.push((0, lint_1.generateForSelf)(this, { start }, 'variable anchor in a section header'));
|
|
133
|
+
errors.push((0, lint_1.generateForSelf)(this, { start }, 'var-anchor', 'variable anchor in a section header'));
|
|
134
134
|
}
|
|
135
135
|
return errors;
|
|
136
136
|
}
|
package/dist/src/gallery.js
CHANGED
|
@@ -67,6 +67,7 @@ class GalleryToken extends index_2.Token {
|
|
|
67
67
|
const child = this.childNodes[i], str = String(child), { length } = str, trimmed = str.trim(), startLine = top + i, startCol = i ? 0 : left;
|
|
68
68
|
if (child.type === 'noinclude' && trimmed && !/^<!--.*-->$/u.test(trimmed)) {
|
|
69
69
|
errors.push({
|
|
70
|
+
rule: 'no-ignored',
|
|
70
71
|
message: index_1.default.msg('invalid content in <$1>', 'gallery'),
|
|
71
72
|
severity: 'error',
|
|
72
73
|
startIndex: start,
|
package/dist/src/heading.js
CHANGED
|
@@ -129,23 +129,23 @@ let HeadingToken = (() => {
|
|
|
129
129
|
let rect;
|
|
130
130
|
if (this.level === 1) {
|
|
131
131
|
rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
132
|
-
errors.push((0, lint_1.generateForChild)(firstChild, rect, '<h1>'));
|
|
132
|
+
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'h1', '<h1>'));
|
|
133
133
|
}
|
|
134
134
|
if (innerStr.startsWith('=') || innerStr.endsWith('=')) {
|
|
135
135
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
136
|
-
errors.push((0, lint_1.generateForChild)(firstChild, rect, index_1.default.msg('unbalanced $1 in a section header', '"="')));
|
|
136
|
+
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'unbalanced-header', index_1.default.msg('unbalanced $1 in a section header', '"="')));
|
|
137
137
|
}
|
|
138
138
|
if (this.closest('html-attrs, table-attrs')) {
|
|
139
139
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
140
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, 'section header in a HTML tag'));
|
|
140
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, 'parsing-order', 'section header in a HTML tag'));
|
|
141
141
|
}
|
|
142
142
|
if (boldQuotes.length % 2) {
|
|
143
143
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
144
|
-
errors.push((0, lint_1.generateForChild)(boldQuotes[boldQuotes.length - 1], { ...rect, start: start + level, left: rect.left + level }, index_1.default.msg('unbalanced $1 in a section header', 'bold apostrophes')));
|
|
144
|
+
errors.push((0, lint_1.generateForChild)(boldQuotes[boldQuotes.length - 1], { ...rect, start: start + level, left: rect.left + level }, 'format-leakage', index_1.default.msg('unbalanced $1 in a section header', 'bold apostrophes')));
|
|
145
145
|
}
|
|
146
146
|
if (italicQuotes.length % 2) {
|
|
147
147
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
148
|
-
errors.push((0, lint_1.generateForChild)(italicQuotes[italicQuotes.length - 1], { start: start + level }, index_1.default.msg('unbalanced $1 in a section header', 'italic apostrophes')));
|
|
148
|
+
errors.push((0, lint_1.generateForChild)(italicQuotes[italicQuotes.length - 1], { start: start + level }, 'format-leakage', index_1.default.msg('unbalanced $1 in a section header', 'italic apostrophes')));
|
|
149
149
|
}
|
|
150
150
|
return errors;
|
|
151
151
|
}
|
package/dist/src/html.js
CHANGED
|
@@ -181,13 +181,14 @@ let HtmlToken = (() => {
|
|
|
181
181
|
const errors = super.lint(start);
|
|
182
182
|
let refError;
|
|
183
183
|
if (this.name === 'h1' && !this.closing) {
|
|
184
|
-
refError = (0, lint_1.generateForSelf)(this, { start }, '<h1>');
|
|
184
|
+
refError = (0, lint_1.generateForSelf)(this, { start }, 'h1', '<h1>');
|
|
185
185
|
errors.push(refError);
|
|
186
186
|
}
|
|
187
187
|
if (this.closest('table-attrs')) {
|
|
188
|
-
refError ??= (0, lint_1.generateForSelf)(this, { start }, '');
|
|
188
|
+
refError ??= (0, lint_1.generateForSelf)(this, { start }, 'h1', '');
|
|
189
189
|
errors.push({
|
|
190
190
|
...refError,
|
|
191
|
+
rule: 'parsing-order',
|
|
191
192
|
message: index_1.default.msg('HTML tag in table attributes'),
|
|
192
193
|
});
|
|
193
194
|
}
|
|
@@ -197,8 +198,8 @@ let HtmlToken = (() => {
|
|
|
197
198
|
catch (e) {
|
|
198
199
|
if (e instanceof SyntaxError) {
|
|
199
200
|
const { message } = e;
|
|
200
|
-
refError ??= (0, lint_1.generateForSelf)(this, { start }, '');
|
|
201
|
-
const [msg] = message.split(':'), error = { ...refError, message: index_1.default.msg(msg) };
|
|
201
|
+
refError ??= (0, lint_1.generateForSelf)(this, { start }, 'h1', '');
|
|
202
|
+
const [msg] = message.split(':'), error = { ...refError, rule: 'unmatched-tag', message: index_1.default.msg(msg) };
|
|
202
203
|
if (msg === 'unclosed tag' && !this.closest('heading-title')) {
|
|
203
204
|
if (formattingTags.has(this.name)) {
|
|
204
205
|
const childNodes = this.parentNode?.childNodes, i = childNodes?.indexOf(this);
|
|
@@ -220,17 +221,19 @@ let HtmlToken = (() => {
|
|
|
220
221
|
}
|
|
221
222
|
}
|
|
222
223
|
if (obsoleteTags.has(this.name)) {
|
|
223
|
-
refError ??= (0, lint_1.generateForSelf)(this, { start }, '');
|
|
224
|
+
refError ??= (0, lint_1.generateForSelf)(this, { start }, 'h1', '');
|
|
224
225
|
errors.push({
|
|
225
226
|
...refError,
|
|
227
|
+
rule: 'obsolete-tag',
|
|
226
228
|
message: index_1.default.msg('obsolete HTML tag'),
|
|
227
229
|
severity: 'warning',
|
|
228
230
|
});
|
|
229
231
|
}
|
|
230
232
|
if ((this.name === 'b' || this.name === 'strong') && this.closest('heading-title')) {
|
|
231
|
-
refError ??= (0, lint_1.generateForSelf)(this, { start }, '');
|
|
233
|
+
refError ??= (0, lint_1.generateForSelf)(this, { start }, 'h1', '');
|
|
232
234
|
errors.push({
|
|
233
235
|
...refError,
|
|
236
|
+
rule: 'format-leakage',
|
|
234
237
|
message: index_1.default.msg('bold in section header'),
|
|
235
238
|
severity: 'warning',
|
|
236
239
|
});
|
|
@@ -168,10 +168,10 @@ class ImageParameterToken extends index_2.Token {
|
|
|
168
168
|
lint(start = this.getAbsoluteIndex()) {
|
|
169
169
|
const errors = super.lint(start), { link, name } = this;
|
|
170
170
|
if (name === 'invalid') {
|
|
171
|
-
errors.push((0, lint_1.generateForSelf)(this, { start }, 'invalid gallery image parameter'));
|
|
171
|
+
errors.push((0, lint_1.generateForSelf)(this, { start }, 'invalid-gallery', 'invalid gallery image parameter'));
|
|
172
172
|
}
|
|
173
173
|
else if (typeof link === 'object' && link.encoded) {
|
|
174
|
-
errors.push((0, lint_1.generateForSelf)(this, { start }, 'unnecessary URL encoding in an internal link'));
|
|
174
|
+
errors.push((0, lint_1.generateForSelf)(this, { start }, 'url-encoding', 'unnecessary URL encoding in an internal link'));
|
|
175
175
|
}
|
|
176
176
|
return errors;
|
|
177
177
|
}
|
package/dist/src/imagemap.js
CHANGED
|
@@ -103,10 +103,10 @@ class ImagemapToken extends index_2.Token {
|
|
|
103
103
|
errors.push(...this.childNodes.filter(child => {
|
|
104
104
|
const str = String(child).trim();
|
|
105
105
|
return child.type === 'noinclude' && str && !str.startsWith('#');
|
|
106
|
-
}).map(child => (0, lint_1.generateForChild)(child, rect, 'invalid link in <imagemap>')));
|
|
106
|
+
}).map(child => (0, lint_1.generateForChild)(child, rect, 'invalid-imagemap', 'invalid link in <imagemap>')));
|
|
107
107
|
}
|
|
108
108
|
else {
|
|
109
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, '<imagemap> without an image'));
|
|
109
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, 'invalid-imagemap', '<imagemap> without an image'));
|
|
110
110
|
}
|
|
111
111
|
return errors;
|
|
112
112
|
}
|
package/dist/src/index.js
CHANGED
|
@@ -414,7 +414,7 @@ class Token extends element_1.AstElement {
|
|
|
414
414
|
}
|
|
415
415
|
for (const value of Object.values(record)) {
|
|
416
416
|
if (value.size > 1) {
|
|
417
|
-
errors.push(...[...value].map(cat => (0, lint_1.generateForSelf)(cat, { start: cat.getAbsoluteIndex() }, 'duplicated category')));
|
|
417
|
+
errors.push(...[...value].map(cat => (0, lint_1.generateForSelf)(cat, { start: cat.getAbsoluteIndex() }, 'no-duplicate', 'duplicated category')));
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
420
|
}
|
package/dist/src/link/base.js
CHANGED
|
@@ -135,20 +135,20 @@ class LinkBaseToken extends index_2.Token {
|
|
|
135
135
|
let rect;
|
|
136
136
|
if (target.childNodes.some(({ type }) => type === 'template')) {
|
|
137
137
|
rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
138
|
-
errors.push((0, lint_1.generateForChild)(target, rect, 'template in an internal link target', 'warning'));
|
|
138
|
+
errors.push((0, lint_1.generateForChild)(target, rect, 'unknown-page', 'template in an internal link target', 'warning'));
|
|
139
139
|
}
|
|
140
140
|
if (encoded) {
|
|
141
141
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
142
|
-
errors.push((0, lint_1.generateForChild)(target, rect, 'unnecessary URL encoding in an internal link'));
|
|
142
|
+
errors.push((0, lint_1.generateForChild)(target, rect, 'url-encoding', 'unnecessary URL encoding in an internal link'));
|
|
143
143
|
}
|
|
144
144
|
if ((linkType === 'link' || linkType === 'category')
|
|
145
145
|
&& linkText?.childNodes.some(({ type, data }) => type === 'text' && data.includes('|'))) {
|
|
146
146
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
147
|
-
errors.push((0, lint_1.generateForChild)(linkText, rect, 'additional "|" in the link text', 'warning'));
|
|
147
|
+
errors.push((0, lint_1.generateForChild)(linkText, rect, 'pipe-like', 'additional "|" in the link text', 'warning'));
|
|
148
148
|
}
|
|
149
149
|
else if (linkType !== 'link' && fragment !== undefined) {
|
|
150
150
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
151
|
-
errors.push((0, lint_1.generateForChild)(target, rect, 'useless fragment'));
|
|
151
|
+
errors.push((0, lint_1.generateForChild)(target, rect, 'no-ignored', 'useless fragment'));
|
|
152
152
|
}
|
|
153
153
|
return errors;
|
|
154
154
|
}
|
package/dist/src/link/file.js
CHANGED
|
@@ -104,7 +104,7 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
104
104
|
return visibleNodes.length !== 1 || visibleNodes[0].type !== 'arg';
|
|
105
105
|
}), keys = [...new Set(args.map(({ name }) => name))].filter(key => key !== 'invalid'), frameKeys = keys.filter(key => frame.has(key)), horizAlignKeys = keys.filter(key => horizAlign.has(key)), vertAlignKeys = keys.filter(key => vertAlign.has(key));
|
|
106
106
|
if (this.closest('ext-link-text') && this.getValue('link')?.trim() !== '') {
|
|
107
|
-
errors.push((0, lint_1.generateForSelf)(this, { start }, 'internal link in an external link'));
|
|
107
|
+
errors.push((0, lint_1.generateForSelf)(this, { start }, 'nested-link', 'internal link in an external link'));
|
|
108
108
|
}
|
|
109
109
|
if (args.length === keys.length
|
|
110
110
|
&& frameKeys.length < 2
|
|
@@ -118,7 +118,7 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
118
118
|
* @param msg 消息键
|
|
119
119
|
* @param p1 替换$1
|
|
120
120
|
*/
|
|
121
|
-
const generate = (msg, p1) => (arg) => (0, lint_1.generateForChild)(arg, rect, index_1.default.msg(`${msg} image $1 parameter`, p1));
|
|
121
|
+
const generate = (msg, p1) => (arg) => (0, lint_1.generateForChild)(arg, rect, 'no-duplicate', index_1.default.msg(`${msg} image $1 parameter`, p1));
|
|
122
122
|
for (const key of keys) {
|
|
123
123
|
let relevantArgs = args.filter(({ name }) => name === key);
|
|
124
124
|
if (key === 'caption') {
|
|
@@ -102,7 +102,7 @@ let GalleryImageToken = (() => {
|
|
|
102
102
|
lint(start = this.getAbsoluteIndex()) {
|
|
103
103
|
const errors = super.lint(start), { ns, interwiki } = this.getAttribute('title');
|
|
104
104
|
if (interwiki || ns !== 6) {
|
|
105
|
-
errors.push((0, lint_1.generateForSelf)(this, { start }, 'invalid gallery image'));
|
|
105
|
+
errors.push((0, lint_1.generateForSelf)(this, { start }, 'invalid-gallery', 'invalid gallery image'));
|
|
106
106
|
}
|
|
107
107
|
return errors;
|
|
108
108
|
}
|
package/dist/src/link/index.js
CHANGED
|
@@ -51,7 +51,7 @@ class LinkToken extends base_1.LinkBaseToken {
|
|
|
51
51
|
lint(start = this.getAbsoluteIndex()) {
|
|
52
52
|
const errors = super.lint(start);
|
|
53
53
|
if (this.closest('ext-link-text')) {
|
|
54
|
-
errors.push((0, lint_1.generateForSelf)(this, { start }, 'internal link in an external link'));
|
|
54
|
+
errors.push((0, lint_1.generateForSelf)(this, { start }, 'nested-link', 'internal link in an external link'));
|
|
55
55
|
}
|
|
56
56
|
return errors;
|
|
57
57
|
}
|
package/dist/src/magicLink.js
CHANGED
|
@@ -111,7 +111,7 @@ let MagicLinkToken = (() => {
|
|
|
111
111
|
continue;
|
|
112
112
|
}
|
|
113
113
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
114
|
-
const refError = (0, lint_1.generateForChild)(child, rect, '', 'warning');
|
|
114
|
+
const refError = (0, lint_1.generateForChild)(child, rect, 'unterminated-url', '', 'warning');
|
|
115
115
|
regexGlobal.lastIndex = 0;
|
|
116
116
|
for (let mt = regexGlobal.exec(data); mt; mt = regexGlobal.exec(data)) {
|
|
117
117
|
const { index, 0: s } = mt, lines = data.slice(0, index).split('\n'), top = lines.length, left = lines[top - 1].length, startIndex = refError.startIndex + index, startLine = refError.startLine + top - 1, startCol = top === 1 ? refError.startCol + left : left;
|
package/dist/src/nested.js
CHANGED
|
@@ -61,7 +61,7 @@ class NestedToken extends index_2.Token {
|
|
|
61
61
|
return str && !/^<!--.*-->$/su.test(str);
|
|
62
62
|
}).map(child => {
|
|
63
63
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
64
|
-
return (0, lint_1.generateForChild)(child, rect, index_1.default.msg('invalid content in <$1>', this.name));
|
|
64
|
+
return (0, lint_1.generateForChild)(child, rect, 'no-ignored', index_1.default.msg('invalid content in <$1>', this.name));
|
|
65
65
|
}),
|
|
66
66
|
];
|
|
67
67
|
}
|
|
@@ -31,7 +31,9 @@ class CommentToken extends (0, hidden_1.hiddenToken)(base_1.NowikiBaseToken) {
|
|
|
31
31
|
}
|
|
32
32
|
/** @override */
|
|
33
33
|
lint(start = this.getAbsoluteIndex()) {
|
|
34
|
-
return this.closed
|
|
34
|
+
return this.closed
|
|
35
|
+
? []
|
|
36
|
+
: [(0, lint_1.generateForSelf)(this, { start }, 'unclosed-comment', index_1.default.msg('unclosed $1', 'HTML comment'))];
|
|
35
37
|
}
|
|
36
38
|
/** @private */
|
|
37
39
|
toString() {
|
package/dist/src/nowiki/index.js
CHANGED
|
@@ -13,7 +13,7 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
13
13
|
lint(start = this.getAbsoluteIndex()) {
|
|
14
14
|
const { name, firstChild: { data } } = this;
|
|
15
15
|
return (name === 'templatestyles' || name === 'section') && data
|
|
16
|
-
? [(0, lint_1.generateForSelf)(this, { start }, index_1.default.msg('nothing should be in <$1>', name))]
|
|
16
|
+
? [(0, lint_1.generateForSelf)(this, { start }, 'void-ext', index_1.default.msg('nothing should be in <$1>', name))]
|
|
17
17
|
: super.lint(start);
|
|
18
18
|
}
|
|
19
19
|
}
|
package/dist/src/nowiki/quote.js
CHANGED
|
@@ -70,7 +70,7 @@ let QuoteToken = (() => {
|
|
|
70
70
|
const { previousSibling, nextSibling, bold } = this, message = index_1.default.msg('lonely "$1"', `'`), errors = [];
|
|
71
71
|
let refError;
|
|
72
72
|
if (previousSibling?.type === 'text' && previousSibling.data.endsWith(`'`)) {
|
|
73
|
-
refError = (0, lint_1.generateForSelf)(this, { start }, message);
|
|
73
|
+
refError = (0, lint_1.generateForSelf)(this, { start }, 'lonely-apos', message);
|
|
74
74
|
const { startIndex: endIndex, startLine: endLine, startCol: endCol } = refError, [, { length }] = /(?:^|[^'])('+)$/u.exec(previousSibling.data), startIndex = start - length;
|
|
75
75
|
errors.push({
|
|
76
76
|
...refError,
|
|
@@ -82,7 +82,7 @@ let QuoteToken = (() => {
|
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
if (nextSibling?.type === 'text' && nextSibling.data.startsWith(`'`)) {
|
|
85
|
-
refError ??= (0, lint_1.generateForSelf)(this, { start }, message);
|
|
85
|
+
refError ??= (0, lint_1.generateForSelf)(this, { start }, 'lonely-apos', message);
|
|
86
86
|
const { endIndex: startIndex, endLine: startLine, endCol: startCol } = refError, [{ length }] = /^'+/u.exec(nextSibling.data), endIndex = startIndex + length;
|
|
87
87
|
errors.push({
|
|
88
88
|
...refError,
|
|
@@ -94,9 +94,10 @@ let QuoteToken = (() => {
|
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
if (bold && this.closest('heading-title')) {
|
|
97
|
-
refError ??= (0, lint_1.generateForSelf)(this, { start }, message);
|
|
97
|
+
refError ??= (0, lint_1.generateForSelf)(this, { start }, 'lonely-apos', message);
|
|
98
98
|
errors.push({
|
|
99
99
|
...refError,
|
|
100
|
+
rule: 'bold-header',
|
|
100
101
|
message: index_1.default.msg('bold in section header'),
|
|
101
102
|
severity: 'warning',
|
|
102
103
|
});
|
|
@@ -47,7 +47,7 @@ class ParamTagToken extends index_2.Token {
|
|
|
47
47
|
return str && !(i >= 0 ? /^[a-z]+(?:\[\])?\s*(?:=|$)/iu : /^[a-z]+(?:\[\])?\s*=/iu).test(str);
|
|
48
48
|
}).map(child => {
|
|
49
49
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
50
|
-
return (0, lint_1.generateForChild)(child, rect, index_1.default.msg('invalid parameter of <$1>', this.name));
|
|
50
|
+
return (0, lint_1.generateForChild)(child, rect, 'no-ignored', index_1.default.msg('invalid parameter of <$1>', this.name));
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
/** @override */
|
package/dist/src/parameter.js
CHANGED
|
@@ -158,7 +158,7 @@ let ParameterToken = (() => {
|
|
|
158
158
|
/https?:\/\/(?:\[[\da-f:.]+\]|[^[\]<>"\t\n\p{Zs}])(?:[^[\]<>"\0\t\n\p{Zs}]|\0\d+c\x7F)*$/iu;
|
|
159
159
|
const errors = super.lint(start), { firstChild } = this, link = new RegExp(`https?://${string_1.extUrlCharFirst}${string_1.extUrlChar}$`, 'iu').exec(firstChild.text())?.[0];
|
|
160
160
|
if (link && new URL(link).search) {
|
|
161
|
-
const e = (0, lint_1.generateForChild)(firstChild, { start }, 'unescaped query string in an anonymous parameter');
|
|
161
|
+
const e = (0, lint_1.generateForChild)(firstChild, { start }, 'unescaped', 'unescaped query string in an anonymous parameter');
|
|
162
162
|
errors.push({
|
|
163
163
|
...e,
|
|
164
164
|
startIndex: e.endIndex,
|
package/dist/src/table/index.js
CHANGED
|
@@ -41,7 +41,7 @@ class TableToken extends trBase_1.TrBaseToken {
|
|
|
41
41
|
lint(start = this.getAbsoluteIndex()) {
|
|
42
42
|
const errors = super.lint(start);
|
|
43
43
|
if (!this.closed) {
|
|
44
|
-
errors.push((0, lint_1.generateForChild)(this.firstChild, { start }, index_1.default.msg('unclosed $1', 'table')));
|
|
44
|
+
errors.push((0, lint_1.generateForChild)(this.firstChild, { start }, 'unclosed-table', index_1.default.msg('unclosed $1', 'table')));
|
|
45
45
|
}
|
|
46
46
|
/* NOT FOR BROWSER */
|
|
47
47
|
const layout = this.getLayout(), { length } = layout;
|
|
@@ -49,7 +49,7 @@ class TableToken extends trBase_1.TrBaseToken {
|
|
|
49
49
|
const j = new Array(length - 1).fill(undefined)
|
|
50
50
|
.findIndex((_, i) => layout[i].length !== layout[i + 1].length) + 1;
|
|
51
51
|
if (j) {
|
|
52
|
-
errors.push((0, lint_1.generateForChild)(this.getNthRow(j), { start }, 'inconsistent table layout', 'warning'));
|
|
52
|
+
errors.push((0, lint_1.generateForChild)(this.getNthRow(j), { start }, 'table-layout', 'inconsistent table layout', 'warning'));
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
/* NOT FOR BROWSER END */
|
package/dist/src/table/td.js
CHANGED
|
@@ -193,7 +193,7 @@ let TdToken = (() => {
|
|
|
193
193
|
if (child.type === 'text') {
|
|
194
194
|
const { data } = child;
|
|
195
195
|
if (data.includes('|')) {
|
|
196
|
-
errors.push((0, lint_1.generateForChild)(child, { start }, 'additional "|" in a table cell', data.includes('||') ? 'error' : 'warning'));
|
|
196
|
+
errors.push((0, lint_1.generateForChild)(child, { start }, 'pipe-like', 'additional "|" in a table cell', data.includes('||') ? 'error' : 'warning'));
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
}
|
package/dist/src/table/trBase.js
CHANGED
|
@@ -29,7 +29,7 @@ class TrBaseToken extends base_1.TableBaseToken {
|
|
|
29
29
|
}
|
|
30
30
|
catch { }
|
|
31
31
|
}
|
|
32
|
-
const error = (0, lint_1.generateForChild)(inter, { start }, 'content to be moved out from the table');
|
|
32
|
+
const error = (0, lint_1.generateForChild)(inter, { start }, 'fostered-content', 'content to be moved out from the table');
|
|
33
33
|
errors.push({
|
|
34
34
|
...error,
|
|
35
35
|
severity: first.type === 'template' ? 'warning' : 'error',
|
package/dist/src/tagPair/ext.js
CHANGED
|
@@ -177,11 +177,11 @@ let ExtToken = (() => {
|
|
|
177
177
|
let rect;
|
|
178
178
|
if (this.name !== 'nowiki' && this.closest('html-attrs, table-attrs')) {
|
|
179
179
|
rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
180
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, 'extension tag in HTML tag attributes'));
|
|
180
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, 'parsing-order', 'extension tag in HTML tag attributes'));
|
|
181
181
|
}
|
|
182
182
|
if (this.name === 'ref' && this.closest('heading-title')) {
|
|
183
183
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
184
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, 'variable anchor in a section header'));
|
|
184
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, 'var-anchor', 'variable anchor in a section header'));
|
|
185
185
|
}
|
|
186
186
|
return errors;
|
|
187
187
|
}
|
|
@@ -38,7 +38,9 @@ class IncludeToken extends (0, hidden_1.hiddenToken)(index_2.TagPairToken) {
|
|
|
38
38
|
}
|
|
39
39
|
/** @override */
|
|
40
40
|
lint(start = this.getAbsoluteIndex()) {
|
|
41
|
-
return this.closed
|
|
41
|
+
return this.closed
|
|
42
|
+
? []
|
|
43
|
+
: [(0, lint_1.generateForSelf)(this, { start }, 'unclosed-comment', index_1.default.msg('unclosed $1', `<${this.name}>`))];
|
|
42
44
|
}
|
|
43
45
|
/* NOT FOR BROWSER */
|
|
44
46
|
/** @override */
|
package/dist/src/transclude.js
CHANGED
|
@@ -232,21 +232,21 @@ class TranscludeToken extends index_2.Token {
|
|
|
232
232
|
const title = this.#getTitle();
|
|
233
233
|
if (title.fragment !== undefined) {
|
|
234
234
|
rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
235
|
-
errors.push((0, lint_1.generateForChild)(childNodes[type === 'template' ? 0 : 1], rect, 'useless fragment'));
|
|
235
|
+
errors.push((0, lint_1.generateForChild)(childNodes[type === 'template' ? 0 : 1], rect, 'no-ignored', 'useless fragment'));
|
|
236
236
|
}
|
|
237
237
|
if (!title.valid) {
|
|
238
238
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
239
|
-
errors.push((0, lint_1.generateForChild)(childNodes[1], rect, 'illegal module name'));
|
|
239
|
+
errors.push((0, lint_1.generateForChild)(childNodes[1], rect, 'invalid-invoke', 'illegal module name'));
|
|
240
240
|
}
|
|
241
241
|
if (type === 'magic-word' && length === 2) {
|
|
242
242
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
243
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, 'missing module function'));
|
|
243
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, 'invalid-invoke', 'missing module function'));
|
|
244
244
|
return errors;
|
|
245
245
|
}
|
|
246
246
|
const duplicatedArgs = this.getDuplicatedArgs();
|
|
247
247
|
if (duplicatedArgs.length > 0) {
|
|
248
248
|
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
249
|
-
errors.push(...duplicatedArgs.flatMap(([, args]) => args).map(arg => (0, lint_1.generateForChild)(arg, rect, 'duplicated parameter')));
|
|
249
|
+
errors.push(...duplicatedArgs.flatMap(([, args]) => args).map(arg => (0, lint_1.generateForChild)(arg, rect, 'no-duplicate', 'duplicated parameter')));
|
|
250
250
|
}
|
|
251
251
|
return errors;
|
|
252
252
|
}
|
package/dist/util/lint.js
CHANGED
|
@@ -6,9 +6,10 @@ const index_1 = require("../index");
|
|
|
6
6
|
* 生成lint函数
|
|
7
7
|
* @param func lint函数
|
|
8
8
|
*/
|
|
9
|
-
const factory = (func) => (token, boundingRect, msg, severity = 'error') => {
|
|
9
|
+
const factory = (func) => (token, boundingRect, rule, msg, severity = 'error') => {
|
|
10
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);
|
|
11
11
|
return {
|
|
12
|
+
rule,
|
|
12
13
|
message: index_1.default.msg(msg),
|
|
13
14
|
severity,
|
|
14
15
|
startIndex,
|