wikilint 2.43.0 → 2.44.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/config/default.json +31 -0
- package/config/moegirl.json +39 -1
- package/dist/base.d.mts +4 -4
- package/dist/base.d.ts +4 -4
- package/dist/base.js +1 -0
- package/dist/base.mjs +1 -0
- package/dist/bin/config.js +6 -5
- package/dist/index.js +8 -5
- package/dist/lib/document.d.ts +17 -14
- package/dist/lib/lintConfig.js +4 -1
- package/dist/lib/title.d.ts +4 -1
- package/dist/lib/title.js +5 -1
- package/dist/mixin/attributesParent.js +1 -1
- package/dist/parser/converter.js +1 -1
- package/dist/src/attributes.d.ts +1 -0
- package/dist/src/attributes.js +27 -3
- package/dist/src/converterFlags.js +8 -3
- package/dist/src/converterRule.js +1 -1
- package/dist/src/imageParameter.d.ts +4 -3
- package/dist/src/imageParameter.js +15 -7
- package/dist/src/link/file.d.ts +5 -4
- package/dist/src/link/file.js +1 -1
- package/dist/src/nowiki/index.d.ts +1 -0
- package/dist/src/nowiki/index.js +39 -28
- package/dist/src/tagPair/ext.d.ts +1 -0
- package/dist/src/tagPair/ext.js +36 -3
- package/dist/util/search.js +24 -6
- package/dist/util/string.js +7 -1
- package/i18n/en.json +7 -0
- package/i18n/zh-hans.json +7 -0
- package/i18n/zh-hant.json +7 -0
- package/package.json +10 -11
package/config/default.json
CHANGED
|
@@ -144,6 +144,10 @@
|
|
|
144
144
|
"105": "API talk",
|
|
145
145
|
"106": "Skin",
|
|
146
146
|
"107": "Skin talk",
|
|
147
|
+
"114": "Creation",
|
|
148
|
+
"115": "Creation talk",
|
|
149
|
+
"116": "Document",
|
|
150
|
+
"117": "Document talk",
|
|
147
151
|
"118": "Draft",
|
|
148
152
|
"119": "Draft talk",
|
|
149
153
|
"126": "MOS",
|
|
@@ -375,9 +379,36 @@
|
|
|
375
379
|
"skins": 106,
|
|
376
380
|
"skin talk": 107,
|
|
377
381
|
"skins talk": 107,
|
|
382
|
+
"creation": 114,
|
|
383
|
+
"创作": 114,
|
|
384
|
+
"萌创": 114,
|
|
385
|
+
"創作": 114,
|
|
386
|
+
"萌創": 114,
|
|
387
|
+
"萌娘创作": 114,
|
|
388
|
+
"萌娘創作": 114,
|
|
389
|
+
"creation talk": 115,
|
|
390
|
+
"萌娘创作 talk": 115,
|
|
391
|
+
"创作 talk": 115,
|
|
392
|
+
"萌创 talk": 115,
|
|
393
|
+
"萌娘創作 talk": 115,
|
|
394
|
+
"創作 talk": 115,
|
|
395
|
+
"萌創 talk": 115,
|
|
396
|
+
"萌娘创作讨论": 115,
|
|
397
|
+
"萌娘創作討論": 115,
|
|
398
|
+
"document": 116,
|
|
399
|
+
"library": 116,
|
|
400
|
+
"文档": 116,
|
|
401
|
+
"文檔": 116,
|
|
402
|
+
"document talk": 117,
|
|
403
|
+
"library talk": 117,
|
|
404
|
+
"文档 talk": 117,
|
|
405
|
+
"文檔 talk": 117,
|
|
406
|
+
"文档讨论": 117,
|
|
407
|
+
"文檔討論": 117,
|
|
378
408
|
"draft": 118,
|
|
379
409
|
"草稿": 118,
|
|
380
410
|
"draft talk": 119,
|
|
411
|
+
"草稿 talk": 119,
|
|
381
412
|
"草稿讨论": 119,
|
|
382
413
|
"草稿討論": 119,
|
|
383
414
|
"mos": 126,
|
package/config/moegirl.json
CHANGED
|
@@ -110,6 +110,12 @@
|
|
|
110
110
|
"13": "Help talk",
|
|
111
111
|
"14": "Category",
|
|
112
112
|
"15": "Category talk",
|
|
113
|
+
"114": "Creation",
|
|
114
|
+
"115": "Creation talk",
|
|
115
|
+
"116": "Document",
|
|
116
|
+
"117": "Document talk",
|
|
117
|
+
"118": "Draft",
|
|
118
|
+
"119": "Draft talk",
|
|
113
119
|
"274": "Widget",
|
|
114
120
|
"275": "Widget talk",
|
|
115
121
|
"710": "TimedText",
|
|
@@ -138,6 +144,12 @@
|
|
|
138
144
|
"help talk": 13,
|
|
139
145
|
"category": 14,
|
|
140
146
|
"category talk": 15,
|
|
147
|
+
"creation": 114,
|
|
148
|
+
"creation talk": 115,
|
|
149
|
+
"document": 116,
|
|
150
|
+
"document talk": 117,
|
|
151
|
+
"draft": 118,
|
|
152
|
+
"draft talk": 119,
|
|
141
153
|
"widget": 274,
|
|
142
154
|
"widget talk": 275,
|
|
143
155
|
"timedtext": 710,
|
|
@@ -146,6 +158,14 @@
|
|
|
146
158
|
"module talk": 829,
|
|
147
159
|
"media": -2,
|
|
148
160
|
"special": -1,
|
|
161
|
+
"创作": 114,
|
|
162
|
+
"萌创": 114,
|
|
163
|
+
"文档": 116,
|
|
164
|
+
"萌娘创作 talk": 115,
|
|
165
|
+
"创作 talk": 115,
|
|
166
|
+
"萌创 talk": 115,
|
|
167
|
+
"文档 talk": 117,
|
|
168
|
+
"草稿 talk": 119,
|
|
149
169
|
"媒体": -2,
|
|
150
170
|
"媒体文件": -2,
|
|
151
171
|
"媒体档案": -2,
|
|
@@ -291,7 +311,25 @@
|
|
|
291
311
|
"模組討論": 829,
|
|
292
312
|
"模组对话": 829,
|
|
293
313
|
"模组讨论": 829,
|
|
294
|
-
"モジュール・トーク": 829
|
|
314
|
+
"モジュール・トーク": 829,
|
|
315
|
+
"創作": 114,
|
|
316
|
+
"萌創": 114,
|
|
317
|
+
"文檔": 116,
|
|
318
|
+
"萌娘創作 talk": 115,
|
|
319
|
+
"創作 talk": 115,
|
|
320
|
+
"萌創 talk": 115,
|
|
321
|
+
"文檔 talk": 117,
|
|
322
|
+
"library": 116,
|
|
323
|
+
"library talk": 117,
|
|
324
|
+
"萌娘创作": 114,
|
|
325
|
+
"萌娘创作讨论": 115,
|
|
326
|
+
"文档讨论": 117,
|
|
327
|
+
"草稿": 118,
|
|
328
|
+
"草稿讨论": 119,
|
|
329
|
+
"萌娘創作": 114,
|
|
330
|
+
"萌娘創作討論": 115,
|
|
331
|
+
"文檔討論": 117,
|
|
332
|
+
"草稿討論": 119
|
|
295
333
|
},
|
|
296
334
|
"functionHook": [
|
|
297
335
|
"ns",
|
package/dist/base.d.mts
CHANGED
|
@@ -4,14 +4,14 @@ export interface Config {
|
|
|
4
4
|
readonly html: [string[], string[], string[]];
|
|
5
5
|
readonly namespaces: Record<string, string>;
|
|
6
6
|
readonly nsid: Record<string, number>;
|
|
7
|
-
readonly variable: string[];
|
|
8
|
-
readonly functionHook: string[];
|
|
9
7
|
readonly parserFunction: [Record<string, string>, Record<string, string>, string[], string[]];
|
|
10
8
|
readonly doubleUnderscore: [string[], string[], Record<string, string>, Record<string, string>];
|
|
11
9
|
readonly protocol: string;
|
|
12
10
|
readonly img: Record<string, string>;
|
|
13
11
|
readonly redirection: string[];
|
|
14
|
-
|
|
12
|
+
variable: string[];
|
|
13
|
+
functionHook: string[];
|
|
14
|
+
variants: string[];
|
|
15
15
|
articlePath?: string;
|
|
16
16
|
}
|
|
17
17
|
export type ConfigData = Omit<Config, 'excludes'>;
|
|
@@ -43,7 +43,7 @@ export declare const stages: {
|
|
|
43
43
|
converter: number;
|
|
44
44
|
};
|
|
45
45
|
export type Stage = keyof typeof stages;
|
|
46
|
-
export declare const rules: readonly ["arg-in-ext", "blank-alt", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-json", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "required-attr", "syntax-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext", "invalid-css", "invalid-math"];
|
|
46
|
+
export declare const rules: readonly ["arg-in-ext", "blank-alt", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-json", "invalid-ref", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "required-attr", "syntax-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext", "invalid-css", "invalid-math"];
|
|
47
47
|
export declare namespace LintError {
|
|
48
48
|
type Severity = 'error' | 'warning';
|
|
49
49
|
type Rule = typeof rules[number];
|
package/dist/base.d.ts
CHANGED
|
@@ -4,14 +4,14 @@ export interface Config {
|
|
|
4
4
|
readonly html: [string[], string[], string[]];
|
|
5
5
|
readonly namespaces: Record<string, string>;
|
|
6
6
|
readonly nsid: Record<string, number>;
|
|
7
|
-
readonly variable: string[];
|
|
8
|
-
readonly functionHook: string[];
|
|
9
7
|
readonly parserFunction: [Record<string, string>, Record<string, string>, string[], string[]];
|
|
10
8
|
readonly doubleUnderscore: [string[], string[], Record<string, string>, Record<string, string>];
|
|
11
9
|
readonly protocol: string;
|
|
12
10
|
readonly img: Record<string, string>;
|
|
13
11
|
readonly redirection: string[];
|
|
14
|
-
|
|
12
|
+
variable: string[];
|
|
13
|
+
functionHook: string[];
|
|
14
|
+
variants: string[];
|
|
15
15
|
articlePath?: string;
|
|
16
16
|
}
|
|
17
17
|
export type ConfigData = Omit<Config, 'excludes'>;
|
|
@@ -43,7 +43,7 @@ export declare const stages: {
|
|
|
43
43
|
converter: number;
|
|
44
44
|
};
|
|
45
45
|
export type Stage = keyof typeof stages;
|
|
46
|
-
export declare const rules: readonly ["arg-in-ext", "blank-alt", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-json", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "required-attr", "syntax-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext", "invalid-css", "invalid-math"];
|
|
46
|
+
export declare const rules: readonly ["arg-in-ext", "blank-alt", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-json", "invalid-ref", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "required-attr", "syntax-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext", "invalid-css", "invalid-math"];
|
|
47
47
|
export declare namespace LintError {
|
|
48
48
|
type Severity = 'error' | 'warning';
|
|
49
49
|
type Rule = typeof rules[number];
|
package/dist/base.js
CHANGED
package/dist/base.mjs
CHANGED
package/dist/bin/config.js
CHANGED
|
@@ -10,6 +10,7 @@ const child_process_1 = require("child_process");
|
|
|
10
10
|
const strict_1 = __importDefault(require("assert/strict"));
|
|
11
11
|
const cm_util_1 = require("@bhsd/cm-util");
|
|
12
12
|
const diff_1 = require("../util/diff");
|
|
13
|
+
const string_1 = require("../util/string");
|
|
13
14
|
/**
|
|
14
15
|
* Converts an array to an object.
|
|
15
16
|
* @param config parser configuration
|
|
@@ -40,7 +41,7 @@ const filterGadget = (id) => {
|
|
|
40
41
|
const n = Number(id);
|
|
41
42
|
return n < 2300 || n > 2303; // Gadget, Gadget talk, Gadget definition, Gadget definition talk
|
|
42
43
|
};
|
|
43
|
-
const pkg = "wikilint", version = "2.
|
|
44
|
+
const pkg = "wikilint", version = "2.44.0";
|
|
44
45
|
/**
|
|
45
46
|
* Get the parser configuration for a Wikimedia Foundation project.
|
|
46
47
|
* @param site site nickname
|
|
@@ -108,7 +109,7 @@ exports.default = async (site, url, user, force, internal) => {
|
|
|
108
109
|
siprop: `general|magicwords|namespaces|namespacealiases${mwConfig.functionHooks ? '' : '|functionhooks'}`,
|
|
109
110
|
format: 'json',
|
|
110
111
|
formatversion: '2',
|
|
111
|
-
}, { general: { articlepath, server, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params)
|
|
112
|
+
}, { general: { articlepath, server, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${String(new URLSearchParams(params))}`, headers)).json()).query, ns = Object.entries(namespaces).filter(([id]) => filterGadget(id))
|
|
112
113
|
.flatMap(([id, { name, canonical = '' }]) => [
|
|
113
114
|
[id, name],
|
|
114
115
|
...name === canonical ? [] : [[id, canonical]],
|
|
@@ -130,11 +131,11 @@ exports.default = async (site, url, user, force, internal) => {
|
|
|
130
131
|
parserFunction[2] = getAliases(magicwords, new Set(['msg', 'raw']));
|
|
131
132
|
parserFunction[3] = getAliases(magicwords, new Set(['subst', 'safesubst']));
|
|
132
133
|
if (!mwConfig.functionHooks) {
|
|
133
|
-
|
|
134
|
+
config.functionHook = [...(0, string_1.toLowerCase)(functionhooks), 'msgnw'];
|
|
134
135
|
}
|
|
135
136
|
if (!mwConfig.variableIDs) {
|
|
136
|
-
const { variables } = (await (await fetch(`${url}/api.php?${new URLSearchParams({ ...params, siprop: 'variables' })
|
|
137
|
-
|
|
137
|
+
const { variables } = (await (await fetch(`${url}/api.php?${String(new URLSearchParams({ ...params, siprop: 'variables' }))}`, headers)).json()).query;
|
|
138
|
+
config.variable = [...new Set([...variables, '='])];
|
|
138
139
|
}
|
|
139
140
|
if ('#choose' in parserFunction[0]) {
|
|
140
141
|
delete parserFunction[0]['choose'];
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
/* eslint n/exports-style: 0 */
|
|
6
|
+
const cm_util_1 = require("@bhsd/cm-util");
|
|
6
7
|
const base_1 = require("./base");
|
|
7
8
|
const debug_1 = require("./util/debug");
|
|
8
9
|
const constants_1 = require("./util/constants");
|
|
@@ -114,7 +115,8 @@ const Parser = {
|
|
|
114
115
|
return this.getConfig();
|
|
115
116
|
}
|
|
116
117
|
/* NOT FOR BROWSER ONLY END */
|
|
117
|
-
const parserConfig = config ?? this.config
|
|
118
|
+
const parserConfig = config ?? this.config;
|
|
119
|
+
const { doubleUnderscore, ext, parserFunction, variable, variants, } = parserConfig;
|
|
118
120
|
for (let i = 0; i < 2; i++) {
|
|
119
121
|
if (doubleUnderscore[i].length === 0) {
|
|
120
122
|
doubleUnderscore[i] = Object.keys(doubleUnderscore[i + 2]);
|
|
@@ -124,6 +126,7 @@ const Parser = {
|
|
|
124
126
|
variable.push('translationlanguage');
|
|
125
127
|
parserFunction[1]['TRANSLATIONLANGUAGE'] = 'translationlanguage';
|
|
126
128
|
}
|
|
129
|
+
parserConfig.variants = (0, cm_util_1.getBCP47Variants)(variants);
|
|
127
130
|
return {
|
|
128
131
|
...parserConfig,
|
|
129
132
|
excludes: [],
|
|
@@ -135,19 +138,19 @@ const Parser = {
|
|
|
135
138
|
&& (this.i18n[msg] ?? msg).replace('$1', this.msg(arg));
|
|
136
139
|
},
|
|
137
140
|
/** @implements */
|
|
138
|
-
normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt) {
|
|
141
|
+
normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt, accum = []) {
|
|
139
142
|
let titleObj;
|
|
140
143
|
if (opt?.halfParsed) {
|
|
141
|
-
titleObj = new title_1.Title(title, defaultNs, config, opt);
|
|
144
|
+
titleObj = new title_1.Title(title, defaultNs, config, opt, accum);
|
|
142
145
|
}
|
|
143
146
|
else {
|
|
144
147
|
const { Token } = require('./src/index');
|
|
145
148
|
titleObj = debug_1.Shadow.run(() => {
|
|
146
|
-
const root = new Token(title, config);
|
|
149
|
+
const root = new Token(title, config, accum);
|
|
147
150
|
root.type = 'root';
|
|
148
151
|
root.pageName = opt?.page;
|
|
149
152
|
root.parseOnce(0, include).parseOnce();
|
|
150
|
-
const t = new title_1.Title(root.firstChild.toString(), defaultNs, config, opt);
|
|
153
|
+
const t = new title_1.Title(root.firstChild.toString(), defaultNs, config, opt, accum);
|
|
151
154
|
root.build();
|
|
152
155
|
const keys = [
|
|
153
156
|
'main',
|
package/dist/lib/document.d.ts
CHANGED
|
@@ -10,23 +10,26 @@ export interface TexvcLocation {
|
|
|
10
10
|
line: number;
|
|
11
11
|
column: number;
|
|
12
12
|
}
|
|
13
|
+
export type TexvcReport = {
|
|
14
|
+
status: '+';
|
|
15
|
+
output: string;
|
|
16
|
+
} | {
|
|
17
|
+
status: 'C';
|
|
18
|
+
} | {
|
|
19
|
+
status: 'F' | 'S';
|
|
20
|
+
error: {
|
|
21
|
+
message: string;
|
|
22
|
+
location: {
|
|
23
|
+
start: TexvcLocation;
|
|
24
|
+
end: TexvcLocation;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
};
|
|
13
28
|
declare interface Texvcjs {
|
|
14
29
|
check(input: string, options?: {
|
|
30
|
+
usemathrm?: boolean;
|
|
15
31
|
usemhchem?: boolean;
|
|
16
|
-
}):
|
|
17
|
-
status: '+';
|
|
18
|
-
} | {
|
|
19
|
-
status: 'C';
|
|
20
|
-
} | {
|
|
21
|
-
status: 'F' | 'S';
|
|
22
|
-
error: {
|
|
23
|
-
message: string;
|
|
24
|
-
location: {
|
|
25
|
-
start: TexvcLocation;
|
|
26
|
-
end: TexvcLocation;
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
};
|
|
32
|
+
}): TexvcReport;
|
|
30
33
|
}
|
|
31
34
|
export declare const loadTexvcjs: () => Texvcjs | null;
|
|
32
35
|
export declare const loadJsonLSP: () => JSONLanguageService | null;
|
package/dist/lib/lintConfig.js
CHANGED
|
@@ -79,6 +79,7 @@ const defaultLintRuleConfig = {
|
|
|
79
79
|
duplicate: 1,
|
|
80
80
|
},
|
|
81
81
|
],
|
|
82
|
+
'invalid-ref': [2],
|
|
82
83
|
'invalid-url': [1],
|
|
83
84
|
'lonely-apos': [
|
|
84
85
|
1,
|
|
@@ -234,9 +235,11 @@ const defaultLintRuleConfig = {
|
|
|
234
235
|
'void-ext': [
|
|
235
236
|
2,
|
|
236
237
|
{
|
|
237
|
-
//
|
|
238
|
+
// dynamicpagelist: 2,
|
|
238
239
|
// languages: 2,
|
|
240
|
+
// rss: 2,
|
|
239
241
|
// section: 2,
|
|
242
|
+
// templatedata: 2,
|
|
240
243
|
// templatestyles: 2,
|
|
241
244
|
},
|
|
242
245
|
],
|
package/dist/lib/title.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { Config } from '../base';
|
|
2
|
+
import type { Token } from '../internal';
|
|
2
3
|
export interface TitleOptions {
|
|
3
4
|
temporary?: boolean | undefined;
|
|
4
5
|
decode?: boolean | undefined;
|
|
5
6
|
selfLink?: boolean | undefined;
|
|
6
7
|
halfParsed?: boolean | undefined;
|
|
7
8
|
page?: string | undefined;
|
|
9
|
+
nowiki?: boolean;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* title object of a MediaWiki page
|
|
@@ -43,8 +45,9 @@ export declare class Title {
|
|
|
43
45
|
* @param opt.decode 是否需要解码
|
|
44
46
|
* @param opt.selfLink 是否允许selfLink
|
|
45
47
|
* @param opt.page 当前页面标题
|
|
48
|
+
* @param opt.nowiki 是否剥离nowiki标签
|
|
46
49
|
*/
|
|
47
|
-
constructor(title: string, defaultNs: number, config: Config, { temporary, decode, selfLink, page }?: TitleOptions);
|
|
50
|
+
constructor(title: string, defaultNs: number, config: Config, { temporary, decode, selfLink, page, nowiki }?: TitleOptions, accum?: Token[]);
|
|
48
51
|
/**
|
|
49
52
|
* Check if the title is a redirect and get the redirect target
|
|
50
53
|
*
|
package/dist/lib/title.js
CHANGED
|
@@ -74,9 +74,13 @@ class Title {
|
|
|
74
74
|
* @param opt.decode 是否需要解码
|
|
75
75
|
* @param opt.selfLink 是否允许selfLink
|
|
76
76
|
* @param opt.page 当前页面标题
|
|
77
|
+
* @param opt.nowiki 是否剥离nowiki标签
|
|
77
78
|
*/
|
|
78
|
-
constructor(title, defaultNs, config, { temporary, decode, selfLink, page } = {}) {
|
|
79
|
+
constructor(title, defaultNs, config, { temporary, decode, selfLink, page, nowiki } = {}, accum = []) {
|
|
79
80
|
this.page = page;
|
|
81
|
+
if (nowiki) {
|
|
82
|
+
title = title.replace(/\0(\d+)e\x7F/gu, (_, p1) => accum[p1].innerText ?? '');
|
|
83
|
+
}
|
|
80
84
|
const trimmed = title.trim(), subpage = trimmed.startsWith('../');
|
|
81
85
|
if (decode && title.includes('%')) {
|
|
82
86
|
try {
|
|
@@ -14,7 +14,7 @@ const attributesParent = (i = 0) => (constructor) => {
|
|
|
14
14
|
return this.childNodes[i];
|
|
15
15
|
}
|
|
16
16
|
hasAttr(key) {
|
|
17
|
-
|
|
17
|
+
return this.#getAttributesChild().hasAttr(key);
|
|
18
18
|
}
|
|
19
19
|
getAttr(key) {
|
|
20
20
|
return this.#getAttributesChild().getAttr(key);
|
package/dist/parser/converter.js
CHANGED
|
@@ -9,7 +9,7 @@ const converter_1 = require("../src/converter");
|
|
|
9
9
|
* @param accum
|
|
10
10
|
*/
|
|
11
11
|
const parseConverter = (text, config, accum) => {
|
|
12
|
-
config.regexConverter ??= new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*(?:${config.variants.join('|')})\s*:|(?:\s|\0\d+[cn]\x7F)*$)`, '
|
|
12
|
+
config.regexConverter ??= new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*(?:${config.variants.join('|')})\s*:|(?:\s|\0\d+[cn]\x7F)*$)`, 'u');
|
|
13
13
|
const regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, stack = [];
|
|
14
14
|
let regex = regex1, mt = regex.exec(text);
|
|
15
15
|
while (mt) {
|
package/dist/src/attributes.d.ts
CHANGED
package/dist/src/attributes.js
CHANGED
|
@@ -144,9 +144,24 @@ class AttributesToken extends index_2.Token {
|
|
|
144
144
|
return parentNode?.type === 'html' && parentNode.closing && this.text().trim() !== '';
|
|
145
145
|
}
|
|
146
146
|
/** @private */
|
|
147
|
+
lintRef(rect, severity) {
|
|
148
|
+
LINT: {
|
|
149
|
+
const followAttr = this.getAttrToken('follow'), follow = followAttr?.getValue(), name = this.getAttr('name'), rule = 'invalid-ref';
|
|
150
|
+
if (follow && !/\D/u.test(follow)) {
|
|
151
|
+
const msg = 'int-name';
|
|
152
|
+
return rect ? (0, lint_1.generateForChild)(followAttr, rect, rule, msg, severity) : msg;
|
|
153
|
+
}
|
|
154
|
+
else if (follow && (this.hasAttr('details') || name && /\D/u.test(name))) {
|
|
155
|
+
const msg = 'ref-follow';
|
|
156
|
+
return rect ? (0, lint_1.generateForSelf)(this, rect, rule, msg, severity) : msg;
|
|
157
|
+
}
|
|
158
|
+
return '';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** @private */
|
|
147
162
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
148
163
|
LINT: {
|
|
149
|
-
const errors = super.lint(start, re), { parentNode, childNodes, type, name: tag } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start), rules = ['no-ignored', 'required-attr', 'no-duplicate'], { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, s = ['closingTag', 'invalidAttributes', 'nonWordAttributes']
|
|
164
|
+
const errors = super.lint(start, re), { parentNode, childNodes, type, name: tag } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start), rules = ['no-ignored', 'required-attr', 'invalid-ref', 'no-duplicate'], { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, s = ['closingTag', 'invalidAttributes', 'nonWordAttributes']
|
|
150
165
|
.map(k => lintConfig.getSeverity(rules[0], k));
|
|
151
166
|
if (s[0] && this.#lint()) {
|
|
152
167
|
const e = (0, lint_1.generateForSelf)(this, rect, rules[0], 'attributes-of-closing-tag', s[0]);
|
|
@@ -192,12 +207,21 @@ class AttributesToken extends index_2.Token {
|
|
|
192
207
|
}
|
|
193
208
|
}
|
|
194
209
|
}
|
|
195
|
-
|
|
210
|
+
if (tag === 'ref') {
|
|
211
|
+
const severity = lintConfig.getSeverity(rules[2]);
|
|
212
|
+
if (severity) {
|
|
213
|
+
const e = this.lintRef(rect, severity);
|
|
214
|
+
if (e) {
|
|
215
|
+
errors.push(e);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const severity = lintConfig.getSeverity(rules[3], 'attribute');
|
|
196
220
|
if (severity && duplicated.size > 0) {
|
|
197
221
|
for (const key of duplicated) {
|
|
198
222
|
const pairs = attrs.get(key).map(attr => [attr, attr.getValue()]);
|
|
199
223
|
Array.prototype.push.apply(errors, pairs.map(([attr, value], i) => {
|
|
200
|
-
const e = (0, lint_1.generateForChild)(attr, rect, rules[
|
|
224
|
+
const e = (0, lint_1.generateForChild)(attr, rect, rules[3], index_1.default.msg('duplicate-attribute', key), severity);
|
|
201
225
|
if (computeEditInfo || fix) {
|
|
202
226
|
const remove = (0, lint_1.fixByRemove)(e);
|
|
203
227
|
if (!value || pairs.slice(0, i).some(([, v]) => v === value)) {
|
|
@@ -39,6 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.ConverterFlagsToken = void 0;
|
|
41
41
|
const lint_1 = require("../util/lint");
|
|
42
|
+
const string_1 = require("../util/string");
|
|
42
43
|
const rect_1 = require("../lib/rect");
|
|
43
44
|
const gapped_1 = require("../mixin/gapped");
|
|
44
45
|
const noEscape_1 = require("../mixin/noEscape");
|
|
@@ -97,20 +98,24 @@ let ConverterFlagsToken = (() => {
|
|
|
97
98
|
getUnknownFlags() {
|
|
98
99
|
return new Set(this.#flags.filter(flag => /\{{3}[^{}]+\}{3}/u.test(flag)));
|
|
99
100
|
}
|
|
101
|
+
/** 从解析设置中获取语言变体 */
|
|
102
|
+
#getVariants() {
|
|
103
|
+
return new Set((0, string_1.toLowerCase)(this.getAttribute('config').variants));
|
|
104
|
+
}
|
|
100
105
|
/**
|
|
101
106
|
* Get language coversion flags that specify a language variant
|
|
102
107
|
*
|
|
103
108
|
* 获取指定语言变体的转换标记
|
|
104
109
|
*/
|
|
105
110
|
getVariantFlags() {
|
|
106
|
-
const variants =
|
|
107
|
-
return new Set(this.#flags.filter(flag => variants.has(flag)));
|
|
111
|
+
const variants = this.#getVariants();
|
|
112
|
+
return new Set((0, string_1.toLowerCase)(this.#flags).filter(flag => variants.has(flag)));
|
|
108
113
|
}
|
|
109
114
|
/** @private */
|
|
110
115
|
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
111
116
|
isInvalidFlag(flag, variant, unknown) {
|
|
112
117
|
return Boolean(flag)
|
|
113
|
-
&& !variant.has(flag)
|
|
118
|
+
&& !variant.has(flag.toLowerCase())
|
|
114
119
|
&& !unknown.has(flag)
|
|
115
120
|
&& (variant.size > 0 || !definedFlags.has(flag));
|
|
116
121
|
}
|
|
@@ -87,7 +87,7 @@ let ConverterRuleToken = (() => {
|
|
|
87
87
|
constructor(rule, hasColon = true, config = index_1.default.getConfig(), accum = []) {
|
|
88
88
|
super(undefined, config, accum, {});
|
|
89
89
|
const i = rule.indexOf(':'), j = rule.slice(0, i).indexOf('=>'), v = j === -1 ? rule.slice(0, i) : rule.slice(j + 2, i);
|
|
90
|
-
if (hasColon && config.variants.includes(v.trim()
|
|
90
|
+
if (hasColon && config.variants.includes(v.trim())) {
|
|
91
91
|
super.insertAt(new atom_1.AtomToken(v, 'converter-rule-variant', config, accum));
|
|
92
92
|
super.insertAt(getRuleFromTo(rule.slice(i + 1), 'to', config, accum));
|
|
93
93
|
if (j !== -1) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Token } from './index';
|
|
2
|
-
import type { LintError, Config
|
|
2
|
+
import type { LintError, Config } from '../base';
|
|
3
3
|
import type { Title } from '../lib/title';
|
|
4
4
|
import type { AtomToken, FileToken } from '../internal';
|
|
5
|
+
export type GalleryImageTypes = 'gallery-image' | 'imagemap-image';
|
|
5
6
|
/**
|
|
6
7
|
* image parameter
|
|
7
8
|
*
|
|
@@ -26,9 +27,9 @@ export declare abstract class ImageParameterToken extends Token {
|
|
|
26
27
|
/**
|
|
27
28
|
* @param str 图片参数
|
|
28
29
|
* @param extension 文件扩展名
|
|
29
|
-
* @param type
|
|
30
|
+
* @param type 图库节点类型
|
|
30
31
|
*/
|
|
31
|
-
constructor(str: string, extension: string | undefined, type:
|
|
32
|
+
constructor(str: string, extension: string | undefined, type: GalleryImageTypes | undefined, config: Config, accum?: Token[]);
|
|
32
33
|
/**
|
|
33
34
|
* Get the parameter value
|
|
34
35
|
*
|
|
@@ -62,7 +62,7 @@ const getUrl = (link) => {
|
|
|
62
62
|
}
|
|
63
63
|
return new URL(link).href;
|
|
64
64
|
};
|
|
65
|
-
function validate(key, val, config, extOrType, halfParsed) {
|
|
65
|
+
function validate(key, val, config, extOrType, halfParsed, accum) {
|
|
66
66
|
val = (0, string_1.removeComment)(val).trim();
|
|
67
67
|
let value = val.replace(key === 'link' ? /\0\d+[tq]\x7F/gu : /\0\d+t\x7F/gu, '').trim();
|
|
68
68
|
switch (key) {
|
|
@@ -70,6 +70,7 @@ function validate(key, val, config, extOrType, halfParsed) {
|
|
|
70
70
|
return !value && Boolean(val) || /^(?:\d+x?|\d*x\d+)(?:\s*px)?$/u.test(value);
|
|
71
71
|
case 'link': {
|
|
72
72
|
const isGalleryImage = extOrType === 'gallery-image';
|
|
73
|
+
let nowiki = true;
|
|
73
74
|
if (!value) {
|
|
74
75
|
return val;
|
|
75
76
|
}
|
|
@@ -78,8 +79,9 @@ function validate(key, val, config, extOrType, halfParsed) {
|
|
|
78
79
|
}
|
|
79
80
|
else if (value.startsWith('[[') && value.endsWith(']]')) {
|
|
80
81
|
value = value.slice(2, -2);
|
|
82
|
+
nowiki = false;
|
|
81
83
|
}
|
|
82
|
-
const title = index_1.default.normalizeTitle(value, 0, false, config, { halfParsed, decode: true, selfLink: true, page: '' });
|
|
84
|
+
const title = index_1.default.normalizeTitle(value, 0, false, config, { halfParsed, decode: true, selfLink: true, page: '', nowiki }, accum);
|
|
83
85
|
return title.valid ? title : isGalleryImage;
|
|
84
86
|
}
|
|
85
87
|
case 'lang':
|
|
@@ -137,12 +139,12 @@ let ImageParameterToken = (() => {
|
|
|
137
139
|
}
|
|
138
140
|
const value = super.text().trim();
|
|
139
141
|
return debug_1.Shadow.run(() => {
|
|
140
|
-
const config = this.getAttribute('config'), token = new index_2.Token(value, config);
|
|
142
|
+
const config = this.getAttribute('config'), accum = [], token = new index_2.Token(value, config, accum);
|
|
141
143
|
token.parseOnce(0, this.getAttribute('include')).parseOnce();
|
|
142
144
|
if (/^\0\d+m\x7F/u.test(token.firstChild.toString())) {
|
|
143
145
|
return value;
|
|
144
146
|
}
|
|
145
|
-
const link = validate('link', value, config, this.parentNode?.type);
|
|
147
|
+
const link = validate('link', value, config, this.parentNode?.type, undefined, accum);
|
|
146
148
|
return link === true ? undefined : link;
|
|
147
149
|
}, index_1.default);
|
|
148
150
|
}
|
|
@@ -150,7 +152,7 @@ let ImageParameterToken = (() => {
|
|
|
150
152
|
/**
|
|
151
153
|
* @param str 图片参数
|
|
152
154
|
* @param extension 文件扩展名
|
|
153
|
-
* @param type
|
|
155
|
+
* @param type 图库节点类型
|
|
154
156
|
*/
|
|
155
157
|
constructor(str, extension, type, config, accum) {
|
|
156
158
|
let mt;
|
|
@@ -159,7 +161,7 @@ let ImageParameterToken = (() => {
|
|
|
159
161
|
mt = regex.exec(str);
|
|
160
162
|
return mt
|
|
161
163
|
&& (mt.length !== 4
|
|
162
|
-
|| validate(key, mt[2], config, key === 'link' ? type : extension, true) !== false);
|
|
164
|
+
|| validate(key, mt[2], config, key === 'link' ? type : extension, true, accum) !== false);
|
|
163
165
|
});
|
|
164
166
|
// @ts-expect-error mt already assigned
|
|
165
167
|
if (param && mt) {
|
|
@@ -285,7 +287,13 @@ let ImageParameterToken = (() => {
|
|
|
285
287
|
* 获取参数值
|
|
286
288
|
*/
|
|
287
289
|
getValue() {
|
|
288
|
-
LINT:
|
|
290
|
+
LINT: {
|
|
291
|
+
const { name, childNodes } = this;
|
|
292
|
+
if (name === 'link') {
|
|
293
|
+
return (0, string_1.text)(childNodes.map(child => child.is('ext') && child.name === 'nowiki' ? child.innerText ?? '' : child));
|
|
294
|
+
}
|
|
295
|
+
return name === 'invalid' ? this.text() : this.#isVoid() || super.text();
|
|
296
|
+
}
|
|
289
297
|
}
|
|
290
298
|
};
|
|
291
299
|
return ImageParameterToken = _classThis;
|
package/dist/src/link/file.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LinkBaseToken } from './base';
|
|
2
2
|
import { ImageParameterToken } from '../imageParameter';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Config, LintError } from '../../base';
|
|
4
|
+
import type { GalleryImageTypes } from '../imageParameter';
|
|
4
5
|
import type { Token, AtomToken } from '../../internal';
|
|
5
6
|
/**
|
|
6
7
|
* image
|
|
@@ -11,7 +12,7 @@ import type { Token, AtomToken } from '../../internal';
|
|
|
11
12
|
export declare abstract class FileToken extends LinkBaseToken {
|
|
12
13
|
readonly childNodes: readonly [AtomToken, ...ImageParameterToken[]];
|
|
13
14
|
abstract get lastChild(): AtomToken | ImageParameterToken;
|
|
14
|
-
get type(): 'file' |
|
|
15
|
+
get type(): 'file' | GalleryImageTypes;
|
|
15
16
|
/**
|
|
16
17
|
* file extension
|
|
17
18
|
*
|
|
@@ -23,9 +24,9 @@ export declare abstract class FileToken extends LinkBaseToken {
|
|
|
23
24
|
* @param link 文件名
|
|
24
25
|
* @param text 图片参数
|
|
25
26
|
* @param delimiter `|`
|
|
26
|
-
* @param type
|
|
27
|
+
* @param type 图库节点类型
|
|
27
28
|
*/
|
|
28
|
-
constructor(link: string, text?: string, config?: Config, accum?: Token[], delimiter?: string, type?:
|
|
29
|
+
constructor(link: string, text?: string, config?: Config, accum?: Token[], delimiter?: string, type?: GalleryImageTypes);
|
|
29
30
|
/**
|
|
30
31
|
* Get all image parameter tokens
|
|
31
32
|
*
|
package/dist/src/link/file.js
CHANGED
|
@@ -69,7 +69,7 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
69
69
|
* @param link 文件名
|
|
70
70
|
* @param text 图片参数
|
|
71
71
|
* @param delimiter `|`
|
|
72
|
-
* @param type
|
|
72
|
+
* @param type 图库节点类型
|
|
73
73
|
*/
|
|
74
74
|
constructor(link, text, config, accum = [], delimiter = '|', type) {
|
|
75
75
|
super(link, undefined, config, accum, delimiter);
|
package/dist/src/nowiki/index.js
CHANGED
|
@@ -44,9 +44,7 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
44
44
|
/** @private */
|
|
45
45
|
lint(start = this.getAbsoluteIndex()) {
|
|
46
46
|
LINT: {
|
|
47
|
-
const { name, innerText,
|
|
48
|
-
/* NOT FOR BROWSER ONLY */
|
|
49
|
-
previousSibling, } = this, { lintConfig } = index_1.default;
|
|
47
|
+
const { name, innerText } = this, { lintConfig } = index_1.default;
|
|
50
48
|
let rule = 'void-ext', s = lintConfig.getSeverity(rule, name);
|
|
51
49
|
if (s && this.#lint()) {
|
|
52
50
|
const e = (0, lint_1.generateForSelf)(this, { start }, rule, index_1.default.msg('nothing-in', name), s);
|
|
@@ -82,31 +80,9 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
82
80
|
rule = 'invalid-math';
|
|
83
81
|
s = lintConfig.getSeverity(rule);
|
|
84
82
|
if (s && constants_2.mathTags.has(name)) {
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
const
|
|
88
|
-
let tex = innerText, n = 0;
|
|
89
|
-
if (isChem) {
|
|
90
|
-
tex = String.raw `\ce{${tex}}`;
|
|
91
|
-
n = 4;
|
|
92
|
-
}
|
|
93
|
-
switch (display) {
|
|
94
|
-
case 'block':
|
|
95
|
-
tex = String.raw `{\displaystyle ${tex}}`;
|
|
96
|
-
n += 15;
|
|
97
|
-
break;
|
|
98
|
-
case 'inline':
|
|
99
|
-
tex = String.raw `{\textstyle ${tex}}`;
|
|
100
|
-
n += 12;
|
|
101
|
-
break;
|
|
102
|
-
case 'linebreak':
|
|
103
|
-
tex = String.raw `\[ ${tex} \]`;
|
|
104
|
-
n += 3;
|
|
105
|
-
// no default
|
|
106
|
-
}
|
|
107
|
-
const result = texvcjs.check(tex, {
|
|
108
|
-
usemhchem: isChem || Boolean(previousSibling?.hasAttr('chem')),
|
|
109
|
-
});
|
|
83
|
+
const report = this.texvcCheck();
|
|
84
|
+
if (report) {
|
|
85
|
+
const [result, n] = report;
|
|
110
86
|
if (result.status === '+') {
|
|
111
87
|
return [];
|
|
112
88
|
}
|
|
@@ -125,5 +101,40 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
125
101
|
return super.lint(start, getLintRegex(name));
|
|
126
102
|
}
|
|
127
103
|
}
|
|
104
|
+
/* NOT FOR BROWSER ONLY */
|
|
105
|
+
/** @private */
|
|
106
|
+
texvcCheck() {
|
|
107
|
+
const texvcjs = (0, document_1.loadTexvcjs)();
|
|
108
|
+
if (!texvcjs) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
let tex = this.innerText, n = 0;
|
|
112
|
+
if (this.name !== 'math') {
|
|
113
|
+
tex = String.raw `\ce{${tex}}`;
|
|
114
|
+
n = 4;
|
|
115
|
+
}
|
|
116
|
+
switch (this.previousSibling?.getAttr('display') ?? 'block') {
|
|
117
|
+
case 'block':
|
|
118
|
+
tex = String.raw `{\displaystyle ${tex}}`;
|
|
119
|
+
n += 15;
|
|
120
|
+
break;
|
|
121
|
+
case 'inline':
|
|
122
|
+
tex = String.raw `{\textstyle ${tex}}`;
|
|
123
|
+
n += 12;
|
|
124
|
+
break;
|
|
125
|
+
case 'linebreak':
|
|
126
|
+
tex = String.raw `\[ ${tex} \]`;
|
|
127
|
+
n += 3;
|
|
128
|
+
// no default
|
|
129
|
+
}
|
|
130
|
+
return [
|
|
131
|
+
texvcjs.check(tex, {
|
|
132
|
+
usemathrm: true,
|
|
133
|
+
usemhchem: this.name !== 'math' || Boolean(this.previousSibling?.hasAttr('chem')),
|
|
134
|
+
}),
|
|
135
|
+
n,
|
|
136
|
+
tex,
|
|
137
|
+
];
|
|
138
|
+
}
|
|
128
139
|
}
|
|
129
140
|
exports.NowikiToken = NowikiToken;
|
package/dist/src/tagPair/ext.js
CHANGED
|
@@ -45,6 +45,7 @@ const attributesParent_1 = require("../../mixin/attributesParent");
|
|
|
45
45
|
const index_2 = require("../index");
|
|
46
46
|
const index_3 = require("./index");
|
|
47
47
|
const attributes_1 = require("../attributes");
|
|
48
|
+
const nonVoidExt = new Set(['dynamicpagelist', 'templatedata', 'rss']);
|
|
48
49
|
/**
|
|
49
50
|
* extension tag
|
|
50
51
|
*
|
|
@@ -202,16 +203,35 @@ let ExtToken = (() => {
|
|
|
202
203
|
super(name, attrToken, innerToken, closed, config, accum);
|
|
203
204
|
}
|
|
204
205
|
/** @private */
|
|
206
|
+
lintRef(rect, severity) {
|
|
207
|
+
LINT: {
|
|
208
|
+
const refName = this.getAttr('name'), text = this.innerText?.trim();
|
|
209
|
+
let msg = '';
|
|
210
|
+
if (this.closest('ext#references')) {
|
|
211
|
+
if (!refName) {
|
|
212
|
+
msg = 'no-named-in-references';
|
|
213
|
+
}
|
|
214
|
+
else if (!text) {
|
|
215
|
+
msg = 'no-empty-in-references';
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else if (!refName && !text) {
|
|
219
|
+
msg = this.hasAttr('details') ? 'ref-details' : 'ref-no-name';
|
|
220
|
+
}
|
|
221
|
+
return msg && (rect ? (0, lint_1.generateForSelf)(this, rect, 'invalid-ref', msg, severity) : msg);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/** @private */
|
|
205
225
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
206
226
|
LINT: {
|
|
207
|
-
const errors = super.lint(start, re), { lintConfig } = index_1.default, rect = new rect_1.BoundingRect(this, start);
|
|
208
|
-
if (
|
|
227
|
+
const errors = super.lint(start, re), { name } = this, { lintConfig } = index_1.default, rect = new rect_1.BoundingRect(this, start);
|
|
228
|
+
if (name !== 'nowiki') {
|
|
209
229
|
const s = this.inHtmlAttrs(), rule = 'parsing-order', severity = s && lintConfig.getSeverity(rule, s === 2 ? 'ext' : 'templateInTable');
|
|
210
230
|
if (severity) {
|
|
211
231
|
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'ext-in-html', severity));
|
|
212
232
|
}
|
|
213
233
|
}
|
|
214
|
-
if (
|
|
234
|
+
if (name === 'ref') {
|
|
215
235
|
let rule = 'var-anchor', s = lintConfig.getSeverity(rule, 'ref');
|
|
216
236
|
if (s && this.closest('heading-title')) {
|
|
217
237
|
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'variable-anchor', s));
|
|
@@ -221,6 +241,19 @@ let ExtToken = (() => {
|
|
|
221
241
|
if (s && this.closest('link-text,ext-link-text')) {
|
|
222
242
|
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'ref-in-link', s));
|
|
223
243
|
}
|
|
244
|
+
s = lintConfig.getSeverity('invalid-ref');
|
|
245
|
+
if (s) {
|
|
246
|
+
const e = this.lintRef(rect, s);
|
|
247
|
+
if (e) {
|
|
248
|
+
errors.push(e);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
const rule = 'void-ext', s = lintConfig.getSeverity(rule, name);
|
|
254
|
+
if (s && nonVoidExt.has(name) && !this.innerText) {
|
|
255
|
+
errors.push((0, lint_1.generateForSelf)(this, { start }, rule, index_1.default.msg('no-empty', name), s));
|
|
256
|
+
}
|
|
224
257
|
}
|
|
225
258
|
return errors;
|
|
226
259
|
}
|
package/dist/util/search.js
CHANGED
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const binary_search_1 = __importDefault(require("binary-search"));
|
|
7
3
|
/**
|
|
8
4
|
* 二分法查找索引
|
|
9
5
|
* @param haystack 数组
|
|
10
6
|
* @param needle 目标值
|
|
11
7
|
* @param comparator 比较函数
|
|
8
|
+
* @author The Dark Sky Company, LLC <support@darkskyapp.com>
|
|
9
|
+
* @license CC0-1.0
|
|
10
|
+
* @see https://github.com/darkskyapp/binary-search/blob/master/index.js
|
|
12
11
|
*/
|
|
13
12
|
exports.default = (haystack, needle, comparator) => {
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
let low = 0, high = haystack.length - 1;
|
|
14
|
+
while (low <= high) {
|
|
15
|
+
// The naive `low + high >>> 1` could fail for array lengths > 2**31
|
|
16
|
+
// because `>>>` converts its operands to int32. `low + (high - low >>> 1)`
|
|
17
|
+
// works for array lengths <= 2**32-1 which is also Javascript's max array
|
|
18
|
+
// length.
|
|
19
|
+
const mid = low + (high - low >>> 1), // eslint-disable-line no-bitwise
|
|
20
|
+
cmp = comparator(haystack[mid], needle);
|
|
21
|
+
if (cmp < 0) {
|
|
22
|
+
low = mid + 1;
|
|
23
|
+
}
|
|
24
|
+
else if (cmp > 0) {
|
|
25
|
+
high = mid - 1;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// Key found.
|
|
29
|
+
return mid;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Key not found.
|
|
33
|
+
return low;
|
|
16
34
|
};
|
package/dist/util/string.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.decodeNumber = exports.decodeHtml = exports.decodeHtmlBasic = exports.text = exports.removeComment = exports.tidy = exports.trimLc = exports.extUrlChar = exports.extUrlCharFirst = exports.zs = void 0;
|
|
3
|
+
exports.toLowerCase = exports.decodeNumber = exports.decodeHtml = exports.decodeHtmlBasic = exports.text = exports.removeComment = exports.tidy = exports.trimLc = exports.extUrlChar = exports.extUrlCharFirst = exports.zs = void 0;
|
|
4
4
|
exports.restore = restore;
|
|
5
5
|
exports.zs = String.raw ` \xA0\u1680\u2000-\u200A\u202F\u205F\u3000`;
|
|
6
6
|
const commonExtUrlChar = String.raw `[^[\]<>"\0-\x1F\x7F${exports.zs}\uFFFD]`;
|
|
@@ -68,3 +68,9 @@ const decodeHtml = (str) => {
|
|
|
68
68
|
exports.decodeHtml = decodeHtml;
|
|
69
69
|
/** decode numbered HTML entities */
|
|
70
70
|
exports.decodeNumber = factory(/&#(\d+|x[\da-f]+);/giu, (_, code) => String.fromCodePoint(Number((/^x/iu.test(code) ? '0' : '') + code)));
|
|
71
|
+
/**
|
|
72
|
+
* Convert an array of strings to lowercase
|
|
73
|
+
* @param str array of strings
|
|
74
|
+
*/
|
|
75
|
+
const toLowerCase = (str) => str.map(s => s.toLowerCase());
|
|
76
|
+
exports.toLowerCase = toLowerCase;
|
package/i18n/en.json
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"in-url": "$1 in URL",
|
|
35
35
|
"inconsistent-table": "inconsistent table layout",
|
|
36
36
|
"insecure-style": "insecure style",
|
|
37
|
+
"int-name": "name cannot be a simple integer",
|
|
37
38
|
"invalid-attribute": "element containing an invalid attribute name",
|
|
38
39
|
"invalid-category": "invalid category name",
|
|
39
40
|
"invalid-content": "invalid content in <$1>",
|
|
@@ -55,6 +56,9 @@
|
|
|
55
56
|
"missing-extension": "missing file extension",
|
|
56
57
|
"missing-function": "missing Scribunto module function name",
|
|
57
58
|
"newline": null,
|
|
59
|
+
"no-empty": "<$1> should not be empty",
|
|
60
|
+
"no-empty-in-references": "<ref> tag defined in <references> has no content",
|
|
61
|
+
"no-named-in-references": "<ref> tag defined in <references> has no name attribute",
|
|
58
62
|
"no-self-closing": "no self-closing",
|
|
59
63
|
"nonzero-tabindex": "nonzero tabindex",
|
|
60
64
|
"nothing-in": "nothing should be in <$1>",
|
|
@@ -65,7 +69,10 @@
|
|
|
65
69
|
"pipe-in-link": "additional \"|\" in the link text",
|
|
66
70
|
"pipe-in-table": "additional \"|\" in a table cell",
|
|
67
71
|
"redirect-like": "redirect-like syntax in a list item",
|
|
72
|
+
"ref-details": "a <ref> tag with details must contain content or point to a parent reference by name",
|
|
73
|
+
"ref-follow": "a <ref follow> tag that is the continuation of a previous one cannot be named individually or have details",
|
|
68
74
|
"ref-in-link": "<ref> in an internal or external link",
|
|
75
|
+
"ref-no-name": "<ref> with no name must have content",
|
|
69
76
|
"remove": null,
|
|
70
77
|
"required-attribute": "required $1 attribute is missing",
|
|
71
78
|
"template-in-link": "template in an internal link target",
|
package/i18n/zh-hans.json
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"imagemap-without-image": "没有图像的<imagemap>",
|
|
34
34
|
"in-url": "URL中的$1",
|
|
35
35
|
"inconsistent-table": "不一致的表格布局",
|
|
36
|
+
"int-name": "name不能是单纯整数",
|
|
36
37
|
"insecure-style": "不安全的样式",
|
|
37
38
|
"invalid-attribute": "包含无效属性名称的元素",
|
|
38
39
|
"invalid-category": "无效的分类名",
|
|
@@ -55,6 +56,9 @@
|
|
|
55
56
|
"missing-extension": "缺少文件扩展名",
|
|
56
57
|
"missing-function": "缺少Scribunto模块函数名",
|
|
57
58
|
"newline": "换行",
|
|
59
|
+
"no-empty": "<$1>不应为空",
|
|
60
|
+
"no-empty-in-references": "<references>内定义的<ref>标签没有内容",
|
|
61
|
+
"no-named-in-references": "<references>内定义的<ref>标签没有设置name属性",
|
|
58
62
|
"no-self-closing": "移除自封闭",
|
|
59
63
|
"nonzero-tabindex": "非零的tabindex",
|
|
60
64
|
"nothing-in": "<$1>不应有任何内容",
|
|
@@ -65,7 +69,10 @@
|
|
|
65
69
|
"pipe-in-link": "链接文本中的额外\"|\"",
|
|
66
70
|
"pipe-in-table": "表格单元格中的额外\"|\"",
|
|
67
71
|
"redirect-like": "列表项中的疑似重定向语法",
|
|
72
|
+
"ref-details": "带有详细信息的<ref>标签必须包含内容或通过名称指向父级参考",
|
|
73
|
+
"ref-follow": "作为前一个标签的延续的<ref follow>标签不能被单独命名或包含详细信息",
|
|
68
74
|
"ref-in-link": "内部或外部链接中的<ref>",
|
|
75
|
+
"ref-no-name": "没有name的<ref>必须有内容",
|
|
69
76
|
"remove": "移除",
|
|
70
77
|
"required-attribute": "缺少必需的$1属性",
|
|
71
78
|
"template-in-link": "内部链接目标中的模板",
|
package/i18n/zh-hant.json
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"imagemap-without-image": "<imagemap>沒有圖片",
|
|
34
34
|
"in-url": "URL中有$1",
|
|
35
35
|
"inconsistent-table": "表格版面不一致",
|
|
36
|
+
"int-name": "name屬性不能使用數字",
|
|
36
37
|
"insecure-style": "不安全的樣式",
|
|
37
38
|
"invalid-attribute": "包含無效屬性名稱的元素",
|
|
38
39
|
"invalid-category": "無效的分類名",
|
|
@@ -55,6 +56,9 @@
|
|
|
55
56
|
"missing-extension": "缺少副檔名",
|
|
56
57
|
"missing-function": "缺少Scribunto模組函式名稱",
|
|
57
58
|
"newline": "換行",
|
|
59
|
+
"no-empty": "<$1>不應為空",
|
|
60
|
+
"no-empty-in-references": "<references>內定義的<ref>標籤沒有內容",
|
|
61
|
+
"no-named-in-references": "<references> 中定義的 <ref> 沒有設定 name 屬性",
|
|
58
62
|
"no-self-closing": "移除自封閉",
|
|
59
63
|
"nonzero-tabindex": "非零的tabindex",
|
|
60
64
|
"nothing-in": "<$1>不應有任何內容",
|
|
@@ -65,7 +69,10 @@
|
|
|
65
69
|
"pipe-in-link": "連結文字有額外的\"|\"字元",
|
|
66
70
|
"pipe-in-table": "表格儲存格有額外的\"|\"字元",
|
|
67
71
|
"redirect-like": "列表項中的疑似重新導向語法",
|
|
72
|
+
"ref-details": "一個帶有詳細資訊的 <ref> 標籤必須包含內容、或透過名稱指向父級參考",
|
|
73
|
+
"ref-follow": "作為前一個延續的 <ref follow> 標籤,不能單獨命名或包含詳細資訊",
|
|
68
74
|
"ref-in-link": "內部或外部連結裡的<ref>",
|
|
75
|
+
"ref-no-name": "沒有名稱的<ref>必須要有內容",
|
|
69
76
|
"remove": "移除",
|
|
70
77
|
"required-attribute": "缺少必需的$1屬性",
|
|
71
78
|
"template-in-link": "內部連結目標中的模板",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikilint",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.44.0",
|
|
4
4
|
"description": "A Node.js linter for MediaWiki markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"url": "git+https://github.com/bhsd-harry/wikiparser-node.git"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
|
-
"ls": "npm i --package-lock-only && npm ls --package-lock-only --all --omit=dev",
|
|
42
|
+
"ls": "npm i --package-lock-only && npm ls --package-lock-only --all --include=peer --omit=dev",
|
|
43
43
|
"prepublishOnly": "npm run build:core",
|
|
44
44
|
"build:core": "bash build.sh",
|
|
45
45
|
"build:define": "bash sed.sh -i \"s/pkg = \\$PKG/pkg = $(npm pkg get name)/; s/version = \\$VERSION/version = $(npm pkg get version)/\" dist/bin/config.js",
|
|
@@ -73,14 +73,6 @@
|
|
|
73
73
|
"json-summary"
|
|
74
74
|
]
|
|
75
75
|
},
|
|
76
|
-
"dependencies": {
|
|
77
|
-
"@bhsd/cm-util": "^2.1.0",
|
|
78
|
-
"@bhsd/common": "^2.2.1",
|
|
79
|
-
"@bhsd/stylelint-util": "^1.0.3",
|
|
80
|
-
"binary-search": "^1.3.6",
|
|
81
|
-
"entities": "^8.0.0",
|
|
82
|
-
"vscode-languageserver-types": "^3.17.5"
|
|
83
|
-
},
|
|
84
76
|
"peerDependencies": {
|
|
85
77
|
"color-name": ">=2.0.0",
|
|
86
78
|
"mathoid-texvcjs": ">=0.4.0",
|
|
@@ -109,6 +101,13 @@
|
|
|
109
101
|
"optional": true
|
|
110
102
|
}
|
|
111
103
|
},
|
|
104
|
+
"dependencies": {
|
|
105
|
+
"@bhsd/cm-util": "^2.2.0",
|
|
106
|
+
"@bhsd/common": "^2.2.1",
|
|
107
|
+
"@bhsd/stylelint-util": "^1.1.0",
|
|
108
|
+
"entities": "^8.0.0",
|
|
109
|
+
"vscode-languageserver-types": "^3.17.5"
|
|
110
|
+
},
|
|
112
111
|
"devDependencies": {
|
|
113
112
|
"@bhsd/code-standard": "^2.6.2",
|
|
114
113
|
"@bhsd/nodejs": "^1.0.1",
|
|
@@ -124,7 +123,7 @@
|
|
|
124
123
|
"markdownlint-cli2": "^0.22.1",
|
|
125
124
|
"mathoid-texvcjs": "^0.6.0",
|
|
126
125
|
"mocha": "^11.7.6",
|
|
127
|
-
"stylelint": "^17.
|
|
126
|
+
"stylelint": "^17.13.0",
|
|
128
127
|
"typescript": "^6.0.3",
|
|
129
128
|
"v8r": "^6.1.0",
|
|
130
129
|
"vscode-css-languageservice": "^6.3.10",
|