wikilint 2.9.0 → 2.9.1
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/dist/base.d.ts +2 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1 -0
- package/dist/lib/element.d.ts +0 -7
- package/dist/lib/element.js +2 -5
- package/dist/lib/rect.d.ts +18 -0
- package/dist/lib/rect.js +32 -0
- package/dist/lib/text.js +2 -9
- package/dist/mixin/attributesParent.js +2 -1
- package/dist/mixin/hidden.d.ts +2 -0
- package/dist/mixin/hidden.js +9 -4
- package/dist/parser/braces.js +11 -8
- package/dist/parser/commentAndExt.js +1 -8
- package/dist/parser/converter.js +2 -3
- package/dist/parser/externalLinks.js +1 -8
- package/dist/parser/hrAndDoubleUnderscore.js +1 -1
- package/dist/parser/html.js +1 -1
- package/dist/parser/links.js +1 -1
- package/dist/parser/magicLinks.js +6 -12
- package/dist/parser/redirect.js +1 -1
- package/dist/src/arg.d.ts +0 -2
- package/dist/src/arg.js +4 -3
- package/dist/src/atom.d.ts +2 -2
- package/dist/src/atom.js +3 -4
- package/dist/src/attribute.d.ts +0 -2
- package/dist/src/attribute.js +4 -16
- package/dist/src/attributes.js +4 -9
- package/dist/src/converter.d.ts +0 -2
- package/dist/src/converter.js +1 -1
- package/dist/src/converterFlags.d.ts +0 -2
- package/dist/src/converterFlags.js +3 -2
- package/dist/src/converterRule.d.ts +0 -2
- package/dist/src/converterRule.js +1 -1
- package/dist/src/extLink.d.ts +0 -2
- package/dist/src/extLink.js +1 -1
- package/dist/src/gallery.d.ts +0 -2
- package/dist/src/gallery.js +1 -1
- package/dist/src/heading.d.ts +0 -2
- package/dist/src/heading.js +3 -8
- package/dist/src/hidden.d.ts +1 -1
- package/dist/src/hidden.js +53 -3
- package/dist/src/html.d.ts +2 -5
- package/dist/src/html.js +14 -34
- package/dist/src/imageParameter.d.ts +0 -2
- package/dist/src/imageParameter.js +4 -4
- package/dist/src/imagemap.d.ts +0 -2
- package/dist/src/imagemap.js +4 -3
- package/dist/src/index.d.ts +0 -11
- package/dist/src/index.js +6 -18
- package/dist/src/link/base.d.ts +0 -2
- package/dist/src/link/base.js +3 -7
- package/dist/src/link/file.js +6 -6
- package/dist/src/link/redirectTarget.d.ts +0 -2
- package/dist/src/link/redirectTarget.js +1 -1
- package/dist/src/magicLink.js +6 -8
- package/dist/src/nested.js +2 -2
- package/dist/src/nowiki/base.d.ts +2 -2
- package/dist/src/nowiki/base.js +3 -4
- package/dist/src/nowiki/comment.d.ts +3 -4
- package/dist/src/nowiki/comment.js +78 -28
- package/dist/src/nowiki/doubleUnderscore.d.ts +3 -3
- package/dist/src/nowiki/doubleUnderscore.js +68 -19
- package/dist/src/nowiki/index.js +1 -1
- package/dist/src/nowiki/noinclude.d.ts +1 -1
- package/dist/src/nowiki/noinclude.js +53 -3
- package/dist/src/nowiki/quote.js +18 -24
- package/dist/src/paramTag/index.d.ts +0 -2
- package/dist/src/paramTag/index.js +3 -3
- package/dist/src/parameter.js +2 -1
- package/dist/src/redirect.d.ts +4 -1
- package/dist/src/redirect.js +83 -33
- package/dist/src/syntax.d.ts +2 -2
- package/dist/src/syntax.js +3 -4
- package/dist/src/table/index.d.ts +2 -3
- package/dist/src/table/index.js +6 -5
- package/dist/src/table/td.d.ts +0 -2
- package/dist/src/table/td.js +11 -5
- package/dist/src/table/tr.d.ts +2 -2
- package/dist/src/table/tr.js +1 -2
- package/dist/src/tagPair/ext.js +5 -7
- package/dist/src/tagPair/include.d.ts +6 -4
- package/dist/src/tagPair/include.js +76 -26
- package/dist/src/tagPair/index.d.ts +2 -4
- package/dist/src/tagPair/index.js +4 -5
- package/dist/src/transclude.d.ts +0 -2
- package/dist/src/transclude.js +8 -12
- package/dist/util/debug.js +10 -1
- package/dist/util/lint.js +3 -2
- package/dist/util/string.js +5 -5
- package/package.json +10 -10
package/dist/base.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -8,16 +8,14 @@ declare interface Parser extends ParserBase {
|
|
|
8
8
|
* @param title 标题(含或不含命名空间前缀)
|
|
9
9
|
* @param defaultNs 命名空间
|
|
10
10
|
* @param include 是否嵌入
|
|
11
|
-
* @param halfParsed 是否是半解析状态
|
|
12
|
-
* @param decode 是否需要解码
|
|
13
|
-
* @param selfLink 是否允许selfLink
|
|
14
11
|
*/
|
|
15
|
-
normalizeTitle(title: string, defaultNs?: number, include?: boolean, config?: Config
|
|
12
|
+
normalizeTitle(title: string, defaultNs?: number, include?: boolean, config?: Config): Title;
|
|
16
13
|
parse(wikitext: string, include?: boolean, maxStage?: number, config?: Config): Token;
|
|
17
14
|
}
|
|
18
15
|
declare const Parser: Parser;
|
|
19
16
|
// @ts-expect-error mixed export styles
|
|
20
17
|
export = Parser;
|
|
18
|
+
export default Parser;
|
|
21
19
|
export type { Config, LintError };
|
|
22
20
|
export type * from './internal';
|
|
23
21
|
declare global { type Acceptable = unknown; }
|
package/dist/index.js
CHANGED
package/dist/lib/element.d.ts
CHANGED
|
@@ -8,13 +8,6 @@ export declare abstract class AstElement extends AstNode {
|
|
|
8
8
|
readonly data: undefined;
|
|
9
9
|
/** 子节点总数 */
|
|
10
10
|
get length(): number;
|
|
11
|
-
/**
|
|
12
|
-
* 可见部分
|
|
13
|
-
* @param separator 子节点间的连接符
|
|
14
|
-
*/
|
|
15
|
-
text(separator?: string): string;
|
|
16
|
-
/** 合并相邻的文本子节点 */
|
|
17
|
-
normalize(): void;
|
|
18
11
|
/**
|
|
19
12
|
* 移除子节点
|
|
20
13
|
* @param i 移除位置
|
package/dist/lib/element.js
CHANGED
|
@@ -10,14 +10,11 @@ class AstElement extends node_1.AstNode {
|
|
|
10
10
|
get length() {
|
|
11
11
|
return this.childNodes.length;
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
14
|
-
* 可见部分
|
|
15
|
-
* @param separator 子节点间的连接符
|
|
16
|
-
*/
|
|
13
|
+
/** @private */
|
|
17
14
|
text(separator) {
|
|
18
15
|
return (0, string_1.text)(this.childNodes, separator);
|
|
19
16
|
}
|
|
20
|
-
/**
|
|
17
|
+
/** @private */
|
|
21
18
|
normalize() {
|
|
22
19
|
const childNodes = [...this.childNodes];
|
|
23
20
|
/**
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AstNodes, Position } from './node';
|
|
2
|
+
/** 节点位置 */
|
|
3
|
+
export declare class BoundingRect {
|
|
4
|
+
#private;
|
|
5
|
+
readonly token: AstNodes;
|
|
6
|
+
readonly start: number;
|
|
7
|
+
/** 起点行 */
|
|
8
|
+
get top(): number;
|
|
9
|
+
/** 起点列 */
|
|
10
|
+
get left(): number;
|
|
11
|
+
/**
|
|
12
|
+
* @param token 节点
|
|
13
|
+
* @param start 起点
|
|
14
|
+
*/
|
|
15
|
+
constructor(token: AstNodes, start: number);
|
|
16
|
+
/** 计算位置 */
|
|
17
|
+
getPosition(): Position;
|
|
18
|
+
}
|
package/dist/lib/rect.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BoundingRect = void 0;
|
|
4
|
+
/** 节点位置 */
|
|
5
|
+
class BoundingRect {
|
|
6
|
+
#pos;
|
|
7
|
+
token;
|
|
8
|
+
start;
|
|
9
|
+
/** 起点行 */
|
|
10
|
+
get top() {
|
|
11
|
+
this.#pos ??= this.getPosition();
|
|
12
|
+
return this.#pos.top;
|
|
13
|
+
}
|
|
14
|
+
/** 起点列 */
|
|
15
|
+
get left() {
|
|
16
|
+
this.#pos ??= this.getPosition();
|
|
17
|
+
return this.#pos.left;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @param token 节点
|
|
21
|
+
* @param start 起点
|
|
22
|
+
*/
|
|
23
|
+
constructor(token, start) {
|
|
24
|
+
this.token = token;
|
|
25
|
+
this.start = start;
|
|
26
|
+
}
|
|
27
|
+
/** 计算位置 */
|
|
28
|
+
getPosition() {
|
|
29
|
+
return this.token.getRootNode().posFromIndex(this.start);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.BoundingRect = BoundingRect;
|
package/dist/lib/text.js
CHANGED
|
@@ -4,14 +4,7 @@ exports.AstText = void 0;
|
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
5
|
const index_1 = require("../index");
|
|
6
6
|
const node_1 = require("./node");
|
|
7
|
-
const source =
|
|
8
|
-
+ '|'
|
|
9
|
-
+ '\\{+|\\}+' // `{`、`}`
|
|
10
|
-
+ '|'
|
|
11
|
-
+ '\\[{2,}|\\[(?![^[]*?\\])' // `[`
|
|
12
|
-
+ '|'
|
|
13
|
-
+ '((?:^|\\])[^[]*?)\\]+', // `]`
|
|
14
|
-
errorSyntax = new RegExp(`${source}|https?[:/]\\/+`, 'giu'), errorSyntaxUrl = new RegExp(source, 'giu'), extImage = new RegExp(`^https?:\\/\\/${string_1.extUrlCharFirst}${string_1.extUrlChar}\\.(?:gif|png|jpg|jpeg)$`, 'iu'), regexes = {
|
|
7
|
+
const source = String.raw `<\s*(?:/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])|((?:^|\])[^[]*?)\]+`, errorSyntax = new RegExp(String.raw `${source}|https?[:/]/+`, 'giu'), errorSyntaxUrl = new RegExp(source, 'giu'), extImage = new RegExp(String.raw `^https?://${string_1.extUrlCharFirst}${string_1.extUrlChar}\.(?:gif|png|jpg|jpeg)$`, 'iu'), regexes = {
|
|
15
8
|
'[': /[[\]]/u,
|
|
16
9
|
'{': /[{}]/u,
|
|
17
10
|
']': /[[\]](?=[^[\]]*$)/u,
|
|
@@ -77,7 +70,7 @@ class AstText extends node_1.AstNode {
|
|
|
77
70
|
lint(start = this.getAbsoluteIndex(), errorRegex) {
|
|
78
71
|
const { data, parentNode, nextSibling, previousSibling } = this;
|
|
79
72
|
if (!parentNode) {
|
|
80
|
-
throw new Error('
|
|
73
|
+
throw new Error('An isolated text node cannot be linted!');
|
|
81
74
|
}
|
|
82
75
|
const { type, name, parentNode: grandparent } = parentNode;
|
|
83
76
|
let isHtmlAttrVal = false;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.attributesParent = void 0;
|
|
4
|
+
const debug_1 = require("../util/debug");
|
|
4
5
|
/**
|
|
5
6
|
* 子节点含有AttributesToken的类
|
|
6
7
|
* @param i AttributesToken子节点的位置
|
|
@@ -19,7 +20,7 @@ const attributesParent = (i = 0) => (constructor, _) => {
|
|
|
19
20
|
return this.#attributesChild.getAttr(key);
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
+
(0, debug_1.mixin)(AttributesParent, constructor);
|
|
23
24
|
return AttributesParent;
|
|
24
25
|
};
|
|
25
26
|
exports.attributesParent = attributesParent;
|
package/dist/mixin/hidden.d.ts
CHANGED
package/dist/mixin/hidden.js
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.hiddenToken = void 0;
|
|
4
|
+
const debug_1 = require("../util/debug");
|
|
4
5
|
/**
|
|
5
6
|
* 解析后不可见的类
|
|
7
|
+
* @param linter 是否覆写 lint 方法
|
|
6
8
|
* @param constructor 基类
|
|
9
|
+
* @param _ context
|
|
7
10
|
*/
|
|
8
|
-
const hiddenToken = (constructor) => {
|
|
11
|
+
const hiddenToken = (linter) => (constructor, _) => {
|
|
9
12
|
/** 解析后不可见的类 */
|
|
10
13
|
class AnyHiddenToken extends constructor {
|
|
11
14
|
/** 没有可见部分 */
|
|
12
15
|
text() {
|
|
13
16
|
return '';
|
|
14
17
|
}
|
|
15
|
-
/** @
|
|
16
|
-
lint() {
|
|
17
|
-
|
|
18
|
+
/** @private */
|
|
19
|
+
lint(start) {
|
|
20
|
+
// @ts-expect-error private argument
|
|
21
|
+
return linter ? [] : super.lint(start);
|
|
18
22
|
}
|
|
19
23
|
}
|
|
24
|
+
(0, debug_1.mixin)(AnyHiddenToken, constructor);
|
|
20
25
|
return AnyHiddenToken;
|
|
21
26
|
};
|
|
22
27
|
exports.hiddenToken = hiddenToken;
|
package/dist/parser/braces.js
CHANGED
|
@@ -5,6 +5,12 @@ const string_1 = require("../util/string");
|
|
|
5
5
|
const heading_1 = require("../src/heading");
|
|
6
6
|
const transclude_1 = require("../src/transclude");
|
|
7
7
|
const arg_1 = require("../src/arg");
|
|
8
|
+
const closes = {
|
|
9
|
+
'=': '\n',
|
|
10
|
+
'{': String.raw `\}{2,}|\|`,
|
|
11
|
+
'-': String.raw `\}-`,
|
|
12
|
+
'[': String.raw `\]\]`,
|
|
13
|
+
}, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~']]), re = new RegExp(String.raw `\{\{\s*(${[...marks.keys()].map(string_1.escapeRegExp).join('|')})\s*\}\}(?!\})`, 'gu');
|
|
8
14
|
/**
|
|
9
15
|
* 解析花括号
|
|
10
16
|
* @param wikitext
|
|
@@ -13,17 +19,14 @@ const arg_1 = require("../src/arg");
|
|
|
13
19
|
* @throws TranscludeToken.constructor()
|
|
14
20
|
*/
|
|
15
21
|
const parseBraces = (wikitext, config, accum) => {
|
|
16
|
-
|
|
17
|
-
/\{\{\s*([!=]|!!|\(!|!\)|!-)\s*\}\}(?!\})/gu;
|
|
18
|
-
const source = `${config.excludes?.includes('heading') ? '' : '^(\0\\d+c\x7F)*={1,6}|'}\\[\\[|\\{{2,}|-\\{(?!\\{)`, { parserFunction: [, , , subst] } = config, stack = [], closes = { '=': '\n', '{': '\\}{2,}|\\|', '-': '\\}-', '[': '\\]\\]' }, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~']]), re = new RegExp(`\\{\\{\\s*(${[...marks.keys()].map(string_1.escapeRegExp).join('|')})\\s*\\}\\}(?!\\})`, 'gu');
|
|
22
|
+
const source = String.raw `${config.excludes?.includes('heading') ? '' : String.raw `^(\0\d+c\x7F)*={1,6}|`}\[\[|\{{2,}|-\{(?!\{)`, { parserFunction: [, , , subst] } = config, stack = [];
|
|
19
23
|
wikitext = wikitext.replace(re, (m, p1) => {
|
|
20
24
|
// @ts-expect-error abstract class
|
|
21
25
|
new transclude_1.TranscludeToken(m.slice(2, -2), [], config, accum);
|
|
22
26
|
return `\0${accum.length - 2}${marks.get(p1)}\x7F`;
|
|
23
27
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let regex = new RegExp(source, 'gmu'), mt = regex.exec(wikitext), moreBraces = wikitext.includes('}}'), lastIndex;
|
|
28
|
+
const lastBraces = wikitext.lastIndexOf('}}') - wikitext.length;
|
|
29
|
+
let regex = new RegExp(source, 'gmu'), mt = regex.exec(wikitext), moreBraces = lastBraces + wikitext.length !== -1, lastIndex;
|
|
27
30
|
while (mt
|
|
28
31
|
|| lastIndex !== undefined && lastIndex <= wikitext.length && stack[stack.length - 1]?.[0]?.startsWith('=')) {
|
|
29
32
|
if (mt?.[1]) {
|
|
@@ -95,7 +98,7 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
100
|
catch (e) {
|
|
98
|
-
if (e instanceof SyntaxError && e.message === '
|
|
101
|
+
if (e instanceof SyntaxError && e.message === 'Invalid template name') {
|
|
99
102
|
skip = true;
|
|
100
103
|
}
|
|
101
104
|
else {
|
|
@@ -122,7 +125,7 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
122
125
|
}
|
|
123
126
|
stack.push(...'0' in top ? [top] : [], mt);
|
|
124
127
|
}
|
|
125
|
-
moreBraces &&= wikitext.
|
|
128
|
+
moreBraces &&= lastBraces + wikitext.length >= lastIndex;
|
|
126
129
|
let curTop = stack[stack.length - 1];
|
|
127
130
|
if (!moreBraces && curTop?.[0]?.startsWith('{')) {
|
|
128
131
|
stack.pop();
|
|
@@ -49,14 +49,7 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
|
|
|
49
49
|
return str;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
const ext = config.ext.join('|'), noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly', regex = new RegExp(
|
|
53
|
-
+ '|'
|
|
54
|
-
+ `<${noincludeRegex}(?:\\s[^>]*)?/?>|</${noincludeRegex}\\s*>` // <noinclude>
|
|
55
|
-
+ '|'
|
|
56
|
-
+ `<(${ext})(\\s[^>]*?)?(?:/>|>(.*?)</(\\1\\s*)>)` // 扩展标签
|
|
57
|
-
+ '|'
|
|
58
|
-
+ `<(${includeRegex})(\\s[^>]*?)?(?:/>|>(.*?)(?:</(${includeRegex}\\s*)>|$))`, // <includeonly>
|
|
59
|
-
'gisu');
|
|
52
|
+
const ext = config.ext.join('|'), noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly', regex = new RegExp(String.raw `<!--.*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext})(\s[^>]*?)?(?:/>|>(.*?)</(\1\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>(.*?)(?:</(${includeRegex}\s*)>|$))`, 'gisu');
|
|
60
53
|
return wikitext.replace(regex, (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
|
|
61
54
|
const str = `\0${accum.length}${name ? 'e' : 'c'}\x7F`;
|
|
62
55
|
if (name) {
|
package/dist/parser/converter.js
CHANGED
|
@@ -9,13 +9,12 @@ const converter_1 = require("../src/converter");
|
|
|
9
9
|
* @param accum
|
|
10
10
|
*/
|
|
11
11
|
const parseConverter = (text, config, accum) => {
|
|
12
|
-
const regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, stack = [];
|
|
12
|
+
const variants = `(?:${config.variants.join('|')})`, regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, regex3 = new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*${variants}\s*:|(?:\s|\0\d+c\x7F)*$)`, 'u'), stack = [];
|
|
13
13
|
let regex = regex1, mt = regex.exec(text);
|
|
14
14
|
while (mt) {
|
|
15
15
|
const { 0: syntax, index } = mt;
|
|
16
16
|
if (syntax === '}-') {
|
|
17
|
-
const top = stack.pop(), { length } = accum, str = text.slice(top.index + 2, index), i = str.indexOf('|'), [flags, raw] = i === -1 ? [[], str] : [str.slice(0, i).split(';'), str.slice(i + 1)], temp = raw.replace(/(&[#a-z\d]+);/giu, '$1\x01'),
|
|
18
|
-
.map(rule => rule.replace(/\x01/gu, ';'));
|
|
17
|
+
const top = stack.pop(), { length } = accum, str = text.slice(top.index + 2, index), i = str.indexOf('|'), [flags, raw] = i === -1 ? [[], str] : [str.slice(0, i).split(';'), str.slice(i + 1)], temp = raw.replace(/(&[#a-z\d]+);/giu, '$1\x01'), rules = temp.split(regex3).map(rule => rule.replace(/\x01/gu, ';'));
|
|
19
18
|
// @ts-expect-error abstract class
|
|
20
19
|
new converter_1.ConverterToken(flags, rules, config, accum);
|
|
21
20
|
text = `${text.slice(0, top.index)}\0${length}v\x7F${text.slice(index + 2)}`;
|
|
@@ -12,14 +12,7 @@ const magicLink_1 = require("../src/magicLink");
|
|
|
12
12
|
* @param inFile 是否在图链中
|
|
13
13
|
*/
|
|
14
14
|
const parseExternalLinks = (wikitext, config, accum, inFile) => {
|
|
15
|
-
const regex = new RegExp(
|
|
16
|
-
+ `(${'\0\\d+f\x7F' // 预先解析的MagicLinkToken
|
|
17
|
-
+ '|'
|
|
18
|
-
+ `(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\\d+m\x7F)${string_1.extUrlChar}(?=[[\\]<>"\\t\\p{Zs}]|\0\\d)`})` // 链接网址
|
|
19
|
-
+ '(\\p{Zs}*(?=\\P{Zs}))' // 空格
|
|
20
|
-
+ '([^\\]\x01-\x08\x0A-\x1F\uFFFD]*)' // 链接文字
|
|
21
|
-
+ '\\]', // 右括号
|
|
22
|
-
'giu');
|
|
15
|
+
const regex = new RegExp(String.raw `\[(\0\d+f\x7F|(?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\d+m\x7F)${string_1.extUrlChar}(?=[[\]<>"\t\p{Zs}]|\0\d))(\p{Zs}*(?!\p{Zs}))([^\]\x01-\x08\x0A-\x1F\uFFFD]*)\]`, 'giu');
|
|
23
16
|
return wikitext.replace(regex, (_, url, space, text) => {
|
|
24
17
|
const { length } = accum, mt = /&[lg]t;/u.exec(url);
|
|
25
18
|
if (mt) {
|
|
@@ -19,7 +19,7 @@ const parseHrAndDoubleUnderscore = ({ firstChild: { data }, type, name }, config
|
|
|
19
19
|
// @ts-expect-error abstract class
|
|
20
20
|
new hr_1.HrToken(m, config, accum);
|
|
21
21
|
return `${lead}\0${accum.length - 1}r\x7F`;
|
|
22
|
-
}).replace(new RegExp(`__(${doubleUnderscore.
|
|
22
|
+
}).replace(new RegExp(`__(${[...doubleUnderscore[0], ...doubleUnderscore[1]].join('|')})__`, 'giu'), (m, p1) => {
|
|
23
23
|
const caseSensitive = sensitive.has(p1);
|
|
24
24
|
if (caseSensitive || insensitive.has(p1.toLowerCase())) {
|
|
25
25
|
// @ts-expect-error abstract class
|
package/dist/parser/html.js
CHANGED
|
@@ -10,7 +10,7 @@ const html_1 = require("../src/html");
|
|
|
10
10
|
* @param accum
|
|
11
11
|
*/
|
|
12
12
|
const parseHtml = (wikitext, config, accum) => {
|
|
13
|
-
const regex = /^(\/?)([a-z][^\s/>]*)((?:\s|\/(?!>))[^>]*?)?(\/?>)([^<]*)$/iu, elements = new Set(
|
|
13
|
+
const regex = /^(\/?)([a-z][^\s/>]*)((?:\s|\/(?!>))[^>]*?)?(\/?>)([^<]*)$/iu, { html } = config, elements = new Set([...html[0], ...html[1], ...html[2]]), bits = wikitext.split('<');
|
|
14
14
|
let text = bits.shift();
|
|
15
15
|
for (const x of bits) {
|
|
16
16
|
const mt = regex.exec(x), t = mt?.[2], name = t?.toLowerCase();
|
package/dist/parser/links.js
CHANGED
|
@@ -16,7 +16,7 @@ const category_1 = require("../src/link/category");
|
|
|
16
16
|
const parseLinks = (wikitext, config, accum) => {
|
|
17
17
|
const regex = true // eslint-disable-line no-constant-condition, @typescript-eslint/no-unnecessary-condition
|
|
18
18
|
? /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]]))?\]\](.*)$/su
|
|
19
|
-
: /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]])?)?\]\](.*)$/su, regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(.*)$/su, regexExt = new RegExp(
|
|
19
|
+
: /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]])?)?\]\](.*)$/su, regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(.*)$/su, regexExt = new RegExp(String.raw `^\s*(?:${config.protocol}|//)`, 'iu'), bits = wikitext.split('[[');
|
|
20
20
|
let s = bits.shift();
|
|
21
21
|
for (let i = 0; i < bits.length; i++) {
|
|
22
22
|
let mightBeImg = false, link, delimiter, text, after;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseMagicLinks = void 0;
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
5
|
const magicLink_1 = require("../src/magicLink");
|
|
6
|
+
const sepRegex = /[^,;\\.:!?)][,;\\.:!?)]+$/u, sepLparRegex = /[^,;\\.:!?][,;\\.:!?]+$/u;
|
|
6
7
|
/**
|
|
7
8
|
* 解析自由外链
|
|
8
9
|
* @param wikitext
|
|
@@ -10,14 +11,7 @@ const magicLink_1 = require("../src/magicLink");
|
|
|
10
11
|
* @param accum
|
|
11
12
|
*/
|
|
12
13
|
const parseMagicLinks = (wikitext, config, accum) => {
|
|
13
|
-
const space =
|
|
14
|
-
+ '(?:'
|
|
15
|
-
+ `(?:${config.protocol})(${string_1.extUrlCharFirst}${string_1.extUrlChar})` // free external link
|
|
16
|
-
+ '|'
|
|
17
|
-
+ `(?:RFC|PMID)(?:${space})+\\d+\\b` // RFC or PMID
|
|
18
|
-
+ '|'
|
|
19
|
-
+ `ISBN(?:${space})+(?:97[89]${spdash}?)?(?:\\d${spdash}?){9}[\\dx]\\b` // ISBN
|
|
20
|
-
+ ')', 'giu');
|
|
14
|
+
const space = String.raw `[\p{Zs}\t]| |�*160;|�*a0;`, spdash = `(?:${space}|-)`, regex = new RegExp(String.raw `(^|[^\p{L}\d_])(?:(?:${config.protocol})(${string_1.extUrlCharFirst}${string_1.extUrlChar})|(?:RFC|PMID)(?:${space})+\d+\b|ISBN(?:${space})+(?:97[89]${spdash}?)?(?:\d${spdash}?){9}[\dx]\b)`, 'giu');
|
|
21
15
|
return wikitext.replace(regex, (m, lead, p1) => {
|
|
22
16
|
let url = lead ? m.slice(lead.length) : m;
|
|
23
17
|
if (p1) {
|
|
@@ -27,12 +21,12 @@ const parseMagicLinks = (wikitext, config, accum) => {
|
|
|
27
21
|
trail = url.slice(m2.index);
|
|
28
22
|
url = url.slice(0, m2.index);
|
|
29
23
|
}
|
|
30
|
-
const sep =
|
|
24
|
+
const sep = url.includes('(') ? sepLparRegex : sepRegex, sepChars = sep.exec(url);
|
|
31
25
|
if (sepChars) {
|
|
32
|
-
let correction =
|
|
33
|
-
if (sepChars[0]
|
|
26
|
+
let correction = 1;
|
|
27
|
+
if (sepChars[0][1] === ';'
|
|
34
28
|
&& /&(?:[a-z]+|#x[\da-f]+|#\d+)$/iu.test(url.slice(0, sepChars.index))) {
|
|
35
|
-
correction =
|
|
29
|
+
correction = 2;
|
|
36
30
|
}
|
|
37
31
|
trail = url.slice(sepChars.index + correction) + trail;
|
|
38
32
|
url = url.slice(0, sepChars.index + correction);
|
package/dist/parser/redirect.js
CHANGED
|
@@ -10,7 +10,7 @@ const redirect_1 = require("../src/redirect");
|
|
|
10
10
|
* @param accum
|
|
11
11
|
*/
|
|
12
12
|
const parseRedirect = (text, config, accum) => {
|
|
13
|
-
const re = new RegExp(`^(
|
|
13
|
+
const re = new RegExp(String.raw `^(\s*)((?:${config.redirection.join('|')})\s*(?::\s*)?)\[\[([^\n|\]]+)(\|.*?)?\]\](\s*)`, 'iu'), mt = re.exec(text);
|
|
14
14
|
if (mt && index_1.default.normalizeTitle(mt[3], 0, false, config, true, true).valid) {
|
|
15
15
|
text = `\0${accum.length}c\x7F${text.slice(mt[0].length)}`;
|
|
16
16
|
// @ts-expect-error abstract class
|
package/dist/src/arg.d.ts
CHANGED
package/dist/src/arg.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ArgToken = void 0;
|
|
4
4
|
const string_1 = require("../util/string");
|
|
5
5
|
const lint_1 = require("../util/lint");
|
|
6
|
+
const rect_1 = require("../lib/rect");
|
|
6
7
|
const index_1 = require("../index");
|
|
7
8
|
const index_2 = require("./index");
|
|
8
9
|
const atom_1 = require("./atom");
|
|
@@ -26,7 +27,7 @@ class ArgToken extends index_2.Token {
|
|
|
26
27
|
super.insertAt(token);
|
|
27
28
|
}
|
|
28
29
|
else if (i > 1) {
|
|
29
|
-
const token = new hidden_1.HiddenToken(parts[i], config, accum
|
|
30
|
+
const token = new hidden_1.HiddenToken(parts[i], config, accum);
|
|
30
31
|
super.insertAt(token);
|
|
31
32
|
}
|
|
32
33
|
else {
|
|
@@ -41,7 +42,7 @@ class ArgToken extends index_2.Token {
|
|
|
41
42
|
toString() {
|
|
42
43
|
return `{{{${super.toString('|')}}}}`;
|
|
43
44
|
}
|
|
44
|
-
/** @
|
|
45
|
+
/** @private */
|
|
45
46
|
text() {
|
|
46
47
|
return `{{{${(0, string_1.text)(this.childNodes.slice(0, 2), '|')}}}}`;
|
|
47
48
|
}
|
|
@@ -71,7 +72,7 @@ class ArgToken extends index_2.Token {
|
|
|
71
72
|
errors.push(...argDefault.lint(start + 4 + argName.toString().length, re));
|
|
72
73
|
}
|
|
73
74
|
if (rest.length > 0) {
|
|
74
|
-
const rect =
|
|
75
|
+
const rect = new rect_1.BoundingRect(this, start);
|
|
75
76
|
errors.push(...rest.map(child => {
|
|
76
77
|
const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', 'invisible content inside triple braces');
|
|
77
78
|
e.startIndex--;
|
package/dist/src/atom.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import Parser from '../index';
|
|
2
1
|
import { Token } from './index';
|
|
2
|
+
import type { Config } from '../base';
|
|
3
3
|
declare type AtomTypes = 'arg-name' | 'attr-key' | 'attr-value' | 'ext-attr-dirty' | 'html-attr-dirty' | 'table-attr-dirty' | 'converter-flag' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'invoke-function' | 'invoke-module' | 'template-name' | 'link-target' | 'param-line';
|
|
4
4
|
/** 不会被继续解析的plain Token */
|
|
5
5
|
export declare class AtomToken extends Token {
|
|
6
6
|
type: AtomTypes;
|
|
7
7
|
/** @class */
|
|
8
|
-
constructor(wikitext: string | undefined, type: AtomTypes, config?:
|
|
8
|
+
constructor(wikitext: string | undefined, type: AtomTypes, config?: Config, accum?: Token[], acceptable?: Acceptable);
|
|
9
9
|
}
|
|
10
10
|
export {};
|
package/dist/src/atom.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AtomToken = void 0;
|
|
4
|
-
const index_1 = require("
|
|
5
|
-
const index_2 = require("./index");
|
|
4
|
+
const index_1 = require("./index");
|
|
6
5
|
/** 不会被继续解析的plain Token */
|
|
7
|
-
class AtomToken extends
|
|
6
|
+
class AtomToken extends index_1.Token {
|
|
8
7
|
/** @class */
|
|
9
|
-
constructor(wikitext, type, config
|
|
8
|
+
constructor(wikitext, type, config, accum, acceptable) {
|
|
10
9
|
super(wikitext, config, accum, acceptable);
|
|
11
10
|
this.type = type;
|
|
12
11
|
}
|
package/dist/src/attribute.d.ts
CHANGED
|
@@ -31,8 +31,6 @@ export declare abstract class AttributeToken extends Token {
|
|
|
31
31
|
* @param quotes 引号
|
|
32
32
|
*/
|
|
33
33
|
constructor(type: AttributeTypes, tag: string, key: string, equal?: string, value?: string, quotes?: readonly [string?, string?], config?: Parser.Config, accum?: Token[]);
|
|
34
|
-
/** @override */
|
|
35
|
-
text(): string;
|
|
36
34
|
/** 获取属性值 */
|
|
37
35
|
getValue(): string | true;
|
|
38
36
|
}
|
package/dist/src/attribute.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AttributeToken = void 0;
|
|
4
4
|
const lint_1 = require("../util/lint");
|
|
5
|
+
const rect_1 = require("../lib/rect");
|
|
5
6
|
const string_1 = require("../util/string");
|
|
6
7
|
const constants_1 = require("../util/constants");
|
|
7
8
|
const index_1 = require("../index");
|
|
@@ -144,13 +145,7 @@ const commonHtmlAttrs = new Set([
|
|
|
144
145
|
]),
|
|
145
146
|
tabs: new Set(['plain', 'class', 'container', 'id', 'title', 'style']),
|
|
146
147
|
combobox: new Set(['placeholder', 'value', 'id', 'class', 'text', 'dropdown', 'style']),
|
|
147
|
-
}, insecureStyle =
|
|
148
|
-
+ '|'
|
|
149
|
-
+ '(?:accelerator|-o-link(?:-source)?|-o-replace)\\s*:'
|
|
150
|
-
+ '|'
|
|
151
|
-
+ '(?:url|image(?:-set)?)\\s*\\('
|
|
152
|
-
+ '|'
|
|
153
|
-
+ 'attr\\s*\\([^)]+[\\s,]url', 'u'), obsoleteAttrs = {
|
|
148
|
+
}, insecureStyle = /expression|(?:accelerator|-o-link(?:-source)?|-o-replace)\s*:|(?:url|image(?:-set)?)\s*\(|attr\s*\([^)]+[\s,]url/u, obsoleteAttrs = {
|
|
154
149
|
table: obsoleteTableAttrs,
|
|
155
150
|
td: new Set([...obsoleteTdAttrs, 'scope']),
|
|
156
151
|
th: obsoleteTdAttrs,
|
|
@@ -246,7 +241,7 @@ class AttributeToken extends index_2.Token {
|
|
|
246
241
|
const [quoteStart = '', quoteEnd = ''] = this.#quotes;
|
|
247
242
|
return this.#equal ? super.toString(this.#equal + quoteStart) + quoteEnd : this.firstChild.toString();
|
|
248
243
|
}
|
|
249
|
-
/** @
|
|
244
|
+
/** @private */
|
|
250
245
|
text() {
|
|
251
246
|
return this.#equal ? `${super.text(`${this.#equal.trim()}"`)}"` : this.firstChild.text();
|
|
252
247
|
}
|
|
@@ -256,11 +251,8 @@ class AttributeToken extends index_2.Token {
|
|
|
256
251
|
}
|
|
257
252
|
/** @private */
|
|
258
253
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
259
|
-
const errors = super.lint(start, re), { balanced, firstChild, lastChild, type, name, tag } = this, value = this.getValue();
|
|
260
|
-
let rect;
|
|
254
|
+
const errors = super.lint(start, re), { balanced, firstChild, lastChild, type, name, tag } = this, value = this.getValue(), rect = new rect_1.BoundingRect(this, start);
|
|
261
255
|
if (!balanced) {
|
|
262
|
-
const root = this.getRootNode();
|
|
263
|
-
rect = { start, ...root.posFromIndex(start) };
|
|
264
256
|
const e = (0, lint_1.generateForChild)(lastChild, rect, 'unclosed-quote', index_1.default.msg('unclosed $1', 'quotes'), 'warning');
|
|
265
257
|
e.startIndex--;
|
|
266
258
|
e.startCol--;
|
|
@@ -287,19 +279,15 @@ class AttributeToken extends index_2.Token {
|
|
|
287
279
|
&& !htmlAttrs[tag]?.has(name)
|
|
288
280
|
&& !/^(?:xmlns:[\w:.-]+|data-[^:]*)$/u.test(name)
|
|
289
281
|
&& (tag === 'meta' || tag === 'link' || !commonHtmlAttrs.has(name))) {
|
|
290
|
-
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
291
282
|
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'illegal-attr', 'illegal attribute name'));
|
|
292
283
|
}
|
|
293
284
|
else if (obsoleteAttrs[tag]?.has(name)) {
|
|
294
|
-
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
295
285
|
errors.push((0, lint_1.generateForChild)(firstChild, rect, 'obsolete-attr', 'obsolete attribute', 'warning'));
|
|
296
286
|
}
|
|
297
287
|
else if (name === 'style' && typeof value === 'string' && insecureStyle.test(value)) {
|
|
298
|
-
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
299
288
|
errors.push((0, lint_1.generateForChild)(lastChild, rect, 'insecure-style', 'insecure style'));
|
|
300
289
|
}
|
|
301
290
|
else if (name === 'tabindex' && typeof value === 'string' && value.trim() !== '0') {
|
|
302
|
-
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
303
291
|
const e = (0, lint_1.generateForChild)(lastChild, rect, 'illegal-attr', 'nonzero tabindex');
|
|
304
292
|
e.suggestions = [
|
|
305
293
|
{
|
package/dist/src/attributes.js
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AttributesToken = void 0;
|
|
4
4
|
const lint_1 = require("../util/lint");
|
|
5
|
+
const rect_1 = require("../lib/rect");
|
|
5
6
|
const string_1 = require("../util/string");
|
|
6
7
|
const index_1 = require("../index");
|
|
7
8
|
const index_2 = require("./index");
|
|
8
9
|
const atom_1 = require("./atom");
|
|
9
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;
|
|
10
12
|
/**
|
|
11
13
|
* 将属性类型转换为单属性类型
|
|
12
14
|
* @param type 属性类型
|
|
@@ -32,10 +34,7 @@ class AttributesToken extends index_2.Token {
|
|
|
32
34
|
this.type = type;
|
|
33
35
|
this.setAttribute('name', name);
|
|
34
36
|
if (attr) {
|
|
35
|
-
|
|
36
|
-
+ `(?:${'((?:\\s|\0\\d+c\x7F)*(?:=|\0\\d+~\x7F)(?:\\s|\0\\d+c\x7F)*)' // `=`和前后的空白字符
|
|
37
|
-
+ `(?:(["'])(.*?)(\\3|$)|(\\S*))` // 属性值
|
|
38
|
-
})?`, 'gsu');
|
|
37
|
+
regex.lastIndex = 0;
|
|
39
38
|
let out = '', mt = regex.exec(attr), lastIndex = 0;
|
|
40
39
|
const insertDirty = /** 插入无效属性 */ () => {
|
|
41
40
|
if (out) {
|
|
@@ -94,10 +93,8 @@ class AttributesToken extends index_2.Token {
|
|
|
94
93
|
}
|
|
95
94
|
/** @private */
|
|
96
95
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
97
|
-
const errors = super.lint(start, re), { parentNode, length, childNodes } = this, attrs = new Map(), duplicated = new Set();
|
|
98
|
-
let rect;
|
|
96
|
+
const errors = super.lint(start, re), { parentNode, length, childNodes } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start);
|
|
99
97
|
if (parentNode?.type === 'html' && parentNode.closing && this.text().trim()) {
|
|
100
|
-
rect = { start, ...this.getRootNode().posFromIndex(start) };
|
|
101
98
|
const e = (0, lint_1.generateForSelf)(this, rect, 'no-ignored', 'attributes of a closing tag');
|
|
102
99
|
e.fix = { range: [start, e.endIndex], text: '' };
|
|
103
100
|
errors.push(e);
|
|
@@ -105,7 +102,6 @@ class AttributesToken extends index_2.Token {
|
|
|
105
102
|
for (let i = 0; i < length; i++) {
|
|
106
103
|
const attr = childNodes[i];
|
|
107
104
|
if (attr instanceof atom_1.AtomToken && attr.text().trim()) {
|
|
108
|
-
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
109
105
|
const e = (0, lint_1.generateForChild)(attr, rect, 'no-ignored', 'containing invalid attribute');
|
|
110
106
|
e.suggestions = [
|
|
111
107
|
{
|
|
@@ -128,7 +124,6 @@ class AttributesToken extends index_2.Token {
|
|
|
128
124
|
}
|
|
129
125
|
}
|
|
130
126
|
if (duplicated.size > 0) {
|
|
131
|
-
rect ??= { start, ...this.getRootNode().posFromIndex(start) };
|
|
132
127
|
for (const key of duplicated) {
|
|
133
128
|
errors.push(...attrs.get(key).map(attr => (0, lint_1.generateForChild)(attr, rect, 'no-duplicate', index_1.default.msg('duplicated $1 attribute', key))));
|
|
134
129
|
}
|
package/dist/src/converter.d.ts
CHANGED
package/dist/src/converter.js
CHANGED
|
@@ -38,7 +38,7 @@ class ConverterToken extends index_2.Token {
|
|
|
38
38
|
const { childNodes: [flags, ...rules] } = this;
|
|
39
39
|
return `-{${flags.toString()}${flags.length > 0 ? '|' : ''}${rules.map(String).join(';')}}-`;
|
|
40
40
|
}
|
|
41
|
-
/** @
|
|
41
|
+
/** @private */
|
|
42
42
|
text() {
|
|
43
43
|
const { childNodes: [flags, ...rules] } = this;
|
|
44
44
|
return `-{${flags.text()}|${(0, string_1.text)(rules, ';')}}-`;
|
|
@@ -18,8 +18,6 @@ export declare abstract class ConverterFlagsToken extends Token {
|
|
|
18
18
|
abstract get nextSibling(): ConverterRuleToken | undefined;
|
|
19
19
|
/** @param flags 转换类型标记 */
|
|
20
20
|
constructor(flags: readonly string[], config?: Parser.Config, accum?: Token[]);
|
|
21
|
-
/** @override */
|
|
22
|
-
text(): string;
|
|
23
21
|
/** 获取未知的转换类型标记 */
|
|
24
22
|
getUnknownFlags(): Set<string>;
|
|
25
23
|
/** 获取指定语言变体的转换标记 */
|