wikilint 2.33.0 → 2.35.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 +1 -0
- 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 +3 -3
- package/dist/index.js +3 -5
- package/dist/internal.d.ts +3 -0
- package/dist/lib/lintConfig.js +6 -0
- package/dist/lib/lsp.js +13 -3
- package/dist/lib/node.js +3 -11
- package/dist/lib/text.js +14 -14
- package/dist/parser/magicLinks.js +1 -1
- package/dist/src/attribute.d.ts +0 -1
- package/dist/src/attribute.js +5 -6
- package/dist/src/attributes.d.ts +0 -1
- package/dist/src/attributes.js +3 -4
- package/dist/src/link/categorytree.d.ts +0 -2
- package/dist/src/link/categorytree.js +2 -0
- 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 +2 -1
- package/dist/src/table/base.d.ts +0 -1
- package/dist/src/table/base.js +7 -8
- package/dist/src/table/td.d.ts +0 -1
- package/dist/src/table/td.js +1 -0
- 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/diff.js +6 -17
- package/package.json +6 -7
package/config/default.json
CHANGED
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
|
@@ -77,7 +77,7 @@ const mw = {
|
|
|
77
77
|
},
|
|
78
78
|
},
|
|
79
79
|
};
|
|
80
|
-
const pkg = "wikilint", version = "2.
|
|
80
|
+
const pkg = "wikilint", version = "2.35.0";
|
|
81
81
|
let mwConfig;
|
|
82
82
|
/**
|
|
83
83
|
* Get the parser configuration for a Wikimedia Foundation project.
|
|
@@ -122,7 +122,7 @@ exports.default = async (site, url, user, force, internal) => {
|
|
|
122
122
|
siprop: 'general|magicwords|functionhooks|namespaces|namespacealiases',
|
|
123
123
|
format: 'json',
|
|
124
124
|
formatversion: '2',
|
|
125
|
-
}, { query: { general: { articlepath, variants }, magicwords, namespaces, namespacealiases, functionhooks, }, } = await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json();
|
|
125
|
+
}, { query: { general: { articlepath, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, }, } = await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json();
|
|
126
126
|
try {
|
|
127
127
|
eval(m); // eslint-disable-line no-eval
|
|
128
128
|
}
|
|
@@ -140,7 +140,7 @@ exports.default = async (site, url, user, force, internal) => {
|
|
|
140
140
|
]), config = {
|
|
141
141
|
...(0, cm_util_1.getParserConfig)(require(path_1.default.join(dir, 'minimum')), mwConfig),
|
|
142
142
|
...(0, cm_util_1.getKeywords)(magicwords),
|
|
143
|
-
variants: (0, cm_util_1.getVariants)(variants),
|
|
143
|
+
variants: langconversion ? (0, cm_util_1.getVariants)(variants) : [],
|
|
144
144
|
namespaces: Object.fromEntries(ns),
|
|
145
145
|
nsid: Object.fromEntries([
|
|
146
146
|
...ns.map(([id, canonical]) => [canonical.toLowerCase(), Number(id)]),
|
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
package/dist/lib/lsp.js
CHANGED
|
@@ -820,8 +820,21 @@ class LanguageService {
|
|
|
820
820
|
async provideDiagnostics(text, warning = true) {
|
|
821
821
|
const root = await this.#queue(text), { lintConfig } = index_1.default, needFix = lintConfig.fix;
|
|
822
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 */
|
|
823
831
|
const errors = root.lint();
|
|
824
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 */
|
|
825
838
|
const diagnostics = (warning ? errors : errors.filter(({ severity }) => severity === 'error')).map(({ startLine, startCol, endLine, endCol, severity, rule, message, fix, suggestions,
|
|
826
839
|
/* NOT FOR BROWSER ONLY */
|
|
827
840
|
code, }) => ({
|
|
@@ -843,9 +856,6 @@ class LanguageService {
|
|
|
843
856
|
...suggestions ? suggestions.map(suggestion => getQuickFix(root, suggestion)) : [],
|
|
844
857
|
],
|
|
845
858
|
})),
|
|
846
|
-
/* NOT FOR BROWSER ONLY */
|
|
847
|
-
stylelint = await (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)(),
|
|
848
|
-
/* NOT FOR BROWSER ONLY END */
|
|
849
859
|
/* eslint-disable @stylistic/operator-linebreak */
|
|
850
860
|
cssDiagnostics = stylelint ?
|
|
851
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
|
@@ -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
|
}
|
|
@@ -23,7 +23,7 @@ const parseMagicLinks = (wikitext, config, accum) => {
|
|
|
23
23
|
let url = lead ? m.slice(lead.length) : m;
|
|
24
24
|
if (p1) {
|
|
25
25
|
let trail = '';
|
|
26
|
-
const m2 = /&(?:
|
|
26
|
+
const m2 = /&(?:[lg]t|nbsp|#x0*(?:3[ce]|a0)|#0*(?:6[02]|160));/iu.exec(url);
|
|
27
27
|
if (m2) {
|
|
28
28
|
trail = url.slice(m2.index);
|
|
29
29
|
url = url.slice(0, m2.index);
|
package/dist/src/attribute.d.ts
CHANGED
package/dist/src/attribute.js
CHANGED
|
@@ -14,7 +14,7 @@ const index_2 = require("./index");
|
|
|
14
14
|
const atom_1 = require("./atom");
|
|
15
15
|
/* NOT FOR BROWSER ONLY */
|
|
16
16
|
const document_1 = require("../lib/document");
|
|
17
|
-
const insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|src|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u, evil = /(?:^|\s|\*\/)(?:
|
|
17
|
+
const insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|src|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u, evil = /(?:^|\s|\*\/)(?:java|vb)script(?:\W|$)/iu, complexTypes = new Set(['ext', 'arg', 'magic-word', 'template']), urlAttrs = new Set([
|
|
18
18
|
'about',
|
|
19
19
|
'property',
|
|
20
20
|
'resource',
|
|
@@ -250,12 +250,11 @@ class AttributeToken extends index_2.Token {
|
|
|
250
250
|
getValue() {
|
|
251
251
|
return this.#equal ? this.lastChild.text().trim() : this.type === 'ext-attr' || '';
|
|
252
252
|
}
|
|
253
|
+
/** @private */
|
|
253
254
|
escape() {
|
|
254
|
-
LSP: {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
this.lastChild.escape();
|
|
258
|
-
}
|
|
255
|
+
LSP: if (this.type !== 'ext-attr') {
|
|
256
|
+
this.#equal = '{{=}}';
|
|
257
|
+
this.lastChild.escape();
|
|
259
258
|
}
|
|
260
259
|
}
|
|
261
260
|
}
|
package/dist/src/attributes.d.ts
CHANGED
package/dist/src/attributes.js
CHANGED
|
@@ -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
|
}
|
|
@@ -16,6 +16,4 @@ export declare abstract class CategorytreeToken extends LinkBaseToken {
|
|
|
16
16
|
get type(): 'ext-inner';
|
|
17
17
|
/** @param link 链接标题 */
|
|
18
18
|
constructor(link: string, linkText?: undefined, config?: Config, accum?: Token[]);
|
|
19
|
-
getTitle(): Title;
|
|
20
|
-
lint(start?: number): LintError[];
|
|
21
19
|
}
|
|
@@ -69,12 +69,14 @@ let CategorytreeToken = (() => {
|
|
|
69
69
|
super(link, linkText, config, accum);
|
|
70
70
|
this.setAttribute('bracket', false);
|
|
71
71
|
}
|
|
72
|
+
/** @private */
|
|
72
73
|
getTitle() {
|
|
73
74
|
const target = this.firstChild.toString().trim(), opt = { halfParsed: true }, title = this.normalizeTitle(target, 14, opt);
|
|
74
75
|
return title.valid && title.ns === 14
|
|
75
76
|
? title
|
|
76
77
|
: this.normalizeTitle(`Category:${target}`, 0, opt);
|
|
77
78
|
}
|
|
79
|
+
/** @private */
|
|
78
80
|
lint(start = this.getAbsoluteIndex()) {
|
|
79
81
|
LINT: {
|
|
80
82
|
const rule = 'no-ignored', s = index_1.default.lintConfig.getSeverity(rule, 'categorytree');
|
package/dist/src/nowiki/index.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.NowikiToken = void 0;
|
|
7
7
|
const common_1 = require("@bhsd/common");
|
|
8
8
|
const lint_1 = require("../../util/lint");
|
|
9
|
+
const rect_1 = require("../../lib/rect");
|
|
9
10
|
const index_1 = __importDefault(require("../../index"));
|
|
10
11
|
const base_1 = require("./base");
|
|
11
12
|
/* NOT FOR BROWSER ONLY */
|
|
@@ -42,9 +43,9 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
42
43
|
/** @private */
|
|
43
44
|
lint(start = this.getAbsoluteIndex()) {
|
|
44
45
|
LINT: {
|
|
45
|
-
const { name,
|
|
46
|
+
const { name, innerText,
|
|
46
47
|
/* NOT FOR BROWSER ONLY */
|
|
47
|
-
|
|
48
|
+
previousSibling, } = this, { lintConfig } = index_1.default;
|
|
48
49
|
let rule = 'void-ext', s = lintConfig.getSeverity(rule, name);
|
|
49
50
|
if (s && this.#lint()) {
|
|
50
51
|
const e = (0, lint_1.generateForSelf)(this, { start }, rule, index_1.default.msg('nothing-in', name), s);
|
|
@@ -53,9 +54,42 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
53
54
|
}
|
|
54
55
|
return [e];
|
|
55
56
|
}
|
|
56
|
-
const errors = super.lint(start, getLintRegex(name));
|
|
57
|
-
/* NOT FOR BROWSER ONLY */
|
|
58
57
|
NPM: {
|
|
58
|
+
rule = 'invalid-json';
|
|
59
|
+
const sSyntax = lintConfig.getSeverity(rule);
|
|
60
|
+
/* NOT FOR BROWSER ONLY */
|
|
61
|
+
const sDuplicate = lintConfig.getSeverity(rule, 'duplicate');
|
|
62
|
+
/* NOT FOR BROWSER ONLY END */
|
|
63
|
+
if (name === 'templatedata' && (sSyntax
|
|
64
|
+
|| sDuplicate)) {
|
|
65
|
+
// browser版本使用`lintJSONNative()`
|
|
66
|
+
return (0, common_1.lintJSON)(innerText).map(({ message, from, to = from, line, endLine = line, column, endColumn = column,
|
|
67
|
+
/* NOT FOR BROWSER ONLY */
|
|
68
|
+
severity, }) => {
|
|
69
|
+
s =
|
|
70
|
+
/* eslint-disable @stylistic/operator-linebreak */
|
|
71
|
+
severity === 'warning' ?
|
|
72
|
+
sDuplicate :
|
|
73
|
+
/* eslint-enable @stylistic/operator-linebreak */
|
|
74
|
+
sSyntax;
|
|
75
|
+
if (!s) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const rect = new rect_1.BoundingRect(this, start);
|
|
79
|
+
return {
|
|
80
|
+
rule,
|
|
81
|
+
message,
|
|
82
|
+
severity: s,
|
|
83
|
+
startIndex: start + from,
|
|
84
|
+
endIndex: start + to,
|
|
85
|
+
startLine: rect.top + line - 1,
|
|
86
|
+
endLine: rect.top + endLine - 1,
|
|
87
|
+
startCol: (line > 1 ? 0 : rect.left) + column - 1,
|
|
88
|
+
endCol: (endLine > 1 ? 0 : rect.left) + endColumn - 1,
|
|
89
|
+
};
|
|
90
|
+
}).filter((e) => e !== false);
|
|
91
|
+
}
|
|
92
|
+
/* NOT FOR BROWSER ONLY */
|
|
59
93
|
rule = 'invalid-math';
|
|
60
94
|
s = lintConfig.getSeverity(rule);
|
|
61
95
|
if (s && constants_1.mathTags.has(name)) {
|
|
@@ -84,20 +118,21 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
84
118
|
const result = texvcjs.check(tex, {
|
|
85
119
|
usemhchem: isChem || Boolean(previousSibling?.hasAttr('chem')),
|
|
86
120
|
});
|
|
87
|
-
if (result.status
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
121
|
+
if (result.status === '+') {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'chem-required', s);
|
|
125
|
+
if (result.status !== 'C') {
|
|
126
|
+
const { message, location } = result.error, [endIndex, endLine, endCol] = updateLocation(e, location.end, n);
|
|
127
|
+
[e.startIndex, e.startLine, e.startCol] = updateLocation(e, location.start, n);
|
|
128
|
+
Object.assign(e, { endIndex, endLine, endCol, message });
|
|
95
129
|
}
|
|
130
|
+
return [e];
|
|
96
131
|
}
|
|
97
132
|
}
|
|
98
133
|
}
|
|
99
134
|
/* NOT FOR BROWSER ONLY END */
|
|
100
|
-
return
|
|
135
|
+
return super.lint(start, getLintRegex(name));
|
|
101
136
|
}
|
|
102
137
|
}
|
|
103
138
|
}
|
package/dist/src/nowiki/list.js
CHANGED
|
@@ -17,6 +17,7 @@ class ListToken extends listBase_1.ListBaseToken {
|
|
|
17
17
|
get type() {
|
|
18
18
|
return 'list';
|
|
19
19
|
}
|
|
20
|
+
/** @private */
|
|
20
21
|
lint(start = this.getAbsoluteIndex()) {
|
|
21
22
|
LINT: {
|
|
22
23
|
const rule = 'syntax-like', s = index_1.default.lintConfig.getSeverity(rule, 'redirect'), { innerText } = this;
|
|
@@ -69,11 +69,12 @@ let NoincludeToken = (() => {
|
|
|
69
69
|
toString(skip) {
|
|
70
70
|
return skip ? '' : super.toString();
|
|
71
71
|
}
|
|
72
|
+
/** @private */
|
|
72
73
|
lint(start = this.getAbsoluteIndex()) {
|
|
73
74
|
LINT: {
|
|
74
75
|
const { lintConfig } = index_1.default, rule = 'no-ignored', s = lintConfig.getSeverity(rule, 'include');
|
|
75
76
|
if (s) {
|
|
76
|
-
const { innerText } = this, mt = /^<(
|
|
77
|
+
const { innerText } = this, mt = /^<(includeonly|(?:no|only)include)\s+(?:[^\s>/]|\/(?!>))[^>]*>$/iu.exec(innerText);
|
|
77
78
|
if (mt) {
|
|
78
79
|
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'useless-attribute', s), { computeEditInfo } = lintConfig, before = mt[1].length + 1, after = innerText.endsWith('/>') ? 2 : 1;
|
|
79
80
|
e.startIndex += before;
|
package/dist/src/table/base.d.ts
CHANGED
|
@@ -24,6 +24,5 @@ export declare abstract class TableBaseToken extends Token {
|
|
|
24
24
|
* @param attr 表格属性
|
|
25
25
|
*/
|
|
26
26
|
constructor(pattern: RegExp, syntax: string | undefined, type: TableTypes, attr?: string, config?: Config, accum?: Token[], acceptable?: WikiParserAcceptable);
|
|
27
|
-
escape(): void;
|
|
28
27
|
}
|
|
29
28
|
export {};
|
package/dist/src/table/base.js
CHANGED
|
@@ -89,15 +89,14 @@ let TableBaseToken = (() => {
|
|
|
89
89
|
// @ts-expect-error abstract class
|
|
90
90
|
new attributes_1.AttributesToken(attr, 'table-attrs', type, config, accum));
|
|
91
91
|
}
|
|
92
|
+
/** @private */
|
|
92
93
|
escape() {
|
|
93
|
-
LSP: {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
child.escape();
|
|
100
|
-
}
|
|
94
|
+
LSP: for (const child of this.childNodes) {
|
|
95
|
+
if (child instanceof syntax_1.SyntaxToken) {
|
|
96
|
+
escapeTable(child);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
child.escape();
|
|
101
100
|
}
|
|
102
101
|
}
|
|
103
102
|
}
|
package/dist/src/table/td.d.ts
CHANGED
package/dist/src/table/td.js
CHANGED
|
@@ -10,13 +10,14 @@ export declare abstract class TagPairToken extends Token {
|
|
|
10
10
|
#private;
|
|
11
11
|
readonly name: string;
|
|
12
12
|
closed: boolean;
|
|
13
|
-
selfClosing: boolean;
|
|
14
13
|
abstract get type(): 'ext' | 'include' | 'translate';
|
|
15
14
|
readonly childNodes: readonly [AstNodes, AstNodes];
|
|
16
15
|
abstract get firstChild(): AstNodes;
|
|
17
16
|
abstract get lastChild(): AstNodes;
|
|
18
17
|
/** inner wikitext / 内部wikitext */
|
|
19
18
|
get innerText(): string | undefined;
|
|
19
|
+
/** whether to be self-closing / 是否自封闭 */
|
|
20
|
+
get selfClosing(): boolean;
|
|
20
21
|
/**
|
|
21
22
|
* @param name 标签名
|
|
22
23
|
* @param attr 标签属性
|
|
@@ -59,11 +59,15 @@ let TagPairToken = (() => {
|
|
|
59
59
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
60
60
|
}
|
|
61
61
|
#tags;
|
|
62
|
+
#selfClosing;
|
|
62
63
|
closed;
|
|
63
|
-
selfClosing;
|
|
64
64
|
/** inner wikitext / 内部wikitext */
|
|
65
65
|
get innerText() {
|
|
66
|
-
return this
|
|
66
|
+
return this.#selfClosing ? undefined : this.lastChild.text();
|
|
67
|
+
}
|
|
68
|
+
/** whether to be self-closing / 是否自封闭 */
|
|
69
|
+
get selfClosing() {
|
|
70
|
+
return this.#selfClosing;
|
|
67
71
|
}
|
|
68
72
|
/**
|
|
69
73
|
* @param name 标签名
|
|
@@ -76,22 +80,22 @@ let TagPairToken = (() => {
|
|
|
76
80
|
this.setAttribute('name', name.toLowerCase());
|
|
77
81
|
this.#tags = [name, closed || name];
|
|
78
82
|
this.closed = closed !== '';
|
|
79
|
-
this
|
|
83
|
+
this.#selfClosing = closed === undefined;
|
|
80
84
|
this.append(attr, inner);
|
|
81
85
|
const index = typeof attr === 'string' ? -1 : accum.indexOf(attr);
|
|
82
86
|
accum.splice(index === -1 ? Infinity : index, 0, this);
|
|
83
87
|
}
|
|
84
88
|
/** @private */
|
|
85
89
|
toString(skip) {
|
|
86
|
-
const {
|
|
87
|
-
return selfClosing
|
|
90
|
+
const { firstChild, lastChild, } = this, [opening, closing] = this.#tags;
|
|
91
|
+
return this.#selfClosing
|
|
88
92
|
? `<${opening}${firstChild.toString(skip)}/>`
|
|
89
93
|
: `<${opening}${firstChild.toString(skip)}>${lastChild.toString(skip)}${this.closed ? `</${closing}>` : ''}`;
|
|
90
94
|
}
|
|
91
95
|
/** @private */
|
|
92
96
|
text() {
|
|
93
97
|
const [opening, closing] = this.#tags;
|
|
94
|
-
return this
|
|
98
|
+
return this.#selfClosing
|
|
95
99
|
? `<${opening}${this.firstChild.text()}/>`
|
|
96
100
|
: `<${opening}${super.text('>')}${this.closed ? `</${closing}>` : ''}`;
|
|
97
101
|
}
|
|
@@ -9,12 +9,12 @@ import type { Config } from '../../base';
|
|
|
9
9
|
export declare abstract class TranslateToken extends TagPairToken {
|
|
10
10
|
name: 'translate';
|
|
11
11
|
closed: true;
|
|
12
|
-
selfClosing: false;
|
|
13
12
|
readonly childNodes: readonly [SyntaxToken, Token];
|
|
14
13
|
abstract get firstChild(): SyntaxToken;
|
|
15
14
|
abstract get lastChild(): Token;
|
|
16
15
|
abstract get innerText(): string;
|
|
17
16
|
get type(): 'translate';
|
|
17
|
+
get selfClosing(): false;
|
|
18
18
|
/**
|
|
19
19
|
* @param attr 标签属性
|
|
20
20
|
* @param inner 内部wikitext
|
package/dist/util/diff.js
CHANGED
|
@@ -3,8 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.info = exports.error = exports.
|
|
6
|
+
exports.info = exports.error = exports.diff = exports.cmd = void 0;
|
|
7
7
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
|
+
const util_1 = __importDefault(require("util"));
|
|
8
9
|
const child_process_1 = require("child_process");
|
|
9
10
|
/* istanbul ignore next */
|
|
10
11
|
process.on('unhandledRejection', e => {
|
|
@@ -76,29 +77,17 @@ const diff = async (oldStr, newStr, uid) => {
|
|
|
76
77
|
await Promise.allSettled([promises_1.default.unlink(oldFile), promises_1.default.unlink(newFile)]);
|
|
77
78
|
};
|
|
78
79
|
exports.diff = diff;
|
|
79
|
-
let chalk;
|
|
80
|
-
/* istanbul ignore next */
|
|
81
|
-
const loadChalk = () => {
|
|
82
|
-
if (chalk === undefined) {
|
|
83
|
-
try {
|
|
84
|
-
chalk = require('chalk');
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
chalk = null;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return chalk;
|
|
91
|
-
};
|
|
92
|
-
exports.loadChalk = loadChalk;
|
|
93
80
|
/* istanbul ignore next */
|
|
94
81
|
/** @implements */
|
|
95
82
|
const error = (msg, ...args) => {
|
|
96
|
-
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
84
|
+
console.error(util_1.default.styleText?.('red', msg) ?? msg, ...args);
|
|
97
85
|
};
|
|
98
86
|
exports.error = error;
|
|
99
87
|
/* istanbul ignore next */
|
|
100
88
|
/** @implements */
|
|
101
89
|
const info = (msg, ...args) => {
|
|
102
|
-
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
91
|
+
console.info(util_1.default.styleText?.('green', msg) ?? msg, ...args);
|
|
103
92
|
};
|
|
104
93
|
exports.info = info;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikilint",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.35.0",
|
|
4
4
|
"description": "A Node.js linter for MediaWiki markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -72,18 +72,17 @@
|
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@bhsd/cm-util": "^0.1.0",
|
|
75
|
-
"@bhsd/common": "^1.0
|
|
76
|
-
"@bhsd/stylelint-util": "^0.1
|
|
75
|
+
"@bhsd/common": "^1.3.0",
|
|
76
|
+
"@bhsd/stylelint-util": "^1.0.1",
|
|
77
77
|
"binary-search": "^1.3.6",
|
|
78
78
|
"vscode-languageserver-types": "^3.17.5"
|
|
79
79
|
},
|
|
80
80
|
"optionalDependencies": {
|
|
81
|
-
"chalk": "^4.1.2",
|
|
82
81
|
"color-name": "^2.0.0",
|
|
83
82
|
"entities": "^7.0.0",
|
|
84
83
|
"mathoid-texvcjs": "^0.6.0",
|
|
85
84
|
"minimatch": "^10.1.1",
|
|
86
|
-
"stylelint": "^
|
|
85
|
+
"stylelint": "^17.0.0",
|
|
87
86
|
"vscode-css-languageservice": "^6.3.8",
|
|
88
87
|
"vscode-html-languageservice": "^5.6.0",
|
|
89
88
|
"vscode-json-languageservice": "^5.6.3"
|
|
@@ -91,7 +90,7 @@
|
|
|
91
90
|
"devDependencies": {
|
|
92
91
|
"@bhsd/code-standard": "^1.3.2",
|
|
93
92
|
"@bhsd/nodejs": "^0.1.0",
|
|
94
|
-
"@bhsd/test-util": "^0.
|
|
93
|
+
"@bhsd/test-util": "^0.3.0",
|
|
95
94
|
"@stylistic/eslint-plugin": "^5.5.0",
|
|
96
95
|
"@types/color-name": "^2.0.0",
|
|
97
96
|
"@types/color-rgba": "^2.1.3",
|
|
@@ -118,6 +117,6 @@
|
|
|
118
117
|
"vscode-languageserver-textdocument": "^1.0.12"
|
|
119
118
|
},
|
|
120
119
|
"engines": {
|
|
121
|
-
"node": ">=
|
|
120
|
+
"node": ">=20.19.5"
|
|
122
121
|
}
|
|
123
122
|
}
|