wikilint 2.18.2 → 2.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/cli.js +1 -1
- package/config/minimum.json +7 -0
- package/dist/base.d.mts +2 -0
- package/dist/base.d.ts +2 -0
- package/dist/base.js +1 -0
- package/dist/base.mjs +2 -1
- package/dist/bin/config.js +3 -2
- package/dist/index.d.ts +12 -1
- package/dist/index.js +45 -28
- package/dist/lib/lsp.d.ts +1 -0
- package/dist/lib/lsp.js +19 -14
- package/dist/lib/text.js +2 -2
- package/dist/lib/title.d.ts +18 -4
- package/dist/lib/title.js +12 -4
- package/dist/parser/braces.js +79 -37
- package/dist/parser/commentAndExt.js +5 -16
- package/dist/parser/links.js +1 -1
- package/dist/parser/redirect.js +1 -3
- package/dist/src/arg.js +1 -1
- package/dist/src/attribute.js +1 -1
- package/dist/src/converter.js +1 -1
- package/dist/src/gallery.js +1 -1
- package/dist/src/heading.js +3 -3
- package/dist/src/imageParameter.js +9 -9
- package/dist/src/imagemap.js +3 -2
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +7 -5
- package/dist/src/link/base.js +1 -1
- package/dist/src/link/file.d.ts +2 -0
- package/dist/src/link/file.js +15 -13
- package/dist/src/link/galleryImage.js +1 -1
- package/dist/src/link/redirectTarget.js +1 -2
- package/dist/src/magicLink.js +1 -1
- package/dist/src/nested.js +5 -5
- package/dist/src/nowiki/index.js +3 -2
- package/dist/src/redirect.js +1 -2
- package/dist/src/syntax.d.ts +4 -2
- package/dist/src/syntax.js +4 -2
- package/dist/src/table/base.js +1 -1
- package/dist/src/table/index.d.ts +1 -0
- package/dist/src/table/index.js +3 -6
- package/dist/src/table/trBase.js +31 -14
- package/dist/src/transclude.js +14 -6
- package/dist/util/debug.js +11 -1
- package/dist/util/diff.js +1 -1
- package/dist/util/string.js +3 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
# WikiLint
|
|
8
8
|
|
|
9
|
-
This is a minimal version of [WikiParser-Node](https://www.npmjs.com/package/wikiparser-node)
|
|
9
|
+
This is a minimal version of [WikiParser-Node](https://www.npmjs.com/package/wikiparser-node). The [WikiParser Language Server](https://marketplace.visualstudio.com/items?itemName=Bhsd.vscode-extension-wikiparser) VSCode extension is written based on this package.
|
|
10
10
|
|
|
11
11
|
You can also directly lint Wikitext articles in the command line using this package:
|
|
12
12
|
|
package/bin/cli.js
CHANGED
package/config/minimum.json
CHANGED
|
@@ -98,6 +98,13 @@
|
|
|
98
98
|
],
|
|
99
99
|
"parserFunction": [
|
|
100
100
|
{
|
|
101
|
+
"msgnw": "msgnw",
|
|
102
|
+
"pageid": "pageid",
|
|
103
|
+
"articlepath": "articlepath",
|
|
104
|
+
"server": "server",
|
|
105
|
+
"servername": "servername",
|
|
106
|
+
"scriptpath": "scriptpath",
|
|
107
|
+
"stylepath": "stylepath",
|
|
101
108
|
"#language": "language",
|
|
102
109
|
"#special": "special",
|
|
103
110
|
"#speciale": "speciale",
|
package/dist/base.d.mts
CHANGED
|
@@ -41,6 +41,7 @@ export declare const stages: {
|
|
|
41
41
|
list: number;
|
|
42
42
|
dd: number;
|
|
43
43
|
converter: number;
|
|
44
|
+
'list-range': number;
|
|
44
45
|
};
|
|
45
46
|
export type Stage = keyof typeof stages;
|
|
46
47
|
export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-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"];
|
|
@@ -271,6 +272,7 @@ export interface Parser {
|
|
|
271
272
|
*
|
|
272
273
|
* 创建语言服务
|
|
273
274
|
* @param uri document URI / 文档标识
|
|
275
|
+
* @since v1.16.1
|
|
274
276
|
*/
|
|
275
277
|
createLanguageService(uri: object): LanguageService;
|
|
276
278
|
}
|
package/dist/base.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export declare const stages: {
|
|
|
41
41
|
list: number;
|
|
42
42
|
dd: number;
|
|
43
43
|
converter: number;
|
|
44
|
+
'list-range': number;
|
|
44
45
|
};
|
|
45
46
|
export type Stage = keyof typeof stages;
|
|
46
47
|
export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-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"];
|
|
@@ -271,6 +272,7 @@ export interface Parser {
|
|
|
271
272
|
*
|
|
272
273
|
* 创建语言服务
|
|
273
274
|
* @param uri document URI / 文档标识
|
|
275
|
+
* @since v1.16.1
|
|
274
276
|
*/
|
|
275
277
|
createLanguageService(uri: object): LanguageService;
|
|
276
278
|
}
|
package/dist/base.js
CHANGED
package/dist/base.mjs
CHANGED
package/dist/bin/config.js
CHANGED
|
@@ -81,8 +81,9 @@ let mwConfig;
|
|
|
81
81
|
* @param site site nickname
|
|
82
82
|
* @param url script path
|
|
83
83
|
* @param force whether to overwrite the existing configuration
|
|
84
|
+
* @param internal for internal use
|
|
84
85
|
*/
|
|
85
|
-
exports.default = async (site, url, force) => {
|
|
86
|
+
exports.default = async (site, url, force, internal) => {
|
|
86
87
|
if (!site || !url) {
|
|
87
88
|
console.error('Usage: npx getParserConfig <site> <script path> [force]');
|
|
88
89
|
process.exit(1);
|
|
@@ -133,7 +134,7 @@ exports.default = async (site, url, force) => {
|
|
|
133
134
|
if (force || !fs_1.default.existsSync(file)) {
|
|
134
135
|
fs_1.default.writeFileSync(file, `${JSON.stringify(config, null, '\t')}\n`);
|
|
135
136
|
}
|
|
136
|
-
else {
|
|
137
|
+
else if (!internal) {
|
|
137
138
|
assert_1.default.deepStrictEqual(arrToObj(require(file)), arrToObj(config));
|
|
138
139
|
}
|
|
139
140
|
return config;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Config, LintError, TokenTypes, Parser as ParserBase, Stage } from './base';
|
|
2
|
-
import type { Title } from './lib/title';
|
|
2
|
+
import type { Title, TitleOptions } from './lib/title';
|
|
3
3
|
import type { LanguageService, QuickFixData } from './lib/lsp';
|
|
4
4
|
import type { Token } from './internal';
|
|
5
5
|
declare interface Parser extends ParserBase {
|
|
6
|
+
/** @since v1.5.1 */
|
|
6
7
|
rules: readonly LintError.Rule[];
|
|
7
8
|
/**
|
|
8
9
|
* Normalize page title
|
|
@@ -19,8 +20,18 @@ declare interface Parser extends ParserBase {
|
|
|
19
20
|
*
|
|
20
21
|
* 创建语言服务
|
|
21
22
|
* @param uri document URI / 文档标识
|
|
23
|
+
* @since v1.16.1
|
|
22
24
|
*/
|
|
23
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>;
|
|
24
35
|
}
|
|
25
36
|
declare const Parser: Parser;
|
|
26
37
|
// @ts-expect-error mixed export styles
|
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
|
|
@@ -25,6 +26,9 @@ const Parser = {
|
|
|
25
26
|
config: 'default',
|
|
26
27
|
i18n: undefined,
|
|
27
28
|
rules: base_1.rules,
|
|
29
|
+
/* NOT FOR BROWSER ONLY */
|
|
30
|
+
lintCSS: true,
|
|
31
|
+
/* NOT FOR BROWSER ONLY END */
|
|
28
32
|
/** @implements */
|
|
29
33
|
getConfig(config) {
|
|
30
34
|
/* NOT FOR BROWSER ONLY */
|
|
@@ -39,7 +43,7 @@ const Parser = {
|
|
|
39
43
|
return this.getConfig();
|
|
40
44
|
}
|
|
41
45
|
/* NOT FOR BROWSER ONLY END */
|
|
42
|
-
const parserConfig = config ?? this.config, { doubleUnderscore } = parserConfig;
|
|
46
|
+
const parserConfig = config ?? this.config, { doubleUnderscore, } = parserConfig;
|
|
43
47
|
for (let i = 0; i < 2; i++) {
|
|
44
48
|
if (doubleUnderscore.length > i + 2 && doubleUnderscore[i].length === 0) {
|
|
45
49
|
doubleUnderscore[i] = Object.keys(doubleUnderscore[i + 2]);
|
|
@@ -61,11 +65,11 @@ const Parser = {
|
|
|
61
65
|
return msg && (this.i18n?.[msg] ?? msg).replace('$1', this.msg(arg));
|
|
62
66
|
},
|
|
63
67
|
/** @implements */
|
|
64
|
-
normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(),
|
|
68
|
+
normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt) {
|
|
65
69
|
const { Title } = require('./lib/title');
|
|
66
70
|
let titleObj;
|
|
67
|
-
if (halfParsed) {
|
|
68
|
-
titleObj = new Title(title, defaultNs, config,
|
|
71
|
+
if (opt?.halfParsed) {
|
|
72
|
+
titleObj = new Title(title, defaultNs, config, opt);
|
|
69
73
|
}
|
|
70
74
|
else {
|
|
71
75
|
const { Token } = require('./src/index');
|
|
@@ -73,7 +77,7 @@ const Parser = {
|
|
|
73
77
|
const root = new Token(title, config);
|
|
74
78
|
root.type = 'root';
|
|
75
79
|
root.parseOnce(0, include).parseOnce();
|
|
76
|
-
const t = new Title(root.toString(), defaultNs, config,
|
|
80
|
+
const t = new Title(root.toString(), defaultNs, config, opt);
|
|
77
81
|
for (const key of ['main', 'fragment']) {
|
|
78
82
|
const str = t[key];
|
|
79
83
|
if (str?.includes('\0')) {
|
|
@@ -94,8 +98,9 @@ const Parser = {
|
|
|
94
98
|
/** @implements */
|
|
95
99
|
parse(wikitext, include, maxStage = constants_1.MAX_STAGE, config = Parser.getConfig()) {
|
|
96
100
|
wikitext = (0, string_1.tidy)(wikitext);
|
|
101
|
+
let types;
|
|
97
102
|
if (typeof maxStage !== 'number') {
|
|
98
|
-
|
|
103
|
+
types = Array.isArray(maxStage) ? maxStage : [maxStage];
|
|
99
104
|
maxStage = Math.max(...types.map(t => base_1.stages[t] || constants_1.MAX_STAGE));
|
|
100
105
|
}
|
|
101
106
|
const { Token } = require('./src/index');
|
|
@@ -132,28 +137,34 @@ const Parser = {
|
|
|
132
137
|
const token = new Token((0, string_1.tidy)(wikitext), config);
|
|
133
138
|
token.type = 'root';
|
|
134
139
|
let i = 0;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
140
|
+
try {
|
|
141
|
+
await new Promise(resolve => {
|
|
142
|
+
const /** @ignore */ check = () => {
|
|
143
|
+
if (watch() === wikitext) {
|
|
144
|
+
i++;
|
|
145
|
+
set(parseOnce, 0);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
resolve();
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
/** @ignore */ parseOnce = () => {
|
|
152
|
+
if (i === constants_1.MAX_STAGE + 1) {
|
|
153
|
+
token.afterBuild();
|
|
154
|
+
resolve();
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
token[i === constants_1.MAX_STAGE ? 'build' : 'parseOnce'](i, include);
|
|
158
|
+
check();
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
set(parseOnce, 0);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch (e) /* istanbul ignore next */ {
|
|
165
|
+
debug_1.Shadow.running = running;
|
|
166
|
+
throw e;
|
|
167
|
+
}
|
|
157
168
|
debug_1.Shadow.running = running;
|
|
158
169
|
return token;
|
|
159
170
|
},
|
|
@@ -165,6 +176,12 @@ const Parser = {
|
|
|
165
176
|
return tasks.get(uri) ?? new LanguageService(uri);
|
|
166
177
|
}
|
|
167
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 */
|
|
168
185
|
};
|
|
169
186
|
const def = {
|
|
170
187
|
default: { value: Parser },
|
package/dist/lib/lsp.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare const isAttr: ({ type, parentNode, length, firstChild }: Token, s
|
|
|
20
20
|
/** VSCode-style language service */
|
|
21
21
|
export declare class LanguageService implements LanguageServiceBase {
|
|
22
22
|
#private;
|
|
23
|
+
/** @since v1.17.1 */
|
|
23
24
|
include: boolean;
|
|
24
25
|
lilypond: string;
|
|
25
26
|
/** @param uri 任务标识 */
|
package/dist/lib/lsp.js
CHANGED
|
@@ -16,13 +16,13 @@ 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
24
|
}, jsonSelector = document_1.jsonTags.map(s => `ext-inner#${s}`).join(), scores = new Map();
|
|
25
|
+
let colors;
|
|
26
26
|
/* NOT FOR BROWSER ONLY END */
|
|
27
27
|
exports.tasks = new WeakMap();
|
|
28
28
|
const refTags = new Set(['ref']), referencesTags = new Set(['ref', 'references']), nameAttrs = new Set(['name', 'extends', 'follow']), groupAttrs = new Set(['group']), renameTypes = new Set([
|
|
@@ -40,6 +40,7 @@ const refTags = new Set(['ref']), referencesTags = new Set(['ref', 'references']
|
|
|
40
40
|
'magic-word-name',
|
|
41
41
|
...renameTypes,
|
|
42
42
|
]), plainTypes = new Set(['text', 'comment', 'noinclude', 'include']), cssSelector = ['ext', 'html', 'table'].map(s => `${s}-attr#style`).join();
|
|
43
|
+
const getLinkRegex = (0, common_1.getRegex)(protocol => new RegExp(`^(?:${protocol}|//)`, 'iu'));
|
|
43
44
|
/**
|
|
44
45
|
* Check if a token is a plain attribute.
|
|
45
46
|
* @param token
|
|
@@ -273,6 +274,7 @@ class LanguageService {
|
|
|
273
274
|
#config;
|
|
274
275
|
#include;
|
|
275
276
|
#completionConfig;
|
|
277
|
+
/** @since v1.17.1 */
|
|
276
278
|
include = true;
|
|
277
279
|
/** @private */
|
|
278
280
|
config;
|
|
@@ -406,11 +408,14 @@ class LanguageService {
|
|
|
406
408
|
async provideDocumentColors(rgba, text, hsl = true) {
|
|
407
409
|
const root = await this.#queue(text);
|
|
408
410
|
/* NOT FOR BROWSER ONLY */
|
|
409
|
-
|
|
411
|
+
/* eslint-disable require-atomic-updates */
|
|
410
412
|
try {
|
|
411
|
-
colors
|
|
413
|
+
colors ??= new RegExp(String.raw `\b${Object.keys((await import('color-name')).default).join('|')}\b`, 'giu');
|
|
412
414
|
}
|
|
413
|
-
catch {
|
|
415
|
+
catch {
|
|
416
|
+
colors = false;
|
|
417
|
+
}
|
|
418
|
+
/* eslint-enable require-atomic-updates */
|
|
414
419
|
/* NOT FOR BROWSER ONLY END */
|
|
415
420
|
return root.querySelectorAll('attr-value,parameter-value,arg-default').reverse()
|
|
416
421
|
.flatMap(token => {
|
|
@@ -637,7 +642,7 @@ class LanguageService {
|
|
|
637
642
|
if (t === 'magic-word' && n !== 'invoke') {
|
|
638
643
|
return undefined;
|
|
639
644
|
}
|
|
640
|
-
const key = this.#text.slice(cur.getAbsoluteIndex(), root.indexFromPos(line, character)).trimStart(), [
|
|
645
|
+
const key = this.#text.slice(cur.getAbsoluteIndex(), root.indexFromPos(line, character)).trimStart(), [mod, func] = t === 'magic-word' ? transclusion.getModule() : [];
|
|
641
646
|
return key
|
|
642
647
|
? getCompletion(root.querySelectorAll('parameter').filter(token => {
|
|
643
648
|
if (token === parentNode
|
|
@@ -650,7 +655,7 @@ class LanguageService {
|
|
|
650
655
|
return true;
|
|
651
656
|
}
|
|
652
657
|
const [m, f] = token.parentNode.getModule();
|
|
653
|
-
return m ===
|
|
658
|
+
return m === mod && f === func;
|
|
654
659
|
}).map(({ name }) => name), 'Variable', key, position, type === 'parameter-value' ? '=' : '')
|
|
655
660
|
: undefined;
|
|
656
661
|
/* NOT FOR BROWSER ONLY */
|
|
@@ -893,7 +898,7 @@ class LanguageService {
|
|
|
893
898
|
*/
|
|
894
899
|
async provideLinks(text) {
|
|
895
900
|
this.config ??= index_1.default.getConfig();
|
|
896
|
-
const { articlePath, protocol } = this.config, absolute = articlePath?.includes('//'), protocolRegex =
|
|
901
|
+
const { articlePath, protocol } = this.config, absolute = articlePath?.includes('//'), protocolRegex = getLinkRegex(protocol);
|
|
897
902
|
return (await this.#queue(text))
|
|
898
903
|
.querySelectorAll(`magic-link,ext-link-url,free-ext-link,attr-value,image-parameter#link${absolute ? ',link-target,template-name,invoke-module,magic-word#filepath,magic-word#widget' : ''}`)
|
|
899
904
|
.reverse()
|
|
@@ -953,8 +958,8 @@ class LanguageService {
|
|
|
953
958
|
ns = name === 'filepath' ? 6 : 274;
|
|
954
959
|
// no default
|
|
955
960
|
}
|
|
956
|
-
const title = index_1.default
|
|
957
|
-
|
|
961
|
+
const title = index_1.default
|
|
962
|
+
.normalizeTitle(target, ns, false, this.config, { temporary: true });
|
|
958
963
|
if (!title.valid) {
|
|
959
964
|
return false;
|
|
960
965
|
}
|
|
@@ -1110,13 +1115,13 @@ class LanguageService {
|
|
|
1110
1115
|
}
|
|
1111
1116
|
else if (type === 'magic-word-name') {
|
|
1112
1117
|
info = this.#getParserFunction(parentNode.name);
|
|
1113
|
-
f = offsetNode.
|
|
1118
|
+
f = offsetNode.text().trim();
|
|
1114
1119
|
colon = parentNode.getAttribute('colon');
|
|
1115
1120
|
}
|
|
1116
1121
|
else if (offsetNode.is('magic-word') && !offsetNode.modifier && length === 1
|
|
1117
1122
|
&& (offset > 0 || root.posFromIndex(offsetNode.getAbsoluteIndex()).left === position.character)) {
|
|
1118
1123
|
info = this.#getParserFunction(name);
|
|
1119
|
-
f = offsetNode.firstChild.
|
|
1124
|
+
f = offsetNode.firstChild.text().trim();
|
|
1120
1125
|
colon = offsetNode.getAttribute('colon');
|
|
1121
1126
|
}
|
|
1122
1127
|
else if ((offsetNode.is('magic-word') || offsetNode.is('template'))
|
|
@@ -1203,7 +1208,7 @@ class LanguageService {
|
|
|
1203
1208
|
}
|
|
1204
1209
|
const n = childNodes.length - 1, candidates = info.signatures.filter(params => (params.length >= n || params[params.length - 1]?.rest)
|
|
1205
1210
|
&& params.every(({ label, const: c }, i) => {
|
|
1206
|
-
const p = c && i < n && childNodes[i + 1]?.
|
|
1211
|
+
const p = c && i < n && childNodes[i + 1]?.text().trim();
|
|
1207
1212
|
return !p || label.toLowerCase().includes(p.toLowerCase());
|
|
1208
1213
|
}));
|
|
1209
1214
|
if (candidates.length === 0) {
|
|
@@ -1216,7 +1221,7 @@ class LanguageService {
|
|
|
1216
1221
|
break;
|
|
1217
1222
|
}
|
|
1218
1223
|
}
|
|
1219
|
-
const f = firstChild.
|
|
1224
|
+
const f = firstChild.text().trim(), colon = lastChild.getAttribute('colon');
|
|
1220
1225
|
return {
|
|
1221
1226
|
signatures: candidates.map((params) => ({
|
|
1222
1227
|
label: `{{${f}${params.length === 0 ? '' : colon}${params.map(({ label }) => label).join('|')}}}`,
|
|
@@ -1331,7 +1336,7 @@ class LanguageService {
|
|
|
1331
1336
|
this.config = index_1.default.getConfig(config);
|
|
1332
1337
|
}
|
|
1333
1338
|
catch {
|
|
1334
|
-
this.config = index_1.default.
|
|
1339
|
+
this.config = await index_1.default.fetchConfig(site, `${mt[0]}/w`);
|
|
1335
1340
|
}
|
|
1336
1341
|
Object.assign(this.config, { articlePath: `${mt[0]}/wiki/` });
|
|
1337
1342
|
}
|
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/lib/title.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { Config } from '../base';
|
|
2
|
+
export interface TitleOptions {
|
|
3
|
+
temporary?: boolean | undefined;
|
|
4
|
+
decode?: boolean | undefined;
|
|
5
|
+
selfLink?: boolean | undefined;
|
|
6
|
+
halfParsed?: boolean | undefined;
|
|
7
|
+
}
|
|
2
8
|
/**
|
|
3
9
|
* title object of a MediaWiki page
|
|
4
10
|
*
|
|
@@ -18,21 +24,28 @@ export declare class Title {
|
|
|
18
24
|
get prefix(): string;
|
|
19
25
|
/** full title / 完整标题 */
|
|
20
26
|
get title(): string;
|
|
21
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* file extension / 扩展名
|
|
29
|
+
* @since v1.1.0
|
|
30
|
+
*/
|
|
22
31
|
get extension(): string | undefined;
|
|
23
32
|
/**
|
|
24
33
|
* @see MediaWikiTitleCodec::splitTitleString
|
|
25
34
|
*
|
|
26
35
|
* @param title 标题(含或不含命名空间前缀)
|
|
27
36
|
* @param defaultNs 命名空间
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
37
|
+
* @param config
|
|
38
|
+
* @param opt 选项
|
|
39
|
+
* @param opt.temporary 是否是临时标题
|
|
40
|
+
* @param opt.decode 是否需要解码
|
|
41
|
+
* @param opt.selfLink 是否允许selfLink
|
|
30
42
|
*/
|
|
31
|
-
constructor(title: string, defaultNs: number, config: Config, temporary
|
|
43
|
+
constructor(title: string, defaultNs: number, config: Config, { temporary, decode, selfLink }?: TitleOptions);
|
|
32
44
|
/**
|
|
33
45
|
* Check if the title is a redirect
|
|
34
46
|
*
|
|
35
47
|
* 检测是否是重定向
|
|
48
|
+
* @since v1.12.2
|
|
36
49
|
*/
|
|
37
50
|
getRedirection(): [boolean, string];
|
|
38
51
|
/**
|
|
@@ -40,6 +53,7 @@ export declare class Title {
|
|
|
40
53
|
*
|
|
41
54
|
* 生成URL
|
|
42
55
|
* @param articlePath article path / 条目路径
|
|
56
|
+
* @since v1.10.0
|
|
43
57
|
*/
|
|
44
58
|
getUrl(articlePath?: string): string;
|
|
45
59
|
}
|
package/dist/lib/title.js
CHANGED
|
@@ -41,7 +41,10 @@ class Title {
|
|
|
41
41
|
get title() {
|
|
42
42
|
return this.getRedirection()[1];
|
|
43
43
|
}
|
|
44
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* file extension / 扩展名
|
|
46
|
+
* @since v1.1.0
|
|
47
|
+
*/
|
|
45
48
|
get extension() {
|
|
46
49
|
const { main } = this, i = main.lastIndexOf('.');
|
|
47
50
|
return i === -1 ? undefined : main.slice(i + 1).toLowerCase();
|
|
@@ -51,10 +54,13 @@ class Title {
|
|
|
51
54
|
*
|
|
52
55
|
* @param title 标题(含或不含命名空间前缀)
|
|
53
56
|
* @param defaultNs 命名空间
|
|
54
|
-
* @param
|
|
55
|
-
* @param
|
|
57
|
+
* @param config
|
|
58
|
+
* @param opt 选项
|
|
59
|
+
* @param opt.temporary 是否是临时标题
|
|
60
|
+
* @param opt.decode 是否需要解码
|
|
61
|
+
* @param opt.selfLink 是否允许selfLink
|
|
56
62
|
*/
|
|
57
|
-
constructor(title, defaultNs, config, temporary, decode, selfLink) {
|
|
63
|
+
constructor(title, defaultNs, config, { temporary, decode, selfLink } = {}) {
|
|
58
64
|
const subpage = title.trim().startsWith('../');
|
|
59
65
|
if (decode && title.includes('%')) {
|
|
60
66
|
try {
|
|
@@ -116,6 +122,7 @@ class Title {
|
|
|
116
122
|
* Check if the title is a redirect
|
|
117
123
|
*
|
|
118
124
|
* 检测是否是重定向
|
|
125
|
+
* @since v1.12.2
|
|
119
126
|
*/
|
|
120
127
|
getRedirection() {
|
|
121
128
|
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
|
|
@@ -133,6 +140,7 @@ class Title {
|
|
|
133
140
|
*
|
|
134
141
|
* 生成URL
|
|
135
142
|
* @param articlePath article path / 条目路径
|
|
143
|
+
* @since v1.10.0
|
|
136
144
|
*/
|
|
137
145
|
getUrl(articlePath) {
|
|
138
146
|
LSP: { // eslint-disable-line no-unused-labels
|