wikilint 2.23.0 → 2.25.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/README.md +3 -3
- package/bin/config.js +2 -2
- package/config/default.json +6 -0
- package/config/enwiki.json +2 -2
- package/config/llwiki.json +382 -261
- package/config/moegirl.json +325 -325
- package/coverage/badge.svg +1 -1
- package/dist/base.d.mts +20 -2
- package/dist/base.d.ts +20 -2
- package/dist/bin/config.js +17 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +32 -12
- package/dist/lib/element.d.ts +0 -7
- package/dist/lib/element.js +7 -13
- package/dist/lib/lintConfig.js +0 -3
- package/dist/lib/lsp.d.ts +19 -1
- package/dist/lib/lsp.js +130 -15
- package/dist/lib/text.d.ts +17 -0
- package/dist/lib/text.js +73 -11
- package/dist/lib/title.js +3 -2
- package/dist/mixin/attributesParent.js +1 -1
- package/dist/mixin/elementLike.d.ts +7 -0
- package/dist/mixin/elementLike.js +7 -0
- package/dist/mixin/noEscape.d.ts +4 -0
- package/dist/mixin/noEscape.js +20 -0
- package/dist/parser/commentAndExt.js +7 -8
- package/dist/parser/externalLinks.js +1 -1
- package/dist/parser/hrAndDoubleUnderscore.js +8 -5
- package/dist/src/arg.js +7 -6
- package/dist/src/attribute.d.ts +1 -0
- package/dist/src/attribute.js +18 -13
- package/dist/src/attributes.js +6 -6
- package/dist/src/converter.js +2 -1
- package/dist/src/converterFlags.js +3 -3
- package/dist/src/extLink.js +1 -1
- package/dist/src/gallery.js +9 -8
- package/dist/src/heading.js +158 -98
- package/dist/src/html.js +20 -18
- package/dist/src/imageParameter.js +4 -4
- package/dist/src/imagemap.js +4 -4
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +2 -2
- package/dist/src/link/base.js +9 -22
- package/dist/src/link/file.js +18 -8
- package/dist/src/link/galleryImage.js +2 -2
- package/dist/src/link/index.d.ts +2 -0
- package/dist/src/link/index.js +10 -1
- package/dist/src/link/redirectTarget.js +2 -2
- package/dist/src/magicLink.js +5 -5
- package/dist/src/nested.js +3 -3
- package/dist/src/nowiki/base.js +61 -10
- package/dist/src/nowiki/comment.js +2 -2
- package/dist/src/nowiki/index.js +3 -3
- package/dist/src/nowiki/quote.js +11 -11
- package/dist/src/onlyinclude.js +2 -1
- package/dist/src/paramTag/index.js +2 -2
- package/dist/src/parameter.js +2 -2
- package/dist/src/redirect.js +2 -1
- package/dist/src/table/base.d.ts +2 -0
- package/dist/src/table/base.js +30 -2
- package/dist/src/table/index.js +4 -5
- package/dist/src/table/td.d.ts +1 -0
- package/dist/src/table/td.js +14 -13
- package/dist/src/table/trBase.js +1 -1
- package/dist/src/tagPair/ext.js +2 -2
- package/dist/src/tagPair/include.js +4 -4
- package/dist/src/tagPair/index.js +2 -1
- package/dist/src/transclude.js +13 -18
- package/dist/util/constants.js +2 -1
- package/dist/util/lint.js +91 -2
- package/dist/util/sharable.js +1 -1
- package/dist/util/sharable.mjs +1 -1
- package/dist/util/string.js +11 -10
- package/i18n/en.json +77 -0
- package/i18n/zh-hans.json +71 -56
- package/i18n/zh-hant.json +71 -56
- package/package.json +8 -9
package/dist/src/heading.js
CHANGED
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
2
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
38
|
};
|
|
@@ -7,6 +41,7 @@ exports.HeadingToken = void 0;
|
|
|
7
41
|
const lint_1 = require("../util/lint");
|
|
8
42
|
const debug_1 = require("../util/debug");
|
|
9
43
|
const rect_1 = require("../lib/rect");
|
|
44
|
+
const noEscape_1 = require("../mixin/noEscape");
|
|
10
45
|
const index_1 = __importDefault(require("../index"));
|
|
11
46
|
const index_2 = require("./index");
|
|
12
47
|
const syntax_1 = require("./syntax");
|
|
@@ -16,115 +51,140 @@ const syntax_1 = require("./syntax");
|
|
|
16
51
|
* 章节标题
|
|
17
52
|
* @classdesc `{childNodes: [Token, SyntaxToken]}`
|
|
18
53
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
super(undefined, config, accum);
|
|
34
|
-
this.#level = level;
|
|
35
|
-
const token = new index_2.Token(input[0], config, accum);
|
|
36
|
-
token.type = 'heading-title';
|
|
37
|
-
token.setAttribute('stage', 2);
|
|
38
|
-
const trail = new syntax_1.SyntaxToken(input[1], 'heading-trail', config, accum);
|
|
39
|
-
this.append(token, trail);
|
|
40
|
-
}
|
|
41
|
-
/** 标题格式的等号 */
|
|
42
|
-
#getEquals() {
|
|
43
|
-
return '='.repeat(this.level);
|
|
44
|
-
}
|
|
45
|
-
/** @private */
|
|
46
|
-
toString(skip) {
|
|
47
|
-
const equals = this.#getEquals();
|
|
48
|
-
return equals + this.firstChild.toString(skip) + equals + this.lastChild.toString(skip);
|
|
49
|
-
}
|
|
50
|
-
/** @private */
|
|
51
|
-
text() {
|
|
52
|
-
const equals = this.#getEquals();
|
|
53
|
-
return equals + this.firstChild.text() + equals;
|
|
54
|
-
}
|
|
55
|
-
/** @private */
|
|
56
|
-
getAttribute(key) {
|
|
57
|
-
return key === 'padding' ? this.level : super.getAttribute(key);
|
|
58
|
-
}
|
|
59
|
-
/** @private */
|
|
60
|
-
getGaps() {
|
|
61
|
-
return this.level;
|
|
62
|
-
}
|
|
63
|
-
/** @private */
|
|
64
|
-
lint(start = this.getAbsoluteIndex(), re) {
|
|
65
|
-
const errors = super.lint(start, re), { firstChild, level } = this, innerStr = firstChild.toString(), unbalancedStart = innerStr.startsWith('='), unbalanced = unbalancedStart || innerStr.endsWith('='), rect = new rect_1.BoundingRect(this, start), s = this.inHtmlAttrs(), rules = ['h1', 'unbalanced-header', 'format-leakage'], severities = rules.map(rule => index_1.default.lintConfig.getSeverity(rule, 'apostrophe'));
|
|
66
|
-
if (severities[0] && this.level === 1) {
|
|
67
|
-
const e = (0, lint_1.generateForChild)(firstChild, rect, rules[0], '<h1>', severities[0]);
|
|
68
|
-
if (!unbalanced) {
|
|
69
|
-
e.suggestions = [{ desc: 'h2', range: [e.startIndex, e.endIndex], text: `=${innerStr}=` }];
|
|
70
|
-
}
|
|
71
|
-
errors.push(e);
|
|
54
|
+
let HeadingToken = (() => {
|
|
55
|
+
let _classDecorators = [noEscape_1.noEscape];
|
|
56
|
+
let _classDescriptor;
|
|
57
|
+
let _classExtraInitializers = [];
|
|
58
|
+
let _classThis;
|
|
59
|
+
let _classSuper = index_2.Token;
|
|
60
|
+
var HeadingToken = class extends _classSuper {
|
|
61
|
+
static { _classThis = this; }
|
|
62
|
+
static {
|
|
63
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
64
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
65
|
+
HeadingToken = _classThis = _classDescriptor.value;
|
|
66
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
67
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
72
68
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
69
|
+
#level;
|
|
70
|
+
get type() {
|
|
71
|
+
return 'heading';
|
|
72
|
+
}
|
|
73
|
+
/** level of the heading / 标题层级 */
|
|
74
|
+
get level() {
|
|
75
|
+
return this.#level;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* @param level 标题层级
|
|
79
|
+
* @param input 标题文字
|
|
80
|
+
*/
|
|
81
|
+
constructor(level, input, config, accum = []) {
|
|
82
|
+
super(undefined, config, accum);
|
|
83
|
+
this.#level = level;
|
|
84
|
+
const token = new index_2.Token(input[0], config, accum);
|
|
85
|
+
token.type = 'heading-title';
|
|
86
|
+
token.setAttribute('stage', 2);
|
|
87
|
+
const trail = new syntax_1.SyntaxToken(input[1], 'heading-trail', config, accum);
|
|
88
|
+
this.append(token, trail);
|
|
89
|
+
}
|
|
90
|
+
/** 标题格式的等号 */
|
|
91
|
+
#getEquals() {
|
|
92
|
+
return '='.repeat(this.level);
|
|
93
|
+
}
|
|
94
|
+
/** @private */
|
|
95
|
+
toString(skip) {
|
|
96
|
+
const equals = this.#getEquals();
|
|
97
|
+
return equals + this.firstChild.toString(skip) + equals + this.lastChild.toString(skip);
|
|
98
|
+
}
|
|
99
|
+
/** @private */
|
|
100
|
+
text() {
|
|
101
|
+
const equals = this.#getEquals();
|
|
102
|
+
return equals + this.firstChild.text() + equals;
|
|
103
|
+
}
|
|
104
|
+
/** @private */
|
|
105
|
+
getAttribute(key) {
|
|
106
|
+
return key === 'padding' ? this.level : super.getAttribute(key);
|
|
107
|
+
}
|
|
108
|
+
/** @private */
|
|
109
|
+
getGaps() {
|
|
110
|
+
return this.level;
|
|
111
|
+
}
|
|
112
|
+
/** @private */
|
|
113
|
+
lint(start = this.getAbsoluteIndex(), re) {
|
|
114
|
+
const errors = super.lint(start, re), { firstChild, level } = this, innerStr = firstChild.toString(), unbalancedStart = innerStr.startsWith('='), unbalanced = unbalancedStart || innerStr.endsWith('='), rect = new rect_1.BoundingRect(this, start), s = this.inHtmlAttrs(), rules = ['h1', 'unbalanced-header', 'format-leakage'], severities = rules.map(rule => index_1.default.lintConfig.getSeverity(rule, 'apostrophe'));
|
|
115
|
+
if (severities[0] && this.level === 1) {
|
|
116
|
+
const e = (0, lint_1.generateForChild)(firstChild, rect, rules[0], '<h1>', severities[0]);
|
|
117
|
+
if (!unbalanced) {
|
|
118
|
+
e.suggestions = [(0, lint_1.fixBy)(e, 'h2', `=${innerStr}=`)];
|
|
83
119
|
}
|
|
120
|
+
errors.push(e);
|
|
84
121
|
}
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
e.suggestions.push({ desc: `h${newLevel}`, range: [e.startIndex, e.startIndex], text: extra });
|
|
122
|
+
if (severities[1] && unbalanced) {
|
|
123
|
+
const msg = index_1.default.msg('unbalanced-in-section-header', '"="'), e = (0, lint_1.generateForChild)(firstChild, rect, rules[1], msg, severities[1]);
|
|
124
|
+
if (innerStr === '=') {
|
|
125
|
+
//
|
|
90
126
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'section header in HTML tag attributes', severity));
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
if (severities[2]) {
|
|
101
|
-
const rootStr = this.getRootNode().toString(), quotes = firstChild.childNodes.filter((0, debug_1.isToken)('quote')), boldQuotes = quotes.filter(({ bold }) => bold), italicQuotes = quotes.filter(({ italic }) => italic);
|
|
102
|
-
if (boldQuotes.length % 2) {
|
|
103
|
-
const e = (0, lint_1.generateForChild)(boldQuotes[boldQuotes.length - 1], {
|
|
104
|
-
...rect, // eslint-disable-line @typescript-eslint/no-misused-spread
|
|
105
|
-
start: start + level,
|
|
106
|
-
left: rect.left + level,
|
|
107
|
-
}, rules[2], index_1.default.msg('unbalanced $1 in a section header', 'bold apostrophes'), severities[2]), end = start + level + innerStr.length;
|
|
108
|
-
if (rootStr.slice(e.endIndex, end).trim()) {
|
|
109
|
-
e.suggestions = [{ desc: 'close', range: [end, end], text: `'''` }];
|
|
127
|
+
else if (unbalancedStart) {
|
|
128
|
+
const [extra] = /^=+/u.exec(innerStr), newLevel = level + extra.length;
|
|
129
|
+
e.suggestions = [{ desc: `h${level}`, range: [e.startIndex, e.startIndex + extra.length], text: '' }];
|
|
130
|
+
if (newLevel < 7) {
|
|
131
|
+
e.suggestions.push({ desc: `h${newLevel}`, range: [e.endIndex, e.endIndex], text: extra });
|
|
132
|
+
}
|
|
110
133
|
}
|
|
111
134
|
else {
|
|
112
|
-
|
|
135
|
+
const extra = /[^=](=+)$/u.exec(innerStr)[1], newLevel = level + extra.length;
|
|
136
|
+
e.suggestions = [{ desc: `h${level}`, range: [e.endIndex - extra.length, e.endIndex], text: '' }];
|
|
137
|
+
if (newLevel < 7) {
|
|
138
|
+
e.suggestions.push({ desc: `h${newLevel}`, range: [e.startIndex, e.startIndex], text: extra });
|
|
139
|
+
}
|
|
113
140
|
}
|
|
114
141
|
errors.push(e);
|
|
115
142
|
}
|
|
116
|
-
if (
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
119
|
-
|
|
143
|
+
if (s) {
|
|
144
|
+
const rule = 'parsing-order', severity = index_1.default.lintConfig.getSeverity(rule, s === 2 ? 'heading' : 'templateInTable');
|
|
145
|
+
if (severity) {
|
|
146
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'header-in-html', severity));
|
|
120
147
|
}
|
|
121
|
-
|
|
122
|
-
|
|
148
|
+
}
|
|
149
|
+
if (severities[2]) {
|
|
150
|
+
const rootStr = this.getRootNode().toString(), quotes = firstChild.childNodes.filter((0, debug_1.isToken)('quote')), boldQuotes = quotes.filter(({ bold }) => bold), italicQuotes = quotes.filter(({ italic }) => italic);
|
|
151
|
+
if (boldQuotes.length % 2) {
|
|
152
|
+
const e = (0, lint_1.generateForChild)(boldQuotes[boldQuotes.length - 1], {
|
|
153
|
+
...rect, // eslint-disable-line @typescript-eslint/no-misused-spread
|
|
154
|
+
start: start + level,
|
|
155
|
+
left: rect.left + level,
|
|
156
|
+
}, rules[2], index_1.default.msg('unbalanced-in-section-header', 'bold-apostrophes'), severities[2]), end = start + level + innerStr.length, remove = (0, lint_1.fixByRemove)(e);
|
|
157
|
+
if (rootStr.slice(e.endIndex, end).trim()) {
|
|
158
|
+
e.suggestions = [
|
|
159
|
+
remove,
|
|
160
|
+
(0, lint_1.fixByClose)(end, `'''`),
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
else if (boldQuotes.length === 1 && italicQuotes.length === 0) {
|
|
164
|
+
e.fix = remove;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
e.suggestions = [remove];
|
|
168
|
+
}
|
|
169
|
+
errors.push(e);
|
|
170
|
+
}
|
|
171
|
+
if (italicQuotes.length % 2) {
|
|
172
|
+
const e = (0, lint_1.generateForChild)(italicQuotes[italicQuotes.length - 1], { start: start + level }, rules[2], index_1.default.msg('unbalanced-in-section-header', 'italic-apostrophes'), severities[2]), end = start + level + innerStr.length;
|
|
173
|
+
if (rootStr.slice(e.endIndex, end).trim()) {
|
|
174
|
+
e.suggestions = [(0, lint_1.fixByClose)(end, `''`)];
|
|
175
|
+
}
|
|
176
|
+
else if (italicQuotes.length === 1 && boldQuotes.length === 0) {
|
|
177
|
+
e.fix = (0, lint_1.fixByRemove)(e);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
e.suggestions = [(0, lint_1.fixByRemove)(e)];
|
|
181
|
+
}
|
|
182
|
+
errors.push(e);
|
|
123
183
|
}
|
|
124
|
-
errors.push(e);
|
|
125
184
|
}
|
|
185
|
+
return errors;
|
|
126
186
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
187
|
+
};
|
|
188
|
+
return HeadingToken = _classThis;
|
|
189
|
+
})();
|
|
130
190
|
exports.HeadingToken = HeadingToken;
|
package/dist/src/html.js
CHANGED
|
@@ -148,63 +148,65 @@ let HtmlToken = (() => {
|
|
|
148
148
|
rule = 'parsing-order';
|
|
149
149
|
s = severity && index_1.default.lintConfig.getSeverity(rule, severity === 2 ? 'html' : 'templateInTable');
|
|
150
150
|
if (s) {
|
|
151
|
-
const e = (0, lint_1.generateForSelf)(this, rect, rule, '
|
|
151
|
+
const e = (0, lint_1.generateForSelf)(this, rect, rule, 'html-in-table', s);
|
|
152
152
|
if (severity === 2) {
|
|
153
|
-
e.
|
|
153
|
+
e.suggestions = [(0, lint_1.fixByRemove)(e)];
|
|
154
154
|
}
|
|
155
155
|
errors.push(e);
|
|
156
156
|
}
|
|
157
157
|
rule = 'obsolete-tag';
|
|
158
158
|
s = index_1.default.lintConfig.getSeverity(rule, name);
|
|
159
159
|
if (s && obsoleteTags.has(name)) {
|
|
160
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'obsolete
|
|
160
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'obsolete-tag', s));
|
|
161
161
|
}
|
|
162
162
|
rule = 'bold-header';
|
|
163
163
|
s = index_1.default.lintConfig.getSeverity(rule, name);
|
|
164
|
-
if (s && (name === 'b' || name === 'strong')
|
|
165
|
-
|
|
164
|
+
if (s && (name === 'b' || name === 'strong')
|
|
165
|
+
&& this.closest('heading-title,ext')?.type === 'heading-title') {
|
|
166
|
+
const e = (0, lint_1.generateForSelf)(this, rect, rule, 'bold-in-header', s);
|
|
167
|
+
e.suggestions = [(0, lint_1.fixByRemove)(e)];
|
|
168
|
+
errors.push(e);
|
|
166
169
|
}
|
|
167
170
|
const { html: [, flexibleTags, voidTags] } = this.getAttribute('config'), isVoid = voidTags.includes(name), isFlexible = flexibleTags.includes(name), isNormal = !isVoid && !isFlexible;
|
|
168
171
|
rule = 'unmatched-tag';
|
|
169
172
|
if (closing && (selfClosing || isVoid) || selfClosing && isNormal) {
|
|
170
173
|
s = index_1.default.lintConfig.getSeverity(rule, closing ? 'both' : 'selfClosing');
|
|
171
174
|
if (s) {
|
|
172
|
-
const
|
|
173
|
-
desc: 'no
|
|
174
|
-
range: [
|
|
175
|
+
const e = (0, lint_1.generateForSelf)(this, rect, rule, closing ? 'closing-and-self-closing' : 'invalid-self-closing', s), open = (0, lint_1.fixByOpen)(start), noSelfClosing = {
|
|
176
|
+
desc: index_1.default.msg('no-self-closing'),
|
|
177
|
+
range: [e.endIndex - 2, e.endIndex - 1],
|
|
175
178
|
text: '',
|
|
176
179
|
};
|
|
177
180
|
if (isFlexible) {
|
|
178
|
-
|
|
181
|
+
e.suggestions = [open, noSelfClosing];
|
|
179
182
|
}
|
|
180
183
|
else if (closing) {
|
|
181
|
-
|
|
184
|
+
e.fix = isVoid ? open : noSelfClosing;
|
|
182
185
|
}
|
|
183
186
|
else {
|
|
184
|
-
|
|
187
|
+
e.suggestions = [
|
|
185
188
|
noSelfClosing,
|
|
186
|
-
|
|
189
|
+
(0, lint_1.fixByClose)(e.endIndex, `></${name}>`, -2),
|
|
187
190
|
];
|
|
188
191
|
}
|
|
189
|
-
errors.push(
|
|
192
|
+
errors.push(e);
|
|
190
193
|
}
|
|
191
194
|
}
|
|
192
195
|
else if (!this.findMatchingTag()) {
|
|
193
|
-
const error = (0, lint_1.generateForSelf)(this, rect, rule, closing ? 'unmatched
|
|
196
|
+
const error = (0, lint_1.generateForSelf)(this, rect, rule, closing ? 'unmatched-closing' : 'unclosed-tag'), ancestor = this.closest('magic-word');
|
|
194
197
|
if (ancestor && magicWords.has(ancestor.name)) {
|
|
195
198
|
s = index_1.default.lintConfig.getSeverity(rule, 'conditional');
|
|
196
199
|
}
|
|
197
200
|
else if (closing) {
|
|
198
201
|
s = index_1.default.lintConfig.getSeverity(rule, 'closing');
|
|
199
|
-
error.suggestions = [
|
|
202
|
+
error.suggestions = [(0, lint_1.fixByRemove)(error)];
|
|
200
203
|
}
|
|
201
204
|
else {
|
|
202
205
|
s = index_1.default.lintConfig.getSeverity(rule, 'opening');
|
|
203
206
|
const childNodes = parentNode?.childNodes;
|
|
204
207
|
if (formattingTags.has(name)) {
|
|
205
|
-
if (childNodes?.slice(0, childNodes.indexOf(this))
|
|
206
|
-
.
|
|
207
|
-
error.suggestions = [{ desc: 'close', range: [start + 1, start + 1], text: '/' }];
|
|
208
|
+
if (childNodes?.slice(0, childNodes.indexOf(this)).some(tag => tag.type === 'html' && tag.name === name && !tag.findMatchingTag())) {
|
|
209
|
+
error.suggestions = [(0, lint_1.fixByClose)(start + 1, '/')];
|
|
208
210
|
}
|
|
209
211
|
if (this.closest('heading-title')) {
|
|
210
212
|
error.rule = 'format-leakage';
|
|
@@ -122,16 +122,16 @@ class ImageParameterToken extends index_2.Token {
|
|
|
122
122
|
if (name === 'invalid') {
|
|
123
123
|
const rule = 'invalid-gallery', s = index_1.default.lintConfig.getSeverity(rule, 'parameter');
|
|
124
124
|
if (s) {
|
|
125
|
-
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'invalid
|
|
126
|
-
e.fix =
|
|
125
|
+
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'invalid-image-parameter', s);
|
|
126
|
+
e.fix = (0, lint_1.fixByRemove)(e, -1);
|
|
127
127
|
errors.push(e);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
else if (typeof link === 'object' && link.encoded) {
|
|
131
131
|
const rule = 'url-encoding', s = index_1.default.lintConfig.getSeverity(rule, 'file');
|
|
132
132
|
if (s) {
|
|
133
|
-
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'unnecessary
|
|
134
|
-
e.
|
|
133
|
+
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'unnecessary-encoding', s);
|
|
134
|
+
e.fix = (0, lint_1.fixByDecode)(e, this);
|
|
135
135
|
errors.push(e);
|
|
136
136
|
}
|
|
137
137
|
}
|
package/dist/src/imagemap.js
CHANGED
|
@@ -140,16 +140,16 @@ let ImagemapToken = (() => {
|
|
|
140
140
|
const str = child.toString().trim();
|
|
141
141
|
return child.is('noinclude') && str && !str.startsWith('#');
|
|
142
142
|
}).map(child => {
|
|
143
|
-
const e = (0, lint_1.generateForChild)(child, rect, rule, 'invalid
|
|
143
|
+
const e = (0, lint_1.generateForChild)(child, rect, rule, 'invalid-imagemap-link', s);
|
|
144
144
|
e.suggestions = [
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
(0, lint_1.fixByRemove)(e, -1),
|
|
146
|
+
(0, lint_1.fixBy)(e, 'comment', '# '),
|
|
147
147
|
];
|
|
148
148
|
return e;
|
|
149
149
|
}));
|
|
150
150
|
}
|
|
151
151
|
else {
|
|
152
|
-
errors.push((0, lint_1.generateForSelf)(this, rect, rule, '
|
|
152
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'imagemap-without-image', s));
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
return errors;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ import { AstText } from '../lib/text';
|
|
|
4
4
|
import type { LintError, TokenTypes } from '../base';
|
|
5
5
|
import type { Title, TitleOptions } from '../lib/title';
|
|
6
6
|
import type { AstNodes } from '../internal';
|
|
7
|
+
declare type ExtendedLintError = LintError[] & {
|
|
8
|
+
output?: string;
|
|
9
|
+
};
|
|
7
10
|
/**
|
|
8
11
|
* base class for all tokens
|
|
9
12
|
*
|
|
@@ -24,3 +27,4 @@ export declare class Token extends AstElement {
|
|
|
24
27
|
insertAt(child: string, i?: number): AstText;
|
|
25
28
|
insertAt<T extends AstNodes>(child: T, i?: number): T;
|
|
26
29
|
}
|
|
30
|
+
export {};
|
package/dist/src/index.js
CHANGED
|
@@ -396,11 +396,11 @@ class Token extends element_1.AstElement {
|
|
|
396
396
|
}
|
|
397
397
|
for (const [key, value] of record) {
|
|
398
398
|
if (value.size > 1 && !key.startsWith('#mw-customcollapsible-')) {
|
|
399
|
-
const isCat = !key.startsWith('#'), msg = `
|
|
399
|
+
const isCat = !key.startsWith('#'), msg = `duplicate-${isCat ? 'category' : 'id'}`, severity = s[isCat ? 0 : 1];
|
|
400
400
|
errors.push(...[...value].map(cat => {
|
|
401
401
|
const e = (0, lint_1.generateForSelf)(cat, { start: cat.getAbsoluteIndex() }, r, msg, severity);
|
|
402
402
|
if (isCat) {
|
|
403
|
-
e.suggestions = [
|
|
403
|
+
e.suggestions = [(0, lint_1.fixByRemove)(e)];
|
|
404
404
|
}
|
|
405
405
|
return e;
|
|
406
406
|
}));
|
package/dist/src/link/base.js
CHANGED
|
@@ -40,9 +40,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
exports.LinkBaseToken = void 0;
|
|
41
41
|
const lint_1 = require("../../util/lint");
|
|
42
42
|
const constants_1 = require("../../util/constants");
|
|
43
|
-
const string_1 = require("../../util/string");
|
|
44
43
|
const rect_1 = require("../../lib/rect");
|
|
45
44
|
const padded_1 = require("../../mixin/padded");
|
|
45
|
+
const noEscape_1 = require("../../mixin/noEscape");
|
|
46
46
|
const index_1 = __importDefault(require("../../index"));
|
|
47
47
|
const index_2 = require("../index");
|
|
48
48
|
const atom_1 = require("../atom");
|
|
@@ -58,7 +58,7 @@ const isLink = (type) => type === 'redirect-target' || type === 'link';
|
|
|
58
58
|
* @classdesc `{childNodes: [AtomToken, ...Token[]]}`
|
|
59
59
|
*/
|
|
60
60
|
let LinkBaseToken = (() => {
|
|
61
|
-
let _classDecorators = [(0, padded_1.padded)('[[')];
|
|
61
|
+
let _classDecorators = [noEscape_1.noEscape, (0, padded_1.padded)('[[')];
|
|
62
62
|
let _classDescriptor;
|
|
63
63
|
let _classExtraInitializers = [];
|
|
64
64
|
let _classThis;
|
|
@@ -140,13 +140,13 @@ let LinkBaseToken = (() => {
|
|
|
140
140
|
const errors = super.lint(start, re), { childNodes: [target, linkText], type } = this, { encoded, fragment } = this.#title, rect = new rect_1.BoundingRect(this, start);
|
|
141
141
|
let rule = 'unknown-page', s = index_1.default.lintConfig.getSeverity(rule);
|
|
142
142
|
if (s && target.childNodes.some(({ type: t }) => t === 'template')) {
|
|
143
|
-
errors.push((0, lint_1.generateForChild)(target, rect, rule, 'template
|
|
143
|
+
errors.push((0, lint_1.generateForChild)(target, rect, rule, 'template-in-link', s));
|
|
144
144
|
}
|
|
145
145
|
rule = 'url-encoding';
|
|
146
146
|
s = index_1.default.lintConfig.getSeverity(rule);
|
|
147
147
|
if (s && encoded) {
|
|
148
|
-
const e = (0, lint_1.generateForChild)(target, rect, rule, 'unnecessary
|
|
149
|
-
e.fix =
|
|
148
|
+
const e = (0, lint_1.generateForChild)(target, rect, rule, 'unnecessary-encoding', s);
|
|
149
|
+
e.fix = (0, lint_1.fixByDecode)(e, target);
|
|
150
150
|
errors.push(e);
|
|
151
151
|
}
|
|
152
152
|
rule = 'pipe-like';
|
|
@@ -154,30 +154,17 @@ let LinkBaseToken = (() => {
|
|
|
154
154
|
if (s && (type === 'link' || type === 'category')) {
|
|
155
155
|
const j = linkText?.childNodes.findIndex(c => c.type === 'text' && c.data.includes('|')), textNode = linkText?.childNodes[j];
|
|
156
156
|
if (textNode) {
|
|
157
|
-
const e = (0, lint_1.generateForChild)(linkText, rect, rule, '
|
|
158
|
-
e.suggestions = [
|
|
159
|
-
{
|
|
160
|
-
desc: 'escape',
|
|
161
|
-
range: [i, i + textNode.data.length],
|
|
162
|
-
text: textNode.data.replace(/\|/gu, '|'),
|
|
163
|
-
},
|
|
164
|
-
];
|
|
157
|
+
const e = (0, lint_1.generateForChild)(linkText, rect, rule, 'pipe-in-link', s), i = e.startIndex + linkText.getRelativeIndex(j);
|
|
158
|
+
e.suggestions = [(0, lint_1.fixByPipe)(i, textNode.data)];
|
|
165
159
|
errors.push(e);
|
|
166
160
|
}
|
|
167
161
|
}
|
|
168
162
|
rule = 'no-ignored';
|
|
169
163
|
s = index_1.default.lintConfig.getSeverity(rule, 'fragment');
|
|
170
164
|
if (s && fragment !== undefined && !isLink(type)) {
|
|
171
|
-
const e = (0, lint_1.generateForChild)(target, rect, rule, 'useless
|
|
165
|
+
const e = (0, lint_1.generateForChild)(target, rect, rule, 'useless-fragment', s), j = target.childNodes.findIndex(c => c.type === 'text' && c.data.includes('#')), textNode = target.childNodes[j];
|
|
172
166
|
if (textNode) {
|
|
173
|
-
e.fix =
|
|
174
|
-
desc: 'remove',
|
|
175
|
-
range: [
|
|
176
|
-
e.startIndex + target.getRelativeIndex(j) + textNode.data.indexOf('#'),
|
|
177
|
-
e.endIndex,
|
|
178
|
-
],
|
|
179
|
-
text: '',
|
|
180
|
-
};
|
|
167
|
+
e.fix = (0, lint_1.fixByRemove)(e, target.getRelativeIndex(j) + textNode.data.indexOf('#'));
|
|
181
168
|
}
|
|
182
169
|
errors.push(e);
|
|
183
170
|
}
|
package/dist/src/link/file.js
CHANGED
|
@@ -81,19 +81,28 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
81
81
|
}
|
|
82
82
|
/** @private */
|
|
83
83
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
84
|
-
const errors = super.lint(start, re), args = filterArgs(this.getAllArgs(), argTypes), keys = [...new Set(args.map(({ name }) => name))], frameKeys = keys.filter(key => frame.has(key)), horizAlignKeys = keys.filter(key => horizAlign.has(key)), vertAlignKeys = keys.filter(key => vertAlign.has(key)), [fr] = frameKeys, unscaled = fr === 'framed' || fr === 'manualthumb', rect = new rect_1.BoundingRect(this, start);
|
|
84
|
+
const errors = super.lint(start, re), args = filterArgs(this.getAllArgs(), argTypes), keys = [...new Set(args.map(({ name }) => name))], frameKeys = keys.filter(key => frame.has(key)), horizAlignKeys = keys.filter(key => horizAlign.has(key)), vertAlignKeys = keys.filter(key => vertAlign.has(key)), [fr] = frameKeys, unscaled = fr === 'framed' || fr === 'manualthumb', rect = new rect_1.BoundingRect(this, start), { extension } = this;
|
|
85
85
|
let rule = 'nested-link', s = index_1.default.lintConfig.getSeverity(rule, 'file');
|
|
86
86
|
if (s
|
|
87
|
+
&& extensions.has(extension)
|
|
87
88
|
&& this.closest('ext-link-text')
|
|
88
89
|
&& this.getValue('link')?.trim() !== '') {
|
|
89
|
-
|
|
90
|
+
const e = (0, lint_1.generateForSelf)(this, rect, rule, 'link-in-extlink', s), link = this.getArg('link');
|
|
91
|
+
if (link) {
|
|
92
|
+
const from = start + link.getRelativeIndex();
|
|
93
|
+
e.fix = { desc: index_1.default.msg('delink'), range: [from, from + link.toString().length], text: 'link=' };
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
e.fix = (0, lint_1.fixByInsert)(e.endIndex - 2, 'delink', '|link=');
|
|
97
|
+
}
|
|
98
|
+
errors.push(e);
|
|
90
99
|
}
|
|
91
100
|
rule = 'invalid-gallery';
|
|
92
101
|
s = index_1.default.lintConfig.getSeverity(rule, 'parameter');
|
|
93
102
|
if (s && unscaled) {
|
|
94
103
|
for (const arg of args.filter(({ name }) => name === 'width')) {
|
|
95
|
-
const e = (0, lint_1.generateForChild)(arg, rect, rule, 'invalid
|
|
96
|
-
e.fix =
|
|
104
|
+
const e = (0, lint_1.generateForChild)(arg, rect, rule, 'invalid-image-parameter', s);
|
|
105
|
+
e.fix = (0, lint_1.fixByRemove)(e, -1);
|
|
97
106
|
errors.push(e);
|
|
98
107
|
}
|
|
99
108
|
}
|
|
@@ -104,7 +113,7 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
104
113
|
return errors;
|
|
105
114
|
}
|
|
106
115
|
rule = 'no-duplicate';
|
|
107
|
-
const
|
|
116
|
+
const severities = ['unknownImageParameter', 'imageParameter'].map(k => index_1.default.lintConfig.getSeverity(rule, k));
|
|
108
117
|
/**
|
|
109
118
|
* 图片参数到语法错误的映射
|
|
110
119
|
* @param tokens 图片参数节点
|
|
@@ -117,8 +126,9 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
117
126
|
if (!s) {
|
|
118
127
|
return false;
|
|
119
128
|
}
|
|
120
|
-
|
|
121
|
-
e
|
|
129
|
+
/** `conflicting-image-parameter`或`duplicate-image-parameter` */
|
|
130
|
+
const e = (0, lint_1.generateForChild)(arg, rect, rule, index_1.default.msg(`${msg}-image-parameter`, p1), s);
|
|
131
|
+
e.suggestions = [(0, lint_1.fixByRemove)(e, -1)];
|
|
122
132
|
return e;
|
|
123
133
|
}).filter((e) => e !== false);
|
|
124
134
|
for (const key of keys) {
|
|
@@ -139,7 +149,7 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
139
149
|
const plainArgs = filterArgs(relevantArgs, transclusion);
|
|
140
150
|
severity = plainArgs.length > 1 && ((arg) => plainArgs.includes(arg));
|
|
141
151
|
}
|
|
142
|
-
errors.push(...generate(relevantArgs, '
|
|
152
|
+
errors.push(...generate(relevantArgs, 'duplicate', key, severity));
|
|
143
153
|
}
|
|
144
154
|
}
|
|
145
155
|
if (frameKeys.length > 1) {
|
|
@@ -103,8 +103,8 @@ let GalleryImageToken = (() => {
|
|
|
103
103
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
104
104
|
const errors = super.lint(start, re), rule = 'invalid-gallery', s = index_1.default.lintConfig.getSeverity(rule, 'image');
|
|
105
105
|
if (s && this.#lint()) {
|
|
106
|
-
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'invalid
|
|
107
|
-
e.suggestions = [
|
|
106
|
+
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'invalid-gallery', s);
|
|
107
|
+
e.suggestions = [(0, lint_1.fixByInsert)(start, 'prefix', 'File:')];
|
|
108
108
|
errors.push(e);
|
|
109
109
|
}
|
|
110
110
|
return errors;
|
package/dist/src/link/index.d.ts
CHANGED
package/dist/src/link/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.LinkToken = void 0;
|
|
7
|
+
const common_1 = require("@bhsd/common");
|
|
7
8
|
const lint_1 = require("../../util/lint");
|
|
8
9
|
const index_1 = __importDefault(require("../../index"));
|
|
9
10
|
const base_1 = require("./base");
|
|
@@ -17,11 +18,19 @@ class LinkToken extends base_1.LinkBaseToken {
|
|
|
17
18
|
get type() {
|
|
18
19
|
return 'link';
|
|
19
20
|
}
|
|
21
|
+
/** link text / 链接显示文字 */
|
|
22
|
+
get innerText() {
|
|
23
|
+
return this.length > 1
|
|
24
|
+
? this.lastChild.text()
|
|
25
|
+
: (0, common_1.rawurldecode)(this.firstChild.text().replace(/^\s*:?/u, ''));
|
|
26
|
+
}
|
|
20
27
|
/** @private */
|
|
21
28
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
22
29
|
const errors = super.lint(start, re), rule = 'nested-link', s = index_1.default.lintConfig.getSeverity(rule);
|
|
23
30
|
if (s && this.closest('ext-link-text')) {
|
|
24
|
-
|
|
31
|
+
const e = (0, lint_1.generateForSelf)(this, { start }, rule, 'link-in-extlink', s);
|
|
32
|
+
e.fix = (0, lint_1.fixBy)(e, 'delink', this.innerText);
|
|
33
|
+
errors.push(e);
|
|
25
34
|
}
|
|
26
35
|
return errors;
|
|
27
36
|
}
|