wikilint 2.46.1 → 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 +19 -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/index.js +2 -1
- package/dist/lib/lsp.d.ts +2 -2
- package/dist/lib/lsp.js +29 -26
- package/dist/lib/text.js +5 -3
- package/dist/lib/title.js +4 -5
- 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/parser/magicLinks.js +4 -5
- package/dist/src/arg.js +6 -7
- package/dist/src/attribute.js +4 -4
- package/dist/src/attributes.js +1 -1
- package/dist/src/heading.js +1 -1
- package/dist/src/imageParameter.js +11 -13
- package/dist/src/index.js +1 -1
- package/dist/src/link/base.js +5 -11
- package/dist/src/magicLink.js +0 -1
- package/dist/src/multiLine/gallery.js +19 -17
- package/dist/src/nested.js +1 -1
- package/dist/src/nowiki/quote.js +2 -2
- package/dist/src/table/td.js +1 -1
- package/dist/src/tagPair/ext.js +2 -2
- package/dist/src/tagPair/include.js +1 -1
- package/dist/src/tagPair/translate.js +2 -2
- package/dist/src/transclude.js +41 -32
- package/dist/util/lint.js +1 -1
- package/dist/util/sharable.js +0 -1
- package/dist/util/string.js +1 -8
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
[](https://github.com/bhsd-harry/wikiparser-node/actions/workflows/node.js.yml)
|
|
8
8
|
[](https://www.npmjs.com/package/wikilint)
|
|
9
9
|

|
|
10
|
+
[](https://www.bestpractices.dev/projects/13661)
|
|
10
11
|
|
|
11
12
|
This is a minimal version of [WikiParser-Node](https://www.npmjs.com/package/wikiparser-node). The [Wikitext LSP](https://www.npmjs.com/package/wikitext-lsp) and the [WikiParser Language Server](https://marketplace.visualstudio.com/items?itemName=Bhsd.vscode-extension-wikiparser) VS Code extension is written based on this package.
|
|
12
13
|
|
|
@@ -39,6 +40,7 @@ npm i mathoid-texvcjs vscode-css-languageservice
|
|
|
39
40
|
|
|
40
41
|
| Option | Argument | Description | Default |
|
|
41
42
|
| :----- | :------- | :---------- | :------ |
|
|
43
|
+
| `--` | | End of options | |
|
|
42
44
|
| `-c`, `--config` | \<path or preset config\> | Choose parser's [configuration](https://github.com/bhsd-harry/wikiparser-node/wiki/Parser-%28EN%29#config) | `default` |
|
|
43
45
|
| `--cache` | | Enable caching | `false` |
|
|
44
46
|
| `--cache-file` | \<path\> | Specify cache file and enable caching | `.wikilintcache` |
|
|
@@ -73,3 +75,20 @@ The generated configuration file will be saved in the `config` directory. You ca
|
|
|
73
75
|
# For example:
|
|
74
76
|
npx wikilint --config frwiki *.wiki
|
|
75
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/index.js
CHANGED
|
@@ -135,7 +135,7 @@ const Parser = {
|
|
|
135
135
|
/** @implements */
|
|
136
136
|
msg(msg, arg = '') {
|
|
137
137
|
LINT: return msg
|
|
138
|
-
&& (this.i18n[msg] ?? msg).replace('$1', this.msg(arg));
|
|
138
|
+
&& (this.i18n[msg] ?? msg).replace('$1', () => this.msg(arg));
|
|
139
139
|
},
|
|
140
140
|
/** @implements */
|
|
141
141
|
normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt, accum = []) {
|
|
@@ -191,6 +191,7 @@ const Parser = {
|
|
|
191
191
|
}
|
|
192
192
|
maxStage ??= constants_1.MAX_STAGE;
|
|
193
193
|
config ??= this.getConfig();
|
|
194
|
+
// eslint-disable-next-line unicorn/prefer-smaller-scope
|
|
194
195
|
let types;
|
|
195
196
|
LSP: if (typeof maxStage !== 'number') {
|
|
196
197
|
types = Array.isArray(maxStage) ? maxStage : [maxStage];
|
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
|
@@ -324,6 +324,7 @@ function getStylelintPos(rect, bottom, lineOrCode, columnOrOffset) {
|
|
|
324
324
|
return (0, lint_1.getEndPos)(top, left, ...adjustPos(height, width, lineOrCode - start, columnOrOffset));
|
|
325
325
|
}
|
|
326
326
|
const lines = lineOrCode.slice(0, columnOrOffset).split(/\r?\n/u);
|
|
327
|
+
// eslint-disable-next-line unicorn/no-useless-recursion
|
|
327
328
|
return getStylelintPos(rect, bottom, lines.length, lines.at(-1).length);
|
|
328
329
|
}
|
|
329
330
|
/**
|
|
@@ -497,10 +498,13 @@ class LanguageService {
|
|
|
497
498
|
* Provide color decorators
|
|
498
499
|
*
|
|
499
500
|
* 提供颜色指示
|
|
500
|
-
* @param rgba color parser / 颜色解析函数
|
|
501
501
|
* @param text source Wikitext / 源代码
|
|
502
|
+
* @param rgba color parser / 颜色解析函数
|
|
502
503
|
*/
|
|
503
|
-
async provideDocumentColors(
|
|
504
|
+
async provideDocumentColors(text, rgba = color_1.rgba) {
|
|
505
|
+
if (typeof text === 'function' && typeof rgba === 'string') {
|
|
506
|
+
[rgba, text] = [text, rgba];
|
|
507
|
+
}
|
|
504
508
|
const root = await this.#queue(text);
|
|
505
509
|
return root.querySelectorAll('attr-value,parameter-value,arg-default').reverse().flatMap(token => {
|
|
506
510
|
const { type, childNodes,
|
|
@@ -576,7 +580,7 @@ class LanguageService {
|
|
|
576
580
|
+ '|'
|
|
577
581
|
// attribute key ($8, $10)
|
|
578
582
|
+ String.raw `<(\w+)(?:\s(?:[^<>{}|=\s]+(?:\s*=\s*(?:[^\s"']\S*|(["']).*?\9))?(?=\s))*)?\s(\w*)`
|
|
579
|
-
+ ')$', 'iu'), allSwitches = doubleUnderscore.slice(0, 2).flat();
|
|
583
|
+
+ ')$', 'iu'), allSwitches = doubleUnderscore.slice(0, 2).flat().map(s => s.toUpperCase());
|
|
580
584
|
this.#completionConfig = [
|
|
581
585
|
{
|
|
582
586
|
re,
|
|
@@ -607,7 +611,7 @@ class LanguageService {
|
|
|
607
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;
|
|
608
612
|
if (mt?.[1] !== undefined) { // tag
|
|
609
613
|
const closing = mt[1].startsWith('/');
|
|
610
|
-
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('>') ? '>' : '');
|
|
611
615
|
}
|
|
612
616
|
else if (mt?.[4] || mt?.[5] && jaSwitches.length > 0) { // behavior switch
|
|
613
617
|
const isJa = mt[5] !== undefined;
|
|
@@ -639,11 +643,12 @@ class LanguageService {
|
|
|
639
643
|
return getCompletion(root.querySelectorAll('arg').filter(token => token.name && token !== cur)
|
|
640
644
|
.map(({ name }) => name), 'Variable', match, position);
|
|
641
645
|
}
|
|
642
|
-
const [insensitive, sensitive] = this.config.parserFunction,
|
|
646
|
+
const [insensitive, sensitive] = this.config.parserFunction, colon = match.startsWith(':'), str = colon ? match.slice(1).trimStart() : match;
|
|
643
647
|
if (mt[2] === '[[') { // link
|
|
644
648
|
return getCompletion(root.querySelectorAll('link,file,category,redirect-target').filter(token => token !== cur).map(({ name }) => name), 'Folder', str, position);
|
|
645
649
|
}
|
|
646
650
|
// parser function or template
|
|
651
|
+
const next = curLine.charAt(character);
|
|
647
652
|
let words = functions;
|
|
648
653
|
if (next === ':') {
|
|
649
654
|
words = functions.filter(s => !s.endsWith(':'));
|
|
@@ -687,20 +692,20 @@ class LanguageService {
|
|
|
687
692
|
}
|
|
688
693
|
({ type, parentNode } = cur);
|
|
689
694
|
}
|
|
690
|
-
if (mt?.[7] !== undefined
|
|
695
|
+
if (type === 'image-parameter' || mt?.[7] !== undefined) { // image parameter
|
|
691
696
|
const index = root.indexFromPos(line, character), match = mt?.[7]?.trimStart()
|
|
692
697
|
?? this.#text.slice(cur.getAbsoluteIndex(), index).trimStart(), equal = this.#text[index] === '=';
|
|
693
698
|
return getCompletion(params, 'Property', match, position)
|
|
694
699
|
.filter(({ label }) => !equal || !/[= ]$/u.test(label));
|
|
695
700
|
}
|
|
696
|
-
else if (mt?.[8] !== undefined
|
|
697
|
-
const tag = mt?.[8]?.toLowerCase() ?? parentNode.tag
|
|
698
|
-
?? cur.toString().slice(0, character - root.posFromIndex(cur.getAbsoluteIndex()).left);
|
|
701
|
+
else if (type === 'attr-key' || mt?.[8] !== undefined) { // attribute key
|
|
702
|
+
const tag = mt?.[8]?.toLowerCase() ?? parentNode.tag;
|
|
699
703
|
if (!tags.has(tag)) {
|
|
700
704
|
return undefined;
|
|
701
705
|
}
|
|
702
|
-
const
|
|
703
|
-
|
|
706
|
+
const key = mt?.[10]
|
|
707
|
+
?? cur.toString().slice(0, character - root.posFromIndex(cur.getAbsoluteIndex()).left), thisHtmlAttrs = sharable_1.htmlAttrs[tag], thisExtAttrs = sharable_1.extAttrs[tag], extCompletion = thisExtAttrs && getCompletion(thisExtAttrs, 'Field', key, position);
|
|
708
|
+
return !thisHtmlAttrs && ext.includes(tag)
|
|
704
709
|
? extCompletion
|
|
705
710
|
: [
|
|
706
711
|
...extCompletion ?? [],
|
|
@@ -871,18 +876,16 @@ class LanguageService {
|
|
|
871
876
|
source: 'Stylelint',
|
|
872
877
|
code: rule,
|
|
873
878
|
message: msg.slice(0, msg.lastIndexOf('(') - 1),
|
|
874
|
-
...fix
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
}
|
|
885
|
-
: {},
|
|
879
|
+
...fix && {
|
|
880
|
+
data: [
|
|
881
|
+
{
|
|
882
|
+
range: getStylelintPos(rects[i], bottoms[i], code, fix.range),
|
|
883
|
+
newText: fix.text,
|
|
884
|
+
title: `Fix: ${rule}`,
|
|
885
|
+
fix: true,
|
|
886
|
+
},
|
|
887
|
+
],
|
|
888
|
+
},
|
|
886
889
|
};
|
|
887
890
|
});
|
|
888
891
|
}
|
|
@@ -1321,7 +1324,7 @@ class LanguageService {
|
|
|
1321
1324
|
f = offsetNode.text().trim();
|
|
1322
1325
|
colon = parentNode.getAttribute('colon');
|
|
1323
1326
|
}
|
|
1324
|
-
else if (offsetNode.is('magic-word') && !offsetNode.modifier
|
|
1327
|
+
else if (length === 1 && offsetNode.is('magic-word') && !offsetNode.modifier
|
|
1325
1328
|
&& (offset > 0 || root.posFromIndex(offsetNode.getAbsoluteIndex()).left === position.character)) {
|
|
1326
1329
|
info = this.#getParserFunction(name);
|
|
1327
1330
|
f = offsetNode.firstChild.text().trim();
|
|
@@ -1432,9 +1435,9 @@ class LanguageService {
|
|
|
1432
1435
|
label: `{{${f}${params.length === 0 ? '' : colon}${params.map(({ label }) => label).join('|')}}}`,
|
|
1433
1436
|
parameters: params.map(({ label, const: c }) => ({
|
|
1434
1437
|
label,
|
|
1435
|
-
...c
|
|
1438
|
+
...c && { documentation: 'Predefined parameter' },
|
|
1436
1439
|
})),
|
|
1437
|
-
...params.length < n
|
|
1440
|
+
...params.length < n && { activeParameter: Math.min(j, params.length - 1) },
|
|
1438
1441
|
})),
|
|
1439
1442
|
activeParameter: j,
|
|
1440
1443
|
};
|
package/dist/lib/text.js
CHANGED
|
@@ -100,7 +100,8 @@ class AstText extends node_1.AstNode {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
errorRegex ??= parentNode.isPlain() && !noLinkTypes.has(type) ? errorSyntax : errorSyntaxUrl;
|
|
103
|
-
|
|
103
|
+
errorRegex.lastIndex = 0;
|
|
104
|
+
if (!errorRegex.test(data)) {
|
|
104
105
|
return [];
|
|
105
106
|
}
|
|
106
107
|
errorRegex.lastIndex = 0;
|
|
@@ -127,7 +128,7 @@ class AstText extends node_1.AstNode {
|
|
|
127
128
|
}
|
|
128
129
|
else if (error.startsWith('<') && !tags.has(tag.toLowerCase())
|
|
129
130
|
|| lbrackInExtLinkText && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
|
|
130
|
-
|| nextSibling?.is('ext')
|
|
131
|
+
|| nextName === 'nowiki' && nextSibling?.is('ext')
|
|
131
132
|
&& nextSibling.innerText?.includes(']'))) {
|
|
132
133
|
continue;
|
|
133
134
|
}
|
|
@@ -142,7 +143,7 @@ class AstText extends node_1.AstNode {
|
|
|
142
143
|
errorRegex.lastIndex--;
|
|
143
144
|
}
|
|
144
145
|
// Rule & Severity
|
|
145
|
-
let startIndex = start + index, endIndex = startIndex + length, rule, severity
|
|
146
|
+
let startIndex = start + index, endIndex = startIndex + length, rule, severity;
|
|
146
147
|
const nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], leftBracket = lbrace || lbrack, lConverter = error === '{' && previousChar === '-' && variants.length > 0, rConverter = error === '}' && nextChar === '-' && variants.length > 0, brokenExtLink = lbrack && nextType === 'free-ext-link' && !data.slice(index + 1).trim()
|
|
147
148
|
|| rbrack && previousType === 'free-ext-link' && index === 0;
|
|
148
149
|
if (magicLink) {
|
|
@@ -222,6 +223,7 @@ class AstText extends node_1.AstNode {
|
|
|
222
223
|
}
|
|
223
224
|
// LintError
|
|
224
225
|
const pos = this.posFromIndex(index), { line: startLine, character: startCol } = (0, lint_1.getEndPos)(top, left, pos.top + 1, pos.left);
|
|
226
|
+
let endLine, endCol;
|
|
225
227
|
if (char === '=') {
|
|
226
228
|
const lineEnd = data.indexOf('\n', index);
|
|
227
229
|
let sibling = nextSibling, line;
|
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
|
/**
|
|
@@ -188,10 +188,9 @@ class Title {
|
|
|
188
188
|
}
|
|
189
189
|
const { title, fragment } = this;
|
|
190
190
|
if (title) {
|
|
191
|
-
return this.#path.replace('$1', encodeURIComponent(title)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
: ''));
|
|
191
|
+
return this.#path.replace('$1', () => encodeURIComponent(title) + (fragment
|
|
192
|
+
? `#${encodeURIComponent(fragment)}`
|
|
193
|
+
: ''));
|
|
195
194
|
}
|
|
196
195
|
return fragment === undefined ? '' : `#${encodeURIComponent(fragment)}`;
|
|
197
196
|
}
|
|
@@ -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;
|
|
@@ -31,11 +31,10 @@ const parseMagicLinks = (wikitext, config, accum) => {
|
|
|
31
31
|
}
|
|
32
32
|
const sep = url.includes('(') ? /[^,;\\.:!?][,;\\.:!?]+$/u : /[^,;\\.:!?)][,;\\.:!?)]+$/u, sepChars = sep.exec(url);
|
|
33
33
|
if (sepChars) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
34
|
+
const correction = sepChars[0][1] === ';'
|
|
35
|
+
&& /&(?:[a-z]+|#x[\da-f]+|#\d+)$/iu.test(url.slice(0, sepChars.index))
|
|
36
|
+
? 2
|
|
37
|
+
: 1;
|
|
39
38
|
trail = url.slice(sepChars.index + correction) + trail;
|
|
40
39
|
url = url.slice(0, sepChars.index + correction);
|
|
41
40
|
}
|
package/dist/src/arg.js
CHANGED
|
@@ -76,20 +76,19 @@ let ArgToken = (() => {
|
|
|
76
76
|
super(undefined, config, accum, {});
|
|
77
77
|
for (let i = 0; i < parts.length; i++) {
|
|
78
78
|
const part = parts[i];
|
|
79
|
+
let token;
|
|
79
80
|
if (i === 0) {
|
|
80
|
-
|
|
81
|
-
super.insertAt(token);
|
|
81
|
+
token = new atom_1.AtomToken(part, 'arg-name', config, accum, {});
|
|
82
82
|
}
|
|
83
83
|
else if (i > 1) {
|
|
84
|
-
|
|
85
|
-
super.insertAt(token);
|
|
84
|
+
token = new hidden_1.HiddenToken(part, config, accum);
|
|
86
85
|
}
|
|
87
86
|
else {
|
|
88
|
-
|
|
87
|
+
token = new index_2.Token(part, config, accum);
|
|
89
88
|
token.type = 'arg-default';
|
|
90
89
|
token.setAttribute('stage', 2);
|
|
91
|
-
super.insertAt(token);
|
|
92
90
|
}
|
|
91
|
+
super.insertAt(token);
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
/** @private */
|
|
@@ -122,7 +121,7 @@ let ArgToken = (() => {
|
|
|
122
121
|
let rule = 'no-arg', s = lintConfig.getSeverity(rule);
|
|
123
122
|
if (s && !this.getAttribute('include')) {
|
|
124
123
|
const e = (0, lint_1.generateForSelf)(this, rect, rule, 'unexpected-argument', s), [, argDefault] = this.childNodes;
|
|
125
|
-
if (lintConfig.computeEditInfo
|
|
124
|
+
if (argDefault && lintConfig.computeEditInfo) {
|
|
126
125
|
e.suggestions = [(0, lint_1.fixBy)(e, 'expand', argDefault.text())];
|
|
127
126
|
}
|
|
128
127
|
errors.push(e);
|
package/dist/src/attribute.js
CHANGED
|
@@ -66,7 +66,7 @@ class AttributeToken extends index_2.Token {
|
|
|
66
66
|
}
|
|
67
67
|
else if (tag === 'gallery' && key === 'caption'
|
|
68
68
|
|| tag === 'ref' && key === 'details'
|
|
69
|
-
||
|
|
69
|
+
|| key === 'text' && (tag === 'mapframe' || tag === 'maplink')
|
|
70
70
|
|| tag === 'choose' && (key === 'before' || key === 'after')) {
|
|
71
71
|
const newConfig = {
|
|
72
72
|
...config,
|
|
@@ -203,7 +203,7 @@ class AttributeToken extends index_2.Token {
|
|
|
203
203
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
204
204
|
LINT: {
|
|
205
205
|
const errors = super.lint(start, re), { balanced, firstChild, lastChild, name, tag } = this, rect = new rect_1.BoundingRect(this, start), rules = ['unclosed-quote', 'obsolete-attr'], { lintConfig } = index_1.default, s = rules.map(rule => lintConfig.getSeverity(rule, name));
|
|
206
|
-
if (s[0]
|
|
206
|
+
if (!balanced && s[0]) {
|
|
207
207
|
const e = (0, lint_1.generateForChild)(lastChild, rect, rules[0], 'unclosed-quotes', s[0]);
|
|
208
208
|
e.startIndex--;
|
|
209
209
|
e.startCol--;
|
|
@@ -221,8 +221,8 @@ class AttributeToken extends index_2.Token {
|
|
|
221
221
|
}
|
|
222
222
|
/* NOT FOR BROWSER ONLY */
|
|
223
223
|
const rule = 'invalid-css', sError = lintConfig.getSeverity(rule), sWarn = lintConfig.getSeverity(rule, 'warn');
|
|
224
|
-
if (
|
|
225
|
-
&&
|
|
224
|
+
if (name === 'style'
|
|
225
|
+
&& (sError || sWarn)
|
|
226
226
|
&& lastChild.length === 1 && lastChild.firstChild.type === 'text') {
|
|
227
227
|
const cssLSP = (0, document_1.loadCssLSP)();
|
|
228
228
|
if (cssLSP) {
|
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/heading.js
CHANGED
|
@@ -126,7 +126,7 @@ let HeadingToken = (() => {
|
|
|
126
126
|
}
|
|
127
127
|
errors.push(e);
|
|
128
128
|
}
|
|
129
|
-
if (severities[1]
|
|
129
|
+
if (unbalanced && severities[1]) {
|
|
130
130
|
const msg = index_1.default.msg('unbalanced-in-section-header', '"="'), e = (0, lint_1.generateForChild)(firstChild, rect, rules[1], msg, severities[1]);
|
|
131
131
|
if (!computeEditInfo || innerStr === '=') {
|
|
132
132
|
//
|
|
@@ -65,24 +65,19 @@ const getUrl = (link) => {
|
|
|
65
65
|
const pdfExtensions = new Set(['djvu', 'djv', 'pdf']);
|
|
66
66
|
function validate(key, val, config, extOrType, halfParsed, accum) {
|
|
67
67
|
val = (0, string_1.removeComment)(val).trim();
|
|
68
|
-
|
|
68
|
+
const value = val.replace(key === 'link' ? /\0\d+[tq]\x7F/gu : /\0\d+t\x7F/gu, '').trim();
|
|
69
69
|
switch (key) {
|
|
70
70
|
case 'width':
|
|
71
71
|
return !value && Boolean(val) || /^(?:\d+x?|\d*x\d+)(?:\s*px)?$/u.test(value);
|
|
72
72
|
case 'link': {
|
|
73
73
|
const isGalleryImage = extOrType === 'gallery-image';
|
|
74
|
-
let nowiki = true;
|
|
75
74
|
if (!value) {
|
|
76
75
|
return val;
|
|
77
76
|
}
|
|
78
77
|
else if (getUrlLikeRegex(config.protocol).test(value)) {
|
|
79
78
|
return getUrlRegex(config.protocol).test(value) ? val : isGalleryImage;
|
|
80
79
|
}
|
|
81
|
-
|
|
82
|
-
value = value.slice(2, -2);
|
|
83
|
-
nowiki = false;
|
|
84
|
-
}
|
|
85
|
-
const title = index_1.default.normalizeTitle(value, 0, false, config, { halfParsed, decode: true, selfLink: true, page: '', nowiki }, accum);
|
|
80
|
+
const title = index_1.default.normalizeTitle(value, 0, false, config, { halfParsed, decode: true, selfLink: true, page: '', nowiki: true }, accum);
|
|
86
81
|
return title.valid ? title : isGalleryImage;
|
|
87
82
|
}
|
|
88
83
|
case 'lang':
|
|
@@ -135,18 +130,20 @@ let ImageParameterToken = (() => {
|
|
|
135
130
|
/** image link / 图片链接 */
|
|
136
131
|
get link() {
|
|
137
132
|
LINT: {
|
|
138
|
-
|
|
133
|
+
const { name, parentNode, childNodes } = this;
|
|
134
|
+
if (name !== 'link') {
|
|
139
135
|
return undefined;
|
|
140
136
|
}
|
|
141
|
-
const value =
|
|
137
|
+
const value = (0, string_1.text)(childNodes.flatMap(child => child.is('link') ? child.lastChild.childNodes : child)
|
|
138
|
+
.filter(({ type }) => type !== 'html')).trim();
|
|
142
139
|
return debug_1.Shadow.run(() => {
|
|
143
140
|
const config = this.getAttribute('config'), accum = [], token = new index_2.Token(value, config, accum);
|
|
144
141
|
token.parseOnce(0, this.getAttribute('include')).parseOnce();
|
|
145
142
|
if (/^\0\d+m\x7F/u.test(token.firstChild.toString())) {
|
|
146
143
|
return value;
|
|
147
144
|
}
|
|
148
|
-
const link = validate('link', value, config,
|
|
149
|
-
return link ===
|
|
145
|
+
const link = validate('link', value, config, parentNode?.type, undefined, accum);
|
|
146
|
+
return typeof link === 'boolean' ? undefined : link;
|
|
150
147
|
}, index_1.default);
|
|
151
148
|
}
|
|
152
149
|
}
|
|
@@ -198,7 +195,8 @@ let ImageParameterToken = (() => {
|
|
|
198
195
|
}
|
|
199
196
|
/** @private */
|
|
200
197
|
toString(skip) {
|
|
201
|
-
|
|
198
|
+
const str = super.toString(skip);
|
|
199
|
+
return this.#syntax ? this.#syntax.replace('$1', () => str) : str;
|
|
202
200
|
}
|
|
203
201
|
/** @private */
|
|
204
202
|
text() {
|
|
@@ -210,7 +208,7 @@ let ImageParameterToken = (() => {
|
|
|
210
208
|
if (name !== 'caption') {
|
|
211
209
|
str = str.trim();
|
|
212
210
|
}
|
|
213
|
-
return this.#syntax ? this.#syntax.replace('$1', str).trim() : str;
|
|
211
|
+
return this.#syntax ? this.#syntax.replace('$1', () => str).trim() : str;
|
|
214
212
|
}
|
|
215
213
|
/** @private */
|
|
216
214
|
isPlain() {
|
package/dist/src/index.js
CHANGED
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
|
}
|
package/dist/src/magicLink.js
CHANGED
|
@@ -63,7 +63,6 @@ class MagicLinkToken extends index_2.Token {
|
|
|
63
63
|
if (this.type === 'magic-link') {
|
|
64
64
|
const { link } = this;
|
|
65
65
|
if (link.startsWith('ISBN')) {
|
|
66
|
-
// eslint-disable-next-line unicorn/no-useless-spread
|
|
67
66
|
const digits = [...link.slice(5)].map(s => s === 'X' ? 10 : Number(s));
|
|
68
67
|
return digits.length === 10
|
|
69
68
|
? digits.reduce((sum, d, i) => sum + d * (10 - i), 0) % 11 !== 0
|
|
@@ -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/nowiki/quote.js
CHANGED
|
@@ -34,8 +34,8 @@ class QuoteToken extends base_1.NowikiBaseToken {
|
|
|
34
34
|
*/
|
|
35
35
|
get closing() {
|
|
36
36
|
LINT: return {
|
|
37
|
-
...this.bold
|
|
38
|
-
...this.italic
|
|
37
|
+
...this.bold && { bold: this.#closing.bold },
|
|
38
|
+
...this.italic && { italic: this.#closing.italic },
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
/** @param closing 是否闭合 */
|
package/dist/src/table/td.js
CHANGED
|
@@ -160,7 +160,7 @@ let TdToken = (() => {
|
|
|
160
160
|
if (computeEditInfo || fix) {
|
|
161
161
|
if (double) {
|
|
162
162
|
const syntax = { caption: '|+', td: '|', th: '!' }[this.subtype];
|
|
163
|
-
e.fix = (0, lint_1.fixBy)(e, 'newline', data.replace(/\|\|/gu, `\n${syntax}`));
|
|
163
|
+
e.fix = (0, lint_1.fixBy)(e, 'newline', data.replace(/\|\|/gu, () => `\n${syntax}`));
|
|
164
164
|
}
|
|
165
165
|
else if (computeEditInfo) {
|
|
166
166
|
e.suggestions = [(0, lint_1.fixByPipe)(e.startIndex, data)];
|
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': {
|
|
@@ -91,7 +91,7 @@ let IncludeToken = (() => {
|
|
|
91
91
|
}
|
|
92
92
|
errors.push(e);
|
|
93
93
|
}
|
|
94
|
-
if (s[1]
|
|
94
|
+
if (!closed && s[1]) {
|
|
95
95
|
const e = (0, lint_1.generateForSelf)(this, rect, rules[1], index_1.default.msg('unclosed', `<${name}>`), s[1]);
|
|
96
96
|
if (computeEditInfo) {
|
|
97
97
|
e.suggestions = [(0, lint_1.fixByClose)(e.endIndex, `</${name}>`)];
|
|
@@ -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
|
@@ -113,7 +113,7 @@ let TranscludeToken = (() => {
|
|
|
113
113
|
const m = /^(?:\s|\0\d+[cn]\x7F)*\0(\d+)h\x7F(?:\s|\0\d+[cn]\x7F)*/u.exec(title);
|
|
114
114
|
if (m) {
|
|
115
115
|
heading = Number(m[1]);
|
|
116
|
-
title = title.replace(`\0${heading}h\x7F`, accum[heading].toString().replace(/^\n/u, ''));
|
|
116
|
+
title = title.replace(`\0${heading}h\x7F`, () => accum[heading].toString().replace(/^\n/u, ''));
|
|
117
117
|
}
|
|
118
118
|
super(undefined, config, accum, {});
|
|
119
119
|
const { parserFunction, variable, functionHook } = config, argSubst = /^(?:\s|\0\d+[cn]\x7F)*\0\d+s\x7F/u.exec(title)?.[0];
|
|
@@ -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) {
|
|
@@ -274,41 +274,43 @@ let TranscludeToken = (() => {
|
|
|
274
274
|
/** @private */
|
|
275
275
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
276
276
|
LINT: {
|
|
277
|
-
const errors = super.lint(start, re);
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
errors.push((0, lint_1.generateForChild)(childNodes[1], rect, rule, 'illegal-module', s));
|
|
277
|
+
const errors = super.lint(start, re), { type, childNodes, length: l, name } = this, rect = new rect_1.BoundingRect(this, start), { lintConfig } = index_1.default, { computeEditInfo } = lintConfig, isTemplate = this.isTemplate();
|
|
278
|
+
let rule, s;
|
|
279
|
+
if (isTemplate) {
|
|
280
|
+
const invoke = type === 'magic-word';
|
|
281
|
+
if (invoke && !this.#getTitle().valid) {
|
|
282
|
+
rule = 'invalid-invoke';
|
|
283
|
+
s = lintConfig.getSeverity(rule, 'name');
|
|
284
|
+
if (s) {
|
|
285
|
+
errors.push((0, lint_1.generateForChild)(childNodes[1], rect, rule, 'illegal-module', s));
|
|
286
|
+
}
|
|
288
287
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
288
|
+
else {
|
|
289
|
+
rule = 'no-ignored';
|
|
290
|
+
s = lintConfig.getSeverity(rule, 'fragment');
|
|
291
|
+
if (s) {
|
|
292
|
+
const child = childNodes[invoke ? 1 : 0], i = child.childNodes
|
|
293
|
+
.findIndex(c => c.type === 'text' && (0, string_1.decodeHtml)(c.data).includes('#')), textNode = child.childNodes[i];
|
|
294
|
+
if (textNode) {
|
|
295
|
+
const e = (0, lint_1.generateForChild)(child, rect, rule, 'useless-fragment', s);
|
|
296
|
+
if (computeEditInfo) {
|
|
297
|
+
e.suggestions = [
|
|
298
|
+
(0, lint_1.fixByRemove)(e, child.getRelativeIndex(i) + textNode.data.indexOf('#')),
|
|
299
|
+
];
|
|
300
|
+
}
|
|
301
|
+
errors.push(e);
|
|
302
|
+
}
|
|
299
303
|
}
|
|
300
|
-
errors.push(e);
|
|
301
304
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
return errors;
|
|
305
|
+
rule = 'invalid-invoke';
|
|
306
|
+
s = lintConfig.getSeverity(rule, 'function');
|
|
307
|
+
if (s && invoke && l === 2) {
|
|
308
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'missing-function', s));
|
|
309
|
+
}
|
|
308
310
|
}
|
|
309
311
|
rule = 'no-duplicate';
|
|
310
312
|
s = lintConfig.getSeverity(rule, 'parameter');
|
|
311
|
-
if (s) {
|
|
313
|
+
if (s && (isTemplate || name === 'tag')) {
|
|
312
314
|
const duplicatedArgs = this.getDuplicatedArgs()
|
|
313
315
|
.filter(([, parameter]) => !parameter[0].querySelector('ext'));
|
|
314
316
|
for (const [, args] of duplicatedArgs) {
|
|
@@ -378,7 +380,14 @@ let TranscludeToken = (() => {
|
|
|
378
380
|
*/
|
|
379
381
|
getDuplicatedArgs() {
|
|
380
382
|
LINT: {
|
|
381
|
-
|
|
383
|
+
const isTemplate = this.isTemplate();
|
|
384
|
+
const duplicatedArgs = [...this.#args].filter(([, { size }]) => size > 1)
|
|
385
|
+
.map(([key, args]) => [key, [...args]]);
|
|
386
|
+
return isTemplate
|
|
387
|
+
? duplicatedArgs
|
|
388
|
+
: duplicatedArgs
|
|
389
|
+
.map(([key, args]) => [key, args.filter(({ anon }) => !anon)])
|
|
390
|
+
.filter(([, args]) => args.length > 1);
|
|
382
391
|
}
|
|
383
392
|
}
|
|
384
393
|
/**
|
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/sharable.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.extParams = exports.obsoleteAttrs = exports.extAttrs = exports.htmlAttrs = exports.commonHtmlAttrs = void 0;
|
|
4
|
-
/* eslint-disable unicorn/no-unreadable-iife */
|
|
5
4
|
const blockAttrs = new Set(['align']), citeAttrs = new Set(['cite']), citeAndAttrs = new Set(['cite', 'datetime']), widthAttrs = new Set(['width']), trAttrs = new Set(['bgcolor', 'align', 'valign']), obsoleteTdAttrs = new Set([...trAttrs, 'axis', 'height', 'nowrap', 'width']), tdAttrs = new Set([...obsoleteTdAttrs, 'abbr', 'headers', 'scope', 'rowspan', 'colspan']), typeAttrs = new Set(['type']), obsoleteTableAttrs = new Set(['summary', 'align', 'bgcolor', 'cellpadding', 'cellspacing', 'frame', 'rules', 'width']), brAttrs = new Set(['clear']), chemAttrs = new Set(['id', 'qid', 'forcemathmode', 'type', 'display']), syntaxHighlightAttrs = new Set([
|
|
6
5
|
'enclose',
|
|
7
6
|
'inline',
|
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,24 +98,24 @@
|
|
|
98
98
|
}
|
|
99
99
|
},
|
|
100
100
|
"dependencies": {
|
|
101
|
-
"@bhsd/cm-util": "^2.
|
|
102
|
-
"@bhsd/common": "^4.
|
|
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": "^
|
|
109
|
+
"@bhsd/code-standard": "^4.1.0",
|
|
110
110
|
"@bhsd/nodejs": "^1.2.1",
|
|
111
|
-
"@bhsd/test-util": "^3.1.
|
|
112
|
-
"c8": "^
|
|
111
|
+
"@bhsd/test-util": "^3.1.1",
|
|
112
|
+
"c8": "^12.0.0",
|
|
113
113
|
"diff2html-cli": "^5.2.15",
|
|
114
|
-
"esbuild": "^0.28.
|
|
115
|
-
"eslint": "^10.
|
|
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
|
-
"stylelint": "^17.14.
|
|
118
|
+
"stylelint": "^17.14.1",
|
|
119
119
|
"typescript": "^6.0.3",
|
|
120
120
|
"v8r": "^6.1.0",
|
|
121
121
|
"vscode-css-languageservice": "^6.3.10",
|