wikilint 2.8.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 +4 -2
- package/dist/base.js +1 -0
- package/dist/index.d.ts +3 -7
- package/dist/index.js +8 -2
- package/dist/lib/element.d.ts +0 -13
- package/dist/lib/element.js +4 -11
- package/dist/lib/node.d.ts +1 -1
- package/dist/lib/node.js +1 -1
- package/dist/lib/rect.d.ts +18 -0
- package/dist/lib/rect.js +32 -0
- package/dist/lib/text.d.ts +0 -6
- package/dist/lib/text.js +6 -17
- 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 +16 -4
- package/dist/parser/commentAndExt.js +1 -8
- package/dist/parser/converter.js +2 -3
- package/dist/parser/externalLinks.js +2 -9
- 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 +28 -17
- package/dist/parser/redirect.js +1 -1
- package/dist/parser/table.js +1 -1
- package/dist/src/arg.d.ts +0 -4
- package/dist/src/arg.js +6 -5
- package/dist/src/atom.d.ts +2 -2
- package/dist/src/atom.js +3 -4
- package/dist/src/attribute.d.ts +0 -4
- package/dist/src/attribute.js +6 -18
- package/dist/src/attributes.d.ts +0 -2
- package/dist/src/attributes.js +5 -10
- package/dist/src/converter.d.ts +0 -2
- package/dist/src/converter.js +2 -2
- package/dist/src/converterFlags.d.ts +0 -4
- package/dist/src/converterFlags.js +4 -3
- package/dist/src/converterRule.d.ts +0 -2
- package/dist/src/converterRule.js +2 -2
- package/dist/src/extLink.d.ts +0 -4
- package/dist/src/extLink.js +3 -3
- package/dist/src/gallery.d.ts +0 -4
- package/dist/src/gallery.js +3 -3
- package/dist/src/heading.d.ts +0 -4
- package/dist/src/heading.js +5 -10
- package/dist/src/hidden.d.ts +1 -1
- package/dist/src/hidden.js +53 -3
- package/dist/src/html.d.ts +2 -7
- package/dist/src/html.js +16 -36
- package/dist/src/imageParameter.d.ts +0 -4
- package/dist/src/imageParameter.js +5 -5
- package/dist/src/imagemap.d.ts +0 -4
- package/dist/src/imagemap.js +6 -5
- package/dist/src/index.d.ts +0 -11
- package/dist/src/index.js +34 -32
- package/dist/src/link/base.d.ts +0 -4
- package/dist/src/link/base.js +4 -8
- package/dist/src/link/file.d.ts +0 -2
- package/dist/src/link/file.js +7 -7
- package/dist/src/link/galleryImage.d.ts +0 -2
- package/dist/src/link/galleryImage.js +2 -3
- package/dist/src/link/index.d.ts +0 -2
- package/dist/src/link/index.js +1 -1
- package/dist/src/link/redirectTarget.d.ts +0 -4
- package/dist/src/link/redirectTarget.js +4 -4
- package/dist/src/magicLink.d.ts +7 -5
- package/dist/src/magicLink.js +37 -7
- package/dist/src/nested.d.ts +0 -2
- package/dist/src/nested.js +5 -5
- 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 -6
- 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.d.ts +0 -2
- package/dist/src/nowiki/index.js +2 -2
- package/dist/src/nowiki/noinclude.d.ts +1 -1
- package/dist/src/nowiki/noinclude.js +53 -3
- package/dist/src/nowiki/quote.d.ts +0 -2
- package/dist/src/nowiki/quote.js +19 -25
- package/dist/src/paramTag/index.d.ts +0 -4
- package/dist/src/paramTag/index.js +5 -5
- package/dist/src/parameter.d.ts +0 -2
- package/dist/src/parameter.js +4 -3
- package/dist/src/pre.d.ts +0 -2
- package/dist/src/pre.js +1 -1
- package/dist/src/redirect.d.ts +4 -5
- package/dist/src/redirect.js +83 -33
- package/dist/src/syntax.d.ts +2 -4
- package/dist/src/syntax.js +4 -5
- package/dist/src/table/index.d.ts +2 -5
- package/dist/src/table/index.js +7 -6
- package/dist/src/table/td.d.ts +0 -4
- package/dist/src/table/td.js +13 -7
- package/dist/src/table/tr.d.ts +2 -2
- package/dist/src/table/tr.js +1 -2
- package/dist/src/table/trBase.d.ts +0 -2
- package/dist/src/table/trBase.js +2 -2
- package/dist/src/tagPair/ext.d.ts +0 -2
- package/dist/src/tagPair/ext.js +6 -8
- package/dist/src/tagPair/include.d.ts +6 -6
- package/dist/src/tagPair/include.js +76 -26
- package/dist/src/tagPair/index.d.ts +2 -4
- package/dist/src/tagPair/index.js +6 -7
- package/dist/src/transclude.d.ts +0 -4
- package/dist/src/transclude.js +10 -14
- package/dist/util/debug.js +10 -1
- package/dist/util/lint.js +4 -3
- package/dist/util/string.js +5 -5
- package/i18n/zh-hans.json +1 -0
- package/i18n/zh-hant.json +1 -0
- package/package.json +12 -12
package/dist/base.d.ts
CHANGED
|
@@ -11,8 +11,8 @@ 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' | 'list' | 'dd' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
|
|
15
|
-
export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "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"];
|
|
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';
|
|
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';
|
|
18
18
|
type Rule = typeof rules[number];
|
|
@@ -49,6 +49,8 @@ interface AstElement extends AstNode {
|
|
|
49
49
|
export interface Parser {
|
|
50
50
|
config: Config | string;
|
|
51
51
|
i18n: Record<string, string> | string | undefined;
|
|
52
|
+
/** 获取当前的解析设置 */
|
|
53
|
+
getConfig(): Config;
|
|
52
54
|
/**
|
|
53
55
|
* 解析wikitext
|
|
54
56
|
* @param include 是否嵌入
|
package/dist/base.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -8,18 +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
|
-
declare global {
|
|
24
|
-
type Acceptable = unknown;
|
|
25
|
-
}
|
|
21
|
+
declare global { type Acceptable = unknown; }
|
package/dist/index.js
CHANGED
|
@@ -43,7 +43,11 @@ const Parser = {
|
|
|
43
43
|
return new Title(title, defaultNs, config, decode, selfLink);
|
|
44
44
|
}
|
|
45
45
|
const { Token } = require('./src/index');
|
|
46
|
-
const token = debug_1.Shadow.run(() =>
|
|
46
|
+
const token = debug_1.Shadow.run(() => {
|
|
47
|
+
const root = new Token(title, config);
|
|
48
|
+
root.type = 'root';
|
|
49
|
+
return root.parseOnce(0, include).parseOnce();
|
|
50
|
+
}), titleObj = new Title(token.toString(), defaultNs, config, decode, selfLink);
|
|
47
51
|
debug_1.Shadow.run(() => {
|
|
48
52
|
for (const key of ['main', 'fragment']) {
|
|
49
53
|
const str = titleObj[key];
|
|
@@ -60,13 +64,14 @@ const Parser = {
|
|
|
60
64
|
const { Token } = require('./src/index');
|
|
61
65
|
const root = debug_1.Shadow.run(() => {
|
|
62
66
|
const token = new Token(wikitext, config);
|
|
67
|
+
token.type = 'root';
|
|
63
68
|
try {
|
|
64
69
|
return token.parse(maxStage, include);
|
|
65
70
|
}
|
|
66
71
|
catch (e) {
|
|
67
72
|
if (e instanceof Error) {
|
|
68
73
|
const file = path.join(__dirname, '..', 'errors', new Date().toISOString()), stage = token.getAttribute('stage');
|
|
69
|
-
fs.writeFileSync(file, stage === constants_1.MAX_STAGE ? wikitext :
|
|
74
|
+
fs.writeFileSync(file, stage === constants_1.MAX_STAGE ? wikitext : token.toString());
|
|
70
75
|
fs.writeFileSync(`${file}.err`, e.stack);
|
|
71
76
|
fs.writeFileSync(`${file}.json`, JSON.stringify({ stage, include, config }, null, '\t'));
|
|
72
77
|
}
|
|
@@ -88,4 +93,5 @@ for (const key in Parser) {
|
|
|
88
93
|
}
|
|
89
94
|
}
|
|
90
95
|
Object.defineProperties(Parser, def);
|
|
96
|
+
exports.default = Parser;
|
|
91
97
|
module.exports = Parser;
|
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 移除位置
|
|
@@ -57,10 +50,4 @@ export declare abstract class AstElement extends AstNode {
|
|
|
57
50
|
* @param i 子节点位置
|
|
58
51
|
*/
|
|
59
52
|
setText(str: string, i?: number): string;
|
|
60
|
-
/**
|
|
61
|
-
* @override
|
|
62
|
-
* @param start
|
|
63
|
-
* @param re 用于`AstText`后代节点的正则表达式
|
|
64
|
-
*/
|
|
65
|
-
lint(start?: number, re?: RegExp): LintError[];
|
|
66
53
|
}
|
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
|
/**
|
|
@@ -164,17 +161,13 @@ class AstElement extends node_1.AstNode {
|
|
|
164
161
|
toString(separator = '') {
|
|
165
162
|
return this.childNodes.map(String).join(separator);
|
|
166
163
|
}
|
|
167
|
-
/**
|
|
168
|
-
* @override
|
|
169
|
-
* @param start
|
|
170
|
-
* @param re 用于`AstText`后代节点的正则表达式
|
|
171
|
-
*/
|
|
164
|
+
/** @private */
|
|
172
165
|
lint(start = this.getAbsoluteIndex(), re) {
|
|
173
166
|
const errors = [];
|
|
174
167
|
for (let i = 0, cur = start + this.getAttribute('padding'); i < this.length; i++) {
|
|
175
168
|
const child = this.childNodes[i];
|
|
176
169
|
errors.push(...child.lint(cur, re));
|
|
177
|
-
cur +=
|
|
170
|
+
cur += child.toString().length + this.getGaps(i);
|
|
178
171
|
}
|
|
179
172
|
return errors;
|
|
180
173
|
}
|
package/dist/lib/node.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare abstract class AstNode implements AstNodeBase {
|
|
|
19
19
|
type: TokenTypes | 'text';
|
|
20
20
|
data?: string | undefined;
|
|
21
21
|
readonly childNodes: readonly AstNodes[];
|
|
22
|
-
|
|
22
|
+
lint(): LintError[];
|
|
23
23
|
/** 首位子节点 */
|
|
24
24
|
get firstChild(): AstNodes | undefined;
|
|
25
25
|
/** 末位子节点 */
|
package/dist/lib/node.js
CHANGED
|
@@ -14,7 +14,7 @@ const getDimension = (str) => {
|
|
|
14
14
|
* @param j 子节点序号
|
|
15
15
|
* @param parent 父节点
|
|
16
16
|
*/
|
|
17
|
-
const getIndex = (j, parent) => parent.childNodes.slice(0, j).reduce((acc, cur, i) => acc +
|
|
17
|
+
const getIndex = (j, parent) => parent.childNodes.slice(0, j).reduce((acc, cur, i) => acc + cur.toString().length + parent.getGaps(i), 0)
|
|
18
18
|
+ parent.getAttribute('padding');
|
|
19
19
|
/** 类似Node */
|
|
20
20
|
class AstNode {
|
|
@@ -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.d.ts
CHANGED
|
@@ -10,12 +10,6 @@ export declare class AstText extends AstNode {
|
|
|
10
10
|
constructor(text: string);
|
|
11
11
|
/** 可见部分 */
|
|
12
12
|
text(): string;
|
|
13
|
-
/**
|
|
14
|
-
* @override
|
|
15
|
-
* @param start
|
|
16
|
-
* @throws `Error` 孤立文本节点
|
|
17
|
-
*/
|
|
18
|
-
lint(start?: number, errorRegex?: RegExp): LintError[];
|
|
19
13
|
/**
|
|
20
14
|
* 替换字符串
|
|
21
15
|
* @param text 替换的字符串
|
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,
|
|
@@ -73,15 +66,11 @@ class AstText extends node_1.AstNode {
|
|
|
73
66
|
text() {
|
|
74
67
|
return this.data;
|
|
75
68
|
}
|
|
76
|
-
/**
|
|
77
|
-
* @override
|
|
78
|
-
* @param start
|
|
79
|
-
* @throws `Error` 孤立文本节点
|
|
80
|
-
*/
|
|
69
|
+
/** @private */
|
|
81
70
|
lint(start = this.getAbsoluteIndex(), errorRegex) {
|
|
82
71
|
const { data, parentNode, nextSibling, previousSibling } = this;
|
|
83
72
|
if (!parentNode) {
|
|
84
|
-
throw new Error('
|
|
73
|
+
throw new Error('An isolated text node cannot be linted!');
|
|
85
74
|
}
|
|
86
75
|
const { type, name, parentNode: grandparent } = parentNode;
|
|
87
76
|
let isHtmlAttrVal = false;
|
|
@@ -129,7 +118,7 @@ class AstText extends node_1.AstNode {
|
|
|
129
118
|
else if (char === 'h' && index === 0 && type === 'ext-link-text' && extImage.test(data)) {
|
|
130
119
|
continue;
|
|
131
120
|
}
|
|
132
|
-
const startIndex = start + index, endIndex = startIndex + length, rootStr =
|
|
121
|
+
const startIndex = start + index, endIndex = startIndex + length, rootStr = root.toString(), nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], severity = length > 1 && !(char === '<' && !/[\s/>]/u.test(nextChar ?? '')
|
|
133
122
|
|| isHtmlAttrVal && (char === '[' || char === ']'))
|
|
134
123
|
|| char === '{' && (nextChar === char || previousChar === '-')
|
|
135
124
|
|| char === '}' && (previousChar === char || nextChar === '-')
|
|
@@ -190,7 +179,7 @@ class AstText extends node_1.AstNode {
|
|
|
190
179
|
];
|
|
191
180
|
}
|
|
192
181
|
else if (char === '[' && type === 'ext-link-text') {
|
|
193
|
-
const i = parentNode.getAbsoluteIndex() +
|
|
182
|
+
const i = parentNode.getAbsoluteIndex() + parentNode.toString().length;
|
|
194
183
|
e.suggestions = [
|
|
195
184
|
{
|
|
196
185
|
desc: 'escape',
|
|
@@ -200,7 +189,7 @@ class AstText extends node_1.AstNode {
|
|
|
200
189
|
];
|
|
201
190
|
}
|
|
202
191
|
else if (char === ']' && previousType === 'free-ext-link' && severity === 'error') {
|
|
203
|
-
const i = start -
|
|
192
|
+
const i = start - previousSibling.toString().length;
|
|
204
193
|
e.fix = {
|
|
205
194
|
range: [i, i],
|
|
206
195
|
text: '[',
|
|
@@ -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,8 +19,14 @@ const arg_1 = require("../src/arg");
|
|
|
13
19
|
* @throws TranscludeToken.constructor()
|
|
14
20
|
*/
|
|
15
21
|
const parseBraces = (wikitext, config, accum) => {
|
|
16
|
-
const source = `${config.excludes?.includes('heading') ? '' :
|
|
17
|
-
|
|
22
|
+
const source = String.raw `${config.excludes?.includes('heading') ? '' : String.raw `^(\0\d+c\x7F)*={1,6}|`}\[\[|\{{2,}|-\{(?!\{)`, { parserFunction: [, , , subst] } = config, stack = [];
|
|
23
|
+
wikitext = wikitext.replace(re, (m, p1) => {
|
|
24
|
+
// @ts-expect-error abstract class
|
|
25
|
+
new transclude_1.TranscludeToken(m.slice(2, -2), [], config, accum);
|
|
26
|
+
return `\0${accum.length - 2}${marks.get(p1)}\x7F`;
|
|
27
|
+
});
|
|
28
|
+
const lastBraces = wikitext.lastIndexOf('}}') - wikitext.length;
|
|
29
|
+
let regex = new RegExp(source, 'gmu'), mt = regex.exec(wikitext), moreBraces = lastBraces + wikitext.length !== -1, lastIndex;
|
|
18
30
|
while (mt
|
|
19
31
|
|| lastIndex !== undefined && lastIndex <= wikitext.length && stack[stack.length - 1]?.[0]?.startsWith('=')) {
|
|
20
32
|
if (mt?.[1]) {
|
|
@@ -86,7 +98,7 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
86
98
|
}
|
|
87
99
|
}
|
|
88
100
|
catch (e) {
|
|
89
|
-
if (e instanceof SyntaxError && e.message === '
|
|
101
|
+
if (e instanceof SyntaxError && e.message === 'Invalid template name') {
|
|
90
102
|
skip = true;
|
|
91
103
|
}
|
|
92
104
|
else {
|
|
@@ -113,7 +125,7 @@ const parseBraces = (wikitext, config, accum) => {
|
|
|
113
125
|
}
|
|
114
126
|
stack.push(...'0' in top ? [top] : [], mt);
|
|
115
127
|
}
|
|
116
|
-
moreBraces &&= wikitext.
|
|
128
|
+
moreBraces &&= lastBraces + wikitext.length >= lastIndex;
|
|
117
129
|
let curTop = stack[stack.length - 1];
|
|
118
130
|
if (!moreBraces && curTop?.[0]?.startsWith('{')) {
|
|
119
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) {
|
|
@@ -29,7 +22,7 @@ const parseExternalLinks = (wikitext, config, accum, inFile) => {
|
|
|
29
22
|
}
|
|
30
23
|
if (inFile) {
|
|
31
24
|
// @ts-expect-error abstract class
|
|
32
|
-
new magicLink_1.MagicLinkToken(url,
|
|
25
|
+
new magicLink_1.MagicLinkToken(url, 'ext-link-url', config, accum);
|
|
33
26
|
return `[\0${length}f\x7F${space}${text}]`;
|
|
34
27
|
}
|
|
35
28
|
// @ts-expect-error abstract class
|
|
@@ -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,29 +11,39 @@ const magicLink_1 = require("../src/magicLink");
|
|
|
10
11
|
* @param accum
|
|
11
12
|
*/
|
|
12
13
|
const parseMagicLinks = (wikitext, config, accum) => {
|
|
13
|
-
const regex = new RegExp(`(^|[
|
|
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');
|
|
14
15
|
return wikitext.replace(regex, (m, lead, p1) => {
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (sepChars
|
|
25
|
-
correction = 1;
|
|
16
|
+
let url = lead ? m.slice(lead.length) : m;
|
|
17
|
+
if (p1) {
|
|
18
|
+
let trail = '';
|
|
19
|
+
const m2 = /&(?:lt|gt|nbsp|#x0*(?:3[ce]|a0)|#0*(?:6[02]|160));/iu.exec(url);
|
|
20
|
+
if (m2) {
|
|
21
|
+
trail = url.slice(m2.index);
|
|
22
|
+
url = url.slice(0, m2.index);
|
|
23
|
+
}
|
|
24
|
+
const sep = url.includes('(') ? sepLparRegex : sepRegex, sepChars = sep.exec(url);
|
|
25
|
+
if (sepChars) {
|
|
26
|
+
let correction = 1;
|
|
27
|
+
if (sepChars[0][1] === ';'
|
|
28
|
+
&& /&(?:[a-z]+|#x[\da-f]+|#\d+)$/iu.test(url.slice(0, sepChars.index))) {
|
|
29
|
+
correction = 2;
|
|
30
|
+
}
|
|
31
|
+
trail = url.slice(sepChars.index + correction) + trail;
|
|
32
|
+
url = url.slice(0, sepChars.index + correction);
|
|
33
|
+
}
|
|
34
|
+
if (trail.length >= p1.length) {
|
|
35
|
+
return m;
|
|
26
36
|
}
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
// @ts-expect-error abstract class
|
|
38
|
+
new magicLink_1.MagicLinkToken(url, undefined, config, accum);
|
|
39
|
+
return `${lead}\0${accum.length - 1}w\x7F${trail}`;
|
|
29
40
|
}
|
|
30
|
-
if (
|
|
41
|
+
else if (!/^(?:RFC|PMID|ISBN)/u.test(url)) {
|
|
31
42
|
return m;
|
|
32
43
|
}
|
|
33
44
|
// @ts-expect-error abstract class
|
|
34
|
-
new magicLink_1.MagicLinkToken(url,
|
|
35
|
-
return `${lead}\0${accum.length - 1}
|
|
45
|
+
new magicLink_1.MagicLinkToken(url, 'magic-link', config, accum);
|
|
46
|
+
return `${lead}\0${accum.length - 1}i\x7F`;
|
|
36
47
|
});
|
|
37
48
|
};
|
|
38
49
|
exports.parseMagicLinks = parseMagicLinks;
|
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/parser/table.js
CHANGED
package/dist/src/arg.d.ts
CHANGED
|
@@ -16,8 +16,4 @@ export declare abstract class ArgToken extends Token {
|
|
|
16
16
|
get default(): string | false;
|
|
17
17
|
/** @param parts 以'|'分隔的各部分 */
|
|
18
18
|
constructor(parts: readonly string[], config?: Parser.Config, accum?: Token[]);
|
|
19
|
-
/** @override */
|
|
20
|
-
text(): string;
|
|
21
|
-
/** @override */
|
|
22
|
-
lint(start?: number, re?: RegExp): LintError[];
|
|
23
19
|
}
|