wikilint 2.9.3 → 2.11.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/.schema.json +5 -0
- package/config/enwiki.json +2 -1
- package/config/llwiki.json +2 -1
- package/config/moegirl.json +2 -1
- package/config/zhwiki.json +2 -1
- package/dist/base.d.ts +3 -2
- package/dist/index.js +21 -18
- package/dist/lib/element.js +2 -2
- package/dist/lib/node.d.ts +6 -1
- package/dist/lib/node.js +7 -0
- package/dist/lib/text.d.ts +0 -2
- package/dist/lib/text.js +8 -10
- package/dist/lib/title.js +4 -9
- package/dist/mixin/hidden.d.ts +1 -0
- package/dist/mixin/hidden.js +2 -2
- package/dist/parser/list.js +23 -6
- package/dist/parser/magicLinks.js +1 -2
- package/dist/parser/table.js +2 -2
- package/dist/src/arg.js +3 -6
- package/dist/src/attribute.js +9 -28
- package/dist/src/attributes.js +2 -3
- package/dist/src/converter.d.ts +1 -1
- package/dist/src/converter.js +4 -3
- package/dist/src/converterFlags.js +4 -7
- package/dist/src/converterRule.js +9 -13
- package/dist/src/extLink.js +3 -3
- package/dist/src/gallery.js +6 -5
- package/dist/src/heading.js +4 -3
- package/dist/src/hidden.js +1 -1
- package/dist/src/html.js +3 -6
- package/dist/src/imageParameter.js +8 -11
- package/dist/src/imagemap.js +2 -2
- package/dist/src/index.js +12 -11
- package/dist/src/link/base.js +15 -13
- package/dist/src/link/file.d.ts +0 -7
- package/dist/src/link/file.js +19 -25
- package/dist/src/link/redirectTarget.d.ts +1 -1
- package/dist/src/link/redirectTarget.js +3 -10
- package/dist/src/magicLink.d.ts +2 -0
- package/dist/src/magicLink.js +37 -53
- package/dist/src/nested.js +1 -1
- package/dist/src/nowiki/comment.js +4 -7
- package/dist/src/nowiki/doubleUnderscore.js +1 -1
- package/dist/src/nowiki/index.js +1 -4
- package/dist/src/nowiki/noinclude.js +5 -1
- package/dist/src/nowiki/quote.js +5 -0
- package/dist/src/onlyinclude.js +2 -2
- package/dist/src/paramTag/index.js +2 -2
- package/dist/src/parameter.js +11 -13
- package/dist/src/redirect.js +3 -3
- package/dist/src/syntax.d.ts +1 -1
- package/dist/src/syntax.js +2 -2
- package/dist/src/table/td.js +2 -2
- package/dist/src/table/trBase.js +3 -4
- package/dist/src/tagPair/ext.js +3 -3
- package/dist/src/tagPair/include.js +5 -1
- package/dist/src/tagPair/index.js +3 -3
- package/dist/src/transclude.js +16 -15
- package/dist/util/html.js +10 -0
- package/dist/util/lint.js +1 -1
- package/dist/util/string.js +11 -3
- package/errors/README +2 -0
- package/i18n/zh-hans.json +1 -1
- package/i18n/zh-hant.json +1 -1
- package/package.json +11 -11
package/dist/src/extLink.js
CHANGED
|
@@ -36,11 +36,11 @@ class ExtLinkToken extends index_2.Token {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
/** @private */
|
|
39
|
-
toString() {
|
|
39
|
+
toString(skip) {
|
|
40
40
|
if (this.length === 1) {
|
|
41
|
-
return `[${super.toString()}${this.#space}]`;
|
|
41
|
+
return `[${super.toString(skip)}${this.#space}]`;
|
|
42
42
|
}
|
|
43
|
-
return `[${super.toString(this.#space)}]`;
|
|
43
|
+
return `[${super.toString(skip, this.#space)}]`;
|
|
44
44
|
}
|
|
45
45
|
/** @private */
|
|
46
46
|
text() {
|
package/dist/src/gallery.js
CHANGED
|
@@ -42,8 +42,8 @@ class GalleryToken extends index_2.Token {
|
|
|
42
42
|
return this.normalizeTitle(file, 6, true, true).valid;
|
|
43
43
|
}
|
|
44
44
|
/** @private */
|
|
45
|
-
toString() {
|
|
46
|
-
return super.toString('\n');
|
|
45
|
+
toString(skip) {
|
|
46
|
+
return super.toString(skip, '\n');
|
|
47
47
|
}
|
|
48
48
|
/** @private */
|
|
49
49
|
text() {
|
|
@@ -59,12 +59,13 @@ class GalleryToken extends index_2.Token {
|
|
|
59
59
|
for (let i = 0; i < this.length; i++) {
|
|
60
60
|
const child = this.childNodes[i], str = child.toString(), { length } = str, trimmed = str.trim(), startLine = top + i, startCol = i ? 0 : left;
|
|
61
61
|
if (child.type === 'noinclude' && trimmed && !/^<!--.*-->$/u.test(trimmed)) {
|
|
62
|
+
const endIndex = start + length;
|
|
62
63
|
errors.push({
|
|
63
64
|
rule: 'no-ignored',
|
|
64
65
|
message: index_1.default.msg('invalid content in <$1>', 'gallery'),
|
|
65
66
|
severity: trimmed.startsWith('|') ? 'warning' : 'error',
|
|
66
67
|
startIndex: start,
|
|
67
|
-
endIndex
|
|
68
|
+
endIndex,
|
|
68
69
|
startLine,
|
|
69
70
|
endLine: startLine,
|
|
70
71
|
startCol,
|
|
@@ -72,12 +73,12 @@ class GalleryToken extends index_2.Token {
|
|
|
72
73
|
suggestions: [
|
|
73
74
|
{
|
|
74
75
|
desc: 'remove',
|
|
75
|
-
range: [start,
|
|
76
|
+
range: [start, endIndex],
|
|
76
77
|
text: '',
|
|
77
78
|
},
|
|
78
79
|
{
|
|
79
80
|
desc: 'comment',
|
|
80
|
-
range: [start,
|
|
81
|
+
range: [start, endIndex],
|
|
81
82
|
text: `<!--${str}-->`,
|
|
82
83
|
},
|
|
83
84
|
],
|
package/dist/src/heading.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.HeadingToken = void 0;
|
|
4
4
|
const lint_1 = require("../util/lint");
|
|
5
5
|
const rect_1 = require("../lib/rect");
|
|
6
|
+
const debug_1 = require("../util/debug");
|
|
6
7
|
const index_1 = require("../index");
|
|
7
8
|
const index_2 = require("./index");
|
|
8
9
|
const syntax_1 = require("./syntax");
|
|
@@ -37,9 +38,9 @@ class HeadingToken extends index_2.Token {
|
|
|
37
38
|
this.append(token, trail);
|
|
38
39
|
}
|
|
39
40
|
/** @private */
|
|
40
|
-
toString() {
|
|
41
|
+
toString(skip) {
|
|
41
42
|
const equals = this.#equals;
|
|
42
|
-
return equals + this.firstChild.toString() + equals + this.lastChild.toString();
|
|
43
|
+
return equals + this.firstChild.toString(skip) + equals + this.lastChild.toString(skip);
|
|
43
44
|
}
|
|
44
45
|
/** @private */
|
|
45
46
|
text() {
|
|
@@ -56,7 +57,7 @@ class HeadingToken extends index_2.Token {
|
|
|
56
57
|
}
|
|
57
58
|
/** @private */
|
|
58
59
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
59
|
-
const errors = super.lint(start, re), { firstChild, level } = this, innerStr = firstChild.toString(), quotes = firstChild.childNodes.filter((
|
|
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
61
|
if (this.level === 1) {
|
|
61
62
|
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'h1', '<h1>'));
|
|
62
63
|
}
|
package/dist/src/hidden.js
CHANGED
|
@@ -39,7 +39,7 @@ const hidden_1 = require("../mixin/hidden");
|
|
|
39
39
|
const index_1 = require("./index");
|
|
40
40
|
/** 不可见的节点 */
|
|
41
41
|
let HiddenToken = (() => {
|
|
42
|
-
let _classDecorators = [(0, hidden_1.hiddenToken)(
|
|
42
|
+
let _classDecorators = [(0, hidden_1.hiddenToken)()];
|
|
43
43
|
let _classDescriptor;
|
|
44
44
|
let _classExtraInitializers = [];
|
|
45
45
|
let _classThis;
|
package/dist/src/html.js
CHANGED
|
@@ -66,8 +66,8 @@ class HtmlToken extends index_1.Token {
|
|
|
66
66
|
this.#tag = name;
|
|
67
67
|
}
|
|
68
68
|
/** @private */
|
|
69
|
-
toString() {
|
|
70
|
-
return `<${this.closing ? '/' : ''}${this.#tag}${super.toString()}${this.#selfClosing ? '/' : ''}>`;
|
|
69
|
+
toString(skip) {
|
|
70
|
+
return `<${this.closing ? '/' : ''}${this.#tag}${super.toString(skip)}${this.#selfClosing ? '/' : ''}>`;
|
|
71
71
|
}
|
|
72
72
|
/** @private */
|
|
73
73
|
text() {
|
|
@@ -125,10 +125,7 @@ class HtmlToken extends index_1.Token {
|
|
|
125
125
|
else if (msg === 'tag that is both closing and self-closing') {
|
|
126
126
|
const { html: [, , voidTags] } = this.getAttribute('config');
|
|
127
127
|
if (voidTags.includes(this.name)) {
|
|
128
|
-
error.fix = {
|
|
129
|
-
range: [start + 1, start + 2],
|
|
130
|
-
text: '',
|
|
131
|
-
};
|
|
128
|
+
error.fix = { range: [start + 1, start + 2], text: '' };
|
|
132
129
|
}
|
|
133
130
|
}
|
|
134
131
|
errors.push(error);
|
|
@@ -8,7 +8,7 @@ const index_2 = require("./index");
|
|
|
8
8
|
exports.galleryParams = new Set(['alt', 'link', 'lang', 'page', 'caption']);
|
|
9
9
|
function validate(key, val, config, halfParsed, ext) {
|
|
10
10
|
val = val.trim();
|
|
11
|
-
let value = val.replace(/\0\d+t\x7F/gu, '').trim();
|
|
11
|
+
let value = val.replace(key === 'link' ? /\0\d+[tq]\x7F/gu : /\0\d+t\x7F/gu, '').trim();
|
|
12
12
|
switch (key) {
|
|
13
13
|
case 'width':
|
|
14
14
|
return !value || /^(?:\d+x?|\d*x\d+)(?:\s*px)?$/u.test(value);
|
|
@@ -16,9 +16,9 @@ function validate(key, val, config, halfParsed, ext) {
|
|
|
16
16
|
if (!value) {
|
|
17
17
|
return val;
|
|
18
18
|
}
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
21
|
-
return val;
|
|
19
|
+
const re1 = new RegExp(String.raw `^(?:${config.protocol}|//|\0\d+m\x7F)`, 'iu'), re2 = new RegExp(String.raw `^(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\d+m\x7F)${string_1.extUrlChar}$`, 'iu');
|
|
20
|
+
if (re1.test(value)) {
|
|
21
|
+
return re2.test(value) && val;
|
|
22
22
|
}
|
|
23
23
|
else if (value.startsWith('[[') && value.endsWith(']]')) {
|
|
24
24
|
value = value.slice(2, -2);
|
|
@@ -86,8 +86,8 @@ class ImageParameterToken extends index_2.Token {
|
|
|
86
86
|
super.afterBuild();
|
|
87
87
|
}
|
|
88
88
|
/** @private */
|
|
89
|
-
toString() {
|
|
90
|
-
return this.#syntax ? this.#syntax.replace('$1', super.toString()) : super.toString();
|
|
89
|
+
toString(skip) {
|
|
90
|
+
return this.#syntax ? this.#syntax.replace('$1', super.toString(skip)) : super.toString(skip);
|
|
91
91
|
}
|
|
92
92
|
/** @private */
|
|
93
93
|
text() {
|
|
@@ -106,11 +106,8 @@ class ImageParameterToken extends index_2.Token {
|
|
|
106
106
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
107
107
|
const errors = super.lint(start, re), { link, name } = this;
|
|
108
108
|
if (name === 'invalid') {
|
|
109
|
-
const e = (0, lint_1.generateForSelf)(this, { start }, 'invalid-gallery', 'invalid
|
|
110
|
-
e.fix = {
|
|
111
|
-
range: [start, start + e.endIndex],
|
|
112
|
-
text: '',
|
|
113
|
-
};
|
|
109
|
+
const e = (0, lint_1.generateForSelf)(this, { start }, 'invalid-gallery', 'invalid image parameter');
|
|
110
|
+
e.fix = { range: [start - 1, e.endIndex], text: '' };
|
|
114
111
|
errors.push(e);
|
|
115
112
|
}
|
|
116
113
|
else if (typeof link === 'object' && link.encoded) {
|
package/dist/src/imagemap.js
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -80,7 +80,7 @@ class Token extends element_1.AstElement {
|
|
|
80
80
|
}
|
|
81
81
|
/** @private */
|
|
82
82
|
parseOnce(n = this.#stage, include = false) {
|
|
83
|
-
if (n < this.#stage || !this.getAttribute('plain')
|
|
83
|
+
if (n < this.#stage || this.length === 0 || !this.getAttribute('plain')) {
|
|
84
84
|
return this;
|
|
85
85
|
}
|
|
86
86
|
else if (this.#stage >= constants_1.MAX_STAGE) {
|
|
@@ -89,7 +89,7 @@ class Token extends element_1.AstElement {
|
|
|
89
89
|
switch (n) {
|
|
90
90
|
case 0:
|
|
91
91
|
if (this.type === 'root') {
|
|
92
|
-
this.#accum.
|
|
92
|
+
this.#accum.pop();
|
|
93
93
|
const isRedirect = this.#parseRedirect();
|
|
94
94
|
include &&= !isRedirect;
|
|
95
95
|
}
|
|
@@ -129,7 +129,7 @@ class Token extends element_1.AstElement {
|
|
|
129
129
|
}
|
|
130
130
|
if (this.type === 'root') {
|
|
131
131
|
for (const token of this.#accum) {
|
|
132
|
-
token
|
|
132
|
+
token?.parseOnce(n, include); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
this.#stage++;
|
|
@@ -163,7 +163,7 @@ class Token extends element_1.AstElement {
|
|
|
163
163
|
this.normalize();
|
|
164
164
|
if (this.type === 'root') {
|
|
165
165
|
for (const token of this.#accum) {
|
|
166
|
-
token
|
|
166
|
+
token?.build(); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
}
|
|
@@ -172,7 +172,7 @@ class Token extends element_1.AstElement {
|
|
|
172
172
|
afterBuild() {
|
|
173
173
|
if (this.type === 'root') {
|
|
174
174
|
for (const token of this.#accum) {
|
|
175
|
-
token
|
|
175
|
+
token?.afterBuild(); // eslint-disable-line @typescript-eslint/no-unnecessary-condition
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
this.#built = true;
|
|
@@ -275,10 +275,10 @@ class Token extends element_1.AstElement {
|
|
|
275
275
|
return;
|
|
276
276
|
}
|
|
277
277
|
const { parseList } = require('../parser/list');
|
|
278
|
-
const lines = this.firstChild.toString().split('\n');
|
|
278
|
+
const lines = this.firstChild.toString().split('\n'), state = { lastPrefix: '' };
|
|
279
279
|
let i = this.type === 'root' || this.type === 'ext-inner' && this.name === 'poem' ? 0 : 1;
|
|
280
280
|
for (; i < lines.length; i++) {
|
|
281
|
-
lines[i] = parseList(lines[i], this.#config, this.#accum);
|
|
281
|
+
lines[i] = parseList(lines[i], state, this.#config, this.#accum);
|
|
282
282
|
}
|
|
283
283
|
this.setText(lines.join('\n'));
|
|
284
284
|
}
|
|
@@ -401,14 +401,15 @@ class Token extends element_1.AstElement {
|
|
|
401
401
|
return errors;
|
|
402
402
|
}
|
|
403
403
|
/** @private */
|
|
404
|
-
toString(separator) {
|
|
404
|
+
toString(skip, separator) {
|
|
405
405
|
const { rev } = debug_1.Shadow, root = this.getRootNode();
|
|
406
|
-
if (
|
|
406
|
+
if (!skip
|
|
407
|
+
&& root.type === 'root'
|
|
407
408
|
&& root.#built) {
|
|
408
|
-
this.#string ??= [rev, super.toString(separator)];
|
|
409
|
+
this.#string ??= [rev, super.toString(false, separator)];
|
|
409
410
|
return this.#string[1];
|
|
410
411
|
}
|
|
411
|
-
return super.toString(separator);
|
|
412
|
+
return super.toString(skip, separator);
|
|
412
413
|
}
|
|
413
414
|
}
|
|
414
415
|
exports.Token = Token;
|
package/dist/src/link/base.js
CHANGED
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LinkBaseToken = void 0;
|
|
4
4
|
const lint_1 = require("../../util/lint");
|
|
5
|
-
const rect_1 = require("../../lib/rect");
|
|
6
5
|
const constants_1 = require("../../util/constants");
|
|
6
|
+
const rect_1 = require("../../lib/rect");
|
|
7
7
|
const index_1 = require("../../index");
|
|
8
8
|
const index_2 = require("../index");
|
|
9
9
|
const atom_1 = require("../atom");
|
|
10
|
+
/**
|
|
11
|
+
* 是否为普通内链
|
|
12
|
+
* @param type 节点类型
|
|
13
|
+
*/
|
|
14
|
+
const isLink = (type) => type === 'redirect-target' || type === 'link';
|
|
10
15
|
/**
|
|
11
16
|
* 内链
|
|
12
17
|
* @classdesc `{childNodes: [AtomToken, ...Token]}`
|
|
@@ -53,8 +58,8 @@ class LinkBaseToken extends index_2.Token {
|
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
60
|
/** @private */
|
|
56
|
-
toString() {
|
|
57
|
-
const str = super.toString(this.#delimiter);
|
|
61
|
+
toString(skip) {
|
|
62
|
+
const str = super.toString(skip, this.#delimiter);
|
|
58
63
|
return this.#bracket ? `[[${str}]]` : str;
|
|
59
64
|
}
|
|
60
65
|
/** @private */
|
|
@@ -75,31 +80,28 @@ class LinkBaseToken extends index_2.Token {
|
|
|
75
80
|
}
|
|
76
81
|
/** @private */
|
|
77
82
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
78
|
-
const errors = super.lint(start, re), { childNodes: [target, linkText], type
|
|
79
|
-
if (target.childNodes.some(({ type }) =>
|
|
83
|
+
const errors = super.lint(start, re), { childNodes: [target, linkText], type } = this, { encoded, fragment } = this.#title, rect = new rect_1.BoundingRect(this, start);
|
|
84
|
+
if (target.childNodes.some(({ type: t }) => t === 'template')) {
|
|
80
85
|
errors.push((0, lint_1.generateForChild)(target, rect, 'unknown-page', 'template in an internal link target', 'warning'));
|
|
81
86
|
}
|
|
82
87
|
if (encoded) {
|
|
83
88
|
errors.push((0, lint_1.generateForChild)(target, rect, 'url-encoding', 'unnecessary URL encoding in an internal link'));
|
|
84
89
|
}
|
|
85
|
-
if (
|
|
90
|
+
if (type === 'link' || type === 'category') {
|
|
86
91
|
const textNode = linkText?.childNodes.find((c) => c.type === 'text' && c.data.includes('|'));
|
|
87
92
|
if (textNode) {
|
|
88
|
-
const e = (0, lint_1.generateForChild)(linkText, rect, 'pipe-like', 'additional "|" in the link text', 'warning');
|
|
93
|
+
const e = (0, lint_1.generateForChild)(linkText, rect, 'pipe-like', 'additional "|" in the link text', 'warning'), i = e.startIndex + textNode.getRelativeIndex();
|
|
89
94
|
e.suggestions = [
|
|
90
95
|
{
|
|
91
96
|
desc: 'escape',
|
|
92
|
-
range: [
|
|
93
|
-
e.startIndex + textNode.getRelativeIndex(),
|
|
94
|
-
e.startIndex + textNode.getRelativeIndex() + textNode.data.length,
|
|
95
|
-
],
|
|
97
|
+
range: [i, i + textNode.data.length],
|
|
96
98
|
text: textNode.data.replace(/\|/gu, '|'),
|
|
97
99
|
},
|
|
98
100
|
];
|
|
99
101
|
errors.push(e);
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
|
-
if (
|
|
104
|
+
if (fragment !== undefined && !isLink(type)) {
|
|
103
105
|
const e = (0, lint_1.generateForChild)(target, rect, 'no-ignored', 'useless fragment'), textNode = target.childNodes.find((c) => c.type === 'text' && c.data.includes('#'));
|
|
104
106
|
if (textNode) {
|
|
105
107
|
e.fix = {
|
|
@@ -113,7 +115,7 @@ class LinkBaseToken extends index_2.Token {
|
|
|
113
115
|
}
|
|
114
116
|
/** @private */
|
|
115
117
|
getTitle(halfParsed) {
|
|
116
|
-
return this.normalizeTitle(this.firstChild.
|
|
118
|
+
return this.normalizeTitle(this.firstChild.toString(true), 0, halfParsed, true, true);
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
exports.LinkBaseToken = LinkBaseToken;
|
package/dist/src/link/file.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ import type { Token, AtomToken } from '../../internal';
|
|
|
8
8
|
* @classdesc `{childNodes: [AtomToken, ...ImageParameterToken]}`
|
|
9
9
|
*/
|
|
10
10
|
export declare abstract class FileToken extends LinkBaseToken {
|
|
11
|
-
#private;
|
|
12
11
|
readonly childNodes: readonly [AtomToken, ...ImageParameterToken[]];
|
|
13
12
|
abstract get lastChild(): AtomToken | ImageParameterToken;
|
|
14
13
|
get type(): 'file' | 'gallery-image' | 'imagemap-image';
|
|
@@ -27,12 +26,6 @@ export declare abstract class FileToken extends LinkBaseToken {
|
|
|
27
26
|
* @param key 参数名
|
|
28
27
|
*/
|
|
29
28
|
getArgs(key: string): ImageParameterToken[];
|
|
30
|
-
/** 获取图片框架属性参数节点 */
|
|
31
|
-
getFrameArgs(): ImageParameterToken[];
|
|
32
|
-
/** 获取图片水平对齐参数节点 */
|
|
33
|
-
getHorizAlignArgs(): ImageParameterToken[];
|
|
34
|
-
/** 获取图片垂直对齐参数节点 */
|
|
35
|
-
getVertAlignArgs(): ImageParameterToken[];
|
|
36
29
|
/**
|
|
37
30
|
* 获取生效的指定图片参数
|
|
38
31
|
* @param key 参数名
|
package/dist/src/link/file.js
CHANGED
|
@@ -7,7 +7,12 @@ const rect_1 = require("../../lib/rect");
|
|
|
7
7
|
const index_1 = require("../../index");
|
|
8
8
|
const base_1 = require("./base");
|
|
9
9
|
const imageParameter_1 = require("../imageParameter");
|
|
10
|
-
const frame = new
|
|
10
|
+
const frame = new Map([
|
|
11
|
+
['manualthumb', 'Thumb'],
|
|
12
|
+
['frameless', 'Frameless'],
|
|
13
|
+
['framed', 'Frame'],
|
|
14
|
+
['thumbnail', 'Thumb'],
|
|
15
|
+
]), horizAlign = new Set(['left', 'right', 'center', 'none']), vertAlign = new Set(['baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom']);
|
|
11
16
|
/**
|
|
12
17
|
* a more sophisticated string-explode function
|
|
13
18
|
* @param start start syntax of a nested AST node
|
|
@@ -57,17 +62,24 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
57
62
|
const { extension } = this.getTitle(true);
|
|
58
63
|
this.append(...explode('-{', '}-', '|', text).map(
|
|
59
64
|
// @ts-expect-error abstract class
|
|
60
|
-
part => new imageParameter_1.ImageParameterToken(part, extension, config, accum)));
|
|
65
|
+
(part) => new imageParameter_1.ImageParameterToken(part, extension, config, accum)));
|
|
61
66
|
}
|
|
62
67
|
/** @private */
|
|
63
68
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
64
69
|
const errors = super.lint(start, re), args = this.getAllArgs().filter(({ childNodes }) => {
|
|
65
70
|
const visibleNodes = childNodes.filter(node => node.text().trim());
|
|
66
71
|
return visibleNodes.length !== 1 || visibleNodes[0].type !== 'arg';
|
|
67
|
-
}), keys = [...new Set(args.map(({ name }) => name))]
|
|
72
|
+
}), 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);
|
|
68
73
|
if (this.closest('ext-link-text') && this.getValue('link')?.trim() !== '') {
|
|
69
74
|
errors.push((0, lint_1.generateForSelf)(this, rect, 'nested-link', 'internal link in an external link'));
|
|
70
75
|
}
|
|
76
|
+
if (unscaled) {
|
|
77
|
+
for (const arg of args.filter(({ name }) => name === 'width')) {
|
|
78
|
+
const e = (0, lint_1.generateForChild)(arg, rect, 'invalid-gallery', 'invalid image parameter');
|
|
79
|
+
e.fix = { range: [e.startIndex - 1, e.endIndex], text: '' };
|
|
80
|
+
errors.push(e);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
71
83
|
if (args.length === keys.length
|
|
72
84
|
&& frameKeys.length < 2
|
|
73
85
|
&& horizAlignKeys.length < 2
|
|
@@ -81,6 +93,9 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
81
93
|
*/
|
|
82
94
|
const generate = (msg, p1) => (arg) => (0, lint_1.generateForChild)(arg, rect, 'no-duplicate', index_1.default.msg(`${msg} image $1 parameter`, p1));
|
|
83
95
|
for (const key of keys) {
|
|
96
|
+
if (key === 'invalid' || key === 'width' && unscaled) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
84
99
|
let relevantArgs = args.filter(({ name }) => name === key);
|
|
85
100
|
if (key === 'caption') {
|
|
86
101
|
relevantArgs = [...relevantArgs.slice(0, -1).filter(arg => arg.text()), ...relevantArgs.slice(-1)];
|
|
@@ -111,34 +126,13 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
111
126
|
getArgs(key) {
|
|
112
127
|
return this.getAllArgs().filter(({ name }) => key === name);
|
|
113
128
|
}
|
|
114
|
-
/**
|
|
115
|
-
* 获取特定类型的图片属性参数节点
|
|
116
|
-
* @param keys 接受的参数名
|
|
117
|
-
* @param type 类型名
|
|
118
|
-
*/
|
|
119
|
-
#getTypedArgs(keys, type) {
|
|
120
|
-
const args = this.getAllArgs().filter(({ name }) => keys.has(name));
|
|
121
|
-
return args;
|
|
122
|
-
}
|
|
123
|
-
/** 获取图片框架属性参数节点 */
|
|
124
|
-
getFrameArgs() {
|
|
125
|
-
return this.#getTypedArgs(frame, 'frame');
|
|
126
|
-
}
|
|
127
|
-
/** 获取图片水平对齐参数节点 */
|
|
128
|
-
getHorizAlignArgs() {
|
|
129
|
-
return this.#getTypedArgs(horizAlign, 'horizontal-align');
|
|
130
|
-
}
|
|
131
|
-
/** 获取图片垂直对齐参数节点 */
|
|
132
|
-
getVertAlignArgs() {
|
|
133
|
-
return this.#getTypedArgs(vertAlign, 'vertical-align');
|
|
134
|
-
}
|
|
135
129
|
/**
|
|
136
130
|
* 获取生效的指定图片参数
|
|
137
131
|
* @param key 参数名
|
|
138
132
|
*/
|
|
139
133
|
getArg(key) {
|
|
140
134
|
const args = this.getArgs(key);
|
|
141
|
-
return args[args.length - 1];
|
|
135
|
+
return args[key === 'manualthumb' ? 0 : args.length - 1];
|
|
142
136
|
}
|
|
143
137
|
/**
|
|
144
138
|
* 获取生效的指定图片参数值
|
|
@@ -6,7 +6,7 @@ import type { Title } from '../../lib/title';
|
|
|
6
6
|
import type { Token, AtomToken } from '../../internal';
|
|
7
7
|
/**
|
|
8
8
|
* 重定向目标
|
|
9
|
-
* @classdesc `{childNodes: [AtomToken, ?
|
|
9
|
+
* @classdesc `{childNodes: [AtomToken, ?NoincludeToken]}`
|
|
10
10
|
*/
|
|
11
11
|
export declare abstract class RedirectTargetToken extends LinkBaseToken {
|
|
12
12
|
readonly childNodes: readonly [AtomToken] | readonly [AtomToken, NoincludeToken];
|
|
@@ -7,7 +7,7 @@ const base_1 = require("./base");
|
|
|
7
7
|
const noinclude_1 = require("../nowiki/noinclude");
|
|
8
8
|
/**
|
|
9
9
|
* 重定向目标
|
|
10
|
-
* @classdesc `{childNodes: [AtomToken, ?
|
|
10
|
+
* @classdesc `{childNodes: [AtomToken, ?NoincludeToken]}`
|
|
11
11
|
*/
|
|
12
12
|
class RedirectTargetToken extends base_1.LinkBaseToken {
|
|
13
13
|
get type() {
|
|
@@ -30,20 +30,13 @@ class RedirectTargetToken extends base_1.LinkBaseToken {
|
|
|
30
30
|
return this.normalizeTitle(this.firstChild.toString(), 0, true, true);
|
|
31
31
|
}
|
|
32
32
|
/** @private */
|
|
33
|
-
text() {
|
|
34
|
-
return `[[${this.firstChild.toString()}]]`;
|
|
35
|
-
}
|
|
36
|
-
/** @private */
|
|
37
33
|
lint(start = this.getAbsoluteIndex()) {
|
|
38
|
-
const errors = super.lint(start,
|
|
34
|
+
const errors = super.lint(start, false);
|
|
39
35
|
if (this.length === 2) {
|
|
40
36
|
const e = (0, lint_1.generateForChild)(this.lastChild, { start }, 'no-ignored', 'useless link text');
|
|
41
37
|
e.startIndex--;
|
|
42
38
|
e.startCol--;
|
|
43
|
-
e.fix = {
|
|
44
|
-
range: [e.startIndex, e.endIndex],
|
|
45
|
-
text: '',
|
|
46
|
-
};
|
|
39
|
+
e.fix = { range: [e.startIndex, e.endIndex], text: '' };
|
|
47
40
|
errors.push(e);
|
|
48
41
|
}
|
|
49
42
|
return errors;
|
package/dist/src/magicLink.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export declare abstract class MagicLinkToken extends Token {
|
|
|
13
13
|
abstract get firstChild(): AstText | TranscludeToken;
|
|
14
14
|
abstract get lastChild(): AstText | CommentToken | IncludeToken | NoincludeToken | TranscludeToken;
|
|
15
15
|
get type(): ExtLinkTypes;
|
|
16
|
+
/** 链接显示文字 */
|
|
17
|
+
get innerText(): string;
|
|
16
18
|
/** 和内链保持一致 */
|
|
17
19
|
get link(): string;
|
|
18
20
|
/**
|
package/dist/src/magicLink.js
CHANGED
|
@@ -16,21 +16,26 @@ class MagicLinkToken extends index_2.Token {
|
|
|
16
16
|
get type() {
|
|
17
17
|
return this.#type;
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
get
|
|
21
|
-
const map =
|
|
19
|
+
/** 链接显示文字 */
|
|
20
|
+
get innerText() {
|
|
21
|
+
const map = new Map([['!', '|'], ['=', '=']]);
|
|
22
22
|
let link = (0, string_1.text)(this.childNodes.map(child => {
|
|
23
|
-
const { type, name
|
|
24
|
-
return type === 'magic-word' &&
|
|
23
|
+
const { type } = child, name = String(child.name);
|
|
24
|
+
return type === 'magic-word' && map.has(name) ? map.get(name) : child;
|
|
25
25
|
}));
|
|
26
26
|
if (this.type === 'magic-link') {
|
|
27
27
|
link = link.replace(spaceRegex, ' ');
|
|
28
|
-
if (link.startsWith('ISBN')) {
|
|
29
|
-
link = `ISBN ${link.slice(5).replace(/[- ]/gu, '').replace(/x$/u, 'X')}`;
|
|
30
|
-
}
|
|
31
28
|
}
|
|
32
29
|
return link;
|
|
33
30
|
}
|
|
31
|
+
/** 和内链保持一致 */
|
|
32
|
+
get link() {
|
|
33
|
+
let { innerText } = this;
|
|
34
|
+
if (this.type === 'magic-link' && innerText.startsWith('ISBN')) {
|
|
35
|
+
innerText = `ISBN ${innerText.slice(5).replace(/[- ]/gu, '').replace(/x$/u, 'X')}`;
|
|
36
|
+
}
|
|
37
|
+
return innerText;
|
|
38
|
+
}
|
|
34
39
|
/**
|
|
35
40
|
* @param url 网址
|
|
36
41
|
* @param type 类型
|
|
@@ -55,51 +60,30 @@ class MagicLinkToken extends index_2.Token {
|
|
|
55
60
|
}
|
|
56
61
|
return errors;
|
|
57
62
|
}
|
|
58
|
-
const pipe = this.type === 'ext-link-url',
|
|
59
|
-
|
|
60
|
-
const {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
range: [startIndex, startIndex],
|
|
83
|
-
text: ' ',
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
desc: 'escape',
|
|
87
|
-
range: [startIndex, e.endIndex],
|
|
88
|
-
text: encodeURI(s),
|
|
89
|
-
},
|
|
90
|
-
];
|
|
91
|
-
}
|
|
92
|
-
else if (s.length === 1) {
|
|
93
|
-
e.suggestions = [
|
|
94
|
-
{
|
|
95
|
-
desc: 'whitespace',
|
|
96
|
-
range: [startIndex, startIndex + 1],
|
|
97
|
-
text: ' ',
|
|
98
|
-
},
|
|
99
|
-
];
|
|
100
|
-
}
|
|
101
|
-
errors.push(e);
|
|
102
|
-
}
|
|
63
|
+
const pipe = this.type === 'ext-link-url', regex = pipe ? /\|/u : /[,;。:!?()]+/u, child = this.childNodes.find((c) => c.type === 'text' && regex.test(c.data));
|
|
64
|
+
if (child) {
|
|
65
|
+
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;
|
|
66
|
+
e.suggestions = pipe
|
|
67
|
+
? [
|
|
68
|
+
{
|
|
69
|
+
desc: 'whitespace',
|
|
70
|
+
range: [i, i + 1],
|
|
71
|
+
text: ' ',
|
|
72
|
+
},
|
|
73
|
+
]
|
|
74
|
+
: [
|
|
75
|
+
{
|
|
76
|
+
desc: 'whitespace',
|
|
77
|
+
range: [i, i],
|
|
78
|
+
text: ' ',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
desc: 'escape',
|
|
82
|
+
range: [i, i + s.length],
|
|
83
|
+
text: encodeURI(s),
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
errors.push(e);
|
|
103
87
|
}
|
|
104
88
|
return errors;
|
|
105
89
|
}
|
package/dist/src/nested.js
CHANGED
|
@@ -41,7 +41,7 @@ const index_1 = require("../../index");
|
|
|
41
41
|
const base_1 = require("./base");
|
|
42
42
|
/** HTML注释,不可见 */
|
|
43
43
|
let CommentToken = (() => {
|
|
44
|
-
let _classDecorators = [(0, hidden_1.hiddenToken)()];
|
|
44
|
+
let _classDecorators = [(0, hidden_1.hiddenToken)(false)];
|
|
45
45
|
let _classDescriptor;
|
|
46
46
|
let _classExtraInitializers = [];
|
|
47
47
|
let _classThis;
|
|
@@ -74,15 +74,12 @@ 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.fix = {
|
|
78
|
-
range: [e.endIndex, e.endIndex],
|
|
79
|
-
text: '-->',
|
|
80
|
-
};
|
|
77
|
+
e.fix = { range: [e.endIndex, e.endIndex], text: '-->' };
|
|
81
78
|
return [e];
|
|
82
79
|
}
|
|
83
80
|
/** @private */
|
|
84
|
-
toString() {
|
|
85
|
-
return `<!--${this.innerText}${this.closed ? '-->' : ''}`;
|
|
81
|
+
toString(skip) {
|
|
82
|
+
return skip ? '' : `<!--${this.innerText}${this.closed ? '-->' : ''}`;
|
|
86
83
|
}
|
|
87
84
|
};
|
|
88
85
|
return CommentToken = _classThis;
|