wikilint 2.12.2 → 2.12.5
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 +4 -1
- package/config/enwiki.json +4 -1
- package/config/minimum.json +10 -2
- package/config/zhwiki.json +4 -1
- package/dist/lib/element.js +4 -4
- package/dist/parser/magicLinks.js +2 -1
- package/dist/src/arg.d.ts +1 -0
- package/dist/src/arg.js +9 -0
- package/dist/src/attribute.js +14 -10
- package/dist/src/attributes.js +1 -1
- package/dist/src/heading.js +1 -1
- package/dist/src/index.js +25 -14
- package/dist/src/tagPair/ext.js +1 -1
- package/dist/src/transclude.js +6 -0
- package/i18n/zh-hans.json +1 -0
- package/i18n/zh-hant.json +1 -0
- package/package.json +1 -1
package/config/default.json
CHANGED
package/config/enwiki.json
CHANGED
package/config/minimum.json
CHANGED
|
@@ -69,7 +69,12 @@
|
|
|
69
69
|
"link"
|
|
70
70
|
]
|
|
71
71
|
],
|
|
72
|
-
"namespaces": {
|
|
72
|
+
"namespaces": {
|
|
73
|
+
"0": "",
|
|
74
|
+
"6": "File",
|
|
75
|
+
"10": "Template",
|
|
76
|
+
"828": "Module"
|
|
77
|
+
},
|
|
73
78
|
"nsid": {
|
|
74
79
|
"file": 6,
|
|
75
80
|
"category": 14
|
|
@@ -114,7 +119,10 @@
|
|
|
114
119
|
},
|
|
115
120
|
[
|
|
116
121
|
"!",
|
|
117
|
-
"="
|
|
122
|
+
"=",
|
|
123
|
+
"#FORMAL",
|
|
124
|
+
"#timef",
|
|
125
|
+
"#timefl"
|
|
118
126
|
],
|
|
119
127
|
[
|
|
120
128
|
"msg",
|
package/config/zhwiki.json
CHANGED
package/dist/lib/element.js
CHANGED
|
@@ -8,10 +8,10 @@ const node_1 = require("./node");
|
|
|
8
8
|
* 将选择器转化为类型谓词
|
|
9
9
|
* @param selector 选择器
|
|
10
10
|
*/
|
|
11
|
-
const getCondition = (selector) => {
|
|
12
|
-
const
|
|
13
|
-
return (
|
|
14
|
-
};
|
|
11
|
+
const getCondition = (selector) => (({ type, name }) => selector.split(',').some(str => {
|
|
12
|
+
const [t, ...ns] = str.trim().split('#');
|
|
13
|
+
return (!t || t === type) && ns.every(n => n === name);
|
|
14
|
+
}));
|
|
15
15
|
/** 类似HTMLElement */
|
|
16
16
|
class AstElement extends node_1.AstNode {
|
|
17
17
|
/** 子节点总数 */
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseMagicLinks = void 0;
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
5
|
const magicLink_1 = require("../src/magicLink");
|
|
6
|
+
const space = String.raw `[\p{Zs}\t]| |�*160;|�*a0;`, sp = `(?:${space})+`, spdash = `(?:${space}|-)`, magicLinkPattern = String.raw `(?:RFC|PMID)${sp}\d+\b|ISBN${sp}(?:97[89]${spdash}?)?(?:\d${spdash}?){9}[\dx]\b`;
|
|
6
7
|
/**
|
|
7
8
|
* 解析自由外链
|
|
8
9
|
* @param wikitext
|
|
@@ -10,7 +11,7 @@ const magicLink_1 = require("../src/magicLink");
|
|
|
10
11
|
* @param accum
|
|
11
12
|
*/
|
|
12
13
|
const parseMagicLinks = (wikitext, config, accum) => {
|
|
13
|
-
const
|
|
14
|
+
const regex = new RegExp(String.raw `(^|[^\p{L}\d_])(?:(?:${config.protocol})(${string_1.extUrlCharFirst}${string_1.extUrlChar})|${magicLinkPattern})`, 'giu');
|
|
14
15
|
return wikitext.replace(regex, (m, lead, p1) => {
|
|
15
16
|
let url = lead ? m.slice(lead.length) : m;
|
|
16
17
|
if (p1) {
|
package/dist/src/arg.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type { LintError } from '../base';
|
|
|
8
8
|
* @classdesc `{childNodes: [AtomToken, ?Token, ...HiddenToken]}`
|
|
9
9
|
*/
|
|
10
10
|
export declare abstract class ArgToken extends Token {
|
|
11
|
+
#private;
|
|
11
12
|
readonly childNodes: readonly [AtomToken] | readonly [AtomToken, Token, ...HiddenToken[]];
|
|
12
13
|
abstract get firstChild(): AtomToken;
|
|
13
14
|
abstract get lastChild(): Token;
|
package/dist/src/arg.js
CHANGED
|
@@ -56,6 +56,15 @@ class ArgToken extends index_2.Token {
|
|
|
56
56
|
getGaps() {
|
|
57
57
|
return 1;
|
|
58
58
|
}
|
|
59
|
+
/** 设置name */
|
|
60
|
+
#setName() {
|
|
61
|
+
this.setAttribute('name', this.firstChild.toString(true).trim());
|
|
62
|
+
}
|
|
63
|
+
/** @private */
|
|
64
|
+
afterBuild() {
|
|
65
|
+
this.#setName();
|
|
66
|
+
super.afterBuild();
|
|
67
|
+
}
|
|
59
68
|
/** @private */
|
|
60
69
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
61
70
|
const { childNodes: [argName, argDefault, ...rest] } = this;
|
package/dist/src/attribute.js
CHANGED
|
@@ -64,10 +64,14 @@ const commonHtmlAttrs = new Set([
|
|
|
64
64
|
time: new Set(['datetime']),
|
|
65
65
|
meta: new Set(['itemprop', 'content']),
|
|
66
66
|
link: new Set(['itemprop', 'href', 'title']),
|
|
67
|
-
gallery:
|
|
68
|
-
poem:
|
|
67
|
+
gallery: typeAttrs,
|
|
68
|
+
poem: blockAttrs,
|
|
69
|
+
categorytree: blockAttrs,
|
|
70
|
+
combooption: blockAttrs,
|
|
71
|
+
}, empty = new Set(), extAttrs = {
|
|
72
|
+
gallery: new Set(['mode', 'showfilename', 'caption', 'perrow', 'widths', 'heights', 'showthumbnails']),
|
|
73
|
+
poem: new Set(['compact']),
|
|
69
74
|
categorytree: new Set([
|
|
70
|
-
'align',
|
|
71
75
|
'hideroot',
|
|
72
76
|
'onlyroot',
|
|
73
77
|
'depth',
|
|
@@ -77,8 +81,7 @@ const commonHtmlAttrs = new Set([
|
|
|
77
81
|
'showcount',
|
|
78
82
|
'notranslations',
|
|
79
83
|
]),
|
|
80
|
-
combooption: new Set(['name', 'for', 'inline'
|
|
81
|
-
}, empty = new Set(), extAttrs = {
|
|
84
|
+
combooption: new Set(['name', 'for', 'inline']),
|
|
82
85
|
nowiki: empty,
|
|
83
86
|
indicator: new Set(['name']),
|
|
84
87
|
langconvert: new Set(['from', 'to']),
|
|
@@ -267,11 +270,12 @@ class AttributeToken extends index_2.Token {
|
|
|
267
270
|
errors.push(e);
|
|
268
271
|
}
|
|
269
272
|
const attrs = extAttrs[tag];
|
|
270
|
-
if (attrs &&
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
if (!(attrs && attrs.has(name))
|
|
274
|
+
&& (type === 'ext-attr' || !/\{\{[^{]+\}\}/u.test(name))
|
|
275
|
+
&& (type === 'ext-attr' && !(tag in htmlAttrs)
|
|
276
|
+
|| !htmlAttrs[tag]?.has(name)
|
|
277
|
+
&& !/^(?:xmlns:[\w:.-]+|data-(?!ooui|mw|parsoid)[^:]*)$/u.test(name)
|
|
278
|
+
&& (tag === 'meta' || tag === 'link' || !commonHtmlAttrs.has(name)))) {
|
|
275
279
|
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'illegal-attr', 'illegal attribute name'));
|
|
276
280
|
}
|
|
277
281
|
else if (obsoleteAttrs[tag]?.has(name)) {
|
package/dist/src/attributes.js
CHANGED
|
@@ -48,7 +48,7 @@ class AttributesToken extends index_2.Token {
|
|
|
48
48
|
while (mt) {
|
|
49
49
|
const { index, 0: full, 1: key, 2: equal, 3: quoteStart, 4: quoted, 5: quoteEnd, 6: unquoted } = mt;
|
|
50
50
|
out += attr.slice(lastIndex, index);
|
|
51
|
-
if (/^(?:[\w:]|\0\d+
|
|
51
|
+
if (/^(?:[\w:]|\0\d+t\x7F)(?:[\w:.-]|\0\d+t\x7F)*$/u.test((0, string_1.removeComment)(key).trim())) {
|
|
52
52
|
const value = quoted ?? unquoted, quotes = [quoteStart, quoteEnd],
|
|
53
53
|
// @ts-expect-error abstract class
|
|
54
54
|
token = new attribute_1.AttributeToken(toAttributeType(type), name, key, equal, value, quotes, config, accum);
|
package/dist/src/heading.js
CHANGED
|
@@ -64,7 +64,7 @@ class HeadingToken extends index_2.Token {
|
|
|
64
64
|
if (innerStr.startsWith('=') || innerStr.endsWith('=')) {
|
|
65
65
|
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'unbalanced-header', index_1.default.msg('unbalanced $1 in a section header', '"="')));
|
|
66
66
|
}
|
|
67
|
-
if (this.closest('html-attrs,
|
|
67
|
+
if (this.closest('html-attrs,table-attrs')) {
|
|
68
68
|
errors.push((0, lint_1.generateForSelf)(this, rect, 'parsing-order', 'section header in a HTML tag'));
|
|
69
69
|
}
|
|
70
70
|
if (boldQuotes.length % 2) {
|
package/dist/src/index.js
CHANGED
|
@@ -337,27 +337,38 @@ class Token extends element_1.AstElement {
|
|
|
337
337
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
338
338
|
let errors = super.lint(start, re);
|
|
339
339
|
if (this.type === 'root') {
|
|
340
|
-
const record = {};
|
|
341
|
-
for (const cat of this.querySelectorAll(
|
|
342
|
-
|
|
340
|
+
const record = {}, selector = 'category,html-attr#id,ext-attr#id,table-attr#id';
|
|
341
|
+
for (const cat of this.querySelectorAll(selector)) {
|
|
342
|
+
let key;
|
|
343
|
+
if (cat.type === 'category') {
|
|
344
|
+
key = cat.name;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
const value = cat.getValue();
|
|
348
|
+
key = `#${value === true ? '' : value}`;
|
|
349
|
+
}
|
|
350
|
+
const thisCat = record[key];
|
|
343
351
|
if (thisCat) {
|
|
344
352
|
thisCat.add(cat);
|
|
345
353
|
}
|
|
346
354
|
else {
|
|
347
|
-
record[
|
|
355
|
+
record[key] = new Set([cat]);
|
|
348
356
|
}
|
|
349
357
|
}
|
|
350
|
-
for (const value of Object.
|
|
351
|
-
if (value.size > 1) {
|
|
358
|
+
for (const [key, value] of Object.entries(record)) {
|
|
359
|
+
if (value.size > 1 && !key.startsWith('#mw-customcollapsible-')) {
|
|
360
|
+
const isCat = !key.startsWith('#'), msg = `duplicated ${isCat ? 'category' : 'id'}`, severity = isCat ? 'error' : 'warning';
|
|
352
361
|
errors.push(...[...value].map(cat => {
|
|
353
|
-
const e = (0, lint_1.generateForSelf)(cat, { start: cat.getAbsoluteIndex() }, 'no-duplicate',
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
362
|
+
const e = (0, lint_1.generateForSelf)(cat, { start: cat.getAbsoluteIndex() }, 'no-duplicate', msg, severity);
|
|
363
|
+
if (isCat) {
|
|
364
|
+
e.suggestions = [
|
|
365
|
+
{
|
|
366
|
+
desc: 'remove',
|
|
367
|
+
range: [e.startIndex, e.endIndex],
|
|
368
|
+
text: '',
|
|
369
|
+
},
|
|
370
|
+
];
|
|
371
|
+
}
|
|
361
372
|
return e;
|
|
362
373
|
}));
|
|
363
374
|
}
|
package/dist/src/tagPair/ext.js
CHANGED
|
@@ -120,7 +120,7 @@ class ExtToken extends index_3.TagPairToken {
|
|
|
120
120
|
/** @private */
|
|
121
121
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
122
122
|
const errors = super.lint(start, re), rect = new rect_1.BoundingRect(this, start);
|
|
123
|
-
if (this.name !== 'nowiki' && this.closest('html-attrs,
|
|
123
|
+
if (this.name !== 'nowiki' && this.closest('html-attrs,table-attrs')) {
|
|
124
124
|
errors.push((0, lint_1.generateForSelf)(this, rect, 'parsing-order', 'extension tag in HTML tag attributes'));
|
|
125
125
|
}
|
|
126
126
|
if (this.name === 'ref' && this.closest('heading-title')) {
|
package/dist/src/transclude.js
CHANGED
|
@@ -131,6 +131,12 @@ class TranscludeToken extends index_2.Token {
|
|
|
131
131
|
this.setAttribute('modifier', this.buildFromStr(this.modifier, constants_1.BuildMethod.String));
|
|
132
132
|
}
|
|
133
133
|
super.afterBuild();
|
|
134
|
+
if (this.isTemplate()) {
|
|
135
|
+
const isTemplate = this.type === 'template';
|
|
136
|
+
if (isTemplate) {
|
|
137
|
+
this.setAttribute('name', this.#getTitle().title);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
134
140
|
}
|
|
135
141
|
/** @private */
|
|
136
142
|
toString(skip) {
|
package/i18n/zh-hans.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"content to be moved out from the table": "将被移出表格的内容",
|
|
12
12
|
"duplicated $1 attribute": "重复的$1属性",
|
|
13
13
|
"duplicated category": "重复的分类",
|
|
14
|
+
"duplicated id": "重复的id",
|
|
14
15
|
"duplicated image $1 parameter": "重复的图片$1参数",
|
|
15
16
|
"duplicated parameter": "重复参数",
|
|
16
17
|
"extension tag in HTML tag attributes": "HTML标签属性中的扩展标签",
|
package/i18n/zh-hant.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"content to be moved out from the table": "將被移出表格的內容",
|
|
12
12
|
"duplicated $1 attribute": "重複的$1屬性",
|
|
13
13
|
"duplicated category": "重複的分類",
|
|
14
|
+
"duplicated id": "重複的id",
|
|
14
15
|
"duplicated image $1 parameter": "重複的圖片$1參數",
|
|
15
16
|
"duplicated parameter": "重複參數",
|
|
16
17
|
"extension tag in HTML tag attributes": "HTML標籤屬性中的擴展標籤",
|