wikilint 2.32.0 → 2.34.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 +1 -1
- package/dist/base.d.ts +1 -1
- package/dist/base.js +1 -0
- package/dist/base.mjs +1 -0
- package/dist/bin/cli.js +8 -19
- package/dist/bin/config.js +1 -1
- package/dist/index.js +3 -5
- package/dist/internal.d.ts +3 -0
- package/dist/lib/lintConfig.js +8 -0
- package/dist/lib/lsp.js +20 -3
- package/dist/lib/node.js +3 -11
- package/dist/lib/text.js +18 -18
- package/dist/src/attribute.d.ts +3 -5
- package/dist/src/attribute.js +11 -9
- package/dist/src/attributes.d.ts +0 -1
- package/dist/src/attributes.js +4 -5
- package/dist/src/imageParameter.d.ts +7 -3
- package/dist/src/imageParameter.js +14 -4
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +22 -20
- package/dist/src/link/base.d.ts +1 -1
- package/dist/src/link/base.js +7 -1
- package/dist/src/link/categorytree.d.ts +19 -0
- package/dist/src/link/categorytree.js +95 -0
- package/dist/src/link/file.d.ts +3 -2
- package/dist/src/link/file.js +3 -2
- package/dist/src/link/galleryImage.js +5 -4
- package/dist/src/multiLine/gallery.d.ts +1 -3
- package/dist/src/multiLine/gallery.js +1 -3
- package/dist/src/multiLine/imagemap.js +2 -3
- package/dist/src/multiLine/inputbox.d.ts +3 -3
- package/dist/src/multiLine/inputbox.js +3 -7
- package/dist/src/multiLine/paramTag.d.ts +3 -4
- package/dist/src/multiLine/paramTag.js +5 -47
- package/dist/src/nowiki/index.js +48 -13
- package/dist/src/nowiki/list.d.ts +0 -1
- package/dist/src/nowiki/list.js +1 -0
- package/dist/src/nowiki/noinclude.d.ts +0 -1
- package/dist/src/nowiki/noinclude.js +1 -0
- package/dist/src/paramLine.d.ts +3 -0
- package/dist/src/paramLine.js +43 -2
- package/dist/src/table/base.d.ts +1 -2
- package/dist/src/table/base.js +7 -8
- package/dist/src/table/index.d.ts +1 -1
- package/dist/src/table/index.js +1 -7
- package/dist/src/table/td.d.ts +0 -1
- package/dist/src/table/td.js +1 -0
- package/dist/src/table/tr.d.ts +1 -1
- package/dist/src/tagPair/ext.js +19 -10
- package/dist/src/tagPair/index.d.ts +2 -1
- package/dist/src/tagPair/index.js +10 -6
- package/dist/src/tagPair/translate.d.ts +1 -1
- package/dist/src/tagPair/translate.js +3 -0
- package/dist/util/debug.js +10 -3
- package/dist/util/diff.js +6 -17
- package/dist/util/sharable.d.mts +1 -0
- package/dist/util/sharable.js +62 -1
- package/dist/util/sharable.mjs +62 -0
- package/i18n/en.json +2 -0
- package/i18n/zh-hans.json +2 -0
- package/i18n/zh-hant.json +2 -0
- package/package.json +3 -3
package/dist/base.d.mts
CHANGED
|
@@ -44,7 +44,7 @@ export declare const stages: {
|
|
|
44
44
|
converter: number;
|
|
45
45
|
};
|
|
46
46
|
export type Stage = keyof typeof stages;
|
|
47
|
-
export declare const rules: readonly ["arg-in-ext", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "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
|
+
export declare const rules: readonly ["arg-in-ext", "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", "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"];
|
|
48
48
|
export declare namespace LintError {
|
|
49
49
|
type Severity = 'error' | 'warning';
|
|
50
50
|
type Rule = typeof rules[number];
|
package/dist/base.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export declare const stages: {
|
|
|
44
44
|
converter: number;
|
|
45
45
|
};
|
|
46
46
|
export type Stage = keyof typeof stages;
|
|
47
|
-
export declare const rules: readonly ["arg-in-ext", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "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
|
+
export declare const rules: readonly ["arg-in-ext", "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", "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"];
|
|
48
48
|
export declare namespace LintError {
|
|
49
49
|
type Severity = 'error' | 'warning';
|
|
50
50
|
type Rule = typeof rules[number];
|
package/dist/base.js
CHANGED
package/dist/base.mjs
CHANGED
package/dist/bin/cli.js
CHANGED
|
@@ -7,21 +7,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const assert_1 = __importDefault(require("assert"));
|
|
10
|
+
const util_1 = __importDefault(require("util"));
|
|
10
11
|
const index_1 = __importDefault(require("../index"));
|
|
11
|
-
const chalk = (() => {
|
|
12
|
-
try {
|
|
13
|
-
return require('chalk');
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
const f = ((text) => text), proxy = new Proxy(f, {
|
|
17
|
-
/** @private */
|
|
18
|
-
get() {
|
|
19
|
-
return proxy;
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
return proxy;
|
|
23
|
-
}
|
|
24
|
-
})();
|
|
25
12
|
const man = `
|
|
26
13
|
Available options:
|
|
27
14
|
-c, --config <path or preset config> Choose parser's configuration
|
|
@@ -159,11 +146,13 @@ const throwOnCacheFile = (input) => {
|
|
|
159
146
|
* @param word item name
|
|
160
147
|
*/
|
|
161
148
|
const plural = (n, word) => `${n} ${word}${n === 1 ? '' : 's'}`;
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
150
|
+
const styleText = util_1.default.styleText ?? ((_, text) => text);
|
|
162
151
|
/**
|
|
163
152
|
* color the severity
|
|
164
153
|
* @param severity problem severity
|
|
165
154
|
*/
|
|
166
|
-
const coloredSeverity = (severity) =>
|
|
155
|
+
const coloredSeverity = (severity) => styleText(severity === 'error' ? 'red' : 'yellow', severity.padEnd(7));
|
|
167
156
|
for (let i = 2; i < argv.length; i++) {
|
|
168
157
|
option = argv[i];
|
|
169
158
|
switch (option) {
|
|
@@ -374,10 +363,10 @@ catch {
|
|
|
374
363
|
nFixableWarn += nLocalFixableWarn;
|
|
375
364
|
}
|
|
376
365
|
if (problems.length > 0) {
|
|
377
|
-
console.error(
|
|
366
|
+
console.error('\n%s', styleText('underline', file));
|
|
378
367
|
const maxLineChars = String(Math.max(...problems.map(({ startLine }) => startLine))).length, maxColChars = String(Math.max(...problems.map(({ startCol }) => startCol))).length, maxMessageChars = Math.max(...problems.map(({ message: { length } }) => length));
|
|
379
368
|
for (const { rule, message, severity, startLine, startCol } of problems) {
|
|
380
|
-
console.error(` ${
|
|
369
|
+
console.error(` ${styleText('dim', '%s:%s')} %s %s %s`, String(startLine).padStart(maxLineChars), String(startCol).padEnd(maxColChars), coloredSeverity(severity), message.padEnd(maxMessageChars), styleText('dim', rule));
|
|
381
370
|
}
|
|
382
371
|
}
|
|
383
372
|
nErr += nLocalErr;
|
|
@@ -385,9 +374,9 @@ catch {
|
|
|
385
374
|
exiting ||= Boolean(nLocalErr || strict && nLocalWarn);
|
|
386
375
|
}
|
|
387
376
|
if (nErr || nWarn) {
|
|
388
|
-
console.error(
|
|
377
|
+
console.error(styleText(['red', 'bold'], '%s'), `\n✖ ${plural(nErr + nWarn, 'problem')} (${plural(nErr, 'error')}, ${plural(nWarn, 'warning')})`);
|
|
389
378
|
if (nFixableErr || nFixableWarn) {
|
|
390
|
-
console.error(
|
|
379
|
+
console.error(styleText(['red', 'bold'], '%s'), ` ${plural(nFixableErr, 'error')} and ${plural(nFixableWarn, 'warning')} potentially fixable with the \`--fix\` option.`);
|
|
391
380
|
}
|
|
392
381
|
console.error();
|
|
393
382
|
}
|
package/dist/bin/config.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -172,11 +172,9 @@ const Parser = {
|
|
|
172
172
|
maxStage ??= constants_1.MAX_STAGE;
|
|
173
173
|
config ??= this.getConfig();
|
|
174
174
|
let types;
|
|
175
|
-
LINT: {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
maxStage = Math.max(...types.map(t => base_1.stages[t] || constants_1.MAX_STAGE));
|
|
179
|
-
}
|
|
175
|
+
LINT: if (typeof maxStage !== 'number') {
|
|
176
|
+
types = Array.isArray(maxStage) ? maxStage : [maxStage];
|
|
177
|
+
maxStage = Math.max(...types.map(t => base_1.stages[t] || constants_1.MAX_STAGE));
|
|
180
178
|
}
|
|
181
179
|
const { Token } = require('./src/index');
|
|
182
180
|
const root = debug_1.Shadow.run(() => {
|
package/dist/internal.d.ts
CHANGED
|
@@ -45,5 +45,8 @@ export type { GalleryToken } from './src/multiLine/gallery';
|
|
|
45
45
|
export type { ImagemapLinkToken } from './src/imagemapLink';
|
|
46
46
|
export type { ImagemapToken } from './src/multiLine/imagemap';
|
|
47
47
|
export type { CommentedToken } from './src/commented';
|
|
48
|
+
export type { CategorytreeToken } from './src/link/categorytree';
|
|
49
|
+
export type { ParamLineToken } from './src/paramLine';
|
|
50
|
+
export type { CommentLineToken } from './src/nowiki/commentLine';
|
|
48
51
|
export type { TranslateToken } from './src/tagPair/translate';
|
|
49
52
|
export type { TvarToken } from './src/tag/tvar';
|
package/dist/lib/lintConfig.js
CHANGED
|
@@ -52,6 +52,7 @@ const defaultLintRuleConfig = {
|
|
|
52
52
|
{
|
|
53
53
|
// extension: 2,
|
|
54
54
|
// image: 2,
|
|
55
|
+
// link: 2,
|
|
55
56
|
parameter: 1,
|
|
56
57
|
// thumb: 2,
|
|
57
58
|
},
|
|
@@ -71,6 +72,12 @@ const defaultLintRuleConfig = {
|
|
|
71
72
|
},
|
|
72
73
|
],
|
|
73
74
|
'invalid-isbn': 2,
|
|
75
|
+
'invalid-json': [
|
|
76
|
+
2,
|
|
77
|
+
{
|
|
78
|
+
duplicate: 1,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
74
81
|
'invalid-url': 1,
|
|
75
82
|
'lonely-apos': [
|
|
76
83
|
1,
|
|
@@ -128,6 +135,7 @@ const defaultLintRuleConfig = {
|
|
|
128
135
|
// invalidAttributes: 2,
|
|
129
136
|
nonWordAttributes: 1,
|
|
130
137
|
redirect: 1,
|
|
138
|
+
// categorytree: 2,
|
|
131
139
|
// choose: 2,
|
|
132
140
|
// combobox: 2,
|
|
133
141
|
// dynamicpagelist: 2,
|
package/dist/lib/lsp.js
CHANGED
|
@@ -741,6 +741,13 @@ class LanguageService {
|
|
|
741
741
|
return token.parentNode.module === mod && token.parentNode.function === func;
|
|
742
742
|
}).map(({ name }) => name), 'Variable', key, position, type === 'parameter-value' ? '=' : '')
|
|
743
743
|
: undefined;
|
|
744
|
+
}
|
|
745
|
+
else if (type === 'param-line') {
|
|
746
|
+
// parameter line of `<dynamicpagelist>` or `<inputbox>`
|
|
747
|
+
const key = this.#text.slice(cur.getAbsoluteIndex(), root.indexFromPos(line, character)).trimStart();
|
|
748
|
+
return /^[a-z]+$/iu.test(key)
|
|
749
|
+
? getCompletion(sharable_1.extParams[cur.name], 'Property', key, position)
|
|
750
|
+
: undefined;
|
|
744
751
|
/* NOT FOR BROWSER ONLY */
|
|
745
752
|
}
|
|
746
753
|
else if (isAttr(cur, true)) {
|
|
@@ -813,8 +820,21 @@ class LanguageService {
|
|
|
813
820
|
async provideDiagnostics(text, warning = true) {
|
|
814
821
|
const root = await this.#queue(text), { lintConfig } = index_1.default, needFix = lintConfig.fix;
|
|
815
822
|
lintConfig.fix = false;
|
|
823
|
+
/* NOT FOR BROWSER ONLY */
|
|
824
|
+
const stylelint = await (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)();
|
|
825
|
+
let s;
|
|
826
|
+
NPM: if (jsonLSP) {
|
|
827
|
+
s = lintConfig.rules['invalid-json'];
|
|
828
|
+
lintConfig.rules['invalid-json'] = 0;
|
|
829
|
+
}
|
|
830
|
+
/* NOT FOR BROWSER ONLY END */
|
|
816
831
|
const errors = root.lint();
|
|
817
832
|
lintConfig.fix = needFix;
|
|
833
|
+
/* NOT FOR BROWSER ONLY */
|
|
834
|
+
NPM: if (jsonLSP) {
|
|
835
|
+
lintConfig.rules['invalid-json'] = s;
|
|
836
|
+
}
|
|
837
|
+
/* NOT FOR BROWSER ONLY END */
|
|
818
838
|
const diagnostics = (warning ? errors : errors.filter(({ severity }) => severity === 'error')).map(({ startLine, startCol, endLine, endCol, severity, rule, message, fix, suggestions,
|
|
819
839
|
/* NOT FOR BROWSER ONLY */
|
|
820
840
|
code, }) => ({
|
|
@@ -836,9 +856,6 @@ class LanguageService {
|
|
|
836
856
|
...suggestions ? suggestions.map(suggestion => getQuickFix(root, suggestion)) : [],
|
|
837
857
|
],
|
|
838
858
|
})),
|
|
839
|
-
/* NOT FOR BROWSER ONLY */
|
|
840
|
-
stylelint = await (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)(),
|
|
841
|
-
/* NOT FOR BROWSER ONLY END */
|
|
842
859
|
/* eslint-disable @stylistic/operator-linebreak */
|
|
843
860
|
cssDiagnostics = stylelint ?
|
|
844
861
|
await (async () => {
|
package/dist/lib/node.js
CHANGED
|
@@ -39,6 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.AstNode = void 0;
|
|
41
41
|
/* eslint-disable @typescript-eslint/no-base-to-string */
|
|
42
|
+
const common_1 = require("@bhsd/common");
|
|
42
43
|
const search_1 = __importDefault(require("../util/search"));
|
|
43
44
|
const lint_1 = require("../util/lint");
|
|
44
45
|
const debug_1 = require("../util/debug");
|
|
@@ -141,7 +142,7 @@ let AstNode = (() => {
|
|
|
141
142
|
* @param left column number / 列号
|
|
142
143
|
*/
|
|
143
144
|
indexFromPos(top, left) {
|
|
144
|
-
|
|
145
|
+
LINT: {
|
|
145
146
|
if (top < 0 || left < 0) {
|
|
146
147
|
return undefined;
|
|
147
148
|
}
|
|
@@ -248,16 +249,7 @@ let AstNode = (() => {
|
|
|
248
249
|
* @since v1.16.3
|
|
249
250
|
*/
|
|
250
251
|
getLines() {
|
|
251
|
-
LINT:
|
|
252
|
-
const results = [];
|
|
253
|
-
let start = 0;
|
|
254
|
-
for (const line of String(this).split('\n')) {
|
|
255
|
-
const end = start + line.length;
|
|
256
|
-
results.push([line, start, end]);
|
|
257
|
-
start = end + 1;
|
|
258
|
-
}
|
|
259
|
-
return results;
|
|
260
|
-
}
|
|
252
|
+
LINT: return (0, common_1.splitLines)(String(this));
|
|
261
253
|
}
|
|
262
254
|
};
|
|
263
255
|
return AstNode = _classThis;
|
package/dist/lib/text.js
CHANGED
|
@@ -88,10 +88,10 @@ class AstText extends node_1.AstNode {
|
|
|
88
88
|
}
|
|
89
89
|
const { type, parentNode: grandparent } = parentNode;
|
|
90
90
|
if (type === 'attr-value') {
|
|
91
|
-
const { name
|
|
92
|
-
if (tag === 'ref' && (
|
|
93
|
-
||
|
|
94
|
-
|| tag === 'choose' && (
|
|
91
|
+
const { name, tag } = grandparent;
|
|
92
|
+
if (tag === 'ref' && (name === 'name' || name === 'follow')
|
|
93
|
+
|| name === 'group' && (tag === 'ref' || tag === 'references')
|
|
94
|
+
|| tag === 'choose' && (name === 'before' || name === 'after')) {
|
|
95
95
|
return [];
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -114,9 +114,15 @@ class AstText extends node_1.AstNode {
|
|
|
114
114
|
...lintConfig.getSeverity('tag-like', 'disallowed') ? disallowedTags : [],
|
|
115
115
|
]);
|
|
116
116
|
for (let mt = errorRegex.exec(data); mt; mt = errorRegex.exec(data)) {
|
|
117
|
-
const [, tag, prefix] = mt;
|
|
118
117
|
let { index, 0: error } = mt;
|
|
119
|
-
|
|
118
|
+
const [, tag, prefix] = mt, lbrackInExtLinkText = error === '[' && type === 'ext-link-text';
|
|
119
|
+
if (error.startsWith('<') && !tags.has(tag.toLowerCase())
|
|
120
|
+
|| lbrackInExtLinkText && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
|
|
121
|
+
|| nextSibling?.is('ext') && nextName === 'nowiki'
|
|
122
|
+
&& nextSibling.innerText?.includes(']'))) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
else if (prefix && prefix !== ']') {
|
|
120
126
|
const { length } = prefix;
|
|
121
127
|
index += length;
|
|
122
128
|
error = error.slice(length);
|
|
@@ -126,20 +132,14 @@ class AstText extends node_1.AstNode {
|
|
|
126
132
|
error = error.slice(1);
|
|
127
133
|
}
|
|
128
134
|
error = error.toLowerCase();
|
|
129
|
-
const [char] = error, magicLink =
|
|
135
|
+
const [char] = error, magicLink = error === 'rfc' || error === 'pmid' || error === 'isbn', lbrace = char === '{', rbrace = char === '}', lbrack = char === '[', rbrack = char === ']';
|
|
130
136
|
let { length } = error;
|
|
131
|
-
if (
|
|
132
|
-
|| lbrack && type === 'ext-link-text' && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
|
|
133
|
-
|| nextSibling?.is('ext') && nextName === 'nowiki'
|
|
134
|
-
&& nextSibling.innerText?.includes(']'))) {
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
else if (rbrack && (index || length > 1)) {
|
|
137
|
+
if (rbrack && (index || length > 1)) {
|
|
138
138
|
errorRegex.lastIndex--;
|
|
139
139
|
}
|
|
140
140
|
// Rule & Severity
|
|
141
141
|
let startIndex = start + index, endIndex = startIndex + length, rule, severity, endLine, endCol;
|
|
142
|
-
const nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], leftBracket = lbrace || lbrack, lConverter =
|
|
142
|
+
const nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], leftBracket = lbrace || lbrack, lConverter = error === '{' && previousChar === '-' && variants.length > 0, rConverter = error === '}' && nextChar === '-' && variants.length > 0, brokenExtLink = lbrack && nextType === 'free-ext-link' && !data.slice(index + 1).trim()
|
|
143
143
|
|| rbrack && previousType === 'free-ext-link'
|
|
144
144
|
&& !data.slice(0, index).includes(']');
|
|
145
145
|
if (magicLink) {
|
|
@@ -190,7 +190,7 @@ class AstText extends node_1.AstNode {
|
|
|
190
190
|
severity = lintConfig.getSeverity(rule, 'double');
|
|
191
191
|
}
|
|
192
192
|
else {
|
|
193
|
-
if (!
|
|
193
|
+
if (!lbrackInExtLinkText) {
|
|
194
194
|
const regex = regexes[char], remains = leftBracket ? data.slice(index + 1) : data.slice(0, index);
|
|
195
195
|
if (lbrace && regex.exec(remains)?.[0] === '}'
|
|
196
196
|
|| rbrace && regex.exec(remains)?.[0] === '{') {
|
|
@@ -272,11 +272,11 @@ class AstText extends node_1.AstNode {
|
|
|
272
272
|
else if (char === 'h' && type !== 'link-text' && wordRegex.test(previousChar || '')) {
|
|
273
273
|
e.suggestions = [(0, lint_1.fixBySpace)(startIndex)];
|
|
274
274
|
}
|
|
275
|
-
else if (
|
|
275
|
+
else if (lbrackInExtLinkText) {
|
|
276
276
|
const i = parentNode.getAbsoluteIndex() + parentNode.toString().length;
|
|
277
277
|
e.suggestions = [(0, lint_1.fixByEscape)(i, ']')];
|
|
278
278
|
}
|
|
279
|
-
else if (
|
|
279
|
+
else if (error === ']' && brokenExtLink) {
|
|
280
280
|
const i = start - previousSibling.toString().length;
|
|
281
281
|
e.suggestions = [(0, lint_1.fixByInsert)(i, 'left-bracket', '[')];
|
|
282
282
|
}
|
package/dist/src/attribute.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import Parser from '../index';
|
|
2
1
|
import { Token } from './index';
|
|
3
2
|
import { AtomToken } from './atom';
|
|
4
|
-
import type { LintError } from '../base';
|
|
3
|
+
import type { LintError, Config } from '../base';
|
|
5
4
|
import type { AttributesToken } from '../internal';
|
|
6
5
|
export type AttributeTypes = 'ext-attr' | 'html-attr' | 'table-attr';
|
|
7
6
|
/**
|
|
@@ -28,16 +27,15 @@ export declare abstract class AttributeToken extends Token {
|
|
|
28
27
|
* @param type 标签类型
|
|
29
28
|
* @param tag 标签名
|
|
30
29
|
* @param key 属性名
|
|
30
|
+
* @param quotes 引号
|
|
31
31
|
* @param equal 等号
|
|
32
32
|
* @param value 属性值
|
|
33
|
-
* @param quotes 引号
|
|
34
33
|
*/
|
|
35
|
-
constructor(type: AttributeTypes, tag: string, key: string,
|
|
34
|
+
constructor(type: AttributeTypes, tag: string, key: string, quotes: readonly [string?, string?], config: Config, equal?: string, value?: string, accum?: Token[]);
|
|
36
35
|
/**
|
|
37
36
|
* Get the attribute value
|
|
38
37
|
*
|
|
39
38
|
* 获取属性值
|
|
40
39
|
*/
|
|
41
40
|
getValue(): string | true;
|
|
42
|
-
escape(): void;
|
|
43
41
|
}
|
package/dist/src/attribute.js
CHANGED
|
@@ -52,11 +52,11 @@ class AttributeToken extends index_2.Token {
|
|
|
52
52
|
* @param type 标签类型
|
|
53
53
|
* @param tag 标签名
|
|
54
54
|
* @param key 属性名
|
|
55
|
+
* @param quotes 引号
|
|
55
56
|
* @param equal 等号
|
|
56
57
|
* @param value 属性值
|
|
57
|
-
* @param quotes 引号
|
|
58
58
|
*/
|
|
59
|
-
constructor(type, tag, key, equal = '', value,
|
|
59
|
+
constructor(type, tag, key, quotes, config, equal = '', value, accum = []) {
|
|
60
60
|
const keyToken = new atom_1.AtomToken(key, 'attr-key', config, accum);
|
|
61
61
|
let valueToken;
|
|
62
62
|
if (key === 'title' || tag === 'img' && key === 'alt') {
|
|
@@ -129,9 +129,12 @@ class AttributeToken extends index_2.Token {
|
|
|
129
129
|
}
|
|
130
130
|
if (!attrs?.has(name)
|
|
131
131
|
&& !attrs2?.has(name)
|
|
132
|
-
//
|
|
132
|
+
// 已知定义的扩展标签或不包含嵌入的HTML标签
|
|
133
133
|
&& (type === 'ext-attr' ? attrs || attrs2 : !/\{\{[^{]+\}\}/u.test(name))
|
|
134
|
-
&& (
|
|
134
|
+
&& (
|
|
135
|
+
// 不支持通用HTML属性的扩展标签
|
|
136
|
+
type === 'ext-attr' && !attrs2
|
|
137
|
+
// 或非通用HTML属性
|
|
135
138
|
|| !/^(?:xmlns:[\w:.-]+|data-(?!ooui|mw|parsoid)[^:]*)$/u.test(name)
|
|
136
139
|
&& (tag === 'meta' || tag === 'link' || !sharable_1.commonHtmlAttrs.has(name)))
|
|
137
140
|
|| (name === 'itemtype' || name === 'itemid' || name === 'itemref')
|
|
@@ -247,12 +250,11 @@ class AttributeToken extends index_2.Token {
|
|
|
247
250
|
getValue() {
|
|
248
251
|
return this.#equal ? this.lastChild.text().trim() : this.type === 'ext-attr' || '';
|
|
249
252
|
}
|
|
253
|
+
/** @private */
|
|
250
254
|
escape() {
|
|
251
|
-
LSP: {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
this.lastChild.escape();
|
|
255
|
-
}
|
|
255
|
+
LSP: if (this.type !== 'ext-attr') {
|
|
256
|
+
this.#equal = '{{=}}';
|
|
257
|
+
this.lastChild.escape();
|
|
256
258
|
}
|
|
257
259
|
}
|
|
258
260
|
}
|
package/dist/src/attributes.d.ts
CHANGED
package/dist/src/attributes.js
CHANGED
|
@@ -66,7 +66,7 @@ class AttributesToken extends index_2.Token {
|
|
|
66
66
|
if (/^(?:[\w:]|\0\d+t\x7F)(?:[\w:.-]|\0\d+t\x7F)*$/u.test((0, string_1.removeComment)(key).trim())) {
|
|
67
67
|
const value = quoted ?? unquoted, quotes = [quoteStart, quoteEnd],
|
|
68
68
|
// @ts-expect-error abstract class
|
|
69
|
-
token = new attribute_1.AttributeToken((0, exports.toAttributeType)(type), name, key,
|
|
69
|
+
token = new attribute_1.AttributeToken((0, exports.toAttributeType)(type), name, key, quotes, config, equal, value, accum);
|
|
70
70
|
insertDirty();
|
|
71
71
|
super.insertAt(token);
|
|
72
72
|
}
|
|
@@ -195,11 +195,10 @@ class AttributesToken extends index_2.Token {
|
|
|
195
195
|
return errors;
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
|
+
/** @private */
|
|
198
199
|
escape() {
|
|
199
|
-
LSP: {
|
|
200
|
-
|
|
201
|
-
super.escape();
|
|
202
|
-
}
|
|
200
|
+
LSP: if (this.type !== 'ext-attrs') {
|
|
201
|
+
super.escape();
|
|
203
202
|
}
|
|
204
203
|
}
|
|
205
204
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Token } from './index';
|
|
2
|
-
import type { LintError, Config } from '../base';
|
|
2
|
+
import type { LintError, Config, TokenTypes } from '../base';
|
|
3
3
|
import type { Title } from '../lib/title';
|
|
4
4
|
import type { AtomToken, FileToken } from '../internal';
|
|
5
5
|
/**
|
|
@@ -23,8 +23,12 @@ export declare abstract class ImageParameterToken extends Token {
|
|
|
23
23
|
get thumb(): Title | undefined;
|
|
24
24
|
/** image link / 图片链接 */
|
|
25
25
|
get link(): string | Title | undefined;
|
|
26
|
-
/**
|
|
27
|
-
|
|
26
|
+
/**
|
|
27
|
+
* @param str 图片参数
|
|
28
|
+
* @param extension 文件扩展名
|
|
29
|
+
* @param type 父节点类型
|
|
30
|
+
*/
|
|
31
|
+
constructor(str: string, extension: string | undefined, type: TokenTypes | undefined, config: Config, accum?: Token[]);
|
|
28
32
|
/**
|
|
29
33
|
* Get the parameter value
|
|
30
34
|
*
|
|
@@ -147,15 +147,19 @@ let ImageParameterToken = (() => {
|
|
|
147
147
|
}, index_1.default);
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
|
-
/**
|
|
151
|
-
|
|
150
|
+
/**
|
|
151
|
+
* @param str 图片参数
|
|
152
|
+
* @param extension 文件扩展名
|
|
153
|
+
* @param type 父节点类型
|
|
154
|
+
*/
|
|
155
|
+
constructor(str, extension, type, config, accum) {
|
|
152
156
|
let mt;
|
|
153
157
|
const regexes = Object.entries(config.img)
|
|
154
158
|
.map(([syntax, param]) => [syntax, param, getSyntaxRegex(syntax)]), param = regexes.find(([, key, regex]) => {
|
|
155
159
|
mt = regex.exec(str);
|
|
156
160
|
return mt
|
|
157
161
|
&& (mt.length !== 4
|
|
158
|
-
|| validate(key, mt[2], config, extension, true) !== false);
|
|
162
|
+
|| validate(key, mt[2], config, key === 'link' ? type : extension, true) !== false);
|
|
159
163
|
});
|
|
160
164
|
// @ts-expect-error mt already assigned
|
|
161
165
|
if (param && mt) {
|
|
@@ -222,7 +226,13 @@ let ImageParameterToken = (() => {
|
|
|
222
226
|
}
|
|
223
227
|
}
|
|
224
228
|
else if (name === 'link') {
|
|
225
|
-
if (
|
|
229
|
+
if (link === undefined) {
|
|
230
|
+
const rule = 'invalid-gallery', s = lintConfig.getSeverity(rule, 'link');
|
|
231
|
+
if (s) {
|
|
232
|
+
errors.push((0, lint_1.generateForSelf)(this, { start }, rule, 'invalid-gallery-link', s));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else if (typeof link === 'string') {
|
|
226
236
|
const rule = 'invalid-url', s = lintConfig.getSeverity(rule);
|
|
227
237
|
if (s && !this.querySelector('magic-word')) {
|
|
228
238
|
try {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -34,5 +34,13 @@ export declare class Token extends AstElement {
|
|
|
34
34
|
*/
|
|
35
35
|
insertAt(child: string, i?: number): AstText;
|
|
36
36
|
insertAt<T extends AstNodes>(child: T, i?: number): T;
|
|
37
|
+
/**
|
|
38
|
+
* Normalize page title
|
|
39
|
+
*
|
|
40
|
+
* 规范化页面标题
|
|
41
|
+
* @param title title (with or without the namespace prefix) / 标题(含或不含命名空间前缀)
|
|
42
|
+
* @param defaultNs default namespace number / 命名空间
|
|
43
|
+
*/
|
|
44
|
+
normalizeTitle(title: string, defaultNs?: number, opt?: TitleOptions): Title;
|
|
37
45
|
}
|
|
38
46
|
export {};
|
package/dist/src/index.js
CHANGED
|
@@ -112,7 +112,7 @@ class Token extends element_1.AstElement {
|
|
|
112
112
|
if (n < this.#stage || this.length !== 1 || !this.isPlain()) {
|
|
113
113
|
return this;
|
|
114
114
|
}
|
|
115
|
-
else if (this.#stage >= constants_1.MAX_STAGE) {
|
|
115
|
+
else /* istanbul ignore if */ if (this.#stage >= constants_1.MAX_STAGE) {
|
|
116
116
|
return this;
|
|
117
117
|
}
|
|
118
118
|
switch (n) {
|
|
@@ -170,10 +170,8 @@ class Token extends element_1.AstElement {
|
|
|
170
170
|
if (i % 2 === 0) {
|
|
171
171
|
return s && new text_1.AstText(s);
|
|
172
172
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
throw new Error(`Failed to build! Unrecognized token: ${s}`);
|
|
173
|
+
const n = Number(s.slice(0, -1));
|
|
174
|
+
return this.#accum[n];
|
|
177
175
|
}).filter(node => node !== '');
|
|
178
176
|
if (type === constants_1.BuildMethod.String) {
|
|
179
177
|
return nodes.map(String).join('');
|
|
@@ -221,7 +219,7 @@ class Token extends element_1.AstElement {
|
|
|
221
219
|
#parseRedirect() {
|
|
222
220
|
const { parseRedirect } = require('../parser/redirect');
|
|
223
221
|
const wikitext = this.firstChild.toString(), parsed = parseRedirect(wikitext, this.#config, this.#accum);
|
|
224
|
-
if (parsed) {
|
|
222
|
+
if (parsed !== false) {
|
|
225
223
|
this.setText(parsed);
|
|
226
224
|
}
|
|
227
225
|
return Boolean(parsed);
|
|
@@ -277,9 +275,6 @@ class Token extends element_1.AstElement {
|
|
|
277
275
|
* @param tidy 是否整理
|
|
278
276
|
*/
|
|
279
277
|
#parseQuotes(tidy) {
|
|
280
|
-
if (this.#config.excludes.includes('quote')) {
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
278
|
const { parseQuotes } = require('../parser/quotes');
|
|
284
279
|
const lines = this.firstChild.toString().split('\n');
|
|
285
280
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -289,17 +284,11 @@ class Token extends element_1.AstElement {
|
|
|
289
284
|
}
|
|
290
285
|
/** 解析外部链接 */
|
|
291
286
|
#parseExternalLinks() {
|
|
292
|
-
if (this.#config.excludes.includes('extLink')) {
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
287
|
const { parseExternalLinks } = require('../parser/externalLinks');
|
|
296
288
|
this.setText(parseExternalLinks(this.firstChild.toString(), this.#config, this.#accum));
|
|
297
289
|
}
|
|
298
290
|
/** 解析自由外链 */
|
|
299
291
|
#parseMagicLinks() {
|
|
300
|
-
if (this.#config.excludes.includes('magicLink')) {
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
292
|
const { parseMagicLinks } = require('../parser/magicLinks');
|
|
304
293
|
this.setText(parseMagicLinks(this.firstChild.toString(), this.#config, this.#accum));
|
|
305
294
|
}
|
|
@@ -338,6 +327,7 @@ class Token extends element_1.AstElement {
|
|
|
338
327
|
return this.#accum;
|
|
339
328
|
case 'built':
|
|
340
329
|
return this.#built;
|
|
330
|
+
/* istanbul ignore next */
|
|
341
331
|
case 'stage':
|
|
342
332
|
return this.#stage;
|
|
343
333
|
default:
|
|
@@ -358,7 +348,8 @@ class Token extends element_1.AstElement {
|
|
|
358
348
|
}
|
|
359
349
|
}
|
|
360
350
|
insertAt(child, i = this.length) {
|
|
361
|
-
const token = typeof child === 'string' ? new text_1.AstText(child) : child;
|
|
351
|
+
const token = typeof child === 'string' ? new text_1.AstText(child) : child, { length } = this;
|
|
352
|
+
i += i < 0 ? length : 0;
|
|
362
353
|
super.insertAt(token, i);
|
|
363
354
|
const { type, } = token;
|
|
364
355
|
if (type === 'root') {
|
|
@@ -366,7 +357,14 @@ class Token extends element_1.AstElement {
|
|
|
366
357
|
}
|
|
367
358
|
return token;
|
|
368
359
|
}
|
|
369
|
-
|
|
360
|
+
// eslint-disable-next-line jsdoc/require-param
|
|
361
|
+
/**
|
|
362
|
+
* Normalize page title
|
|
363
|
+
*
|
|
364
|
+
* 规范化页面标题
|
|
365
|
+
* @param title title (with or without the namespace prefix) / 标题(含或不含命名空间前缀)
|
|
366
|
+
* @param defaultNs default namespace number / 命名空间
|
|
367
|
+
*/
|
|
370
368
|
normalizeTitle(title, defaultNs = 0, opt) {
|
|
371
369
|
return index_1.default.normalizeTitle(title, defaultNs, this.getAttribute('include'), this.#config, { page: this.pageName, ...opt });
|
|
372
370
|
}
|
|
@@ -427,8 +425,12 @@ class Token extends element_1.AstElement {
|
|
|
427
425
|
let mt = regex.exec(wikitext);
|
|
428
426
|
while (mt) {
|
|
429
427
|
const { 1: type, index } = mt, detail = mt[2]?.trim();
|
|
428
|
+
let line;
|
|
429
|
+
if (type === 'disable-line' || type === 'disable-next-line') {
|
|
430
|
+
line = this.posFromIndex(index).top + (type === 'disable-line' ? 0 : 1);
|
|
431
|
+
}
|
|
430
432
|
ignores.push({
|
|
431
|
-
line
|
|
433
|
+
line,
|
|
432
434
|
from: type === 'disable' ? regex.lastIndex : undefined,
|
|
433
435
|
to: type === 'enable' ? regex.lastIndex : undefined,
|
|
434
436
|
rules: detail ? new Set(detail.split(',').map(rule => rule.trim())) : undefined,
|
|
@@ -438,13 +440,13 @@ class Token extends element_1.AstElement {
|
|
|
438
440
|
errors = errors.filter(({ rule, startLine, startIndex }) => {
|
|
439
441
|
const nearest = { pos: 0 };
|
|
440
442
|
for (const { line, from, to, rules } of ignores) {
|
|
441
|
-
if (line > startLine + 1) {
|
|
443
|
+
if (line && line > startLine + 1) {
|
|
442
444
|
break;
|
|
443
445
|
}
|
|
444
446
|
else if (rules && !rules.has(rule)) {
|
|
445
447
|
continue;
|
|
446
448
|
}
|
|
447
|
-
else if (line === startLine
|
|
449
|
+
else if (line === startLine) {
|
|
448
450
|
return false;
|
|
449
451
|
}
|
|
450
452
|
else if (from <= startIndex && from > nearest.pos) {
|