wikilint 2.18.3 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base.d.mts +3 -2
- package/dist/base.d.ts +3 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +7 -0
- package/dist/lib/document.d.ts +4 -0
- package/dist/lib/document.js +22 -1
- package/dist/lib/lsp.js +42 -11
- package/dist/lib/text.js +2 -2
- package/dist/parser/braces.js +57 -29
- package/dist/parser/commentAndExt.js +1 -1
- package/dist/src/arg.js +1 -1
- package/dist/src/attribute.js +1 -1
- package/dist/src/imageParameter.js +7 -5
- package/dist/src/index.js +7 -7
- package/dist/src/link/base.js +1 -1
- package/dist/src/paramTag/inputbox.js +9 -4
- package/dist/src/table/index.d.ts +1 -0
- package/dist/src/table/index.js +1 -1
- package/dist/src/table/trBase.js +31 -16
- package/dist/src/tagPair/ext.js +4 -2
- package/dist/src/transclude.js +12 -4
- package/dist/util/diff.js +1 -1
- package/package.json +7 -6
package/dist/base.d.mts
CHANGED
|
@@ -15,6 +15,7 @@ export interface Config {
|
|
|
15
15
|
readonly variants: string[];
|
|
16
16
|
readonly articlePath?: string;
|
|
17
17
|
}
|
|
18
|
+
export type ConfigData = Omit<Config, 'excludes'>;
|
|
18
19
|
export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'list-range' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
|
|
19
20
|
export declare const stages: {
|
|
20
21
|
redirect: number;
|
|
@@ -250,7 +251,7 @@ export interface LanguageService {
|
|
|
250
251
|
setTargetWikipedia(wiki: string): Promise<void>;
|
|
251
252
|
}
|
|
252
253
|
export interface Parser {
|
|
253
|
-
config:
|
|
254
|
+
config: ConfigData | string;
|
|
254
255
|
i18n: Record<string, string> | string | undefined;
|
|
255
256
|
/**
|
|
256
257
|
* Get the current parser configuration
|
|
@@ -258,7 +259,7 @@ export interface Parser {
|
|
|
258
259
|
* 获取当前的解析设置
|
|
259
260
|
* @param config unprocessed parser configuration / 未处理的解析设置
|
|
260
261
|
*/
|
|
261
|
-
getConfig(config?:
|
|
262
|
+
getConfig(config?: ConfigData): Config;
|
|
262
263
|
/**
|
|
263
264
|
* Parse wikitext
|
|
264
265
|
*
|
package/dist/base.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface Config {
|
|
|
15
15
|
readonly variants: string[];
|
|
16
16
|
readonly articlePath?: string;
|
|
17
17
|
}
|
|
18
|
+
export type ConfigData = Omit<Config, 'excludes'>;
|
|
18
19
|
export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'list-range' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
|
|
19
20
|
export declare const stages: {
|
|
20
21
|
redirect: number;
|
|
@@ -250,7 +251,7 @@ export interface LanguageService {
|
|
|
250
251
|
setTargetWikipedia(wiki: string): Promise<void>;
|
|
251
252
|
}
|
|
252
253
|
export interface Parser {
|
|
253
|
-
config:
|
|
254
|
+
config: ConfigData | string;
|
|
254
255
|
i18n: Record<string, string> | string | undefined;
|
|
255
256
|
/**
|
|
256
257
|
* Get the current parser configuration
|
|
@@ -258,7 +259,7 @@ export interface Parser {
|
|
|
258
259
|
* 获取当前的解析设置
|
|
259
260
|
* @param config unprocessed parser configuration / 未处理的解析设置
|
|
260
261
|
*/
|
|
261
|
-
getConfig(config?:
|
|
262
|
+
getConfig(config?: ConfigData): Config;
|
|
262
263
|
/**
|
|
263
264
|
* Parse wikitext
|
|
264
265
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Config, LintError, TokenTypes, Parser as ParserBase, Stage } from './base';
|
|
1
|
+
import type { Config, ConfigData, LintError, TokenTypes, Parser as ParserBase, Stage } from './base';
|
|
2
2
|
import type { Title, TitleOptions } from './lib/title';
|
|
3
3
|
import type { LanguageService, QuickFixData } from './lib/lsp';
|
|
4
4
|
import type { Token } from './internal';
|
|
@@ -23,11 +23,20 @@ declare interface Parser extends ParserBase {
|
|
|
23
23
|
* @since v1.16.1
|
|
24
24
|
*/
|
|
25
25
|
createLanguageService(uri: object): LanguageService;
|
|
26
|
+
/**
|
|
27
|
+
* Get the parser configuration for a MediaWiki project with Extension:CodeMirror installed
|
|
28
|
+
*
|
|
29
|
+
* 获取一个安装了CodeMirror扩展的MediaWiki项目的解析设置
|
|
30
|
+
* @param site site nickname / 网站别名
|
|
31
|
+
* @param url script path / 脚本路径
|
|
32
|
+
* @since v1.18.4
|
|
33
|
+
*/
|
|
34
|
+
fetchConfig(site: string, url: string): Promise<Config>;
|
|
26
35
|
}
|
|
27
36
|
declare const Parser: Parser;
|
|
28
37
|
// @ts-expect-error mixed export styles
|
|
29
38
|
export = Parser;
|
|
30
39
|
export default Parser;
|
|
31
|
-
export type { Config, LintError, TokenTypes, LanguageService, QuickFixData, };
|
|
40
|
+
export type { Config, ConfigData, LintError, TokenTypes, LanguageService, QuickFixData, };
|
|
32
41
|
export type * from './internal';
|
|
33
42
|
declare global { type Acceptable = unknown; }
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const string_1 = require("./util/string");
|
|
|
11
11
|
const fs_1 = __importDefault(require("fs"));
|
|
12
12
|
const path_1 = __importDefault(require("path"));
|
|
13
13
|
const diff_1 = require("./util/diff");
|
|
14
|
+
const config_1 = __importDefault(require("./bin/config"));
|
|
14
15
|
/* NOT FOR BROWSER ONLY */
|
|
15
16
|
/**
|
|
16
17
|
* 从根路径require
|
|
@@ -175,6 +176,12 @@ const Parser = {
|
|
|
175
176
|
return tasks.get(uri) ?? new LanguageService(uri);
|
|
176
177
|
}
|
|
177
178
|
},
|
|
179
|
+
/* NOT FOR BROWSER ONLY */
|
|
180
|
+
/** @implements */
|
|
181
|
+
async fetchConfig(site, url) {
|
|
182
|
+
return this.getConfig(await (0, config_1.default)(site, url, false, true));
|
|
183
|
+
},
|
|
184
|
+
/* NOT FOR BROWSER ONLY */
|
|
178
185
|
};
|
|
179
186
|
const def = {
|
|
180
187
|
default: { value: Parser },
|
package/dist/lib/document.d.ts
CHANGED
|
@@ -3,6 +3,10 @@ import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
|
3
3
|
import type { JSONDocument } from 'vscode-json-languageservice';
|
|
4
4
|
import type { Stylesheet } from 'vscode-css-languageservice';
|
|
5
5
|
import type { Token } from '../internal';
|
|
6
|
+
declare interface Jax {
|
|
7
|
+
tex2mml(tex: string): string;
|
|
8
|
+
}
|
|
9
|
+
export declare const MathJax: Promise<Jax | undefined>;
|
|
6
10
|
export declare const jsonTags: string[];
|
|
7
11
|
export declare const jsonLSP: import("vscode-json-languageservice").LanguageService | undefined;
|
|
8
12
|
export declare const cssLSP: import("vscode-css-languageservice").LanguageService | undefined;
|
package/dist/lib/document.js
CHANGED
|
@@ -3,9 +3,30 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.stylelint = exports.cssLSP = exports.jsonLSP = exports.jsonTags = void 0;
|
|
6
|
+
exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.stylelint = exports.cssLSP = exports.jsonLSP = exports.jsonTags = exports.MathJax = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const common_1 = require("@bhsd/common");
|
|
9
|
+
exports.MathJax = (async () => {
|
|
10
|
+
try {
|
|
11
|
+
const jax = require('mathjax');
|
|
12
|
+
return await jax.init({
|
|
13
|
+
loader: {
|
|
14
|
+
load: ['input/tex', '[tex]/mhchem'],
|
|
15
|
+
},
|
|
16
|
+
tex: {
|
|
17
|
+
packages: { '[+]': ['mhchem'] },
|
|
18
|
+
/** @ignore */
|
|
19
|
+
formatError(_, error) {
|
|
20
|
+
throw error;
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
startup: { typeset: false },
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
})();
|
|
9
30
|
exports.jsonTags = ['templatedata', 'mapframe', 'maplink'];
|
|
10
31
|
exports.jsonLSP = (() => {
|
|
11
32
|
try {
|
package/dist/lib/lsp.js
CHANGED
|
@@ -16,13 +16,12 @@ const util_1 = __importDefault(require("util"));
|
|
|
16
16
|
const child_process_1 = require("child_process");
|
|
17
17
|
const crypto_1 = require("crypto");
|
|
18
18
|
const stylelint_1 = require("@bhsd/common/dist/stylelint");
|
|
19
|
-
const config_1 = __importDefault(require("../bin/config"));
|
|
20
19
|
const document_1 = require("./document");
|
|
21
20
|
/** @see https://www.npmjs.com/package/stylelint-config-recommended */
|
|
22
21
|
const cssRules = {
|
|
23
22
|
'block-no-empty': null,
|
|
24
23
|
'property-no-unknown': null,
|
|
25
|
-
}, jsonSelector = document_1.jsonTags.map(s => `ext
|
|
24
|
+
}, jsonSelector = document_1.jsonTags.map(s => `ext#${s}`).join(), mathSelector = ['math', 'chem', 'ce'].map(s => `ext#${s}`).join(), scores = new Map();
|
|
26
25
|
let colors;
|
|
27
26
|
/* NOT FOR BROWSER ONLY END */
|
|
28
27
|
exports.tasks = new WeakMap();
|
|
@@ -769,8 +768,11 @@ class LanguageService {
|
|
|
769
768
|
});
|
|
770
769
|
})() :
|
|
771
770
|
[], jsonDiagnostics = document_1.jsonLSP ?
|
|
772
|
-
await Promise.all(root.querySelectorAll(jsonSelector).map(async (
|
|
773
|
-
|
|
771
|
+
await Promise.all(root.querySelectorAll(jsonSelector).map(async ({ name, lastChild, selfClosing }) => {
|
|
772
|
+
if (selfClosing) {
|
|
773
|
+
return [];
|
|
774
|
+
}
|
|
775
|
+
const textDoc = new document_1.EmbeddedJSONDocument(root, lastChild), severityLevel = name === 'templatedata' ? 'error' : 'ignore', e = (await document_1.jsonLSP.doValidation(textDoc, textDoc.jsonDoc, {
|
|
774
776
|
comments: severityLevel,
|
|
775
777
|
trailingCommas: severityLevel,
|
|
776
778
|
})).map((error) => ({
|
|
@@ -825,6 +827,32 @@ class LanguageService {
|
|
|
825
827
|
}));
|
|
826
828
|
}
|
|
827
829
|
}
|
|
830
|
+
const MathJax = await document_1.MathJax, mathDiagnostics = MathJax
|
|
831
|
+
? root.querySelectorAll(mathSelector)
|
|
832
|
+
.map(({ selfClosing, innerText, lastChild, name }) => {
|
|
833
|
+
if (selfClosing) {
|
|
834
|
+
return [];
|
|
835
|
+
}
|
|
836
|
+
try {
|
|
837
|
+
MathJax.tex2mml(name === 'math' ? innerText : String.raw `\ce{${innerText}}`);
|
|
838
|
+
return [];
|
|
839
|
+
}
|
|
840
|
+
catch (e) {
|
|
841
|
+
if (e && typeof e === 'object' && 'id' in e && 'message' in e) {
|
|
842
|
+
return [
|
|
843
|
+
{
|
|
844
|
+
range: createNodeRange(lastChild),
|
|
845
|
+
severity: 1,
|
|
846
|
+
source: 'MathJax',
|
|
847
|
+
code: e.id,
|
|
848
|
+
message: e.message,
|
|
849
|
+
},
|
|
850
|
+
];
|
|
851
|
+
}
|
|
852
|
+
return [];
|
|
853
|
+
}
|
|
854
|
+
})
|
|
855
|
+
: [];
|
|
828
856
|
/* NOT FOR BROWSER ONLY END */
|
|
829
857
|
return [
|
|
830
858
|
diagnostics,
|
|
@@ -832,6 +860,7 @@ class LanguageService {
|
|
|
832
860
|
jsonDiagnostics,
|
|
833
861
|
/* NOT FOR BROWSER ONLY */
|
|
834
862
|
lilypondDiagnostics,
|
|
863
|
+
mathDiagnostics,
|
|
835
864
|
].flat(2);
|
|
836
865
|
}
|
|
837
866
|
/**
|
|
@@ -884,8 +913,10 @@ class LanguageService {
|
|
|
884
913
|
}
|
|
885
914
|
/* NOT FOR BROWSER ONLY */
|
|
886
915
|
if (document_1.jsonLSP) {
|
|
887
|
-
for (const
|
|
888
|
-
|
|
916
|
+
for (const { selfClosing, lastChild } of root.querySelectorAll(jsonSelector)) {
|
|
917
|
+
if (!selfClosing) {
|
|
918
|
+
ranges.push(...document_1.jsonLSP.getFoldingRanges(new document_1.EmbeddedJSONDocument(root, lastChild)));
|
|
919
|
+
}
|
|
889
920
|
}
|
|
890
921
|
}
|
|
891
922
|
/* NOT FOR BROWSER ONLY END */
|
|
@@ -1116,13 +1147,13 @@ class LanguageService {
|
|
|
1116
1147
|
}
|
|
1117
1148
|
else if (type === 'magic-word-name') {
|
|
1118
1149
|
info = this.#getParserFunction(parentNode.name);
|
|
1119
|
-
f = offsetNode.
|
|
1150
|
+
f = offsetNode.text().trim();
|
|
1120
1151
|
colon = parentNode.getAttribute('colon');
|
|
1121
1152
|
}
|
|
1122
1153
|
else if (offsetNode.is('magic-word') && !offsetNode.modifier && length === 1
|
|
1123
1154
|
&& (offset > 0 || root.posFromIndex(offsetNode.getAbsoluteIndex()).left === position.character)) {
|
|
1124
1155
|
info = this.#getParserFunction(name);
|
|
1125
|
-
f = offsetNode.firstChild.
|
|
1156
|
+
f = offsetNode.firstChild.text().trim();
|
|
1126
1157
|
colon = offsetNode.getAttribute('colon');
|
|
1127
1158
|
}
|
|
1128
1159
|
else if ((offsetNode.is('magic-word') || offsetNode.is('template'))
|
|
@@ -1209,7 +1240,7 @@ class LanguageService {
|
|
|
1209
1240
|
}
|
|
1210
1241
|
const n = childNodes.length - 1, candidates = info.signatures.filter(params => (params.length >= n || params[params.length - 1]?.rest)
|
|
1211
1242
|
&& params.every(({ label, const: c }, i) => {
|
|
1212
|
-
const p = c && i < n && childNodes[i + 1]?.
|
|
1243
|
+
const p = c && i < n && childNodes[i + 1]?.text().trim();
|
|
1213
1244
|
return !p || label.toLowerCase().includes(p.toLowerCase());
|
|
1214
1245
|
}));
|
|
1215
1246
|
if (candidates.length === 0) {
|
|
@@ -1222,7 +1253,7 @@ class LanguageService {
|
|
|
1222
1253
|
break;
|
|
1223
1254
|
}
|
|
1224
1255
|
}
|
|
1225
|
-
const f = firstChild.
|
|
1256
|
+
const f = firstChild.text().trim(), colon = lastChild.getAttribute('colon');
|
|
1226
1257
|
return {
|
|
1227
1258
|
signatures: candidates.map((params) => ({
|
|
1228
1259
|
label: `{{${f}${params.length === 0 ? '' : colon}${params.map(({ label }) => label).join('|')}}}`,
|
|
@@ -1337,7 +1368,7 @@ class LanguageService {
|
|
|
1337
1368
|
this.config = index_1.default.getConfig(config);
|
|
1338
1369
|
}
|
|
1339
1370
|
catch {
|
|
1340
|
-
this.config = index_1.default.
|
|
1371
|
+
this.config = await index_1.default.fetchConfig(site, `${mt[0]}/w`);
|
|
1341
1372
|
}
|
|
1342
1373
|
Object.assign(this.config, { articlePath: `${mt[0]}/wiki/` });
|
|
1343
1374
|
}
|
package/dist/lib/text.js
CHANGED
|
@@ -74,7 +74,6 @@ class AstText extends node_1.AstNode {
|
|
|
74
74
|
constructor(text) {
|
|
75
75
|
super();
|
|
76
76
|
Object.defineProperties(this, {
|
|
77
|
-
childNodes: { enumerable: false, configurable: false },
|
|
78
77
|
data: {
|
|
79
78
|
value: text,
|
|
80
79
|
},
|
|
@@ -132,12 +131,13 @@ class AstText extends node_1.AstNode {
|
|
|
132
131
|
]);
|
|
133
132
|
for (let mt = errorRegex.exec(data); mt; mt = errorRegex.exec(data)) {
|
|
134
133
|
const [, tag, prefix] = mt;
|
|
135
|
-
let { index
|
|
134
|
+
let { index, 0: error } = mt;
|
|
136
135
|
if (prefix && prefix !== ']') {
|
|
137
136
|
const { length } = prefix;
|
|
138
137
|
index += length;
|
|
139
138
|
error = error.slice(length);
|
|
140
139
|
}
|
|
140
|
+
error = error.toLowerCase();
|
|
141
141
|
const { 0: char, length } = error, magicLink = char === 'r' || char === 'p' || char === 'i';
|
|
142
142
|
if (char === '<' && !tags.has(tag.toLowerCase())
|
|
143
143
|
|| char === '[' && type === 'ext-link-text' && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
|
package/dist/parser/braces.js
CHANGED
|
@@ -8,14 +8,33 @@ const transclude_1 = require("../src/transclude");
|
|
|
8
8
|
const arg_1 = require("../src/arg");
|
|
9
9
|
/* NOT FOR BROWSER ONLY */
|
|
10
10
|
const v8_1 = require("v8");
|
|
11
|
-
const MAXHEAP = (0, v8_1.getHeapStatistics)().
|
|
11
|
+
const MAXHEAP = (0, v8_1.getHeapStatistics)().heap_size_limit * 0.9;
|
|
12
12
|
/* NOT FOR BROWSER ONLY END */
|
|
13
13
|
const closes = {
|
|
14
14
|
'=': String.raw `\n(?!(?:[^\S\n]|\0\d+[cn]\x7F)*\n)`,
|
|
15
15
|
'{': String.raw `\}{2,}|\|`,
|
|
16
16
|
'-': String.raw `\}-`,
|
|
17
17
|
'[': String.raw `\]\]`,
|
|
18
|
-
}, openBraces = String.raw `|\{{2,}`, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~'], ['server', 'm']]), getExecRegex = (0, common_1.getRegex)(s => new RegExp(s, 'gmu'));
|
|
18
|
+
}, lbrack = String.raw `\[(?!\[)`, newline = String.raw `\n(?![=\0])`, openBraces = String.raw `|\{{2,}`, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~'], ['server', 'm']]), getExecRegex = (0, common_1.getRegex)(s => new RegExp(s, 'gmu'));
|
|
19
|
+
let reReplace;
|
|
20
|
+
/* NOT FOR BROWSER ONLY */
|
|
21
|
+
try {
|
|
22
|
+
reReplace = new RegExp(String.raw `(?<!\{)\{\{((?:[^\n{}[]|${lbrack}|${newline})*)\}\}` // eslint-disable-line prefer-template
|
|
23
|
+
+ '|'
|
|
24
|
+
+ String.raw `\{\{((?:[^\n{}[]|${lbrack}|${newline})*)\}\}(?!\})`
|
|
25
|
+
+ '|'
|
|
26
|
+
+ String.raw `\[\[(?:[^\n[\]{]|${newline})*\]\]`
|
|
27
|
+
+ '|'
|
|
28
|
+
+ String.raw `-\{(?:[^\n{}[]|${lbrack}|${newline})*\}-`, 'gu');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
/* NOT FOR BROWSER ONLY END */
|
|
32
|
+
reReplace = new RegExp(String.raw `\{\{((?:[^\n{}[]|${lbrack}|${newline})*)\}\}(?!\})` // eslint-disable-line prefer-template
|
|
33
|
+
+ '|'
|
|
34
|
+
+ String.raw `\[\[(?:[^\n[\]{]|${newline})*\]\]`
|
|
35
|
+
+ '|'
|
|
36
|
+
+ String.raw `-\{(?:[^\n{}[]|${lbrack}|${newline})*\}-`, 'gu');
|
|
37
|
+
}
|
|
19
38
|
/**
|
|
20
39
|
* 获取模板或魔术字对应的字符
|
|
21
40
|
* @param s 模板或魔术字名
|
|
@@ -42,7 +61,7 @@ const getSymbol = (s) => {
|
|
|
42
61
|
* @throws `TranscludeToken.constructor()`
|
|
43
62
|
*/
|
|
44
63
|
const parseBraces = (wikitext, config, accum) => {
|
|
45
|
-
const source = String.raw `${config.excludes
|
|
64
|
+
const source = String.raw `${config.excludes.includes('heading') ? '' : String.raw `^((?:\0\d+[cno]\x7F)*)={1,6}|`}\[\[|-\{(?!\{)`, { parserFunction: [, , , subst] } = config, stack = [], linkStack = [];
|
|
46
65
|
/**
|
|
47
66
|
* 恢复内链
|
|
48
67
|
* @param s 不含内链的字符串
|
|
@@ -58,36 +77,43 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
58
77
|
const push = (text, parts, lastIndex, index) => {
|
|
59
78
|
parts[parts.length - 1].push(restore(text.slice(lastIndex, index)));
|
|
60
79
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
let replaced;
|
|
81
|
+
do {
|
|
82
|
+
if (replaced !== undefined) {
|
|
83
|
+
wikitext = replaced;
|
|
84
|
+
}
|
|
85
|
+
replaced = wikitext.replace(reReplace, (m, p1, p2) => {
|
|
86
|
+
if (p1 !== undefined || typeof p2 === 'string') {
|
|
87
|
+
try {
|
|
88
|
+
const { length } = accum, parts = (p1 ?? p2).split('|');
|
|
89
|
+
// @ts-expect-error abstract class
|
|
90
|
+
new transclude_1.TranscludeToken(restore(parts[0]), parts.slice(1).map(part => {
|
|
91
|
+
const i = part.indexOf('=');
|
|
92
|
+
return (i === -1 ? [part] : [part.slice(0, i), part.slice(i + 1)]).map(restore);
|
|
93
|
+
}), config, accum);
|
|
94
|
+
return `\0${length}${getSymbol(parts[0])}\x7F`;
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
/* istanbul ignore if */
|
|
98
|
+
if (!(e instanceof SyntaxError) || e.message !== 'Invalid template name') {
|
|
99
|
+
throw e;
|
|
100
|
+
}
|
|
76
101
|
}
|
|
77
102
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
});
|
|
103
|
+
linkStack.push(restore(m));
|
|
104
|
+
return `\0${linkStack.length - 1}\x7F`;
|
|
105
|
+
});
|
|
106
|
+
} while (replaced !== wikitext);
|
|
107
|
+
wikitext = replaced;
|
|
82
108
|
const lastBraces = wikitext.lastIndexOf('}}') - wikitext.length;
|
|
83
109
|
let moreBraces = lastBraces + wikitext.length !== -1;
|
|
84
|
-
let regex = getExecRegex(source + (moreBraces ? openBraces : '')), mt = regex.exec(wikitext),
|
|
110
|
+
let regex = getExecRegex(source + (moreBraces ? openBraces : '')), mt = regex.exec(wikitext), lastIndex;
|
|
85
111
|
while (mt
|
|
86
112
|
|| lastIndex !== undefined && lastIndex <= wikitext.length
|
|
87
113
|
&& stack[stack.length - 1]?.[0]?.startsWith('=')) {
|
|
88
114
|
/* NOT FOR BROWSER ONLY */
|
|
89
|
-
if (
|
|
90
|
-
throw new RangeError('Maximum
|
|
115
|
+
if (process.memoryUsage().heapUsed > MAXHEAP) {
|
|
116
|
+
throw new RangeError('Maximum heap size exceeded');
|
|
91
117
|
}
|
|
92
118
|
/* NOT FOR BROWSER ONLY END */
|
|
93
119
|
if (mt?.[1]) {
|
|
@@ -106,11 +132,13 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
106
132
|
const rmt = /^(={1,6})(.+)\1((?:\s|\0\d+[cn]\x7F)*)$/u
|
|
107
133
|
.exec(wikitext.slice(index, curIndex));
|
|
108
134
|
if (rmt) {
|
|
109
|
-
wikitext = `${wikitext.slice(0, index)}\0${accum.length}h\x7F${wikitext.slice(curIndex)}`;
|
|
110
|
-
lastIndex = index + 4 + String(accum.length).length;
|
|
111
135
|
rmt[2] = restore(rmt[2]);
|
|
112
|
-
|
|
113
|
-
|
|
136
|
+
if (!rmt[2].includes('\n')) {
|
|
137
|
+
wikitext = `${wikitext.slice(0, index)}\0${accum.length}h\x7F${wikitext.slice(curIndex)}`;
|
|
138
|
+
lastIndex = index + 4 + String(accum.length).length;
|
|
139
|
+
// @ts-expect-error abstract class
|
|
140
|
+
new heading_1.HeadingToken(rmt[1].length, rmt.slice(2), config, accum);
|
|
141
|
+
}
|
|
114
142
|
}
|
|
115
143
|
}
|
|
116
144
|
}
|
|
@@ -9,7 +9,7 @@ const ext_1 = require("../src/tagPair/ext");
|
|
|
9
9
|
const comment_1 = require("../src/nowiki/comment");
|
|
10
10
|
const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft, getRegex = [false, true].map(includeOnly => {
|
|
11
11
|
const noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly';
|
|
12
|
-
return (0, common_1.
|
|
12
|
+
return (0, common_1.getRegex)(ext => new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext.join('|')})(\s[^>]*?)?(?:/>|>([\s\S]*?)</(\1\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))`, 'giu'));
|
|
13
13
|
});
|
|
14
14
|
/**
|
|
15
15
|
* 更新`<onlyinclude>`和`</onlyinclude>`的位置
|
package/dist/src/arg.js
CHANGED
|
@@ -61,7 +61,7 @@ class ArgToken extends index_1.Token {
|
|
|
61
61
|
/** 设置name */
|
|
62
62
|
#setName() {
|
|
63
63
|
// eslint-disable-next-line no-unused-labels
|
|
64
|
-
LSP: this.setAttribute('name', this.firstChild.
|
|
64
|
+
LSP: this.setAttribute('name', this.firstChild.text().trim());
|
|
65
65
|
}
|
|
66
66
|
/** @private */
|
|
67
67
|
afterBuild() {
|
package/dist/src/attribute.js
CHANGED
|
@@ -80,7 +80,7 @@ class AttributeToken extends index_2.Token {
|
|
|
80
80
|
if (this.parentNode) {
|
|
81
81
|
this.#tag = this.parentNode.name;
|
|
82
82
|
}
|
|
83
|
-
this.setAttribute('name', this.firstChild.
|
|
83
|
+
this.setAttribute('name', this.firstChild.text().trim().toLowerCase());
|
|
84
84
|
super.afterBuild();
|
|
85
85
|
}
|
|
86
86
|
/** @private */
|
|
@@ -14,7 +14,7 @@ const getUrlRegex = (0, common_1.getRegex)(protocol => new RegExp(String.raw `^(
|
|
|
14
14
|
const getSyntaxRegex = (0, common_1.getRegex)(syntax => new RegExp(String.raw `^(\s*(?!\s))${syntax.replace('$1', '(.*)')}${syntax.endsWith('$1') ? '(?=$|\n)' : ''}(\s*)$`, 'u'));
|
|
15
15
|
exports.galleryParams = new Set(['alt', 'link', 'lang', 'page', 'caption']);
|
|
16
16
|
function validate(key, val, config, halfParsed, ext) {
|
|
17
|
-
val = val.trim();
|
|
17
|
+
val = (0, string_1.removeComment)(val).trim();
|
|
18
18
|
let value = val.replace(key === 'link' ? /\0\d+[tq]\x7F/gu : /\0\d+t\x7F/gu, '').trim();
|
|
19
19
|
switch (key) {
|
|
20
20
|
case 'width':
|
|
@@ -81,10 +81,12 @@ class ImageParameterToken extends index_2.Token {
|
|
|
81
81
|
this.setAttribute('name', param[1]);
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
|
-
super(str,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
super(str, config.excludes.includes('list')
|
|
85
|
+
? config
|
|
86
|
+
: {
|
|
87
|
+
...config,
|
|
88
|
+
excludes: [...config.excludes, 'list'],
|
|
89
|
+
}, accum);
|
|
88
90
|
this.setAttribute('name', 'caption');
|
|
89
91
|
this.setAttribute('stage', 7);
|
|
90
92
|
}
|
package/dist/src/index.js
CHANGED
|
@@ -224,7 +224,7 @@ class Token extends element_1.AstElement {
|
|
|
224
224
|
}
|
|
225
225
|
/** 解析HTML标签 */
|
|
226
226
|
#parseHtml() {
|
|
227
|
-
if (this.#config.excludes
|
|
227
|
+
if (this.#config.excludes.includes('html')) {
|
|
228
228
|
return;
|
|
229
229
|
}
|
|
230
230
|
const { parseHtml } = require('../parser/html');
|
|
@@ -232,7 +232,7 @@ class Token extends element_1.AstElement {
|
|
|
232
232
|
}
|
|
233
233
|
/** 解析表格 */
|
|
234
234
|
#parseTable() {
|
|
235
|
-
if (this.#config.excludes
|
|
235
|
+
if (this.#config.excludes.includes('table')) {
|
|
236
236
|
return;
|
|
237
237
|
}
|
|
238
238
|
const { parseTable } = require('../parser/table');
|
|
@@ -240,7 +240,7 @@ class Token extends element_1.AstElement {
|
|
|
240
240
|
}
|
|
241
241
|
/** 解析`<hr>`和状态开关 */
|
|
242
242
|
#parseHrAndDoubleUnderscore() {
|
|
243
|
-
if (this.#config.excludes
|
|
243
|
+
if (this.#config.excludes.includes('hr')) {
|
|
244
244
|
return;
|
|
245
245
|
}
|
|
246
246
|
const { parseHrAndDoubleUnderscore } = require('../parser/hrAndDoubleUnderscore');
|
|
@@ -259,7 +259,7 @@ class Token extends element_1.AstElement {
|
|
|
259
259
|
* @param tidy 是否整理
|
|
260
260
|
*/
|
|
261
261
|
#parseQuotes(tidy) {
|
|
262
|
-
if (this.#config.excludes
|
|
262
|
+
if (this.#config.excludes.includes('quote')) {
|
|
263
263
|
return;
|
|
264
264
|
}
|
|
265
265
|
const { parseQuotes } = require('../parser/quotes');
|
|
@@ -271,7 +271,7 @@ class Token extends element_1.AstElement {
|
|
|
271
271
|
}
|
|
272
272
|
/** 解析外部链接 */
|
|
273
273
|
#parseExternalLinks() {
|
|
274
|
-
if (this.#config.excludes
|
|
274
|
+
if (this.#config.excludes.includes('extLink')) {
|
|
275
275
|
return;
|
|
276
276
|
}
|
|
277
277
|
const { parseExternalLinks } = require('../parser/externalLinks');
|
|
@@ -279,7 +279,7 @@ class Token extends element_1.AstElement {
|
|
|
279
279
|
}
|
|
280
280
|
/** 解析自由外链 */
|
|
281
281
|
#parseMagicLinks() {
|
|
282
|
-
if (this.#config.excludes
|
|
282
|
+
if (this.#config.excludes.includes('magicLink')) {
|
|
283
283
|
return;
|
|
284
284
|
}
|
|
285
285
|
const { parseMagicLinks } = require('../parser/magicLinks');
|
|
@@ -287,7 +287,7 @@ class Token extends element_1.AstElement {
|
|
|
287
287
|
}
|
|
288
288
|
/** 解析列表 */
|
|
289
289
|
#parseList() {
|
|
290
|
-
if (this.#config.excludes
|
|
290
|
+
if (this.#config.excludes.includes('list')) {
|
|
291
291
|
return;
|
|
292
292
|
}
|
|
293
293
|
const { parseList } = require('../parser/list');
|
package/dist/src/link/base.js
CHANGED
|
@@ -132,7 +132,7 @@ class LinkBaseToken extends index_2.Token {
|
|
|
132
132
|
}
|
|
133
133
|
/** @private */
|
|
134
134
|
getTitle(temporary, halfParsed) {
|
|
135
|
-
return this.normalizeTitle(this.firstChild.
|
|
135
|
+
return this.normalizeTitle(this.firstChild.text(), 0, { halfParsed, temporary, decode: true, selfLink: true });
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
exports.LinkBaseToken = LinkBaseToken;
|
|
@@ -12,12 +12,17 @@ const index_2 = require("./index");
|
|
|
12
12
|
class InputboxToken extends index_2.ParamTagToken {
|
|
13
13
|
/** @class */
|
|
14
14
|
constructor(include, wikitext, config = index_1.default.getConfig(), accum = []) {
|
|
15
|
-
const placeholder = Symbol('InputboxToken'),
|
|
15
|
+
const placeholder = Symbol('InputboxToken'), newConfig = config.excludes.includes('heading')
|
|
16
|
+
? config
|
|
17
|
+
: {
|
|
18
|
+
...config,
|
|
19
|
+
excludes: [...config.excludes, 'heading'],
|
|
20
|
+
}, { length } = accum;
|
|
16
21
|
accum.push(placeholder);
|
|
17
|
-
wikitext &&= (0, commentAndExt_1.parseCommentAndExt)(wikitext,
|
|
18
|
-
wikitext &&= (0, braces_1.parseBraces)(wikitext,
|
|
22
|
+
wikitext &&= (0, commentAndExt_1.parseCommentAndExt)(wikitext, newConfig, accum, include);
|
|
23
|
+
wikitext &&= (0, braces_1.parseBraces)(wikitext, newConfig, accum);
|
|
19
24
|
accum.splice(length, 1);
|
|
20
|
-
super(include, wikitext,
|
|
25
|
+
super(include, wikitext, newConfig, accum, {});
|
|
21
26
|
}
|
|
22
27
|
}
|
|
23
28
|
exports.InputboxToken = InputboxToken;
|
|
@@ -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
|
@@ -108,7 +108,7 @@ class TableToken extends trBase_1.TrBaseToken {
|
|
|
108
108
|
* @param stop.y stop at the column / 中止列
|
|
109
109
|
*/
|
|
110
110
|
getLayout(stop) {
|
|
111
|
-
const rows = this.getAllRows(), { length } = rows, layout =
|
|
111
|
+
const rows = this.getAllRows(), { length } = rows, layout = Layout.from(emptyArray(length, () => []));
|
|
112
112
|
for (let i = 0; i < layout.length; i++) {
|
|
113
113
|
const rowLayout = layout[i];
|
|
114
114
|
let j = 0, k = 0, last;
|
package/dist/src/table/trBase.js
CHANGED
|
@@ -4,7 +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']);
|
|
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
|
+
};
|
|
8
35
|
/**
|
|
9
36
|
* table row or table
|
|
10
37
|
*
|
|
@@ -17,23 +44,11 @@ class TrBaseToken extends base_1.TableBaseToken {
|
|
|
17
44
|
if (!inter) {
|
|
18
45
|
return errors;
|
|
19
46
|
}
|
|
20
|
-
const
|
|
21
|
-
if (!
|
|
22
|
-
|| tdPattern.test(first.toString())
|
|
23
|
-
|| first.is('arg') && tdPattern.test(first.default || '')
|
|
24
|
-
|| first.is('html') && tableTags.has(first.name)) {
|
|
47
|
+
const severity = isFostered(inter);
|
|
48
|
+
if (!severity) {
|
|
25
49
|
return errors;
|
|
26
50
|
}
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
if (first.getPossibleValues().every(token => tdPattern.test(token.text()))) {
|
|
30
|
-
return errors;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
catch { }
|
|
34
|
-
}
|
|
35
|
-
const error = (0, lint_1.generateForChild)(inter, { start }, 'fostered-content', 'content to be moved out from the table');
|
|
36
|
-
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);
|
|
37
52
|
error.startIndex++;
|
|
38
53
|
error.startLine++;
|
|
39
54
|
error.startCol = 0;
|
package/dist/src/tagPair/ext.js
CHANGED
|
@@ -98,7 +98,7 @@ let ExtToken = (() => {
|
|
|
98
98
|
attrToken = new attributes_1.AttributesToken(!attr || /^\s/u.test(attr) ? attr : ` ${attr}`, 'ext-attrs', lcName, config, accum), newConfig = {
|
|
99
99
|
...config,
|
|
100
100
|
ext: del(config.ext, lcName),
|
|
101
|
-
excludes: [...config.excludes
|
|
101
|
+
excludes: [...config.excludes],
|
|
102
102
|
};
|
|
103
103
|
let innerToken;
|
|
104
104
|
switch (lcName) {
|
|
@@ -127,11 +127,11 @@ let ExtToken = (() => {
|
|
|
127
127
|
innerToken = new index_4.ParamTagToken(include, inner, newConfig, accum);
|
|
128
128
|
break;
|
|
129
129
|
case 'inputbox':
|
|
130
|
-
newConfig.excludes.push('heading');
|
|
131
130
|
// @ts-expect-error abstract class
|
|
132
131
|
innerToken = new inputbox_1.InputboxToken(include, inner, newConfig, accum);
|
|
133
132
|
break;
|
|
134
133
|
case 'references': {
|
|
134
|
+
// NestedToken 依赖 ExtToken
|
|
135
135
|
const { NestedToken } = require('../nested');
|
|
136
136
|
newConfig.excludes.push('heading');
|
|
137
137
|
// @ts-expect-error abstract class
|
|
@@ -139,12 +139,14 @@ let ExtToken = (() => {
|
|
|
139
139
|
break;
|
|
140
140
|
}
|
|
141
141
|
case 'choose': {
|
|
142
|
+
// NestedToken 依赖 ExtToken
|
|
142
143
|
const { NestedToken } = require('../nested');
|
|
143
144
|
// @ts-expect-error abstract class
|
|
144
145
|
innerToken = new NestedToken(inner, /<(option|choicetemplate)(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/(\1)>)/gu, ['option', 'choicetemplate'], newConfig, accum);
|
|
145
146
|
break;
|
|
146
147
|
}
|
|
147
148
|
case 'combobox': {
|
|
149
|
+
// NestedToken 依赖 ExtToken
|
|
148
150
|
const { NestedToken } = require('../nested');
|
|
149
151
|
// @ts-expect-error abstract class
|
|
150
152
|
innerToken = new NestedToken(inner, /<(combooption)(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/(combooption\s*)>)/giu, ['combooption'], newConfig, accum);
|
package/dist/src/transclude.js
CHANGED
|
@@ -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/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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikilint",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0",
|
|
4
4
|
"description": "A Node.js linter for MediaWiki markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -65,13 +65,14 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@bhsd/common": "^0.9.
|
|
68
|
+
"@bhsd/common": "^0.9.2",
|
|
69
69
|
"vscode-languageserver-types": "^3.17.5"
|
|
70
70
|
},
|
|
71
71
|
"optionalDependencies": {
|
|
72
72
|
"chalk": "^4.1.2",
|
|
73
73
|
"color-name": "^2.0.0",
|
|
74
74
|
"entities": "^6.0.0",
|
|
75
|
+
"mathjax": "^3.2.2",
|
|
75
76
|
"minimatch": "^10.0.1",
|
|
76
77
|
"stylelint": "^16.14.1",
|
|
77
78
|
"vscode-css-languageservice": "^6.3.2",
|
|
@@ -85,10 +86,10 @@
|
|
|
85
86
|
"@types/color-rgba": "^2.1.3",
|
|
86
87
|
"@types/mocha": "^10.0.10",
|
|
87
88
|
"@types/node": "^22.13.1",
|
|
88
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
89
|
-
"@typescript-eslint/parser": "^8.
|
|
89
|
+
"@typescript-eslint/eslint-plugin": "^8.29.0",
|
|
90
|
+
"@typescript-eslint/parser": "^8.29.0",
|
|
90
91
|
"color-rgba": "^3.0.0",
|
|
91
|
-
"esbuild": "^0.25.
|
|
92
|
+
"esbuild": "^0.25.2",
|
|
92
93
|
"eslint": "^8.57.1",
|
|
93
94
|
"eslint-plugin-es-x": "^8.4.1",
|
|
94
95
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
@@ -103,7 +104,7 @@
|
|
|
103
104
|
"mocha": "^11.1.0",
|
|
104
105
|
"nyc": "^17.1.0",
|
|
105
106
|
"stylelint-config-recommended": "^15.0.0",
|
|
106
|
-
"typescript": "^5.
|
|
107
|
+
"typescript": "^5.8.2",
|
|
107
108
|
"v8r": "^4.2.1",
|
|
108
109
|
"vscode-languageserver-textdocument": "^1.0.12"
|
|
109
110
|
},
|