wikilint 2.13.8 → 2.14.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 +63 -2
- package/config/enwiki.json +2 -0
- package/config/minimum.json +37 -3
- package/config/moegirl.json +0 -1
- package/config/zhwiki.json +2 -0
- package/dist/base.d.ts +2 -3
- package/dist/lib/text.js +32 -36
- package/dist/parser/braces.js +2 -2
- package/dist/parser/commentAndExt.js +14 -9
- package/dist/parser/hrAndDoubleUnderscore.js +5 -3
- package/dist/parser/html.js +4 -2
- package/dist/parser/table.js +9 -5
- package/dist/src/arg.js +3 -11
- package/dist/src/attribute.js +8 -24
- package/dist/src/attributes.js +20 -10
- package/dist/src/converterFlags.js +2 -8
- package/dist/src/gallery.js +2 -10
- package/dist/src/heading.js +40 -6
- package/dist/src/html.js +47 -27
- package/dist/src/imageParameter.js +4 -2
- package/dist/src/imagemap.js +8 -1
- package/dist/src/index.js +12 -24
- package/dist/src/link/base.js +5 -1
- package/dist/src/link/file.js +6 -2
- package/dist/src/link/galleryImage.js +3 -1
- package/dist/src/link/redirectTarget.js +1 -1
- package/dist/src/magicLink.js +3 -17
- package/dist/src/nested.js +2 -10
- package/dist/src/nowiki/comment.js +1 -1
- package/dist/src/nowiki/index.js +1 -1
- package/dist/src/nowiki/quote.js +10 -8
- package/dist/src/paramTag/index.js +1 -7
- package/dist/src/parameter.js +1 -1
- package/dist/src/table/td.js +1 -0
- package/dist/src/tagPair/include.js +2 -14
- package/dist/src/transclude.js +6 -1
- package/i18n/zh-hans.json +1 -1
- package/i18n/zh-hant.json +1 -1
- package/package.json +3 -3
package/dist/src/attributes.js
CHANGED
|
@@ -99,8 +99,11 @@ class AttributesToken extends index_2.Token {
|
|
|
99
99
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
100
100
|
const errors = super.lint(start, re), { parentNode, childNodes } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start);
|
|
101
101
|
if (parentNode?.type === 'html' && parentNode.closing && this.text().trim()) {
|
|
102
|
-
const e = (0, lint_1.generateForSelf)(this, rect, 'no-ignored', 'attributes of a closing tag');
|
|
103
|
-
e.
|
|
102
|
+
const e = (0, lint_1.generateForSelf)(this, rect, 'no-ignored', 'attributes of a closing tag'), index = parentNode.getAbsoluteIndex();
|
|
103
|
+
e.suggestions = [
|
|
104
|
+
{ desc: 'remove', range: [start, e.endIndex], text: '' },
|
|
105
|
+
{ desc: 'open', range: [index + 1, index + 2], text: '' },
|
|
106
|
+
];
|
|
104
107
|
errors.push(e);
|
|
105
108
|
}
|
|
106
109
|
for (const attr of childNodes) {
|
|
@@ -118,20 +121,27 @@ class AttributesToken extends index_2.Token {
|
|
|
118
121
|
const str = attr.text().trim();
|
|
119
122
|
if (str) {
|
|
120
123
|
const e = (0, lint_1.generateForChild)(attr, rect, 'no-ignored', 'containing invalid attribute', /[\p{L}\d]/u.test(str) ? 'error' : 'warning');
|
|
121
|
-
e.suggestions = [
|
|
122
|
-
{
|
|
123
|
-
desc: 'remove',
|
|
124
|
-
range: [e.startIndex, e.endIndex],
|
|
125
|
-
text: ' ',
|
|
126
|
-
},
|
|
127
|
-
];
|
|
124
|
+
e.suggestions = [{ desc: 'remove', range: [e.startIndex, e.endIndex], text: ' ' }];
|
|
128
125
|
errors.push(e);
|
|
129
126
|
}
|
|
130
127
|
}
|
|
131
128
|
}
|
|
132
129
|
if (duplicated.size > 0) {
|
|
133
130
|
for (const key of duplicated) {
|
|
134
|
-
|
|
131
|
+
const pairs = attrs.get(key).map(attr => {
|
|
132
|
+
const value = attr.getValue();
|
|
133
|
+
return [attr, value === true ? '' : value];
|
|
134
|
+
});
|
|
135
|
+
errors.push(...pairs.map(([attr, value], i) => {
|
|
136
|
+
const e = (0, lint_1.generateForChild)(attr, rect, 'no-duplicate', index_1.default.msg('duplicated $1 attribute', key)), remove = { desc: 'remove', range: [e.startIndex, e.endIndex], text: '' };
|
|
137
|
+
if (!value || pairs.slice(0, i).some(([, v]) => v === value)) {
|
|
138
|
+
e.fix = remove;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
e.suggestions = [remove];
|
|
142
|
+
}
|
|
143
|
+
return e;
|
|
144
|
+
}));
|
|
135
145
|
}
|
|
136
146
|
}
|
|
137
147
|
return errors;
|
|
@@ -62,16 +62,10 @@ class ConverterFlagsToken extends index_2.Token {
|
|
|
62
62
|
&& (variantFlags.size > 0 || !validFlags.has(flag))) {
|
|
63
63
|
const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', 'invalid conversion flag');
|
|
64
64
|
if (variantFlags.size === 0 && definedFlags.has(flag.toUpperCase())) {
|
|
65
|
-
e.fix = { range: [e.startIndex, e.endIndex], text: flag.toUpperCase() };
|
|
65
|
+
e.fix = { range: [e.startIndex, e.endIndex], text: flag.toUpperCase(), desc: 'uppercase' };
|
|
66
66
|
}
|
|
67
67
|
else {
|
|
68
|
-
e.suggestions = [
|
|
69
|
-
{
|
|
70
|
-
desc: 'remove',
|
|
71
|
-
range: [e.startIndex - (i && 1), e.endIndex],
|
|
72
|
-
text: '',
|
|
73
|
-
},
|
|
74
|
-
];
|
|
68
|
+
e.suggestions = [{ desc: 'remove', range: [e.startIndex - (i && 1), e.endIndex], text: '' }];
|
|
75
69
|
}
|
|
76
70
|
errors.push(e);
|
|
77
71
|
}
|
package/dist/src/gallery.js
CHANGED
|
@@ -71,16 +71,8 @@ class GalleryToken extends index_2.Token {
|
|
|
71
71
|
startCol,
|
|
72
72
|
endCol: startCol + length,
|
|
73
73
|
suggestions: [
|
|
74
|
-
{
|
|
75
|
-
|
|
76
|
-
range: [start, endIndex],
|
|
77
|
-
text: '',
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
desc: 'comment',
|
|
81
|
-
range: [start, endIndex],
|
|
82
|
-
text: `<!--${str}-->`,
|
|
83
|
-
},
|
|
74
|
+
{ desc: 'remove', range: [start, endIndex], text: '' },
|
|
75
|
+
{ desc: 'comment', range: [start, endIndex], text: `<!--${str}-->` },
|
|
84
76
|
],
|
|
85
77
|
});
|
|
86
78
|
}
|
package/dist/src/heading.js
CHANGED
|
@@ -57,21 +57,55 @@ class HeadingToken extends index_2.Token {
|
|
|
57
57
|
}
|
|
58
58
|
/** @private */
|
|
59
59
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
60
|
-
const errors = super.lint(start, re), { firstChild, level } = this, innerStr = firstChild.toString(), quotes = firstChild.childNodes.filter((0, debug_1.isToken)('quote')), boldQuotes = quotes.filter(({ bold }) => bold), italicQuotes = quotes.filter(({ italic }) => italic), rect = new rect_1.BoundingRect(this, start);
|
|
60
|
+
const errors = super.lint(start, re), { firstChild, level } = this, innerStr = firstChild.toString(), unbalancedStart = innerStr.startsWith('='), unbalanced = unbalancedStart || innerStr.endsWith('='), quotes = firstChild.childNodes.filter((0, debug_1.isToken)('quote')), boldQuotes = quotes.filter(({ bold }) => bold), italicQuotes = quotes.filter(({ italic }) => italic), rect = new rect_1.BoundingRect(this, start);
|
|
61
61
|
if (this.level === 1) {
|
|
62
|
-
|
|
62
|
+
const e = (0, lint_1.generateForChild)(firstChild, rect, 'h1', '<h1>');
|
|
63
|
+
if (!unbalanced) {
|
|
64
|
+
e.suggestions = [{ desc: 'h2', range: [e.startIndex, e.endIndex], text: `=${innerStr}=` }];
|
|
65
|
+
}
|
|
66
|
+
errors.push(e);
|
|
63
67
|
}
|
|
64
|
-
if (
|
|
65
|
-
|
|
68
|
+
if (unbalanced) {
|
|
69
|
+
const e = (0, lint_1.generateForChild)(firstChild, rect, 'unbalanced-header', index_1.default.msg('unbalanced $1 in a section header', '"="'));
|
|
70
|
+
if (innerStr === '=') {
|
|
71
|
+
//
|
|
72
|
+
}
|
|
73
|
+
else if (unbalancedStart) {
|
|
74
|
+
const [extra] = /^=+/u.exec(innerStr);
|
|
75
|
+
e.suggestions = [
|
|
76
|
+
{ desc: `h${level}`, range: [e.startIndex, e.startIndex + extra.length], text: '' },
|
|
77
|
+
{ desc: `h${level + extra.length}`, range: [e.endIndex, e.endIndex], text: extra },
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const extra = /[^=](=+)$/u.exec(innerStr)[1];
|
|
82
|
+
e.suggestions = [
|
|
83
|
+
{ desc: `h${level}`, range: [e.endIndex - extra.length, e.endIndex], text: '' },
|
|
84
|
+
{ desc: `h${level + extra.length}`, range: [e.startIndex, e.startIndex], text: extra },
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
errors.push(e);
|
|
66
88
|
}
|
|
67
89
|
if (this.closest('html-attrs,table-attrs')) {
|
|
68
90
|
errors.push((0, lint_1.generateForSelf)(this, rect, 'parsing-order', 'section header in a HTML tag'));
|
|
69
91
|
}
|
|
92
|
+
const rootStr = this.getRootNode().toString();
|
|
70
93
|
if (boldQuotes.length % 2) {
|
|
71
|
-
|
|
94
|
+
const e = (0, lint_1.generateForChild)(boldQuotes[boldQuotes.length - 1], { ...rect, start: start + level, left: rect.left + level }, 'format-leakage', index_1.default.msg('unbalanced $1 in a section header', 'bold apostrophes')), end = start + level + innerStr.length;
|
|
95
|
+
if (rootStr.slice(e.endIndex, end).trim()) {
|
|
96
|
+
e.suggestions = [{ desc: 'close', range: [end, end], text: "'''" }];
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
e.fix = { desc: 'remove', range: [e.startIndex, e.endIndex], text: '' };
|
|
100
|
+
}
|
|
101
|
+
errors.push(e);
|
|
72
102
|
}
|
|
73
103
|
if (italicQuotes.length % 2) {
|
|
74
|
-
|
|
104
|
+
const e = (0, lint_1.generateForChild)(italicQuotes[italicQuotes.length - 1], { start: start + level }, 'format-leakage', index_1.default.msg('unbalanced $1 in a section header', 'italic apostrophes')), end = start + level + innerStr.length;
|
|
105
|
+
e.fix = rootStr.slice(e.endIndex, end).trim()
|
|
106
|
+
? { desc: 'close', range: [end, end], text: "''" }
|
|
107
|
+
: { desc: 'remove', range: [e.startIndex, e.endIndex], text: '' };
|
|
108
|
+
errors.push(e);
|
|
75
109
|
}
|
|
76
110
|
return errors;
|
|
77
111
|
}
|
package/dist/src/html.js
CHANGED
|
@@ -84,10 +84,15 @@ class HtmlToken extends index_1.Token {
|
|
|
84
84
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
85
85
|
const errors = super.lint(start, re), rect = new rect_1.BoundingRect(this, start);
|
|
86
86
|
if (this.name === 'h1' && !this.closing) {
|
|
87
|
-
errors.push(
|
|
87
|
+
errors.push({
|
|
88
|
+
...(0, lint_1.generateForSelf)(this, rect, 'h1', '<h1>'),
|
|
89
|
+
suggestions: [{ desc: 'h2', range: [start + 2, start + 3], text: '2' }],
|
|
90
|
+
});
|
|
88
91
|
}
|
|
89
92
|
if (this.closest('table-attrs')) {
|
|
90
|
-
|
|
93
|
+
const e = (0, lint_1.generateForSelf)(this, rect, 'parsing-order', 'HTML tag in table attributes');
|
|
94
|
+
e.fix = { desc: 'remove', range: [start, e.endIndex], text: '' };
|
|
95
|
+
errors.push(e);
|
|
91
96
|
}
|
|
92
97
|
try {
|
|
93
98
|
this.findMatchingTag();
|
|
@@ -95,38 +100,53 @@ class HtmlToken extends index_1.Token {
|
|
|
95
100
|
catch (e) {
|
|
96
101
|
if (e instanceof SyntaxError) {
|
|
97
102
|
const { message } = e;
|
|
98
|
-
const msg = message.split(':')[0].toLowerCase(), error = (0, lint_1.generateForSelf)(this, rect, 'unmatched-tag', msg)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
const msg = message.split(':')[0].toLowerCase(), error = (0, lint_1.generateForSelf)(this, rect, 'unmatched-tag', msg), noSelfClosing = {
|
|
104
|
+
desc: 'no self-closing',
|
|
105
|
+
range: [error.endIndex - 2, error.endIndex - 1],
|
|
106
|
+
text: '',
|
|
107
|
+
};
|
|
108
|
+
switch (msg) {
|
|
109
|
+
case 'unclosed tag': {
|
|
110
|
+
const childNodes = this.parentNode?.childNodes;
|
|
111
|
+
if (formattingTags.has(this.name)
|
|
112
|
+
&& childNodes?.slice(0, childNodes.indexOf(this))
|
|
113
|
+
.some(({ type, name }) => type === 'html' && name === this.name)) {
|
|
114
|
+
error.suggestions = [{ desc: 'close', range: [start + 1, start + 1], text: '/' }];
|
|
115
|
+
}
|
|
116
|
+
else if (!this.closest('heading-title')) {
|
|
103
117
|
error.severity = 'warning';
|
|
104
118
|
}
|
|
119
|
+
break;
|
|
105
120
|
}
|
|
106
|
-
|
|
107
|
-
|
|
121
|
+
case 'unmatched closing tag': {
|
|
122
|
+
const ancestor = this.closest('magic-word');
|
|
123
|
+
if (ancestor && magicWords.has(ancestor.name)) {
|
|
124
|
+
error.severity = 'warning';
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
error.suggestions = [{ desc: 'remove', range: [start, error.endIndex], text: '' }];
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
108
130
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
131
|
+
case 'tag that is both closing and self-closing': {
|
|
132
|
+
const { html: [normalTags, , voidTags] } = this.getAttribute('config'), open = { desc: 'open', range: [start + 1, start + 2], text: '' };
|
|
133
|
+
if (voidTags.includes(this.name)) {
|
|
134
|
+
error.fix = open;
|
|
135
|
+
}
|
|
136
|
+
else if (normalTags.includes(this.name)) {
|
|
137
|
+
error.fix = noSelfClosing;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
error.suggestions = [open, noSelfClosing];
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
114
143
|
}
|
|
115
|
-
|
|
144
|
+
case 'invalid self-closing tag':
|
|
116
145
|
error.suggestions = [
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
range: [start, error.endIndex],
|
|
120
|
-
text: '',
|
|
121
|
-
},
|
|
146
|
+
noSelfClosing,
|
|
147
|
+
{ desc: 'close', range: [error.endIndex - 2, error.endIndex], text: `></${this.name}>` },
|
|
122
148
|
];
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
else if (msg === 'tag that is both closing and self-closing') {
|
|
126
|
-
const { html: [, , voidTags] } = this.getAttribute('config');
|
|
127
|
-
if (voidTags.includes(this.name)) {
|
|
128
|
-
error.fix = { range: [start + 1, start + 2], text: '' };
|
|
129
|
-
}
|
|
149
|
+
// no default
|
|
130
150
|
}
|
|
131
151
|
errors.push(error);
|
|
132
152
|
}
|
|
@@ -107,11 +107,13 @@ class ImageParameterToken extends index_2.Token {
|
|
|
107
107
|
const errors = super.lint(start, re), { link, name } = this;
|
|
108
108
|
if (name === 'invalid') {
|
|
109
109
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'invalid-gallery', 'invalid image parameter');
|
|
110
|
-
e.fix = { range: [start - 1, e.endIndex], text: '' };
|
|
110
|
+
e.fix = { range: [start - 1, e.endIndex], text: '', desc: 'remove' };
|
|
111
111
|
errors.push(e);
|
|
112
112
|
}
|
|
113
113
|
else if (typeof link === 'object' && link.encoded) {
|
|
114
|
-
|
|
114
|
+
const e = (0, lint_1.generateForSelf)(this, { start }, 'url-encoding', 'unnecessary URL encoding in an internal link');
|
|
115
|
+
e.suggestions = [{ desc: 'decode', range: [start, e.endIndex], text: (0, string_1.rawurldecode)(this.text()) }];
|
|
116
|
+
errors.push(e);
|
|
115
117
|
}
|
|
116
118
|
return errors;
|
|
117
119
|
}
|
package/dist/src/imagemap.js
CHANGED
|
@@ -95,7 +95,14 @@ class ImagemapToken extends index_2.Token {
|
|
|
95
95
|
errors.push(...this.childNodes.filter(child => {
|
|
96
96
|
const str = child.toString().trim();
|
|
97
97
|
return child.type === 'noinclude' && str && !str.startsWith('#');
|
|
98
|
-
}).map(child =>
|
|
98
|
+
}).map(child => {
|
|
99
|
+
const e = (0, lint_1.generateForChild)(child, rect, 'invalid-imagemap', 'invalid link in <imagemap>');
|
|
100
|
+
e.suggestions = [
|
|
101
|
+
{ desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' },
|
|
102
|
+
{ desc: 'comment', range: [e.startIndex, e.startIndex], text: '# ' },
|
|
103
|
+
];
|
|
104
|
+
return e;
|
|
105
|
+
}));
|
|
99
106
|
}
|
|
100
107
|
else {
|
|
101
108
|
errors.push((0, lint_1.generateForSelf)(this, rect, 'invalid-imagemap', '<imagemap> without an image'));
|
package/dist/src/index.js
CHANGED
|
@@ -337,47 +337,35 @@ 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 = new Map(), selector = 'category,html-attr#id,ext-attr#id,table-attr#id
|
|
340
|
+
const record = new Map(), selector = 'category,html-attr#id,ext-attr#id,table-attr#id';
|
|
341
341
|
for (const cat of this.querySelectorAll(selector)) {
|
|
342
342
|
let key;
|
|
343
343
|
if (cat.type === 'category') {
|
|
344
344
|
key = cat.name;
|
|
345
345
|
}
|
|
346
346
|
else {
|
|
347
|
-
const value = cat.getValue()
|
|
348
|
-
if (
|
|
349
|
-
key = `#${value
|
|
347
|
+
const value = cat.getValue();
|
|
348
|
+
if (value && value !== true) {
|
|
349
|
+
key = `#${value}`;
|
|
350
350
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
351
|
+
}
|
|
352
|
+
if (key) {
|
|
353
|
+
const thisCat = record.get(key);
|
|
354
|
+
if (thisCat) {
|
|
355
|
+
thisCat.add(cat);
|
|
355
356
|
}
|
|
356
357
|
else {
|
|
357
|
-
|
|
358
|
+
record.set(key, new Set([cat]));
|
|
358
359
|
}
|
|
359
360
|
}
|
|
360
|
-
const thisCat = record.get(key);
|
|
361
|
-
if (thisCat) {
|
|
362
|
-
thisCat.add(cat);
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
record.set(key, new Set([cat]));
|
|
366
|
-
}
|
|
367
361
|
}
|
|
368
362
|
for (const [key, value] of record) {
|
|
369
363
|
if (value.size > 1 && !key.startsWith('#mw-customcollapsible-')) {
|
|
370
|
-
const isCat = !key.
|
|
364
|
+
const isCat = !key.startsWith('#'), msg = `duplicated ${isCat ? 'category' : 'id'}`, severity = isCat ? 'error' : 'warning';
|
|
371
365
|
errors.push(...[...value].map(cat => {
|
|
372
366
|
const e = (0, lint_1.generateForSelf)(cat, { start: cat.getAbsoluteIndex() }, 'no-duplicate', msg, severity);
|
|
373
367
|
if (isCat) {
|
|
374
|
-
e.suggestions = [
|
|
375
|
-
{
|
|
376
|
-
desc: 'remove',
|
|
377
|
-
range: [e.startIndex, e.endIndex],
|
|
378
|
-
text: '',
|
|
379
|
-
},
|
|
380
|
-
];
|
|
368
|
+
e.suggestions = [{ desc: 'remove', range: [e.startIndex, e.endIndex], text: '' }];
|
|
381
369
|
}
|
|
382
370
|
return e;
|
|
383
371
|
}));
|
package/dist/src/link/base.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.LinkBaseToken = void 0;
|
|
4
4
|
const lint_1 = require("../../util/lint");
|
|
5
5
|
const constants_1 = require("../../util/constants");
|
|
6
|
+
const string_1 = require("../../util/string");
|
|
6
7
|
const rect_1 = require("../../lib/rect");
|
|
7
8
|
const index_1 = require("../../index");
|
|
8
9
|
const index_2 = require("../index");
|
|
@@ -85,7 +86,9 @@ class LinkBaseToken extends index_2.Token {
|
|
|
85
86
|
errors.push((0, lint_1.generateForChild)(target, rect, 'unknown-page', 'template in an internal link target', 'warning'));
|
|
86
87
|
}
|
|
87
88
|
if (encoded) {
|
|
88
|
-
|
|
89
|
+
const e = (0, lint_1.generateForChild)(target, rect, 'url-encoding', 'unnecessary URL encoding in an internal link');
|
|
90
|
+
e.suggestions = [{ desc: 'decode', range: [e.startIndex, e.endIndex], text: (0, string_1.rawurldecode)(target.text()) }];
|
|
91
|
+
errors.push(e);
|
|
89
92
|
}
|
|
90
93
|
if (type === 'link' || type === 'category') {
|
|
91
94
|
const textNode = linkText?.childNodes.find((c) => c.type === 'text' && c.data.includes('|'));
|
|
@@ -107,6 +110,7 @@ class LinkBaseToken extends index_2.Token {
|
|
|
107
110
|
e.fix = {
|
|
108
111
|
range: [e.startIndex + textNode.getRelativeIndex() + textNode.data.indexOf('#'), e.endIndex],
|
|
109
112
|
text: '',
|
|
113
|
+
desc: 'remove',
|
|
110
114
|
};
|
|
111
115
|
}
|
|
112
116
|
errors.push(e);
|
package/dist/src/link/file.js
CHANGED
|
@@ -76,7 +76,7 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
76
76
|
if (unscaled) {
|
|
77
77
|
for (const arg of args.filter(({ name }) => name === 'width')) {
|
|
78
78
|
const e = (0, lint_1.generateForChild)(arg, rect, 'invalid-gallery', 'invalid image parameter');
|
|
79
|
-
e.fix = { range: [e.startIndex - 1, e.endIndex], text: '' };
|
|
79
|
+
e.fix = { range: [e.startIndex - 1, e.endIndex], text: '', desc: 'remove' };
|
|
80
80
|
errors.push(e);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
@@ -91,7 +91,11 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
91
91
|
* @param msg 消息键
|
|
92
92
|
* @param p1 替换$1
|
|
93
93
|
*/
|
|
94
|
-
const generate = (msg, p1) => (arg) =>
|
|
94
|
+
const generate = (msg, p1) => (arg) => {
|
|
95
|
+
const e = (0, lint_1.generateForChild)(arg, rect, 'no-duplicate', index_1.default.msg(`${msg} image $1 parameter`, p1));
|
|
96
|
+
e.suggestions = [{ desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' }];
|
|
97
|
+
return e;
|
|
98
|
+
};
|
|
95
99
|
for (const key of keys) {
|
|
96
100
|
if (key === 'invalid' || key === 'width' && unscaled) {
|
|
97
101
|
continue;
|
|
@@ -46,7 +46,9 @@ class GalleryImageToken extends file_1.FileToken {
|
|
|
46
46
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
47
47
|
const errors = super.lint(start, re), { ns, interwiki } = this.getAttribute('title');
|
|
48
48
|
if (interwiki || ns !== 6) {
|
|
49
|
-
|
|
49
|
+
const e = (0, lint_1.generateForSelf)(this, { start }, 'invalid-gallery', 'invalid gallery image');
|
|
50
|
+
e.suggestions = [{ desc: 'prefix', range: [start, start], text: 'File:' }];
|
|
51
|
+
errors.push(e);
|
|
50
52
|
}
|
|
51
53
|
return errors;
|
|
52
54
|
}
|
|
@@ -36,7 +36,7 @@ class RedirectTargetToken extends base_1.LinkBaseToken {
|
|
|
36
36
|
const e = (0, lint_1.generateForChild)(this.lastChild, { start }, 'no-ignored', 'useless link text');
|
|
37
37
|
e.startIndex--;
|
|
38
38
|
e.startCol--;
|
|
39
|
-
e.fix = { range: [e.startIndex, e.endIndex], text: '' };
|
|
39
|
+
e.fix = { range: [e.startIndex, e.endIndex], text: '', desc: 'remove' };
|
|
40
40
|
errors.push(e);
|
|
41
41
|
}
|
|
42
42
|
return errors;
|
package/dist/src/magicLink.js
CHANGED
|
@@ -66,24 +66,10 @@ class MagicLinkToken extends index_2.Token {
|
|
|
66
66
|
if (child) {
|
|
67
67
|
const { data } = child, e = (0, lint_1.generateForChild)(child, rect, 'unterminated-url', index_1.default.msg('$1 in URL', pipe ? '"|"' : 'full-width punctuation'), 'warning'), { index, 0: s } = regex.exec(data), i = e.startIndex + index;
|
|
68
68
|
e.suggestions = pipe
|
|
69
|
-
? [
|
|
70
|
-
{
|
|
71
|
-
desc: 'whitespace',
|
|
72
|
-
range: [i, i + 1],
|
|
73
|
-
text: ' ',
|
|
74
|
-
},
|
|
75
|
-
]
|
|
69
|
+
? [{ desc: 'whitespace', range: [i, i + 1], text: ' ' }]
|
|
76
70
|
: [
|
|
77
|
-
{
|
|
78
|
-
|
|
79
|
-
range: [i, i],
|
|
80
|
-
text: ' ',
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
desc: 'escape',
|
|
84
|
-
range: [i, i + s.length],
|
|
85
|
-
text: encodeURI(s),
|
|
86
|
-
},
|
|
71
|
+
{ desc: 'whitespace', range: [i, i], text: ' ' },
|
|
72
|
+
{ desc: 'escape', range: [i, i + s.length], text: encodeURI(s) },
|
|
87
73
|
];
|
|
88
74
|
errors.push(e);
|
|
89
75
|
}
|
package/dist/src/nested.js
CHANGED
|
@@ -68,16 +68,8 @@ class NestedToken extends index_2.Token {
|
|
|
68
68
|
}).map(child => {
|
|
69
69
|
const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', index_1.default.msg('invalid content in <$1>', this.name));
|
|
70
70
|
e.suggestions = [
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
range: [e.startIndex, e.endIndex],
|
|
74
|
-
text: '',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
desc: 'comment',
|
|
78
|
-
range: [e.startIndex, e.endIndex],
|
|
79
|
-
text: `<!--${child.toString()}-->`,
|
|
80
|
-
},
|
|
71
|
+
{ desc: 'remove', range: [e.startIndex, e.endIndex], text: '' },
|
|
72
|
+
{ desc: 'comment', range: [e.startIndex, e.endIndex], text: `<!--${child.toString()}-->` },
|
|
81
73
|
];
|
|
82
74
|
return e;
|
|
83
75
|
}),
|
|
@@ -74,7 +74,7 @@ let CommentToken = (() => {
|
|
|
74
74
|
return [];
|
|
75
75
|
}
|
|
76
76
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'unclosed-comment', index_1.default.msg('unclosed $1', 'HTML comment'));
|
|
77
|
-
e.
|
|
77
|
+
e.suggestions = [{ range: [e.endIndex, e.endIndex], text: '-->', desc: 'close' }];
|
|
78
78
|
return [e];
|
|
79
79
|
}
|
|
80
80
|
/** @private */
|
package/dist/src/nowiki/index.js
CHANGED
|
@@ -14,7 +14,7 @@ class NowikiToken extends base_1.NowikiBaseToken {
|
|
|
14
14
|
const { name, firstChild: { data } } = this;
|
|
15
15
|
if ((name === 'templatestyles' || name === 'section') && data) {
|
|
16
16
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'void-ext', index_1.default.msg('nothing should be in <$1>', name));
|
|
17
|
-
e.fix = { range: [start, e.endIndex], text: '' };
|
|
17
|
+
e.fix = { range: [start, e.endIndex], text: '', desc: 'empty' };
|
|
18
18
|
return [e];
|
|
19
19
|
}
|
|
20
20
|
return super.lint(start, new RegExp(String.raw `<\s*(?:/\s*)${name === 'nowiki' ? '' : '?'}(${name})\b`, 'giu'));
|
package/dist/src/nowiki/quote.js
CHANGED
|
@@ -33,11 +33,10 @@ class QuoteToken extends base_1.NowikiBaseToken {
|
|
|
33
33
|
* @param endIndex 终点
|
|
34
34
|
* @param length 长度
|
|
35
35
|
*/
|
|
36
|
-
const getSuggestion = (startIndex, endIndex, length) =>
|
|
37
|
-
desc: 'escape',
|
|
38
|
-
range: [startIndex, endIndex],
|
|
39
|
-
|
|
40
|
-
});
|
|
36
|
+
const getSuggestion = (startIndex, endIndex, length) => [
|
|
37
|
+
{ desc: 'escape', range: [startIndex, endIndex], text: '''.repeat(length) },
|
|
38
|
+
{ desc: 'remove', range: [startIndex, endIndex], text: '' },
|
|
39
|
+
];
|
|
41
40
|
if (previousSibling?.type === 'text' && previousSibling.data.endsWith(`'`)) {
|
|
42
41
|
refError = (0, lint_1.generateForSelf)(this, rect, 'lonely-apos', message);
|
|
43
42
|
const { startIndex: endIndex, startLine: endLine, startCol: endCol } = refError, [, { length }] = /(?:^|[^'])('+)$/u.exec(previousSibling.data), startIndex = start - length;
|
|
@@ -48,7 +47,7 @@ class QuoteToken extends base_1.NowikiBaseToken {
|
|
|
48
47
|
startCol: endCol - length,
|
|
49
48
|
endLine,
|
|
50
49
|
endCol,
|
|
51
|
-
suggestions:
|
|
50
|
+
suggestions: getSuggestion(startIndex, endIndex, length),
|
|
52
51
|
});
|
|
53
52
|
}
|
|
54
53
|
if (nextSibling?.type === 'text' && nextSibling.data.startsWith(`'`)) {
|
|
@@ -61,11 +60,14 @@ class QuoteToken extends base_1.NowikiBaseToken {
|
|
|
61
60
|
startLine,
|
|
62
61
|
startCol,
|
|
63
62
|
endCol: startCol + length,
|
|
64
|
-
suggestions:
|
|
63
|
+
suggestions: getSuggestion(startIndex, endIndex, length),
|
|
65
64
|
});
|
|
66
65
|
}
|
|
67
66
|
if (bold && this.closest('heading-title')) {
|
|
68
|
-
errors.push(
|
|
67
|
+
errors.push({
|
|
68
|
+
...(0, lint_1.generateForSelf)(this, rect, 'bold-header', 'bold in section header', 'warning'),
|
|
69
|
+
suggestions: [{ desc: 'remove', range: [start, start + 3], text: '' }],
|
|
70
|
+
});
|
|
69
71
|
}
|
|
70
72
|
return errors;
|
|
71
73
|
}
|
|
@@ -52,13 +52,7 @@ class ParamTagToken extends index_2.Token {
|
|
|
52
52
|
const i = grandChildren.findIndex(({ type }) => type !== 'text'), str = grandChildren.slice(0, i === -1 ? undefined : i).map(String).join('');
|
|
53
53
|
if (str && !(i === -1 ? /^[a-z]+(?:\[\])?\s*=/iu : /^[a-z]+(?:\[\])?\s*(?:=|$)/iu).test(str)) {
|
|
54
54
|
const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', msg);
|
|
55
|
-
e.suggestions = [
|
|
56
|
-
{
|
|
57
|
-
desc: 'remove',
|
|
58
|
-
range: [e.startIndex, e.endIndex],
|
|
59
|
-
text: '',
|
|
60
|
-
},
|
|
61
|
-
];
|
|
55
|
+
e.suggestions = [{ desc: 'remove', range: [e.startIndex, e.endIndex], text: '' }];
|
|
62
56
|
errors.push(e);
|
|
63
57
|
}
|
|
64
58
|
else {
|
package/dist/src/parameter.js
CHANGED
|
@@ -69,7 +69,7 @@ class ParameterToken extends index_2.Token {
|
|
|
69
69
|
e.startCol = e.endCol;
|
|
70
70
|
e.endIndex++;
|
|
71
71
|
e.endCol++;
|
|
72
|
-
e.fix = { range: [e.startIndex, e.endIndex], text: '{{=}}' };
|
|
72
|
+
e.fix = { range: [e.startIndex, e.endIndex], text: '{{=}}', desc: 'escape' };
|
|
73
73
|
errors.push(e);
|
|
74
74
|
}
|
|
75
75
|
return errors;
|
package/dist/src/table/td.js
CHANGED
|
@@ -80,24 +80,12 @@ let IncludeToken = (() => {
|
|
|
80
80
|
const errors = [], { firstChild, closed, name } = this, rect = new rect_1.BoundingRect(this, start);
|
|
81
81
|
if (firstChild.data.trim()) {
|
|
82
82
|
const e = (0, lint_1.generateForChild)(firstChild, rect, 'no-ignored', 'useless attribute', 'warning');
|
|
83
|
-
e.suggestions = [
|
|
84
|
-
{
|
|
85
|
-
desc: 'remove',
|
|
86
|
-
range: [e.startIndex, e.endIndex],
|
|
87
|
-
text: '',
|
|
88
|
-
},
|
|
89
|
-
];
|
|
83
|
+
e.suggestions = [{ desc: 'remove', range: [e.startIndex, e.endIndex], text: '' }];
|
|
90
84
|
errors.push(e);
|
|
91
85
|
}
|
|
92
86
|
if (!closed) {
|
|
93
87
|
const e = (0, lint_1.generateForSelf)(this, rect, 'unclosed-comment', index_1.default.msg('unclosed $1', `<${name}>`));
|
|
94
|
-
e.suggestions = [
|
|
95
|
-
{
|
|
96
|
-
desc: 'close',
|
|
97
|
-
range: [e.endIndex, e.endIndex],
|
|
98
|
-
text: `</${name}>`,
|
|
99
|
-
},
|
|
100
|
-
];
|
|
88
|
+
e.suggestions = [{ desc: 'close', range: [e.endIndex, e.endIndex], text: `</${name}>` }];
|
|
101
89
|
errors.push(e);
|
|
102
90
|
}
|
|
103
91
|
return errors;
|
package/dist/src/transclude.js
CHANGED
|
@@ -193,6 +193,7 @@ class TranscludeToken extends index_2.Token {
|
|
|
193
193
|
e.fix = {
|
|
194
194
|
range: [e.startIndex + textNode.getRelativeIndex() + textNode.data.indexOf('#'), e.endIndex],
|
|
195
195
|
text: '',
|
|
196
|
+
desc: 'remove',
|
|
196
197
|
};
|
|
197
198
|
errors.push(e);
|
|
198
199
|
}
|
|
@@ -203,7 +204,11 @@ class TranscludeToken extends index_2.Token {
|
|
|
203
204
|
}
|
|
204
205
|
const duplicatedArgs = this.getDuplicatedArgs().filter(([, parameter]) => !parameter[0].querySelector('ext'));
|
|
205
206
|
if (duplicatedArgs.length > 0) {
|
|
206
|
-
errors.push(...duplicatedArgs.flatMap(([, args]) => args).map(arg =>
|
|
207
|
+
errors.push(...duplicatedArgs.flatMap(([, args]) => args).map(arg => {
|
|
208
|
+
const e = (0, lint_1.generateForChild)(arg, rect, 'no-duplicate', 'duplicated parameter');
|
|
209
|
+
e.suggestions = [{ desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' }];
|
|
210
|
+
return e;
|
|
211
|
+
}));
|
|
207
212
|
}
|
|
208
213
|
return errors;
|
|
209
214
|
}
|
package/i18n/zh-hans.json
CHANGED
|
@@ -11,7 +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
|
|
14
|
+
"duplicated id": "重复的id",
|
|
15
15
|
"duplicated image $1 parameter": "重复的图片$1参数",
|
|
16
16
|
"duplicated parameter": "重复参数",
|
|
17
17
|
"extension tag in HTML tag attributes": "HTML标签属性中的扩展标签",
|