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/config/.schema.json
CHANGED
package/config/enwiki.json
CHANGED
package/config/llwiki.json
CHANGED
package/config/moegirl.json
CHANGED
package/config/zhwiki.json
CHANGED
package/dist/base.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export interface Config {
|
|
|
11
11
|
readonly variants: string[];
|
|
12
12
|
readonly excludes?: string[];
|
|
13
13
|
}
|
|
14
|
-
export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
|
|
14
|
+
export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'list-range' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
|
|
15
15
|
export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext"];
|
|
16
16
|
export declare namespace LintError {
|
|
17
17
|
type Severity = 'error' | 'warning';
|
|
@@ -38,8 +38,9 @@ export interface LintError {
|
|
|
38
38
|
}
|
|
39
39
|
/** 类似Node */
|
|
40
40
|
export interface AstNode {
|
|
41
|
-
type: string;
|
|
42
41
|
readonly childNodes: readonly AstNode[];
|
|
42
|
+
/** 节点类型 */
|
|
43
|
+
type: string;
|
|
43
44
|
/** Linter */
|
|
44
45
|
lint(): LintError[];
|
|
45
46
|
}
|
package/dist/index.js
CHANGED
|
@@ -11,8 +11,7 @@ const string_1 = require("./util/string");
|
|
|
11
11
|
* @param file 文件名
|
|
12
12
|
* @param dir 子路径
|
|
13
13
|
*/
|
|
14
|
-
const rootRequire = (file, dir) => require(
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
14
|
+
const rootRequire = (file, dir) => require(path.isAbsolute(file) ? file : path.join('..', file.includes('/') ? '' : dir, file));
|
|
16
15
|
const Parser = {
|
|
17
16
|
config: 'default',
|
|
18
17
|
i18n: undefined,
|
|
@@ -20,7 +19,7 @@ const Parser = {
|
|
|
20
19
|
/** @implements */
|
|
21
20
|
getConfig() {
|
|
22
21
|
if (typeof this.config === 'string') {
|
|
23
|
-
this.config = rootRequire(this.config, 'config
|
|
22
|
+
this.config = rootRequire(this.config, 'config');
|
|
24
23
|
return this.getConfig();
|
|
25
24
|
}
|
|
26
25
|
return {
|
|
@@ -31,7 +30,7 @@ const Parser = {
|
|
|
31
30
|
/** @implements */
|
|
32
31
|
msg(msg, arg = '') {
|
|
33
32
|
if (typeof this.i18n === 'string') {
|
|
34
|
-
this.i18n = rootRequire(this.i18n, 'i18n
|
|
33
|
+
this.i18n = rootRequire(this.i18n, 'i18n');
|
|
35
34
|
return this.msg(msg, arg);
|
|
36
35
|
}
|
|
37
36
|
return msg && (this.i18n?.[msg] ?? msg).replace('$1', this.msg(arg));
|
|
@@ -39,23 +38,27 @@ const Parser = {
|
|
|
39
38
|
/** @implements */
|
|
40
39
|
normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), halfParsed, decode = false, selfLink = false) {
|
|
41
40
|
const { Title } = require('./lib/title');
|
|
41
|
+
let titleObj;
|
|
42
42
|
if (halfParsed) {
|
|
43
|
-
|
|
43
|
+
titleObj = new Title(title, defaultNs, config, decode, selfLink);
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
45
|
+
else {
|
|
46
|
+
const { Token } = require('./src/index');
|
|
47
|
+
titleObj = debug_1.Shadow.run(() => {
|
|
48
|
+
const root = new Token(title, config);
|
|
49
|
+
root.type = 'root';
|
|
50
|
+
root.parseOnce(0, include).parseOnce();
|
|
51
|
+
const t = new Title(root.toString(), defaultNs, config, decode, selfLink);
|
|
52
|
+
for (const key of ['main', 'fragment']) {
|
|
53
|
+
const str = t[key];
|
|
54
|
+
if (str?.includes('\0')) {
|
|
55
|
+
t[key] = root.buildFromStr(str, constants_1.BuildMethod.Text);
|
|
56
|
+
}
|
|
55
57
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
58
|
+
return t;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return titleObj;
|
|
59
62
|
},
|
|
60
63
|
/** @implements */
|
|
61
64
|
parse(wikitext, include, maxStage = constants_1.MAX_STAGE, config = Parser.getConfig()) {
|
package/dist/lib/element.js
CHANGED
|
@@ -158,8 +158,8 @@ class AstElement extends node_1.AstNode {
|
|
|
158
158
|
return data;
|
|
159
159
|
}
|
|
160
160
|
/** @private */
|
|
161
|
-
toString(separator = '') {
|
|
162
|
-
return this.childNodes.map(
|
|
161
|
+
toString(skip, separator = '') {
|
|
162
|
+
return this.childNodes.map(child => child.toString(skip)).join(separator);
|
|
163
163
|
}
|
|
164
164
|
/** @private */
|
|
165
165
|
lint(start = this.getAbsoluteIndex(), re) {
|
package/dist/lib/node.d.ts
CHANGED
|
@@ -18,9 +18,9 @@ export declare abstract class AstNode implements AstNodeBase {
|
|
|
18
18
|
#private;
|
|
19
19
|
data?: string | undefined;
|
|
20
20
|
readonly childNodes: readonly AstNodes[];
|
|
21
|
-
/** 节点类型 */
|
|
22
21
|
abstract get type(): TokenTypes | 'text';
|
|
23
22
|
abstract set type(value: TokenTypes | 'text');
|
|
23
|
+
/** 可见部分 */
|
|
24
24
|
text(): string;
|
|
25
25
|
lint(): LintError[];
|
|
26
26
|
/** 首位子节点 */
|
|
@@ -51,4 +51,9 @@ export declare abstract class AstNode implements AstNodeBase {
|
|
|
51
51
|
getRelativeIndex(j?: number): number;
|
|
52
52
|
/** 获取当前节点的绝对位置 */
|
|
53
53
|
getAbsoluteIndex(): number;
|
|
54
|
+
/**
|
|
55
|
+
* 是否是某种类型的节点
|
|
56
|
+
* @param type 节点类型
|
|
57
|
+
*/
|
|
58
|
+
is<T extends Token>(type: string): this is T;
|
|
54
59
|
}
|
package/dist/lib/node.js
CHANGED
package/dist/lib/text.d.ts
CHANGED
package/dist/lib/text.js
CHANGED
|
@@ -60,15 +60,18 @@ class AstText extends node_1.AstNode {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
/** @private */
|
|
63
|
-
toString() {
|
|
64
|
-
return this.data;
|
|
63
|
+
toString(skip) {
|
|
64
|
+
return skip && !this.parentNode?.getAttribute('built') ? (0, string_1.removeComment)(this.data) : this.data;
|
|
65
65
|
}
|
|
66
|
-
/**
|
|
66
|
+
/** @private */
|
|
67
67
|
text() {
|
|
68
68
|
return this.data;
|
|
69
69
|
}
|
|
70
70
|
/** @private */
|
|
71
71
|
lint(start = this.getAbsoluteIndex(), errorRegex) {
|
|
72
|
+
if (errorRegex === false) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
72
75
|
const { data, parentNode, nextSibling, previousSibling } = this;
|
|
73
76
|
if (!parentNode) {
|
|
74
77
|
throw new Error('An isolated text node cannot be linted!');
|
|
@@ -108,9 +111,7 @@ class AstText extends node_1.AstNode {
|
|
|
108
111
|
|| char === '['
|
|
109
112
|
&& type === 'ext-link-text'
|
|
110
113
|
&& (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
|
|
111
|
-
||
|
|
112
|
-
&& nextName === 'nowiki'
|
|
113
|
-
&& nextSibling.innerText?.includes(']'))) {
|
|
114
|
+
|| nextSibling?.is('ext') && nextName === 'nowiki' && nextSibling.innerText?.includes(']'))) {
|
|
114
115
|
continue;
|
|
115
116
|
}
|
|
116
117
|
else if (char === ']' && (index || length > 1)) {
|
|
@@ -191,10 +192,7 @@ class AstText extends node_1.AstNode {
|
|
|
191
192
|
}
|
|
192
193
|
else if (char === ']' && previousType === 'free-ext-link' && severity === 'error') {
|
|
193
194
|
const i = start - previousSibling.toString().length;
|
|
194
|
-
e.fix = {
|
|
195
|
-
range: [i, i],
|
|
196
|
-
text: '[',
|
|
197
|
-
};
|
|
195
|
+
e.fix = { range: [i, i], text: '[' };
|
|
198
196
|
}
|
|
199
197
|
errors.push(e);
|
|
200
198
|
}
|
package/dist/lib/title.js
CHANGED
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Title = void 0;
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
|
-
/**
|
|
6
|
-
* PHP的`rawurldecode`函数的JavaScript实现
|
|
7
|
-
* @param str 要解码的字符串
|
|
8
|
-
*/
|
|
9
|
-
const rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, '%25'));
|
|
10
5
|
/** MediaWiki页面标题对象 */
|
|
11
6
|
class Title {
|
|
12
7
|
#main;
|
|
@@ -56,12 +51,12 @@ class Title {
|
|
|
56
51
|
if (decode && title.includes('%')) {
|
|
57
52
|
try {
|
|
58
53
|
const encoded = /%(?!21|3[ce]|5[bd]|7[b-d])[\da-f]{2}/iu.test(title);
|
|
59
|
-
title = rawurldecode(title);
|
|
54
|
+
title = (0, string_1.rawurldecode)(title);
|
|
60
55
|
this.encoded = encoded;
|
|
61
56
|
}
|
|
62
57
|
catch { }
|
|
63
58
|
}
|
|
64
|
-
title = title.replace(/_
|
|
59
|
+
title = title.replace(/[_ ]+/gu, ' ').trim();
|
|
65
60
|
if (subpage) {
|
|
66
61
|
this.ns = 0;
|
|
67
62
|
}
|
|
@@ -73,7 +68,7 @@ class Title {
|
|
|
73
68
|
}
|
|
74
69
|
const m = title.split(':');
|
|
75
70
|
if (m.length > 1) {
|
|
76
|
-
const
|
|
71
|
+
const k = m[0].trim().toLowerCase(), id = Object.prototype.hasOwnProperty.call(config.nsid, k) && config.nsid[k];
|
|
77
72
|
if (id) {
|
|
78
73
|
ns = id;
|
|
79
74
|
title = m.slice(1).join(':').trim();
|
|
@@ -86,7 +81,7 @@ class Title {
|
|
|
86
81
|
let fragment = title.slice(i + 1).trimEnd();
|
|
87
82
|
if (fragment.includes('%')) {
|
|
88
83
|
try {
|
|
89
|
-
fragment = rawurldecode(fragment);
|
|
84
|
+
fragment = (0, string_1.rawurldecode)(fragment);
|
|
90
85
|
}
|
|
91
86
|
catch { }
|
|
92
87
|
}
|
package/dist/mixin/hidden.d.ts
CHANGED
package/dist/mixin/hidden.js
CHANGED
|
@@ -5,17 +5,17 @@ const debug_1 = require("../util/debug");
|
|
|
5
5
|
/**
|
|
6
6
|
* 解析后不可见的类
|
|
7
7
|
* @param linter 是否覆写 lint 方法
|
|
8
|
+
* @param html 是否覆写 toHtml 方法
|
|
8
9
|
* @param constructor 基类
|
|
9
10
|
* @param _ context
|
|
10
11
|
*/
|
|
11
|
-
const hiddenToken = (linter) => (constructor, _) => {
|
|
12
|
+
const hiddenToken = (linter = true, html = true) => (constructor, _) => {
|
|
12
13
|
/** 解析后不可见的类 */
|
|
13
14
|
class AnyHiddenToken extends constructor {
|
|
14
15
|
/** 没有可见部分 */
|
|
15
16
|
text() {
|
|
16
17
|
return '';
|
|
17
18
|
}
|
|
18
|
-
/** @private */
|
|
19
19
|
lint(start) {
|
|
20
20
|
// @ts-expect-error private argument
|
|
21
21
|
return linter ? [] : super.lint(start);
|
package/dist/parser/list.js
CHANGED
|
@@ -1,23 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseList = void 0;
|
|
4
|
+
const html_1 = require("../util/html");
|
|
4
5
|
const list_1 = require("../src/nowiki/list");
|
|
5
6
|
const dd_1 = require("../src/nowiki/dd");
|
|
6
7
|
/**
|
|
7
8
|
* 解析列表
|
|
8
9
|
* @param wikitext
|
|
10
|
+
* @param state
|
|
11
|
+
* @param state.lastPrefix 上一个列表的前缀
|
|
9
12
|
* @param config
|
|
10
13
|
* @param accum
|
|
11
14
|
*/
|
|
12
|
-
const parseList = (wikitext, config, accum) => {
|
|
13
|
-
const mt = /^((?:\0\d+c\x7F)*)([;:*#]
|
|
15
|
+
const parseList = (wikitext, state, config, accum) => {
|
|
16
|
+
const mt = /^((?:\0\d+c\x7F)*)([;:*#]+\s*)/u.exec(wikitext);
|
|
14
17
|
if (!mt) {
|
|
18
|
+
state.lastPrefix = '';
|
|
15
19
|
return wikitext;
|
|
16
20
|
}
|
|
17
|
-
const [total, comment, prefix] = mt;
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
const [total, comment, prefix] = mt, prefix2 = prefix.replace(/;/gu, ':'), commonPrefixLength = (0, html_1.getCommon)(prefix2, state.lastPrefix), parts = (commonPrefixLength > 1 ? prefix.slice(commonPrefixLength - 1) : prefix).split(/(?=;)/u), isDt = parts[0].startsWith(';');
|
|
22
|
+
let dt = parts.length - (isDt ? 0 : 1);
|
|
23
|
+
if (commonPrefixLength > 1) {
|
|
24
|
+
const commonPrefix = prefix.slice(0, commonPrefixLength - 1);
|
|
25
|
+
if (isDt) {
|
|
26
|
+
parts.unshift(commonPrefix);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
parts[0] = commonPrefix + parts[0];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
state.lastPrefix = prefix2;
|
|
33
|
+
let text = comment + parts.map((_, i) => `\0${accum.length + i}d\x7F`).join('') + wikitext.slice(total.length);
|
|
34
|
+
for (const part of parts) {
|
|
35
|
+
// @ts-expect-error abstract class
|
|
36
|
+
new list_1.ListToken(part, config, accum);
|
|
37
|
+
}
|
|
21
38
|
if (!dt) {
|
|
22
39
|
return text;
|
|
23
40
|
}
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseMagicLinks = void 0;
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
5
|
const magicLink_1 = require("../src/magicLink");
|
|
6
|
-
const sepRegex = /[^,;\\.:!?)][,;\\.:!?)]+$/u, sepLparRegex = /[^,;\\.:!?][,;\\.:!?]+$/u;
|
|
7
6
|
/**
|
|
8
7
|
* 解析自由外链
|
|
9
8
|
* @param wikitext
|
|
@@ -21,7 +20,7 @@ const parseMagicLinks = (wikitext, config, accum) => {
|
|
|
21
20
|
trail = url.slice(m2.index);
|
|
22
21
|
url = url.slice(0, m2.index);
|
|
23
22
|
}
|
|
24
|
-
const sep = url.includes('(') ?
|
|
23
|
+
const sep = url.includes('(') ? /[^,;\\.:!?][,;\\.:!?]+$/u : /[^,;\\.:!?)][,;\\.:!?)]+$/u, sepChars = sep.exec(url);
|
|
25
24
|
if (sepChars) {
|
|
26
25
|
let correction = 1;
|
|
27
26
|
if (sepChars[0][1] === ';'
|
package/dist/parser/table.js
CHANGED
|
@@ -67,8 +67,8 @@ const parseTable = ({ firstChild: { data }, type, name }, config, accum) => {
|
|
|
67
67
|
out += `\n${outLine}`;
|
|
68
68
|
continue;
|
|
69
69
|
}
|
|
70
|
-
// eslint-disable-
|
|
71
|
-
|
|
70
|
+
const matches = // eslint-disable-line @stylistic/operator-linebreak
|
|
71
|
+
/^(?:(\|\}|\0\d+!\x7F\}|\0\d+\}\x7F)|(\|-+|\0\d+!\x7F-+|\0\d+-\x7F-*)(?!-)|(!|(?:\||\0\d+!\x7F)\+?))(.*)$/u
|
|
72
72
|
.exec(line);
|
|
73
73
|
if (!matches) {
|
|
74
74
|
push(`\n${outLine}`, top);
|
package/dist/src/arg.js
CHANGED
|
@@ -41,8 +41,8 @@ class ArgToken extends index_2.Token {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
/** @private */
|
|
44
|
-
toString() {
|
|
45
|
-
return `{{{${super.toString('|')}}}}`;
|
|
44
|
+
toString(skip) {
|
|
45
|
+
return `{{{${super.toString(skip, '|')}}}}`;
|
|
46
46
|
}
|
|
47
47
|
/** @private */
|
|
48
48
|
text() {
|
|
@@ -62,10 +62,7 @@ class ArgToken extends index_2.Token {
|
|
|
62
62
|
if (!this.getAttribute('include')) {
|
|
63
63
|
const e = (0, lint_1.generateForSelf)(this, { start }, 'no-arg', 'unexpected template argument');
|
|
64
64
|
if (argDefault) {
|
|
65
|
-
e.fix = {
|
|
66
|
-
range: [start, e.endIndex],
|
|
67
|
-
text: argDefault.text(),
|
|
68
|
-
};
|
|
65
|
+
e.fix = { range: [start, e.endIndex], text: argDefault.text() };
|
|
69
66
|
}
|
|
70
67
|
return [e];
|
|
71
68
|
}
|
package/dist/src/attribute.js
CHANGED
|
@@ -60,7 +60,6 @@ const commonHtmlAttrs = new Set([
|
|
|
60
60
|
img: new Set(['alt', 'src', 'width', 'height', 'srcset']),
|
|
61
61
|
font: new Set(['size', 'color', 'face']),
|
|
62
62
|
hr: widthAttrs,
|
|
63
|
-
rt: new Set(['rbspan']),
|
|
64
63
|
data: new Set(['value']),
|
|
65
64
|
time: new Set(['datetime']),
|
|
66
65
|
meta: new Set(['itemprop', 'content']),
|
|
@@ -194,23 +193,15 @@ class AttributeToken extends index_2.Token {
|
|
|
194
193
|
* @param quotes 引号
|
|
195
194
|
*/
|
|
196
195
|
constructor(type, tag, key, equal = '', value, quotes = [], config = index_1.default.getConfig(), accum = []) {
|
|
197
|
-
const keyToken = new atom_1.AtomToken(key, 'attr-key', config, accum
|
|
196
|
+
const keyToken = new atom_1.AtomToken(key, 'attr-key', config, accum);
|
|
198
197
|
let valueToken;
|
|
199
198
|
if (key === 'title' || tag === 'img' && key === 'alt') {
|
|
200
199
|
valueToken = new index_2.Token(value, config, accum, {});
|
|
201
200
|
valueToken.type = 'attr-value';
|
|
202
201
|
valueToken.setAttribute('stage', constants_1.MAX_STAGE - 1);
|
|
203
202
|
}
|
|
204
|
-
else if (tag === 'gallery' && key === 'caption'
|
|
205
|
-
|
|
206
|
-
...config,
|
|
207
|
-
excludes: [...config.excludes, 'quote', 'extLink', 'magicLink', 'list'],
|
|
208
|
-
};
|
|
209
|
-
valueToken = new index_2.Token(value, newConfig, accum, {});
|
|
210
|
-
valueToken.type = 'attr-value';
|
|
211
|
-
valueToken.setAttribute('stage', 5);
|
|
212
|
-
}
|
|
213
|
-
else if (tag === 'choose' && (key === 'before' || key === 'after')) {
|
|
203
|
+
else if (tag === 'gallery' && key === 'caption'
|
|
204
|
+
|| tag === 'choose' && (key === 'before' || key === 'after')) {
|
|
214
205
|
const newConfig = {
|
|
215
206
|
...config,
|
|
216
207
|
excludes: [...config.excludes, 'heading', 'html', 'table', 'hr', 'list'],
|
|
@@ -238,13 +229,13 @@ class AttributeToken extends index_2.Token {
|
|
|
238
229
|
if (this.parentNode) {
|
|
239
230
|
this.#tag = this.parentNode.name;
|
|
240
231
|
}
|
|
241
|
-
this.setAttribute('name', this.firstChild.
|
|
232
|
+
this.setAttribute('name', this.firstChild.toString(true).trim().toLowerCase());
|
|
242
233
|
super.afterBuild();
|
|
243
234
|
}
|
|
244
235
|
/** @private */
|
|
245
|
-
toString() {
|
|
236
|
+
toString(skip) {
|
|
246
237
|
const [quoteStart = '', quoteEnd = ''] = this.#quotes;
|
|
247
|
-
return this.#equal ? super.toString(this.#equal + quoteStart) + quoteEnd : this.firstChild.toString();
|
|
238
|
+
return this.#equal ? super.toString(skip, this.#equal + quoteStart) + quoteEnd : this.firstChild.toString(skip);
|
|
248
239
|
}
|
|
249
240
|
/** @private */
|
|
250
241
|
text() {
|
|
@@ -261,10 +252,7 @@ class AttributeToken extends index_2.Token {
|
|
|
261
252
|
const e = (0, lint_1.generateForChild)(lastChild, rect, 'unclosed-quote', index_1.default.msg('unclosed $1', 'quotes'), 'warning');
|
|
262
253
|
e.startIndex--;
|
|
263
254
|
e.startCol--;
|
|
264
|
-
const fix = {
|
|
265
|
-
range: [e.endIndex, e.endIndex],
|
|
266
|
-
text: this.#quotes[0],
|
|
267
|
-
};
|
|
255
|
+
const fix = { range: [e.endIndex, e.endIndex], text: this.#quotes[0] };
|
|
268
256
|
if (lastChild.childNodes.some(({ type: t, data }) => t === 'text' && /\s/u.test(data))) {
|
|
269
257
|
e.suggestions = [
|
|
270
258
|
{
|
|
@@ -292,7 +280,7 @@ class AttributeToken extends index_2.Token {
|
|
|
292
280
|
else if (name === 'style' && typeof value === 'string' && insecureStyle.test(value)) {
|
|
293
281
|
errors.push((0, lint_1.generateForChild)(lastChild, rect, 'insecure-style', 'insecure style'));
|
|
294
282
|
}
|
|
295
|
-
else if (name === 'tabindex' && typeof value === 'string' && value
|
|
283
|
+
else if (name === 'tabindex' && typeof value === 'string' && value !== '0') {
|
|
296
284
|
const e = (0, lint_1.generateForChild)(lastChild, rect, 'illegal-attr', 'nonzero tabindex');
|
|
297
285
|
e.suggestions = [
|
|
298
286
|
{
|
|
@@ -312,14 +300,7 @@ class AttributeToken extends index_2.Token {
|
|
|
312
300
|
}
|
|
313
301
|
/** 获取属性值 */
|
|
314
302
|
getValue() {
|
|
315
|
-
|
|
316
|
-
const value = this.lastChild.text();
|
|
317
|
-
if (this.#quotes[1]) {
|
|
318
|
-
return value;
|
|
319
|
-
}
|
|
320
|
-
return value[this.#quotes[0] ? 'trimEnd' : 'trim']();
|
|
321
|
-
}
|
|
322
|
-
return this.type === 'ext-attr' || '';
|
|
303
|
+
return this.#equal ? this.lastChild.text().trim() : this.type === 'ext-attr' || '';
|
|
323
304
|
}
|
|
324
305
|
}
|
|
325
306
|
exports.AttributeToken = AttributeToken;
|
package/dist/src/attributes.js
CHANGED
|
@@ -8,7 +8,6 @@ const index_1 = require("../index");
|
|
|
8
8
|
const index_2 = require("./index");
|
|
9
9
|
const atom_1 = require("./atom");
|
|
10
10
|
const attribute_1 = require("./attribute");
|
|
11
|
-
const regex = /([^\s/](?:(?!\0\d+~\x7F)[^\s/=])*)(?:((?:\s(?:\s|\0\d+c\x7F)*)?(?:=|\0\d+~\x7F)(?:\s|\0\d+c\x7F)*)(?:(["'])(.*?)(\3|$)|(\S*)))?/gsu;
|
|
12
11
|
/**
|
|
13
12
|
* 将属性类型转换为单属性类型
|
|
14
13
|
* @param type 属性类型
|
|
@@ -38,7 +37,7 @@ class AttributesToken extends index_2.Token {
|
|
|
38
37
|
this.#type = type;
|
|
39
38
|
this.setAttribute('name', name);
|
|
40
39
|
if (attr) {
|
|
41
|
-
regex
|
|
40
|
+
const regex = /([^\s/](?:(?!\0\d+~\x7F)[^\s/=])*)(?:((?:\s(?:\s|\0\d+c\x7F)*)?(?:=|\0\d+~\x7F)(?:\s|\0\d+c\x7F)*)(?:(["'])(.*?)(\3|$)|(\S*)))?/gsu;
|
|
42
41
|
let out = '', mt = regex.exec(attr), lastIndex = 0;
|
|
43
42
|
const insertDirty = /** 插入无效属性 */ () => {
|
|
44
43
|
if (out) {
|
|
@@ -123,7 +122,7 @@ class AttributesToken extends index_2.Token {
|
|
|
123
122
|
duplicated.add(name);
|
|
124
123
|
attrs.get(name).push(attr);
|
|
125
124
|
}
|
|
126
|
-
else
|
|
125
|
+
else {
|
|
127
126
|
attrs.set(name, [attr]);
|
|
128
127
|
}
|
|
129
128
|
}
|
package/dist/src/converter.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { ConverterRuleToken } from './converterRule';
|
|
|
7
7
|
* @classdesc `{childNodes: [ConverterFlagsToken, ...ConverterRuleToken]}`
|
|
8
8
|
*/
|
|
9
9
|
export declare abstract class ConverterToken extends Token {
|
|
10
|
-
readonly childNodes: readonly [ConverterFlagsToken, ...ConverterRuleToken[]];
|
|
10
|
+
readonly childNodes: readonly [ConverterFlagsToken, ConverterRuleToken, ...ConverterRuleToken[]];
|
|
11
11
|
abstract get firstChild(): ConverterFlagsToken;
|
|
12
12
|
abstract get lastChild(): ConverterFlagsToken | ConverterRuleToken;
|
|
13
13
|
get type(): 'converter';
|
package/dist/src/converter.js
CHANGED
|
@@ -25,7 +25,8 @@ class ConverterToken extends index_2.Token {
|
|
|
25
25
|
const [firstRule] = rules, hasColon = firstRule.includes(':'),
|
|
26
26
|
// @ts-expect-error abstract class
|
|
27
27
|
firstRuleToken = new converterRule_1.ConverterRuleToken(firstRule, hasColon, config, accum);
|
|
28
|
-
if (hasColon && firstRuleToken.length === 1
|
|
28
|
+
if (hasColon && firstRuleToken.length === 1
|
|
29
|
+
|| !hasColon && rules.length === 2 && !(0, string_1.removeComment)(rules[1]).trim()) {
|
|
29
30
|
// @ts-expect-error abstract class
|
|
30
31
|
this.insertAt(new converterRule_1.ConverterRuleToken(rules.join(';'), false, config, accum));
|
|
31
32
|
}
|
|
@@ -36,9 +37,9 @@ class ConverterToken extends index_2.Token {
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
/** @private */
|
|
39
|
-
toString() {
|
|
40
|
+
toString(skip) {
|
|
40
41
|
const { childNodes: [flags, ...rules] } = this;
|
|
41
|
-
return `-{${flags.toString()}${flags.length > 0 ? '|' : ''}${rules.map(
|
|
42
|
+
return `-{${flags.toString(skip)}${flags.length > 0 ? '|' : ''}${rules.map(rule => rule.toString(skip)).join(';')}}-`;
|
|
42
43
|
}
|
|
43
44
|
/** @private */
|
|
44
45
|
text() {
|
|
@@ -27,8 +27,8 @@ class ConverterFlagsToken extends index_2.Token {
|
|
|
27
27
|
super.afterBuild();
|
|
28
28
|
}
|
|
29
29
|
/** @private */
|
|
30
|
-
toString() {
|
|
31
|
-
return super.toString(';');
|
|
30
|
+
toString(skip) {
|
|
31
|
+
return super.toString(skip, ';');
|
|
32
32
|
}
|
|
33
33
|
/** @private */
|
|
34
34
|
text() {
|
|
@@ -62,16 +62,13 @@ 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 = {
|
|
66
|
-
range: [e.startIndex, e.endIndex],
|
|
67
|
-
text: flag.toUpperCase(),
|
|
68
|
-
};
|
|
65
|
+
e.fix = { range: [e.startIndex, e.endIndex], text: flag.toUpperCase() };
|
|
69
66
|
}
|
|
70
67
|
else {
|
|
71
68
|
e.suggestions = [
|
|
72
69
|
{
|
|
73
70
|
desc: 'remove',
|
|
74
|
-
range: [e.startIndex, e.endIndex],
|
|
71
|
+
range: [e.startIndex - (i && 1), e.endIndex],
|
|
75
72
|
text: '',
|
|
76
73
|
},
|
|
77
74
|
];
|
|
@@ -31,22 +31,18 @@ class ConverterRuleToken extends index_2.Token {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
/** @private */
|
|
34
|
-
toString() {
|
|
35
|
-
const { childNodes } = this;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
return super.toString(':');
|
|
34
|
+
toString(skip) {
|
|
35
|
+
const { childNodes, firstChild, lastChild } = this;
|
|
36
|
+
return childNodes.length === 3
|
|
37
|
+
? `${firstChild.toString(skip)}=>${childNodes[1].toString(skip)}:${lastChild.toString(skip)}`
|
|
38
|
+
: super.toString(skip, ':');
|
|
41
39
|
}
|
|
42
40
|
/** @private */
|
|
43
41
|
text() {
|
|
44
|
-
const { childNodes } = this;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
return super.text(':');
|
|
42
|
+
const { childNodes, firstChild, lastChild } = this;
|
|
43
|
+
return childNodes.length === 3
|
|
44
|
+
? `${firstChild.text()}=>${childNodes[1].text()}:${lastChild.text()}`
|
|
45
|
+
: super.text(':');
|
|
50
46
|
}
|
|
51
47
|
/** @private */
|
|
52
48
|
getGaps(i) {
|