wikilint 2.18.2 → 2.18.4
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.md +1 -1
- package/bin/cli.js +1 -1
- package/config/minimum.json +7 -0
- package/dist/base.d.mts +2 -0
- package/dist/base.d.ts +2 -0
- package/dist/base.js +1 -0
- package/dist/base.mjs +2 -1
- package/dist/bin/config.js +3 -2
- package/dist/index.d.ts +12 -1
- package/dist/index.js +45 -28
- package/dist/lib/lsp.d.ts +1 -0
- package/dist/lib/lsp.js +19 -14
- package/dist/lib/text.js +2 -2
- package/dist/lib/title.d.ts +18 -4
- package/dist/lib/title.js +12 -4
- package/dist/parser/braces.js +79 -37
- package/dist/parser/commentAndExt.js +5 -16
- package/dist/parser/links.js +1 -1
- package/dist/parser/redirect.js +1 -3
- package/dist/src/arg.js +1 -1
- package/dist/src/attribute.js +1 -1
- package/dist/src/converter.js +1 -1
- package/dist/src/gallery.js +1 -1
- package/dist/src/heading.js +3 -3
- package/dist/src/imageParameter.js +9 -9
- package/dist/src/imagemap.js +3 -2
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +7 -5
- package/dist/src/link/base.js +1 -1
- package/dist/src/link/file.d.ts +2 -0
- package/dist/src/link/file.js +15 -13
- package/dist/src/link/galleryImage.js +1 -1
- package/dist/src/link/redirectTarget.js +1 -2
- package/dist/src/magicLink.js +1 -1
- package/dist/src/nested.js +5 -5
- package/dist/src/nowiki/index.js +3 -2
- package/dist/src/redirect.js +1 -2
- package/dist/src/syntax.d.ts +4 -2
- package/dist/src/syntax.js +4 -2
- package/dist/src/table/base.js +1 -1
- package/dist/src/table/index.d.ts +1 -0
- package/dist/src/table/index.js +3 -6
- package/dist/src/table/trBase.js +31 -14
- package/dist/src/transclude.js +14 -6
- package/dist/util/debug.js +11 -1
- package/dist/util/diff.js +1 -1
- package/dist/util/string.js +3 -4
- package/package.json +2 -2
package/dist/src/syntax.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ declare type SyntaxTypes = 'heading-trail' | 'magic-word-name' | 'table-syntax'
|
|
|
9
9
|
export declare class SyntaxToken extends Token {
|
|
10
10
|
#private;
|
|
11
11
|
get type(): SyntaxTypes;
|
|
12
|
-
/**
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* @class
|
|
14
|
+
*/
|
|
15
|
+
constructor(wikitext: string | undefined, type: SyntaxTypes, config?: Config, accum?: Token[], acceptable?: Acceptable);
|
|
14
16
|
}
|
|
15
17
|
export {};
|
package/dist/src/syntax.js
CHANGED
|
@@ -12,8 +12,10 @@ class SyntaxToken extends index_1.Token {
|
|
|
12
12
|
get type() {
|
|
13
13
|
return this.#type;
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* @class
|
|
17
|
+
*/
|
|
18
|
+
constructor(wikitext, type, config, accum, acceptable) {
|
|
17
19
|
super(wikitext, config, accum, acceptable);
|
|
18
20
|
this.#type = type;
|
|
19
21
|
}
|
package/dist/src/table/base.js
CHANGED
|
@@ -24,7 +24,7 @@ class TableBaseToken extends (0, attributesParent_1.attributesParent)(1)(index_2
|
|
|
24
24
|
*/
|
|
25
25
|
constructor(pattern, syntax, type, attr, config = index_1.default.getConfig(), accum = [], acceptable) {
|
|
26
26
|
super(undefined, config, accum, acceptable);
|
|
27
|
-
this.append(new syntax_1.SyntaxToken(syntax,
|
|
27
|
+
this.append(new syntax_1.SyntaxToken(syntax, 'table-syntax', config, accum),
|
|
28
28
|
// @ts-expect-error abstract class
|
|
29
29
|
new attributes_1.AttributesToken(attr, 'table-attrs', type, config, accum));
|
|
30
30
|
}
|
|
@@ -11,6 +11,7 @@ export type TableTokens = TableToken | TrToken | TdToken;
|
|
|
11
11
|
export declare const isRowEnd: ({ type }: Token) => boolean;
|
|
12
12
|
/** @extends {Array<TableCoords[]>} */
|
|
13
13
|
export declare class Layout extends Array<TableCoords[]> {
|
|
14
|
+
abstract static from(arr: TableCoords[][]): Layout;
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
17
|
* table
|
package/dist/src/table/index.js
CHANGED
|
@@ -10,7 +10,6 @@ const rect_1 = require("../../lib/rect");
|
|
|
10
10
|
const index_1 = __importDefault(require("../../index"));
|
|
11
11
|
const trBase_1 = require("./trBase");
|
|
12
12
|
const syntax_1 = require("../syntax");
|
|
13
|
-
const closingPattern = /^\n[^\S\n]*(?:\|\}|\{\{\s*!\s*\}\}\}|\{\{\s*!\)\s*\}\})$/u;
|
|
14
13
|
/**
|
|
15
14
|
* 生成一个指定长度的空数组
|
|
16
15
|
* @param n 数组长度
|
|
@@ -91,11 +90,9 @@ class TableToken extends trBase_1.TrBaseToken {
|
|
|
91
90
|
* @param halfParsed
|
|
92
91
|
*/
|
|
93
92
|
close(syntax = '\n|}', halfParsed) {
|
|
94
|
-
const config = this.getAttribute('config'), accum = this.getAttribute('accum'), inner =
|
|
95
|
-
? [syntax]
|
|
96
|
-
: index_1.default.parse(syntax, this.getAttribute('include'), 2, config).childNodes;
|
|
93
|
+
const config = this.getAttribute('config'), accum = this.getAttribute('accum'), inner = [syntax];
|
|
97
94
|
debug_1.Shadow.run(() => {
|
|
98
|
-
const token = new syntax_1.SyntaxToken(undefined,
|
|
95
|
+
const token = new syntax_1.SyntaxToken(undefined, 'table-syntax', config, accum);
|
|
99
96
|
super.insertAt(token);
|
|
100
97
|
});
|
|
101
98
|
this.lastChild.replaceChildren(...inner);
|
|
@@ -111,7 +108,7 @@ class TableToken extends trBase_1.TrBaseToken {
|
|
|
111
108
|
* @param stop.y stop at the column / 中止列
|
|
112
109
|
*/
|
|
113
110
|
getLayout(stop) {
|
|
114
|
-
const rows = this.getAllRows(), { length } = rows, layout =
|
|
111
|
+
const rows = this.getAllRows(), { length } = rows, layout = Layout.from(emptyArray(length, () => []));
|
|
115
112
|
for (let i = 0; i < layout.length; i++) {
|
|
116
113
|
const rowLayout = layout[i];
|
|
117
114
|
let j = 0, k = 0, last;
|
package/dist/src/table/trBase.js
CHANGED
|
@@ -4,6 +4,34 @@ exports.TrBaseToken = void 0;
|
|
|
4
4
|
const lint_1 = require("../../util/lint");
|
|
5
5
|
const base_1 = require("./base");
|
|
6
6
|
const td_1 = require("./td");
|
|
7
|
+
const tableTags = new Set(['tr', 'td', 'th', 'caption']), tableTemplates = new Set(['Template:!!', 'Template:!-']);
|
|
8
|
+
/**
|
|
9
|
+
* Check if the content is fostered
|
|
10
|
+
* @param token
|
|
11
|
+
*/
|
|
12
|
+
const isFostered = (token) => {
|
|
13
|
+
const first = token.childNodes.find(child => child.text().trim());
|
|
14
|
+
if (!first
|
|
15
|
+
|| first.type === 'text' && first.data.trim().startsWith('!')
|
|
16
|
+
|| first.type === 'magic-word' && first.name === '!'
|
|
17
|
+
|| first.type === 'template' && tableTemplates.has(first.name)
|
|
18
|
+
|| first.is('html') && tableTags.has(first.name)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
else if (first.is('arg')) {
|
|
22
|
+
return first.length > 1 && isFostered(first.childNodes[1]);
|
|
23
|
+
}
|
|
24
|
+
else if (first.is('magic-word')) {
|
|
25
|
+
try {
|
|
26
|
+
const severity = first.getPossibleValues().map(isFostered);
|
|
27
|
+
return severity.includes('error')
|
|
28
|
+
? 'error'
|
|
29
|
+
: severity.includes('warning') && 'warning';
|
|
30
|
+
}
|
|
31
|
+
catch { }
|
|
32
|
+
}
|
|
33
|
+
return first.type === 'template' || first.type === 'magic-word' && first.name === 'invoke' ? 'warning' : 'error';
|
|
34
|
+
};
|
|
7
35
|
/**
|
|
8
36
|
* table row or table
|
|
9
37
|
*
|
|
@@ -16,22 +44,11 @@ class TrBaseToken extends base_1.TableBaseToken {
|
|
|
16
44
|
if (!inter) {
|
|
17
45
|
return errors;
|
|
18
46
|
}
|
|
19
|
-
const
|
|
20
|
-
if (!
|
|
21
|
-
|| tdPattern.test(first.toString())
|
|
22
|
-
|| first.is('arg') && tdPattern.test(first.default || '')) {
|
|
47
|
+
const severity = isFostered(inter);
|
|
48
|
+
if (!severity) {
|
|
23
49
|
return errors;
|
|
24
50
|
}
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
if (first.getPossibleValues().every(token => tdPattern.test(token.text()))) {
|
|
28
|
-
return errors;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
catch { }
|
|
32
|
-
}
|
|
33
|
-
const error = (0, lint_1.generateForChild)(inter, { start }, 'fostered-content', 'content to be moved out from the table');
|
|
34
|
-
error.severity = first.type === 'template' ? 'warning' : 'error';
|
|
51
|
+
const error = (0, lint_1.generateForChild)(inter, { start }, 'fostered-content', 'content to be moved out from the table', severity);
|
|
35
52
|
error.startIndex++;
|
|
36
53
|
error.startLine++;
|
|
37
54
|
error.startCol = 0;
|
package/dist/src/transclude.js
CHANGED
|
@@ -66,7 +66,7 @@ class TranscludeToken extends index_1.Token {
|
|
|
66
66
|
if (fullWidth) {
|
|
67
67
|
this.#colon = ':';
|
|
68
68
|
}
|
|
69
|
-
const
|
|
69
|
+
const token = new syntax_1.SyntaxToken(magicWord, 'magic-word-name', config, accum);
|
|
70
70
|
super.insertAt(token);
|
|
71
71
|
if (arg !== false) {
|
|
72
72
|
parts.unshift([arg]);
|
|
@@ -85,7 +85,7 @@ class TranscludeToken extends index_1.Token {
|
|
|
85
85
|
}
|
|
86
86
|
if (this.type === 'template') {
|
|
87
87
|
const name = (0, string_1.removeComment)(title).trim();
|
|
88
|
-
if (!this.normalizeTitle(name, 10, true, true).valid) {
|
|
88
|
+
if (!this.normalizeTitle(name, 10, { halfParsed: true, temporary: true }).valid) {
|
|
89
89
|
accum.pop();
|
|
90
90
|
throw new SyntaxError('Invalid template name');
|
|
91
91
|
}
|
|
@@ -144,7 +144,7 @@ class TranscludeToken extends index_1.Token {
|
|
|
144
144
|
}
|
|
145
145
|
/** 获取模板或模块名 */
|
|
146
146
|
#getTitle() {
|
|
147
|
-
const isTemplate = this.type === 'template', title = this.normalizeTitle(this.childNodes[isTemplate ? 0 : 1].
|
|
147
|
+
const isTemplate = this.type === 'template', title = this.normalizeTitle(this.childNodes[isTemplate ? 0 : 1].text(), isTemplate ? 10 : 828, { temporary: true });
|
|
148
148
|
return title;
|
|
149
149
|
}
|
|
150
150
|
/**
|
|
@@ -162,7 +162,7 @@ class TranscludeToken extends index_1.Token {
|
|
|
162
162
|
return [
|
|
163
163
|
this.#getTitle().title,
|
|
164
164
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
165
|
-
this.childNodes[2]?.
|
|
165
|
+
this.childNodes[2]?.text().trim(),
|
|
166
166
|
];
|
|
167
167
|
}
|
|
168
168
|
}
|
|
@@ -344,7 +344,7 @@ class TranscludeToken extends index_1.Token {
|
|
|
344
344
|
if (type === 'template') {
|
|
345
345
|
throw new Error('TranscludeToken.getPossibleValues method is only for specific magic words!');
|
|
346
346
|
}
|
|
347
|
-
let start;
|
|
347
|
+
let start, queue;
|
|
348
348
|
switch (name) {
|
|
349
349
|
case 'if':
|
|
350
350
|
case 'ifexist':
|
|
@@ -355,10 +355,18 @@ class TranscludeToken extends index_1.Token {
|
|
|
355
355
|
case 'ifeq':
|
|
356
356
|
start = 3;
|
|
357
357
|
break;
|
|
358
|
+
case 'switch': {
|
|
359
|
+
const parameters = childNodes.slice(2), last = parameters[parameters.length - 1];
|
|
360
|
+
queue = [
|
|
361
|
+
...parameters.filter(({ anon }) => !anon),
|
|
362
|
+
...last?.anon ? [last] : [],
|
|
363
|
+
].map(({ lastChild }) => lastChild);
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
358
366
|
default:
|
|
359
367
|
throw new Error('TranscludeToken.getPossibleValues method is only for specific magic words!');
|
|
360
368
|
}
|
|
361
|
-
|
|
369
|
+
queue ??= childNodes.slice(start, start + 2).map(({ lastChild }) => lastChild);
|
|
362
370
|
for (let i = 0; i < queue.length;) {
|
|
363
371
|
const { length, 0: first } = queue[i].childNodes.filter(child => child.text().trim());
|
|
364
372
|
if (length === 0) {
|
package/dist/util/debug.js
CHANGED
|
@@ -37,7 +37,14 @@ exports.isToken = isToken;
|
|
|
37
37
|
* @param inserted 插入的子节点
|
|
38
38
|
*/
|
|
39
39
|
const setChildNodes = (parent, position, deleteCount, inserted = []) => {
|
|
40
|
-
|
|
40
|
+
let nodes = parent.getChildNodes(), removed;
|
|
41
|
+
if (nodes.length === deleteCount) {
|
|
42
|
+
removed = nodes;
|
|
43
|
+
nodes = inserted;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
removed = nodes.splice(position, deleteCount, ...inserted);
|
|
47
|
+
}
|
|
41
48
|
for (let i = 0; i < inserted.length; i++) {
|
|
42
49
|
const node = inserted[i];
|
|
43
50
|
node.setAttribute('parentNode', parent);
|
|
@@ -46,6 +53,9 @@ const setChildNodes = (parent, position, deleteCount, inserted = []) => {
|
|
|
46
53
|
}
|
|
47
54
|
nodes[position - 1]?.setAttribute('nextSibling', nodes[position]);
|
|
48
55
|
nodes[position + inserted.length]?.setAttribute('previousSibling', nodes[position + inserted.length - 1]);
|
|
56
|
+
if (nodes === inserted) {
|
|
57
|
+
parent.setAttribute('childNodes', nodes);
|
|
58
|
+
}
|
|
49
59
|
return removed;
|
|
50
60
|
};
|
|
51
61
|
exports.setChildNodes = setChildNodes;
|
package/dist/util/diff.js
CHANGED
|
@@ -31,7 +31,7 @@ const cmd = (command, args) => new Promise(resolve => {
|
|
|
31
31
|
shell = (0, child_process_1.spawn)(command, args);
|
|
32
32
|
timer = setTimeout(() => {
|
|
33
33
|
shell.kill('SIGINT');
|
|
34
|
-
}, 60 *
|
|
34
|
+
}, 60 * 1e3);
|
|
35
35
|
let buf = '';
|
|
36
36
|
shell.stdout.on('data', data => {
|
|
37
37
|
buf += String(data);
|
package/dist/util/string.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noWrap = exports.decodeNumber = exports.decodeHtml = exports.text = exports.escapeRegExp = exports.removeComment = exports.tidy = exports.extUrlChar = exports.extUrlCharFirst = exports.zs = exports.rawurldecode = void 0;
|
|
3
|
+
exports.noWrap = exports.decodeNumber = exports.decodeHtml = exports.decodeHtmlBasic = exports.text = exports.escapeRegExp = exports.removeComment = exports.tidy = exports.extUrlChar = exports.extUrlCharFirst = exports.zs = exports.rawurldecode = void 0;
|
|
4
4
|
var common_1 = require("@bhsd/common");
|
|
5
5
|
Object.defineProperty(exports, "rawurldecode", { enumerable: true, get: function () { return common_1.rawurldecode; } });
|
|
6
6
|
exports.zs = String.raw ` \xA0\u1680\u2000-\u200A\u202F\u205F\u3000`;
|
|
@@ -27,9 +27,8 @@ exports.escapeRegExp = factory(/[\\{}()|.?*+^$[\]]/gu, String.raw `\$&`);
|
|
|
27
27
|
const text = (childNodes, separator = '') => childNodes.map(child => typeof child === 'string' ? child : child.text()).join(separator);
|
|
28
28
|
exports.text = text;
|
|
29
29
|
const names = { lt: '<', gt: '>', lbrack: '[', rbrack: ']', lbrace: '{', rbrace: '}', nbsp: ' ', amp: '&', quot: '"' };
|
|
30
|
-
/* istanbul ignore next */
|
|
31
30
|
/** decode HTML entities */
|
|
32
|
-
|
|
31
|
+
exports.decodeHtmlBasic = factory(/&(?:#(\d+|[Xx][\da-fA-F]+)|([lg]t|[LG]T|[lr]brac[ke]|nbsp|amp|AMP|quot|QUOT));/gu, (_, code, name) => code
|
|
33
32
|
? String.fromCodePoint(Number((/^x/iu.test(code) ? '0' : '') + code))
|
|
34
33
|
: names[name.toLowerCase()]);
|
|
35
34
|
/**
|
|
@@ -48,7 +47,7 @@ const decodeHtml = (str) => {
|
|
|
48
47
|
}
|
|
49
48
|
/* istanbul ignore next */
|
|
50
49
|
/* NOT FOR BROWSER ONLY END */
|
|
51
|
-
return decodeHtmlBasic(str);
|
|
50
|
+
return (0, exports.decodeHtmlBasic)(str);
|
|
52
51
|
};
|
|
53
52
|
exports.decodeHtml = decodeHtml;
|
|
54
53
|
/** decode numbered HTML entities */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikilint",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.4",
|
|
4
4
|
"description": "A Node.js linter for MediaWiki markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@bhsd/common": "^0.
|
|
68
|
+
"@bhsd/common": "^0.9.1",
|
|
69
69
|
"vscode-languageserver-types": "^3.17.5"
|
|
70
70
|
},
|
|
71
71
|
"optionalDependencies": {
|