wikilint 2.46.2 → 2.46.3
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 +18 -0
- package/coverage/badge.svg +1 -1
- package/dist/base.d.mts +2 -3
- package/dist/base.d.ts +2 -3
- package/dist/bin/cli.js +11 -0
- package/dist/bin/config.js +1 -1
- package/dist/lib/lsp.d.ts +2 -2
- package/dist/lib/lsp.js +6 -3
- package/dist/lib/title.js +1 -1
- package/dist/mixin/attributesParent.js +3 -0
- package/dist/mixin/elementLike.js +4 -1
- package/dist/mixin/gapped.js +4 -0
- package/dist/mixin/hidden.js +4 -0
- package/dist/mixin/noEscape.js +4 -0
- package/dist/mixin/nodeLike.js +3 -0
- package/dist/mixin/padded.js +4 -0
- package/dist/mixin/paramLineParent.js +4 -1
- package/dist/parser/commentAndExt.js +4 -4
- package/dist/parser/links.js +3 -3
- package/dist/src/attributes.js +1 -1
- package/dist/src/link/base.js +5 -11
- package/dist/src/multiLine/gallery.js +19 -17
- package/dist/src/nested.js +1 -1
- package/dist/src/tagPair/ext.js +2 -2
- package/dist/src/tagPair/translate.js +2 -2
- package/dist/src/transclude.js +1 -1
- package/dist/util/lint.js +1 -1
- package/dist/util/string.js +1 -8
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ npm i mathoid-texvcjs vscode-css-languageservice
|
|
|
40
40
|
|
|
41
41
|
| Option | Argument | Description | Default |
|
|
42
42
|
| :----- | :------- | :---------- | :------ |
|
|
43
|
+
| `--` | | End of options | |
|
|
43
44
|
| `-c`, `--config` | \<path or preset config\> | Choose parser's [configuration](https://github.com/bhsd-harry/wikiparser-node/wiki/Parser-%28EN%29#config) | `default` |
|
|
44
45
|
| `--cache` | | Enable caching | `false` |
|
|
45
46
|
| `--cache-file` | \<path\> | Specify cache file and enable caching | `.wikilintcache` |
|
|
@@ -74,3 +75,20 @@ The generated configuration file will be saved in the `config` directory. You ca
|
|
|
74
75
|
# For example:
|
|
75
76
|
npx wikilint --config frwiki *.wiki
|
|
76
77
|
```
|
|
78
|
+
|
|
79
|
+
## Use with pre-commit
|
|
80
|
+
|
|
81
|
+
To use `wikilint` with [pre-commit](https://pre-commit.com/), add the following to your [`.pre-commit-config.yaml`](https://pre-commit.com/#adding-pre-commit-plugins-to-your-project):
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
repos:
|
|
85
|
+
- repo: local
|
|
86
|
+
hooks:
|
|
87
|
+
- id: wikilint
|
|
88
|
+
name: WikiLint
|
|
89
|
+
# You can add any CLI options as needed
|
|
90
|
+
entry: wikilint
|
|
91
|
+
language: node
|
|
92
|
+
additional_dependencies: ['wikilint@2.46.2']
|
|
93
|
+
files: \.(mediawiki|wiki|wikitext)$
|
|
94
|
+
```
|
package/coverage/badge.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="98" height="20" aria-label="Coverage: 95%"><title>Coverage: 95%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="98" height="20" fill="#fff" rx="3"/></clipPath><g clip-path="url(#r)"><path fill="#555" d="M0 0h63v20H0z"/><path fill="#4c1" d="M63 0h35v20H63z"/><path fill="url(#s)" d="M0 0h98v20H0z"/></g><g fill="#fff" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="110" text-anchor="middle" text-rendering="geometricPrecision"><text x="325" y="150" fill="#010101" fill-opacity=".3" aria-hidden="true" textLength="530" transform="scale(.1)">Coverage</text><text x="325" y="140" textLength="530" transform="scale(.1)">Coverage</text><text x="795" y="150" fill="#010101" fill-opacity=".3" aria-hidden="true" textLength="250" transform="scale(.1)">95%</text><text x="795" y="140" textLength="250" transform="scale(.1)">95%</text></g></svg>
|
package/dist/base.d.mts
CHANGED
|
@@ -128,11 +128,10 @@ export interface LanguageService {
|
|
|
128
128
|
* Provide color decorators
|
|
129
129
|
*
|
|
130
130
|
* 提供颜色指示
|
|
131
|
-
* @param rgba color parser / 颜色解析函数
|
|
132
131
|
* @param text source Wikitext / 源代码
|
|
133
|
-
* @param
|
|
132
|
+
* @param rgba color parser / 颜色解析函数
|
|
134
133
|
*/
|
|
135
|
-
provideDocumentColors(
|
|
134
|
+
provideDocumentColors(text: string, rgba?: (s: string) => [number, number, number, number] | []): Promise<ColorInformation[]>;
|
|
136
135
|
/**
|
|
137
136
|
* Provide color pickers
|
|
138
137
|
*
|
package/dist/base.d.ts
CHANGED
|
@@ -128,11 +128,10 @@ export interface LanguageService {
|
|
|
128
128
|
* Provide color decorators
|
|
129
129
|
*
|
|
130
130
|
* 提供颜色指示
|
|
131
|
-
* @param rgba color parser / 颜色解析函数
|
|
132
131
|
* @param text source Wikitext / 源代码
|
|
133
|
-
* @param
|
|
132
|
+
* @param rgba color parser / 颜色解析函数
|
|
134
133
|
*/
|
|
135
|
-
provideDocumentColors(
|
|
134
|
+
provideDocumentColors(text: string, rgba?: (s: string) => [number, number, number, number] | []): Promise<ColorInformation[]>;
|
|
136
135
|
/**
|
|
137
136
|
* Provide color pickers
|
|
138
137
|
*
|
package/dist/bin/cli.js
CHANGED
|
@@ -11,6 +11,7 @@ const util_1 = __importDefault(require("util"));
|
|
|
11
11
|
const index_1 = __importDefault(require("../index"));
|
|
12
12
|
const man = `
|
|
13
13
|
Available options:
|
|
14
|
+
-- End of options
|
|
14
15
|
-c, --config <path or preset config> Choose parser's configuration
|
|
15
16
|
--cache Enable caching
|
|
16
17
|
--cache-file <path> Specify cache file
|
|
@@ -228,6 +229,10 @@ for (let i = 2; i < argv.length; i++) {
|
|
|
228
229
|
process.exit(0);
|
|
229
230
|
break;
|
|
230
231
|
}
|
|
232
|
+
case '--':
|
|
233
|
+
files = [...files, ...argv.slice(i + 1)];
|
|
234
|
+
i = argv.length;
|
|
235
|
+
break;
|
|
231
236
|
default: {
|
|
232
237
|
let known = true;
|
|
233
238
|
if (option.includes('=')) {
|
|
@@ -277,6 +282,9 @@ if (quiet && strict) {
|
|
|
277
282
|
}
|
|
278
283
|
if (recursive) {
|
|
279
284
|
files = files.flatMap(file => {
|
|
285
|
+
if (!fs_1.default.existsSync(file)) {
|
|
286
|
+
return [];
|
|
287
|
+
}
|
|
280
288
|
if (fs_1.default.statSync(file).isFile()) {
|
|
281
289
|
return file;
|
|
282
290
|
}
|
|
@@ -347,6 +355,9 @@ const { mtimeMs } = fs_1.default.statSync(config), obj = cache?.[include ? 'incl
|
|
|
347
355
|
process.exit(0);
|
|
348
356
|
}
|
|
349
357
|
for (const file of new Set(files.map(f => path_1.default.resolve(f)))) {
|
|
358
|
+
if (!fs_1.default.existsSync(file)) {
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
350
361
|
const stat = fs_1.default.statSync(file);
|
|
351
362
|
if (stat.isDirectory()) {
|
|
352
363
|
console.error(`"${file}" is a directory. Please use -r or --recursive to lint directories.`);
|
package/dist/bin/config.js
CHANGED
|
@@ -41,7 +41,7 @@ const filterGadget = (id) => {
|
|
|
41
41
|
const n = Number(id);
|
|
42
42
|
return n < 2300 || n > 2303; // Gadget, Gadget talk, Gadget definition, Gadget definition talk
|
|
43
43
|
};
|
|
44
|
-
const pkg = 'wikilint', version = '2.46.
|
|
44
|
+
const pkg = 'wikilint', version = '2.46.3';
|
|
45
45
|
/**
|
|
46
46
|
* Get the parser configuration for a Wikimedia Foundation project.
|
|
47
47
|
* @param site site nickname
|
package/dist/lib/lsp.d.ts
CHANGED
|
@@ -22,10 +22,10 @@ export declare class LanguageService implements LanguageServiceBase {
|
|
|
22
22
|
* Provide color decorators
|
|
23
23
|
*
|
|
24
24
|
* 提供颜色指示
|
|
25
|
-
* @param rgba color parser / 颜色解析函数
|
|
26
25
|
* @param text source Wikitext / 源代码
|
|
26
|
+
* @param rgba color parser / 颜色解析函数
|
|
27
27
|
*/
|
|
28
|
-
provideDocumentColors(
|
|
28
|
+
provideDocumentColors(text: string, rgba?: (color: string) => [number, number, number, number] | []): Promise<ColorInformation[]>;
|
|
29
29
|
/**
|
|
30
30
|
* Provide color pickers
|
|
31
31
|
*
|
package/dist/lib/lsp.js
CHANGED
|
@@ -498,10 +498,13 @@ class LanguageService {
|
|
|
498
498
|
* Provide color decorators
|
|
499
499
|
*
|
|
500
500
|
* 提供颜色指示
|
|
501
|
-
* @param rgba color parser / 颜色解析函数
|
|
502
501
|
* @param text source Wikitext / 源代码
|
|
502
|
+
* @param rgba color parser / 颜色解析函数
|
|
503
503
|
*/
|
|
504
|
-
async provideDocumentColors(
|
|
504
|
+
async provideDocumentColors(text, rgba = color_1.rgba) {
|
|
505
|
+
if (typeof text === 'function' && typeof rgba === 'string') {
|
|
506
|
+
[rgba, text] = [text, rgba];
|
|
507
|
+
}
|
|
505
508
|
const root = await this.#queue(text);
|
|
506
509
|
return root.querySelectorAll('attr-value,parameter-value,arg-default').reverse().flatMap(token => {
|
|
507
510
|
const { type, childNodes,
|
|
@@ -608,7 +611,7 @@ class LanguageService {
|
|
|
608
611
|
const { re, allTags, functions, switches, jaSwitches, protocols, params, tags, ext, } = this.#prepareCompletionConfig(), { line, character } = position, curLine = text.split(/\r?\n/u, line + 1)[line], mt = re.exec(curLine?.slice(0, character) ?? ''), [, , iAlias, sAlias] = this.config.doubleUnderscore;
|
|
609
612
|
if (mt?.[1] !== undefined) { // tag
|
|
610
613
|
const closing = mt[1].startsWith('/');
|
|
611
|
-
return getCompletion(allTags, 'Class', mt[1].slice(closing ? 1 : 0), position, closing && !curLine?.slice(character).
|
|
614
|
+
return getCompletion(allTags, 'Class', mt[1].slice(closing ? 1 : 0), position, closing && !curLine?.slice(character).trimStart().startsWith('>') ? '>' : '');
|
|
612
615
|
}
|
|
613
616
|
else if (mt?.[4] || mt?.[5] && jaSwitches.length > 0) { // behavior switch
|
|
614
617
|
const isJa = mt[5] !== undefined;
|
package/dist/lib/title.js
CHANGED
|
@@ -8,7 +8,7 @@ const string_1 = require("../util/string");
|
|
|
8
8
|
* @param title 标题
|
|
9
9
|
*/
|
|
10
10
|
const resolve = (title) => {
|
|
11
|
-
const [, { length }, sub] = /^((?:\.\.\/)*)(
|
|
11
|
+
const [, { length }, sub] = /^((?:\.\.\/)*)(.*)/su.exec(title);
|
|
12
12
|
return [length / 3, sub];
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.attributesParent = void 0;
|
|
4
|
+
/* NOT FOR BROWSER ONLY */
|
|
4
5
|
const debug_1 = require("../util/debug");
|
|
5
6
|
/**
|
|
6
7
|
* 子节点含有AttributesToken的类
|
|
@@ -20,7 +21,9 @@ const attributesParent = (i = 0) => (constructor) => {
|
|
|
20
21
|
return this.#getAttributesChild().getAttr(key);
|
|
21
22
|
}
|
|
22
23
|
}
|
|
24
|
+
/* NOT FOR BROWSER ONLY */
|
|
23
25
|
(0, debug_1.mixin)(AttributesParent, constructor);
|
|
26
|
+
/* NOT FOR BROWSER ONLY END */
|
|
24
27
|
return AttributesParent;
|
|
25
28
|
}
|
|
26
29
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.elementLike = void 0;
|
|
4
|
-
const debug_1 = require("../util/debug");
|
|
5
4
|
const selector_1 = require("../util/selector");
|
|
5
|
+
/* NOT FOR BROWSER ONLY */
|
|
6
|
+
const debug_1 = require("../util/debug");
|
|
6
7
|
/** @ignore */
|
|
7
8
|
const elementLike = (constructor) => {
|
|
8
9
|
LINT: {
|
|
@@ -67,7 +68,9 @@ const elementLike = (constructor) => {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
}
|
|
71
|
+
/* NOT FOR BROWSER ONLY */
|
|
70
72
|
(0, debug_1.mixin)(ElementLike, constructor);
|
|
73
|
+
/* NOT FOR BROWSER ONLY END */
|
|
71
74
|
return ElementLike;
|
|
72
75
|
}
|
|
73
76
|
};
|
package/dist/mixin/gapped.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* NOT FOR BROWSER ONLY */
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.gapped = void 0;
|
|
4
5
|
const debug_1 = require("../util/debug");
|
|
6
|
+
/* NOT FOR BROWSER ONLY END */
|
|
5
7
|
/**
|
|
6
8
|
* 给定 gap 的类
|
|
7
9
|
* @param gap
|
|
@@ -12,7 +14,9 @@ const gapped = (gap = 1) => (constructor) => {
|
|
|
12
14
|
return gap;
|
|
13
15
|
}
|
|
14
16
|
}
|
|
17
|
+
/* NOT FOR BROWSER ONLY */
|
|
15
18
|
(0, debug_1.mixin)(GappedToken, constructor);
|
|
19
|
+
/* NOT FOR BROWSER ONLY END */
|
|
16
20
|
return GappedToken;
|
|
17
21
|
};
|
|
18
22
|
exports.gapped = gapped;
|
package/dist/mixin/hidden.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.hiddenToken = void 0;
|
|
4
|
+
/* NOT FOR BROWSER ONLY */
|
|
4
5
|
const debug_1 = require("../util/debug");
|
|
6
|
+
/* NOT FOR BROWSER ONLY END */
|
|
5
7
|
/**
|
|
6
8
|
* 解析后不可见的类
|
|
7
9
|
* @param linter 是否覆写 lint 方法
|
|
@@ -16,7 +18,9 @@ const hiddenToken = (linter = true, html = true) => (constructor) => {
|
|
|
16
18
|
LINT: return linter ? [] : super.lint(start);
|
|
17
19
|
}
|
|
18
20
|
}
|
|
21
|
+
/* NOT FOR BROWSER ONLY */
|
|
19
22
|
(0, debug_1.mixin)(AnyHiddenToken, constructor);
|
|
23
|
+
/* NOT FOR BROWSER ONLY END */
|
|
20
24
|
return AnyHiddenToken;
|
|
21
25
|
};
|
|
22
26
|
exports.hiddenToken = hiddenToken;
|
package/dist/mixin/noEscape.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* NOT FOR BROWSER ONLY */
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.noEscape = void 0;
|
|
4
5
|
const debug_1 = require("../util/debug");
|
|
6
|
+
/* NOT FOR BROWSER ONLY END */
|
|
5
7
|
/**
|
|
6
8
|
* 不需要转义的类
|
|
7
9
|
* @ignore
|
|
@@ -13,7 +15,9 @@ const noEscape = (constructor) => {
|
|
|
13
15
|
//
|
|
14
16
|
}
|
|
15
17
|
}
|
|
18
|
+
/* NOT FOR BROWSER ONLY */
|
|
16
19
|
(0, debug_1.mixin)(NoEscapeToken, constructor);
|
|
20
|
+
/* NOT FOR BROWSER ONLY END */
|
|
17
21
|
return NoEscapeToken;
|
|
18
22
|
}
|
|
19
23
|
};
|
package/dist/mixin/nodeLike.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.nodeLike = void 0;
|
|
4
|
+
/* NOT FOR BROWSER ONLY */
|
|
4
5
|
const debug_1 = require("../util/debug");
|
|
5
6
|
/** @ignore */
|
|
6
7
|
const nodeLike = (constructor) => {
|
|
@@ -18,7 +19,9 @@ const nodeLike = (constructor) => {
|
|
|
18
19
|
LINT: return this.getDimension().width;
|
|
19
20
|
}
|
|
20
21
|
}
|
|
22
|
+
/* NOT FOR BROWSER ONLY */
|
|
21
23
|
(0, debug_1.mixin)(NodeLike, constructor);
|
|
24
|
+
/* NOT FOR BROWSER ONLY END */
|
|
22
25
|
return NodeLike;
|
|
23
26
|
};
|
|
24
27
|
exports.nodeLike = nodeLike;
|
package/dist/mixin/padded.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* NOT FOR BROWSER ONLY */
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.padded = void 0;
|
|
4
5
|
const debug_1 = require("../util/debug");
|
|
6
|
+
/* NOT FOR BROWSER ONLY END */
|
|
5
7
|
/**
|
|
6
8
|
* 给定 padding 的类
|
|
7
9
|
* @param padding padding 字符串
|
|
@@ -13,7 +15,9 @@ const padded = ({ length }) => (constructor) => {
|
|
|
13
15
|
return key === 'padding' ? length : super.getAttribute(key);
|
|
14
16
|
}
|
|
15
17
|
}
|
|
18
|
+
/* NOT FOR BROWSER ONLY */
|
|
16
19
|
(0, debug_1.mixin)(PaddedToken, constructor);
|
|
20
|
+
/* NOT FOR BROWSER ONLY END */
|
|
17
21
|
return PaddedToken;
|
|
18
22
|
};
|
|
19
23
|
exports.padded = padded;
|
|
@@ -4,10 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.paramLineParent = void 0;
|
|
7
|
-
const debug_1 = require("../util/debug");
|
|
8
7
|
const lint_1 = require("../util/lint");
|
|
9
8
|
const rect_1 = require("../lib/rect");
|
|
10
9
|
const index_1 = __importDefault(require("../index"));
|
|
10
|
+
/* NOT FOR BROWSER ONLY */
|
|
11
|
+
const debug_1 = require("../util/debug");
|
|
11
12
|
/**
|
|
12
13
|
* 子节点为ParamLineToken的类
|
|
13
14
|
* @ignore
|
|
@@ -44,7 +45,9 @@ const paramLineParent = (constructor) => {
|
|
|
44
45
|
return errors;
|
|
45
46
|
}
|
|
46
47
|
}
|
|
48
|
+
/* NOT FOR BROWSER ONLY */
|
|
47
49
|
(0, debug_1.mixin)(ParamLineParent, constructor);
|
|
50
|
+
/* NOT FOR BROWSER ONLY END */
|
|
48
51
|
return ParamLineParent;
|
|
49
52
|
}
|
|
50
53
|
};
|
|
@@ -10,8 +10,8 @@ const ext_1 = require("../src/tagPair/ext");
|
|
|
10
10
|
const comment_1 = require("../src/nowiki/comment");
|
|
11
11
|
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft, getExtRegex = [false, true].map(includeOnly => {
|
|
12
12
|
const noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly';
|
|
13
|
-
return (0, common_1.getRegex)(exts => new RegExp(String.raw
|
|
14
|
-
})(\s[^>]*?)?(?:/>|>(
|
|
13
|
+
return (0, common_1.getRegex)(exts => new RegExp(String.raw `<!--.*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${exts // eslint-disable-next-line unicorn/prefer-string-raw
|
|
14
|
+
})(\s[^>]*?)?(?:/>|>(.*?)</(${'\\1'}\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>(.*?)(?:</(${includeRegex}\s*)>|$))`, 'gisu'));
|
|
15
15
|
});
|
|
16
16
|
/**
|
|
17
17
|
* 更新`<onlyinclude>`和`</onlyinclude>`的位置
|
|
@@ -65,10 +65,10 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
|
|
|
65
65
|
const stack = [];
|
|
66
66
|
newExt = ext.filter(e => e !== 'translate' && e !== 'tvar');
|
|
67
67
|
newConfig = { ...config, ext: newExt };
|
|
68
|
-
wikitext = wikitext.replace(/<nowiki
|
|
68
|
+
wikitext = wikitext.replace(/<nowiki>.*?<\/nowiki>/gisu, m => {
|
|
69
69
|
stack.push(m);
|
|
70
70
|
return `\0${stack.length - 1}\x7F`;
|
|
71
|
-
}).replace(/<translate( nowrap)?>(
|
|
71
|
+
}).replace(/<translate( nowrap)?>(.*?)<\/translate>/gsu, (_, p1, p2) => {
|
|
72
72
|
const l = accum.length;
|
|
73
73
|
// @ts-expect-error abstract class
|
|
74
74
|
new TranslateToken(p1, p2 && (0, string_1.restore)(p2, stack), newConfig, accum);
|
package/dist/parser/links.js
CHANGED
|
@@ -11,7 +11,7 @@ const externalLinks_1 = require("./externalLinks");
|
|
|
11
11
|
const index_2 = require("../src/link/index");
|
|
12
12
|
const file_1 = require("../src/link/file");
|
|
13
13
|
const category_1 = require("../src/link/category");
|
|
14
|
-
const regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(
|
|
14
|
+
const regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(.*)$/su;
|
|
15
15
|
/**
|
|
16
16
|
* 解析内部链接
|
|
17
17
|
* @param wikitext
|
|
@@ -23,8 +23,8 @@ const regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)([\s\S]*)$/u;
|
|
|
23
23
|
const parseLinks = (wikitext, config, accum, page, tidy) => {
|
|
24
24
|
config.regexLinks ??= new RegExp(String.raw `^\s*(?:${config.protocol}|//)`, 'iu');
|
|
25
25
|
const regex = config.inExt
|
|
26
|
-
? /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)([
|
|
27
|
-
: /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])*)(?:(\||\0\d+!\x7F)([
|
|
26
|
+
? /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]]))?\]\](.*)$/su
|
|
27
|
+
: /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])*)(?:(\||\0\d+!\x7F)(.*?[^\]])?)?\]\](.*)$/su, bits = wikitext.split('[[');
|
|
28
28
|
let s = bits.shift();
|
|
29
29
|
for (let i = 0; i < bits.length; i++) {
|
|
30
30
|
let mightBeImg = false, link, delimiter, text, after;
|
package/dist/src/attributes.js
CHANGED
|
@@ -62,7 +62,7 @@ class AttributesToken extends index_2.Token {
|
|
|
62
62
|
this.#type = type;
|
|
63
63
|
this.setAttribute('name', name);
|
|
64
64
|
if (attr) {
|
|
65
|
-
const regex = /([^\s/](?:(?!\0\d+~\x7F)[^\s/=])*)(?:((?:\s(?:\s|\0\d+[cn]\x7F)*)?(?:=|\0\d+~\x7F)(?:\s|\0\d+[cn]\x7F)*)(?:(["'])(
|
|
65
|
+
const regex = /([^\s/](?:(?!\0\d+~\x7F)[^\s/=])*)(?:((?:\s(?:\s|\0\d+[cn]\x7F)*)?(?:=|\0\d+~\x7F)(?:\s|\0\d+[cn]\x7F)*)(?:(["'])(.*?)(\3|$)|(\S*)))?/gsu;
|
|
66
66
|
let out = '', mt = regex.exec(attr), lastIndex = 0;
|
|
67
67
|
const insertDirty = /** 插入无效属性 */ () => {
|
|
68
68
|
if (out) {
|
package/dist/src/link/base.js
CHANGED
|
@@ -131,18 +131,12 @@ let LinkBaseToken = (() => {
|
|
|
131
131
|
}
|
|
132
132
|
/** @private */
|
|
133
133
|
text() {
|
|
134
|
-
const { length, firstChild, childNodes, type, } = this, target = firstChild.text()
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
(0, string_1.trimStart)(target) :
|
|
140
|
-
target.trim();
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
str = `${target.trim()}|${(0, string_1.text)(childNodes.slice(1)
|
|
134
|
+
const { length, firstChild, childNodes, type, } = this, target = firstChild.text(), str = length === 1
|
|
135
|
+
? target[type === 'link' ?
|
|
136
|
+
'trimStart' :
|
|
137
|
+
'trim']()
|
|
138
|
+
: `${target.trim()}|${(0, string_1.text)(childNodes.slice(1)
|
|
144
139
|
.filter(({ type: t, name }) => t !== 'image-parameter' || name !== 'invalid'), '|')}`;
|
|
145
|
-
}
|
|
146
140
|
if (this.#bracket) {
|
|
147
141
|
return `[[${str}]]`;
|
|
148
142
|
}
|
|
@@ -17,24 +17,26 @@ class GalleryToken extends index_2.MultiLineToken {
|
|
|
17
17
|
/** @param inner 标签内部wikitext */
|
|
18
18
|
constructor(inner, config, accum = []) {
|
|
19
19
|
super(undefined, config, accum, {});
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
if (inner) {
|
|
21
|
+
for (const line of inner.split('\n')) {
|
|
22
|
+
const matches = /^([^|]+)(?:\|(.*))?/u.exec(line);
|
|
23
|
+
if (!matches) {
|
|
24
|
+
super.insertAt((line.trim()
|
|
25
|
+
// @ts-expect-error abstract class
|
|
26
|
+
? new commentLine_1.CommentLineToken(line, config, accum)
|
|
27
|
+
: line));
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const [, file, alt] = matches;
|
|
31
|
+
if (this.#checkFile(file)) {
|
|
24
32
|
// @ts-expect-error abstract class
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
super.insertAt(new galleryImage_1.GalleryImageToken('gallery', file, alt, config, accum));
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
super.insertAt(
|
|
36
|
-
// @ts-expect-error abstract class
|
|
37
|
-
new commentLine_1.CommentLineToken(line, config, accum));
|
|
33
|
+
super.insertAt(new galleryImage_1.GalleryImageToken('gallery', file, alt, config, accum));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
super.insertAt(
|
|
37
|
+
// @ts-expect-error abstract class
|
|
38
|
+
new commentLine_1.CommentLineToken(line, config, accum));
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
}
|
package/dist/src/nested.js
CHANGED
|
@@ -64,7 +64,7 @@ class NestedToken extends index_2.Token {
|
|
|
64
64
|
if (!s) {
|
|
65
65
|
return errors;
|
|
66
66
|
}
|
|
67
|
-
const rect = new rect_1.BoundingRect(this, start), msg = index_1.default.msg('invalid-content', name), regex = typeof this.#regex === 'boolean' ? lintRegex[this.#regex ? 1 : 0] :
|
|
67
|
+
const rect = new rect_1.BoundingRect(this, start), msg = index_1.default.msg('invalid-content', name), regex = typeof this.#regex === 'boolean' ? lintRegex[this.#regex ? 1 : 0] : /^<!--.*-->$/su, ignored = childNodes.filter(child => {
|
|
68
68
|
const { type, name: n } = child;
|
|
69
69
|
if (type === 'ext') {
|
|
70
70
|
return !this.#tags.includes(n);
|
package/dist/src/tagPair/ext.js
CHANGED
|
@@ -152,14 +152,14 @@ let ExtToken = (() => {
|
|
|
152
152
|
// NestedToken 依赖 ExtToken
|
|
153
153
|
const { NestedToken } = require('../nested');
|
|
154
154
|
// @ts-expect-error abstract class
|
|
155
|
-
innerToken = new NestedToken(inner, /<(option|choicetemplate)(\s[^>]*?)?(?:\/>|>(
|
|
155
|
+
innerToken = new NestedToken(inner, /<(option|choicetemplate)(\s[^>]*?)?(?:\/>|>(.*?)<\/(\1)>)/gsu, ['option', 'choicetemplate'], newConfig, accum);
|
|
156
156
|
break;
|
|
157
157
|
}
|
|
158
158
|
case 'combobox': {
|
|
159
159
|
// NestedToken 依赖 ExtToken
|
|
160
160
|
const { NestedToken } = require('../nested');
|
|
161
161
|
// @ts-expect-error abstract class
|
|
162
|
-
innerToken = new NestedToken(inner, /<(combooption)(\s[^>]*?)?(?:\/>|>(
|
|
162
|
+
innerToken = new NestedToken(inner, /<(combooption)(\s[^>]*?)?(?:\/>|>(.*?)<\/(combooption\s*)>)/gisu, ['combooption'], newConfig, accum);
|
|
163
163
|
break;
|
|
164
164
|
}
|
|
165
165
|
case 'gallery': {
|
|
@@ -22,13 +22,13 @@ class TranslateToken extends index_2.TagPairToken {
|
|
|
22
22
|
*/
|
|
23
23
|
constructor(attr, inner, config, accum = []) {
|
|
24
24
|
const attrToken = new syntax_1.SyntaxToken(attr, 'translate-attr', config, accum);
|
|
25
|
-
inner = inner?.replace(/<tvar(\|[^>]+)>(
|
|
25
|
+
inner = inner?.replace(/<tvar(\|[^>]+)>(.*?)<\/>/gsu, (_, p1, p2) => {
|
|
26
26
|
// @ts-expect-error abstract class
|
|
27
27
|
new tvar_1.TvarToken('tvar', p1, false, config, accum);
|
|
28
28
|
// @ts-expect-error abstract class
|
|
29
29
|
new tvar_1.TvarToken('', '', true, config, accum);
|
|
30
30
|
return `\0${accum.length - 2}n\x7F${p2}\0${accum.length}n\x7F`;
|
|
31
|
-
}).replace(/<(tvar)(\s+name\s*=(?:\s*(?:(["'])
|
|
31
|
+
}).replace(/<(tvar)(\s+name\s*=(?:\s*(?:(["']).*?\3|[^"'\s>]+))?\s*)>(.*?)<\/(tvar)(\s*)>/gisu, (_, p1, p2, __, p3, p4, p5) => {
|
|
32
32
|
// @ts-expect-error abstract class
|
|
33
33
|
new tvar_1.TvarToken(p1, p2, false, config, accum);
|
|
34
34
|
// @ts-expect-error abstract class
|
package/dist/src/transclude.js
CHANGED
|
@@ -129,7 +129,7 @@ let TranscludeToken = (() => {
|
|
|
129
129
|
}
|
|
130
130
|
const colon = title.search(/[::]/u), fullWidth = title[colon] === ':', isFunction = colon !== -1;
|
|
131
131
|
if (isFunction || parts.length === 0 && !this.#raw) {
|
|
132
|
-
const magicWord = isFunction ? title.slice(0, colon) : title, arg = isFunction && title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = isFunction ?
|
|
132
|
+
const magicWord = isFunction ? title.slice(0, colon) : title, arg = isFunction && title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = isFunction ? cleaned.trimStart() + (fullWidth ? ':' : '') : cleaned.trim(),
|
|
133
133
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
134
134
|
[, isSensitive, canonicalName] = (0, debug_1.getMagicWordInfo)(name, parserFunction), isFunc = !('functionHook' in config) || functionHook.includes(canonicalName), isVar = variable.includes(canonicalName);
|
|
135
135
|
if (isFunction ? canonicalName && isFunc : isVar) {
|
package/dist/util/lint.js
CHANGED
|
@@ -16,7 +16,7 @@ const tableTags = new Set(['tr', 'td', 'th', 'caption']), tableTemplates = new S
|
|
|
16
16
|
const isFostered = (token) => {
|
|
17
17
|
const first = token.childNodes.find(child => child.text().trim());
|
|
18
18
|
if (!first
|
|
19
|
-
|| first.type === 'text' && first.data.
|
|
19
|
+
|| first.type === 'text' && first.data.trimStart().startsWith('!')
|
|
20
20
|
|| first.is('magic-word') && first.name === '!'
|
|
21
21
|
|| first.is('template') && tableTemplates.has(first.name)
|
|
22
22
|
|| first.is('html') && tableTags.has(first.name)) {
|
package/dist/util/string.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toLowerCase = exports.decodeNumber = exports.decodeHtml = exports.decodeHtmlBasic = exports.text = exports.removeCommentLine = exports.removeComment = exports.tidy = exports.
|
|
3
|
+
exports.toLowerCase = exports.decodeNumber = exports.decodeHtml = exports.decodeHtmlBasic = exports.text = exports.removeCommentLine = exports.removeComment = exports.tidy = exports.trimLc = exports.extUrlChar = exports.extUrlCharFirst = exports.zs = void 0;
|
|
4
4
|
exports.restore = restore;
|
|
5
|
-
const common_1 = require("@bhsd/common");
|
|
6
5
|
exports.zs = String.raw ` \xA0\u1680\u2000-\u200A\u202F\u205F\u3000`;
|
|
7
6
|
const commonExtUrlChar = String.raw `[^[\]<>"\0-\x1F\x7F${exports.zs}\uFFFD]`;
|
|
8
7
|
exports.extUrlCharFirst = String.raw `(?:\[[\da-f:.]+\]|${commonExtUrlChar})`;
|
|
@@ -13,12 +12,6 @@ exports.extUrlChar = String.raw `(?:${commonExtUrlChar}|\0\d+[cn!~]\x7F)*`;
|
|
|
13
12
|
*/
|
|
14
13
|
const trimLc = (s) => s.trim().toLowerCase();
|
|
15
14
|
exports.trimLc = trimLc;
|
|
16
|
-
/**
|
|
17
|
-
* trim starting whitespaces
|
|
18
|
-
* @param s 字符串
|
|
19
|
-
*/
|
|
20
|
-
const trimStart = (s) => s.slice((0, common_1.numLeadingSpaces)(s));
|
|
21
|
-
exports.trimStart = trimStart;
|
|
22
15
|
function restore(s, stack, translate) {
|
|
23
16
|
if (translate === 1) {
|
|
24
17
|
return s.replace(/\0(\d+)g\x7F/gu, (_, p1) => restore(String(stack[p1]), stack, 2));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikilint",
|
|
3
|
-
"version": "2.46.
|
|
3
|
+
"version": "2.46.3",
|
|
4
4
|
"description": "A Node.js linter for MediaWiki markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -98,22 +98,22 @@
|
|
|
98
98
|
}
|
|
99
99
|
},
|
|
100
100
|
"dependencies": {
|
|
101
|
-
"@bhsd/cm-util": "^2.4.
|
|
102
|
-
"@bhsd/common": "^4.0
|
|
101
|
+
"@bhsd/cm-util": "^2.4.1",
|
|
102
|
+
"@bhsd/common": "^4.1.0",
|
|
103
103
|
"@bhsd/stylelint-util": "^1.1.0",
|
|
104
104
|
"culori": "^4.0.2",
|
|
105
105
|
"entities": "^8.0.0",
|
|
106
106
|
"vscode-languageserver-types": "^3.18.0"
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
|
-
"@bhsd/code-standard": "^4.
|
|
109
|
+
"@bhsd/code-standard": "^4.1.0",
|
|
110
110
|
"@bhsd/nodejs": "^1.2.1",
|
|
111
|
-
"@bhsd/test-util": "^3.1.
|
|
111
|
+
"@bhsd/test-util": "^3.1.1",
|
|
112
112
|
"c8": "^12.0.0",
|
|
113
113
|
"diff2html-cli": "^5.2.15",
|
|
114
|
-
"esbuild": "^0.28.
|
|
115
|
-
"eslint": "^10.8.
|
|
116
|
-
"markdownlint-cli2": "^0.23.
|
|
114
|
+
"esbuild": "^0.28.2",
|
|
115
|
+
"eslint": "^10.8.1",
|
|
116
|
+
"markdownlint-cli2": "^0.23.2",
|
|
117
117
|
"mathoid-texvcjs": "^0.6.0",
|
|
118
118
|
"stylelint": "^17.14.1",
|
|
119
119
|
"typescript": "^6.0.3",
|