wikiparser-node 1.5.2-b → 1.5.2
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 +172 -0
- package/config/enwiki.json +814 -1
- package/config/llwiki.json +35 -1
- package/config/moegirl.json +44 -1
- package/config/zhwiki.json +466 -1
- package/dist/addon/table.d.ts +6 -0
- package/dist/addon/table.js +564 -0
- package/dist/base.d.ts +72 -0
- package/dist/base.js +38 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +214 -0
- package/dist/internal.d.ts +44 -0
- package/dist/lib/element.d.ts +150 -0
- package/dist/lib/element.js +613 -0
- package/dist/lib/node.d.ts +146 -0
- package/dist/lib/node.js +428 -0
- package/dist/lib/range.d.ts +104 -0
- package/dist/lib/range.js +385 -0
- package/dist/lib/ranges.d.ts +26 -0
- package/dist/lib/ranges.js +118 -0
- package/dist/lib/text.d.ts +62 -0
- package/dist/lib/text.js +361 -0
- package/dist/lib/title.d.ts +38 -0
- package/dist/lib/title.js +166 -0
- package/dist/mixin/attributesParent.d.ts +50 -0
- package/dist/mixin/attributesParent.js +78 -0
- package/dist/mixin/fixed.d.ts +6 -0
- package/dist/mixin/fixed.js +30 -0
- package/dist/mixin/flagsParent.d.ts +72 -0
- package/dist/mixin/flagsParent.js +59 -0
- package/dist/mixin/hidden.d.ts +5 -0
- package/dist/mixin/hidden.js +24 -0
- package/dist/mixin/magicLinkParent.d.ts +40 -0
- package/dist/mixin/magicLinkParent.js +42 -0
- package/dist/mixin/singleLine.d.ts +6 -0
- package/dist/mixin/singleLine.js +26 -0
- package/dist/mixin/sol.d.ts +6 -0
- package/dist/mixin/sol.js +43 -0
- package/dist/mixin/syntax.d.ts +9 -0
- package/dist/mixin/syntax.js +50 -0
- package/dist/parser/braces.js +131 -0
- package/dist/parser/commentAndExt.js +90 -0
- package/dist/parser/converter.js +41 -0
- package/dist/parser/externalLinks.js +32 -0
- package/dist/parser/hrAndDoubleUnderscore.js +41 -0
- package/dist/parser/html.js +39 -0
- package/dist/parser/links.js +95 -0
- package/dist/parser/list.js +98 -0
- package/dist/parser/magicLinks.js +43 -0
- package/dist/parser/quotes.js +68 -0
- package/dist/parser/selector.js +162 -0
- package/dist/parser/table.js +124 -0
- package/dist/src/arg.d.ts +58 -0
- package/dist/src/arg.js +214 -0
- package/dist/src/atom.d.ts +12 -0
- package/dist/src/atom.js +27 -0
- package/dist/src/attribute.d.ts +71 -0
- package/dist/src/attribute.js +502 -0
- package/dist/src/attributes.d.ts +109 -0
- package/dist/src/attributes.js +356 -0
- package/dist/src/converter.d.ts +33 -0
- package/dist/src/converter.js +134 -0
- package/dist/src/converterFlags.d.ts +87 -0
- package/dist/src/converterFlags.js +242 -0
- package/dist/src/converterRule.d.ts +77 -0
- package/dist/src/converterRule.js +209 -0
- package/dist/src/extLink.d.ts +43 -0
- package/dist/src/extLink.js +186 -0
- package/dist/src/gallery.d.ts +54 -0
- package/dist/src/gallery.js +139 -0
- package/dist/src/heading.d.ts +47 -0
- package/dist/src/heading.js +190 -0
- package/dist/src/hidden.d.ts +7 -0
- package/dist/src/hidden.js +23 -0
- package/dist/src/html.d.ts +65 -0
- package/dist/src/html.js +358 -0
- package/dist/src/imageParameter.d.ts +65 -0
- package/dist/src/imageParameter.js +257 -0
- package/dist/src/imagemap.d.ts +56 -0
- package/dist/src/imagemap.js +150 -0
- package/dist/src/imagemapLink.d.ts +31 -0
- package/dist/src/imagemapLink.js +93 -0
- package/dist/src/index.d.ts +143 -0
- package/dist/src/index.js +813 -0
- package/dist/src/link/base.d.ts +52 -0
- package/dist/src/link/base.js +229 -0
- package/dist/src/link/category.d.ts +13 -0
- package/dist/src/link/category.js +28 -0
- package/dist/src/link/file.d.ts +98 -0
- package/dist/src/link/file.js +272 -0
- package/dist/src/link/galleryImage.d.ts +32 -0
- package/dist/src/link/galleryImage.js +157 -0
- package/dist/src/link/index.d.ts +56 -0
- package/dist/src/link/index.js +133 -0
- package/dist/src/magicLink.d.ts +59 -0
- package/dist/src/magicLink.js +223 -0
- package/dist/src/nested.d.ts +43 -0
- package/dist/src/nested.js +105 -0
- package/dist/src/nowiki/base.d.ts +31 -0
- package/dist/src/nowiki/base.js +93 -0
- package/dist/src/nowiki/comment.d.ts +25 -0
- package/dist/src/nowiki/comment.js +76 -0
- package/dist/src/nowiki/dd.d.ts +8 -0
- package/dist/src/nowiki/dd.js +24 -0
- package/dist/src/nowiki/doubleUnderscore.d.ts +18 -0
- package/dist/src/nowiki/doubleUnderscore.js +101 -0
- package/dist/src/nowiki/hr.d.ts +5 -0
- package/dist/src/nowiki/hr.js +63 -0
- package/dist/src/nowiki/index.d.ts +16 -0
- package/dist/src/nowiki/index.js +27 -0
- package/dist/src/nowiki/list.d.ts +16 -0
- package/dist/src/nowiki/list.js +97 -0
- package/dist/src/nowiki/listBase.d.ts +5 -0
- package/dist/src/nowiki/listBase.js +61 -0
- package/dist/src/nowiki/noinclude.d.ts +10 -0
- package/dist/src/nowiki/noinclude.js +23 -0
- package/dist/src/nowiki/quote.d.ts +14 -0
- package/dist/src/nowiki/quote.js +131 -0
- package/dist/src/onlyinclude.d.ts +16 -0
- package/dist/src/onlyinclude.js +57 -0
- package/dist/src/paramTag/index.d.ts +37 -0
- package/dist/src/paramTag/index.js +77 -0
- package/dist/src/paramTag/inputbox.d.ts +8 -0
- package/dist/src/paramTag/inputbox.js +22 -0
- package/dist/src/parameter.d.ts +70 -0
- package/dist/src/parameter.js +264 -0
- package/dist/src/pre.d.ts +28 -0
- package/dist/src/pre.js +55 -0
- package/dist/src/syntax.d.ts +20 -0
- package/dist/src/syntax.js +86 -0
- package/dist/src/table/base.d.ts +30 -0
- package/dist/src/table/base.js +132 -0
- package/dist/src/table/index.d.ts +233 -0
- package/dist/src/table/index.js +396 -0
- package/dist/src/table/td.d.ts +86 -0
- package/dist/src/table/td.js +350 -0
- package/dist/src/table/tr.d.ts +32 -0
- package/dist/src/table/tr.js +58 -0
- package/dist/src/table/trBase.d.ts +53 -0
- package/dist/src/table/trBase.js +152 -0
- package/dist/src/tagPair/ext.d.ts +32 -0
- package/dist/src/tagPair/ext.js +203 -0
- package/dist/src/tagPair/include.d.ts +35 -0
- package/dist/src/tagPair/include.js +74 -0
- package/dist/src/tagPair/index.d.ts +27 -0
- package/dist/src/tagPair/index.js +128 -0
- package/dist/src/transclude.d.ts +167 -0
- package/dist/src/transclude.js +717 -0
- package/dist/util/constants.js +28 -0
- package/dist/util/debug.js +88 -0
- package/dist/util/diff.js +83 -0
- package/dist/util/lint.js +31 -0
- package/dist/util/string.js +54 -0
- package/errors/README +1 -0
- package/package.json +14 -27
- package/printed/README +1 -0
- package/bundle/bundle.min.js +0 -37
- package/extensions/dist/base.js +0 -64
- package/extensions/dist/editor.js +0 -159
- package/extensions/dist/highlight.js +0 -59
- package/extensions/dist/lint.js +0 -60
- package/extensions/editor.css +0 -63
- package/extensions/ui.css +0 -141
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseConverter = void 0;
|
|
4
|
+
const constants_1 = require("../util/constants");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const converter_1 = require("../src/converter");
|
|
7
|
+
/**
|
|
8
|
+
* 解析语言变体转换
|
|
9
|
+
* @param text
|
|
10
|
+
* @param config
|
|
11
|
+
* @param accum
|
|
12
|
+
*/
|
|
13
|
+
const parseConverter = (text, config = index_1.default.getConfig(), accum = []) => {
|
|
14
|
+
const regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, stack = [];
|
|
15
|
+
let regex = regex1, mt = regex.exec(text);
|
|
16
|
+
while (mt) {
|
|
17
|
+
const { 0: syntax, index } = mt;
|
|
18
|
+
if (syntax === '}-') {
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
20
|
+
/;(?=(?:[^;]*?=>)?\s*foo\s*:|(?:\s|\0\d+c\x7F)*$)/u;
|
|
21
|
+
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'), variants = `(?:${config.variants.join('|')})`, rules = temp.split(new RegExp(`;(?=(?:[^;]*?=>)?\\s*${variants}\\s*:|(?:\\s|\0\\d+c\x7F)*$)`, 'u'))
|
|
22
|
+
.map(rule => rule.replace(/\x01/gu, ';'));
|
|
23
|
+
// @ts-expect-error abstract class
|
|
24
|
+
new converter_1.ConverterToken(flags, rules, config, accum);
|
|
25
|
+
text = `${text.slice(0, top.index)}\0${length}v\x7F${text.slice(index + 2)}`;
|
|
26
|
+
if (stack.length === 0) {
|
|
27
|
+
regex = regex1;
|
|
28
|
+
}
|
|
29
|
+
regex.lastIndex = top.index + 3 + String(length).length;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
stack.push(mt);
|
|
33
|
+
regex = regex2;
|
|
34
|
+
regex.lastIndex = index + 2;
|
|
35
|
+
}
|
|
36
|
+
mt = regex.exec(text);
|
|
37
|
+
}
|
|
38
|
+
return text;
|
|
39
|
+
};
|
|
40
|
+
exports.parseConverter = parseConverter;
|
|
41
|
+
constants_1.parsers['parseConverter'] = __filename;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseExternalLinks = void 0;
|
|
4
|
+
const string_1 = require("../util/string");
|
|
5
|
+
const constants_1 = require("../util/constants");
|
|
6
|
+
const index_1 = require("../index");
|
|
7
|
+
const extLink_1 = require("../src/extLink");
|
|
8
|
+
/**
|
|
9
|
+
* 解析外部链接
|
|
10
|
+
* @param wikitext
|
|
11
|
+
* @param config
|
|
12
|
+
* @param accum
|
|
13
|
+
*/
|
|
14
|
+
const parseExternalLinks = (wikitext, config = index_1.default.getConfig(), accum = []) => {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
16
|
+
/\[((?:\[[\da-f:.]+\]|[^[\]\t\n\p{Zs}])[^[\]\t\n\p{Zs}]*(?=[[\]\t\p{Zs}]|\0\d))(\p{Zs}*(?=\P{Zs}))([^\]\n]*)\]/giu;
|
|
17
|
+
const regex = new RegExp(`\\[((?:(?:${config.protocol}|//)${string_1.extUrlCharFirst}|\0\\d+m\x7F)${string_1.extUrlChar}(?=[[\\]<>"\\t\\p{Zs}]|\0\\d))`
|
|
18
|
+
+ '(\\p{Zs}*(?=\\P{Zs}))([^\\]\x01-\x08\x0A-\x1F\uFFFD]*)\\]', 'giu');
|
|
19
|
+
return wikitext.replace(regex, (_, url, space, text) => {
|
|
20
|
+
const { length } = accum, mt = /&[lg]t;/u.exec(url);
|
|
21
|
+
if (mt) {
|
|
22
|
+
url = url.slice(0, mt.index);
|
|
23
|
+
space = '';
|
|
24
|
+
text = `${url.slice(mt.index)}${space}${text}`;
|
|
25
|
+
}
|
|
26
|
+
// @ts-expect-error abstract class
|
|
27
|
+
new extLink_1.ExtLinkToken(url, space, text, config, accum);
|
|
28
|
+
return `\0${length}w\x7F`;
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
exports.parseExternalLinks = parseExternalLinks;
|
|
32
|
+
constants_1.parsers['parseExternalLinks'] = __filename;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseHrAndDoubleUnderscore = void 0;
|
|
4
|
+
const constants_1 = require("../util/constants");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const hr_1 = require("../src/nowiki/hr");
|
|
7
|
+
const doubleUnderscore_1 = require("../src/nowiki/doubleUnderscore");
|
|
8
|
+
const heading_1 = require("../src/heading");
|
|
9
|
+
/**
|
|
10
|
+
* 解析`<hr>`和状态开关
|
|
11
|
+
* @param {Token} root 根节点
|
|
12
|
+
* @param config
|
|
13
|
+
* @param accum
|
|
14
|
+
*/
|
|
15
|
+
const parseHrAndDoubleUnderscore = ({ firstChild: { data }, type, name }, config = index_1.default.getConfig(), accum = []) => {
|
|
16
|
+
const { doubleUnderscore } = config, insensitive = new Set(doubleUnderscore[0]), sensitive = new Set(doubleUnderscore[1]);
|
|
17
|
+
if (type !== 'root' && (type !== 'ext-inner' || name !== 'poem')) {
|
|
18
|
+
data = `\0${data}`;
|
|
19
|
+
}
|
|
20
|
+
data = data.replace(/^((?:\0\d+c\x7F)*)(-{4,})/gmu, (_, lead, m) => {
|
|
21
|
+
// @ts-expect-error abstract class
|
|
22
|
+
new hr_1.HrToken(m, config, accum);
|
|
23
|
+
return `${lead}\0${accum.length - 1}r\x7F`;
|
|
24
|
+
}).replace(new RegExp(`__(${doubleUnderscore.flat().join('|')})__`, 'giu'), (m, p1) => {
|
|
25
|
+
const caseSensitive = sensitive.has(p1);
|
|
26
|
+
if (caseSensitive || insensitive.has(p1.toLowerCase())) {
|
|
27
|
+
// @ts-expect-error abstract class
|
|
28
|
+
new doubleUnderscore_1.DoubleUnderscoreToken(p1, caseSensitive, config, accum);
|
|
29
|
+
return `\0${accum.length - 1}u\x7F`;
|
|
30
|
+
}
|
|
31
|
+
return m;
|
|
32
|
+
}).replace(/^((?:\0\d+c\x7F)*)(={1,6})(.+)\2((?:[^\S\n]|\0\d+c\x7F)*)$/gmu, (_, lead, equals, heading, trail) => {
|
|
33
|
+
const text = `${lead}\0${accum.length}h\x7F`;
|
|
34
|
+
// @ts-expect-error abstract class
|
|
35
|
+
new heading_1.HeadingToken(equals.length, [heading, trail], config, accum);
|
|
36
|
+
return text;
|
|
37
|
+
});
|
|
38
|
+
return type === 'root' || type === 'ext-inner' && name === 'poem' ? data : data.slice(1);
|
|
39
|
+
};
|
|
40
|
+
exports.parseHrAndDoubleUnderscore = parseHrAndDoubleUnderscore;
|
|
41
|
+
constants_1.parsers['parseHrAndDoubleUnderscore'] = __filename;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseHtml = void 0;
|
|
4
|
+
const constants_1 = require("../util/constants");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const attributes_1 = require("../src/attributes");
|
|
7
|
+
const html_1 = require("../src/html");
|
|
8
|
+
/**
|
|
9
|
+
* 解析HTML标签
|
|
10
|
+
* @param wikitext
|
|
11
|
+
* @param config
|
|
12
|
+
* @param accum
|
|
13
|
+
*/
|
|
14
|
+
const parseHtml = (wikitext, config = index_1.default.getConfig(), accum = []) => {
|
|
15
|
+
const regex = /^(\/?)([a-z][^\s/>]*)((?:\s|\/(?!>))[^>]*?)?(\/?>)([^<]*)$/iu, elements = new Set(config.html.flat()), bits = wikitext.split('<');
|
|
16
|
+
let text = bits.shift();
|
|
17
|
+
for (const x of bits) {
|
|
18
|
+
const mt = regex.exec(x), t = mt?.[2], name = t?.toLowerCase();
|
|
19
|
+
if (!mt || !elements.has(name)) {
|
|
20
|
+
text += `<${x}`;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const [, slash, , params = '', brace, rest] = mt,
|
|
24
|
+
// @ts-expect-error abstract class
|
|
25
|
+
attr = new attributes_1.AttributesToken(params, 'html-attrs', name, config, accum), itemprop = attr.getAttr('itemprop');
|
|
26
|
+
if (name === 'meta' && (itemprop === undefined || attr.getAttr('content') === undefined)
|
|
27
|
+
|| name === 'link' && (itemprop === undefined || attr.getAttr('href') === undefined)) {
|
|
28
|
+
text += `<${x}`;
|
|
29
|
+
accum.pop();
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
text += `\0${accum.length}x\x7F${rest}`;
|
|
33
|
+
// @ts-expect-error abstract class
|
|
34
|
+
new html_1.HtmlToken(t, attr, slash === '/', brace === '/>', config, accum);
|
|
35
|
+
}
|
|
36
|
+
return text;
|
|
37
|
+
};
|
|
38
|
+
exports.parseHtml = parseHtml;
|
|
39
|
+
constants_1.parsers['parseHtml'] = __filename;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseLinks = void 0;
|
|
4
|
+
const constants_1 = require("../util/constants");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const index_2 = require("../src/link/index");
|
|
7
|
+
const file_1 = require("../src/link/file");
|
|
8
|
+
const category_1 = require("../src/link/category");
|
|
9
|
+
/**
|
|
10
|
+
* 解析内部链接
|
|
11
|
+
* @param wikitext
|
|
12
|
+
* @param config
|
|
13
|
+
* @param accum
|
|
14
|
+
*/
|
|
15
|
+
const parseLinks = (wikitext, config = index_1.default.getConfig(), accum = []) => {
|
|
16
|
+
const { parseQuotes } = require('./quotes');
|
|
17
|
+
const regex = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]]))?\]\](.*)$/su, regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(.*)$/su, regexExt = new RegExp(`^\\s*(?:${config.protocol}|//)`, 'iu'), bits = wikitext.split('[[');
|
|
18
|
+
let s = bits.shift();
|
|
19
|
+
for (let i = 0; i < bits.length; i++) {
|
|
20
|
+
let mightBeImg = false, link, delimiter, text, after;
|
|
21
|
+
const x = bits[i], m = regex.exec(x);
|
|
22
|
+
if (m) {
|
|
23
|
+
[, link, delimiter, text, after] = m;
|
|
24
|
+
if (after.startsWith(']') && text?.includes('[')) {
|
|
25
|
+
text += ']';
|
|
26
|
+
after = after.slice(1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const m2 = regexImg.exec(x);
|
|
31
|
+
if (m2) {
|
|
32
|
+
mightBeImg = true;
|
|
33
|
+
[, link, delimiter, text] = m2;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (link === undefined || regexExt.test(link) || /\0\d+[exhbru]\x7F/u.test(link)) {
|
|
37
|
+
s += `[[${x}`;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const force = link.trim().startsWith(':');
|
|
41
|
+
if (force && mightBeImg) {
|
|
42
|
+
s += `[[${x}`;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const title = index_1.default.normalizeTitle(link, 0, false, config, true, true, true), { ns, valid, interwiki } = title;
|
|
46
|
+
if (!valid) {
|
|
47
|
+
s += `[[${x}`;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
else if (mightBeImg) {
|
|
51
|
+
if (interwiki || ns !== 6) {
|
|
52
|
+
s += `[[${x}`;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
let found = false;
|
|
56
|
+
for (i++; i < bits.length; i++) {
|
|
57
|
+
const next = bits[i], p = next.split(']]');
|
|
58
|
+
if (p.length > 2) {
|
|
59
|
+
found = true;
|
|
60
|
+
text += `[[${p[0]}]]${p[1]}`;
|
|
61
|
+
after = p.slice(2).join(']]');
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
else if (p.length === 2) {
|
|
65
|
+
text += `[[${p[0]}]]${p[1]}`;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
text += `[[${next}`;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
text = (0, exports.parseLinks)(text, config, accum);
|
|
73
|
+
if (!found) {
|
|
74
|
+
s += `[[${link}${delimiter}${text}`;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
text &&= parseQuotes(text, config, accum);
|
|
79
|
+
s += `\0${accum.length}l\x7F${after}`;
|
|
80
|
+
let SomeLinkToken = index_2.LinkToken;
|
|
81
|
+
if (!force) {
|
|
82
|
+
if (!interwiki && ns === 6) {
|
|
83
|
+
SomeLinkToken = file_1.FileToken;
|
|
84
|
+
}
|
|
85
|
+
else if (!interwiki && ns === 14) {
|
|
86
|
+
SomeLinkToken = category_1.CategoryToken;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// @ts-expect-error abstract class
|
|
90
|
+
new SomeLinkToken(link, text, config, accum, delimiter);
|
|
91
|
+
}
|
|
92
|
+
return s;
|
|
93
|
+
};
|
|
94
|
+
exports.parseLinks = parseLinks;
|
|
95
|
+
constants_1.parsers['parseLinks'] = __filename;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseList = void 0;
|
|
4
|
+
const constants_1 = require("../util/constants");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const list_1 = require("../src/nowiki/list");
|
|
7
|
+
const dd_1 = require("../src/nowiki/dd");
|
|
8
|
+
/**
|
|
9
|
+
* 解析列表
|
|
10
|
+
* @param wikitext
|
|
11
|
+
* @param config
|
|
12
|
+
* @param accum
|
|
13
|
+
*/
|
|
14
|
+
const parseList = (wikitext, config = index_1.default.getConfig(), accum = []) => {
|
|
15
|
+
const mt = /^((?:\0\d+c\x7F)*)([;:*#]+)/u.exec(wikitext);
|
|
16
|
+
if (!mt) {
|
|
17
|
+
return wikitext;
|
|
18
|
+
}
|
|
19
|
+
const [total, comment, prefix] = mt;
|
|
20
|
+
let text = `${comment}\0${accum.length}d\x7F${wikitext.slice(total.length)}`, dt = prefix.split(';').length - 1;
|
|
21
|
+
// @ts-expect-error abstract class
|
|
22
|
+
new list_1.ListToken(prefix, config, accum);
|
|
23
|
+
if (!dt) {
|
|
24
|
+
return text;
|
|
25
|
+
}
|
|
26
|
+
const { html: [normalTags] } = config, fullRegex = /:+|-\{|\0\d+[xq]\x7F/gu;
|
|
27
|
+
let regex = fullRegex, ex = regex.exec(text), lt = 0, lb = false, li = false, lc = 0;
|
|
28
|
+
/**
|
|
29
|
+
* 创建`DdToken`
|
|
30
|
+
* @param syntax `:`
|
|
31
|
+
* @param index 起点
|
|
32
|
+
*/
|
|
33
|
+
const dd = (syntax, index) => {
|
|
34
|
+
// @ts-expect-error abstract class
|
|
35
|
+
new dd_1.DdToken(syntax, config, accum);
|
|
36
|
+
return `${text.slice(0, index)}\0${accum.length - 1}d\x7F${text.slice(index + syntax.length)}`;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* 更新 `lt`
|
|
40
|
+
* @param closing 是否是闭合标签
|
|
41
|
+
*/
|
|
42
|
+
const update = (closing) => {
|
|
43
|
+
if (!closing) {
|
|
44
|
+
lt++;
|
|
45
|
+
}
|
|
46
|
+
else if (lt) {
|
|
47
|
+
lt--;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
while (ex && dt) {
|
|
51
|
+
const { 0: syntax, index } = ex;
|
|
52
|
+
if (syntax === '-{') {
|
|
53
|
+
if (!lc) {
|
|
54
|
+
const { lastIndex } = regex;
|
|
55
|
+
regex = /-\{|\}-/gu;
|
|
56
|
+
regex.lastIndex = lastIndex;
|
|
57
|
+
}
|
|
58
|
+
lc++;
|
|
59
|
+
}
|
|
60
|
+
else if (syntax === '}-') {
|
|
61
|
+
lc--;
|
|
62
|
+
if (!lc) {
|
|
63
|
+
const { lastIndex } = regex;
|
|
64
|
+
regex = fullRegex;
|
|
65
|
+
regex.lastIndex = lastIndex;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (syntax.endsWith('x\x7F')) {
|
|
69
|
+
const { name, closing, selfClosing } = accum[Number(syntax.slice(1, -2))];
|
|
70
|
+
if (!selfClosing || normalTags.includes(name)) {
|
|
71
|
+
update(closing);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (syntax.endsWith('q\x7F')) {
|
|
75
|
+
const { bold, italic } = accum[Number(syntax.slice(1, -2))];
|
|
76
|
+
if (bold) {
|
|
77
|
+
update(lb);
|
|
78
|
+
lb = !lb;
|
|
79
|
+
}
|
|
80
|
+
if (italic) {
|
|
81
|
+
update(li);
|
|
82
|
+
li = !li;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (lt === 0) { // syntax === ':'
|
|
86
|
+
if (syntax.length >= dt) {
|
|
87
|
+
return dd(syntax.slice(0, dt), index);
|
|
88
|
+
}
|
|
89
|
+
dt -= syntax.length;
|
|
90
|
+
regex.lastIndex = index + 4 + String(accum.length).length;
|
|
91
|
+
text = dd(syntax, index);
|
|
92
|
+
}
|
|
93
|
+
ex = regex.exec(text);
|
|
94
|
+
}
|
|
95
|
+
return text;
|
|
96
|
+
};
|
|
97
|
+
exports.parseList = parseList;
|
|
98
|
+
constants_1.parsers['parseList'] = __filename;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseMagicLinks = void 0;
|
|
4
|
+
const string_1 = require("../util/string");
|
|
5
|
+
const constants_1 = require("../util/constants");
|
|
6
|
+
const index_1 = require("../index");
|
|
7
|
+
const magicLink_1 = require("../src/magicLink");
|
|
8
|
+
/**
|
|
9
|
+
* 解析自由外链
|
|
10
|
+
* @param wikitext
|
|
11
|
+
* @param config
|
|
12
|
+
* @param accum
|
|
13
|
+
*/
|
|
14
|
+
const parseMagicLinks = (wikitext, config = index_1.default.getConfig(), accum = []) => {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
16
|
+
/(^|[^\p{L}\d_])((?:\[[\da-f:.]+\]|[^[\]<>"\t\n\p{Zs}])(?:[^[\]<>"\0\t\n\p{Zs}]|\0\d+c\x7F)*)/giu;
|
|
17
|
+
const regex = new RegExp(`(^|[^\\p{L}\\d_])(?:${config.protocol})(${string_1.extUrlCharFirst}${string_1.extUrlChar})`, 'giu');
|
|
18
|
+
return wikitext.replace(regex, (m, lead, p1) => {
|
|
19
|
+
let trail = '', url = lead ? m.slice(1) : m;
|
|
20
|
+
const m2 = /&(?:lt|gt|nbsp|#x0*(?:3[ce]|a0)|#0*(?:6[02]|160));/iu.exec(url);
|
|
21
|
+
if (m2) {
|
|
22
|
+
trail = url.slice(m2.index);
|
|
23
|
+
url = url.slice(0, m2.index);
|
|
24
|
+
}
|
|
25
|
+
const sep = new RegExp(`[,;.:!?${url.includes('(') ? '' : ')'}]+$`, 'u'), sepChars = sep.exec(url);
|
|
26
|
+
if (sepChars) {
|
|
27
|
+
let correction = 0;
|
|
28
|
+
if (sepChars[0].startsWith(';') && /&(?:[a-z]+|#x[\da-f]+|#\d+)$/iu.test(url.slice(0, sepChars.index))) {
|
|
29
|
+
correction = 1;
|
|
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;
|
|
36
|
+
}
|
|
37
|
+
// @ts-expect-error abstract class
|
|
38
|
+
new magicLink_1.MagicLinkToken(url, false, config, accum);
|
|
39
|
+
return `${lead}\0${accum.length - 1}w\x7F${trail}`;
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
exports.parseMagicLinks = parseMagicLinks;
|
|
43
|
+
constants_1.parsers['parseMagicLinks'] = __filename;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseQuotes = void 0;
|
|
4
|
+
const constants_1 = require("../util/constants");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const quote_1 = require("../src/nowiki/quote");
|
|
7
|
+
/**
|
|
8
|
+
* 解析单引号
|
|
9
|
+
* @param wikitext
|
|
10
|
+
* @param config
|
|
11
|
+
* @param accum
|
|
12
|
+
*/
|
|
13
|
+
const parseQuotes = (wikitext, config = index_1.default.getConfig(), accum = []) => {
|
|
14
|
+
const arr = wikitext.split(/('{2,})/u), { length } = arr;
|
|
15
|
+
if (length === 1) {
|
|
16
|
+
return wikitext;
|
|
17
|
+
}
|
|
18
|
+
let nBold = 0, nItalic = 0, firstSingle, firstMulti, firstSpace;
|
|
19
|
+
for (let i = 1; i < length; i += 2) {
|
|
20
|
+
const len = arr[i].length;
|
|
21
|
+
switch (len) {
|
|
22
|
+
case 2:
|
|
23
|
+
nItalic++;
|
|
24
|
+
break;
|
|
25
|
+
case 4:
|
|
26
|
+
arr[i - 1] += `'`;
|
|
27
|
+
arr[i] = `'''`;
|
|
28
|
+
// fall through
|
|
29
|
+
case 3:
|
|
30
|
+
nBold++;
|
|
31
|
+
if (firstSingle !== undefined) {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
else if (arr[i - 1].endsWith(' ')) {
|
|
35
|
+
if (firstMulti === undefined && firstSpace === undefined) {
|
|
36
|
+
firstSpace = i;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (arr[i - 1].slice(-2, -1) === ' ') {
|
|
40
|
+
firstSingle = i;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
firstMulti ??= i;
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
arr[i - 1] += `'`.repeat(len - 5);
|
|
48
|
+
arr[i] = `'''''`;
|
|
49
|
+
nItalic++;
|
|
50
|
+
nBold++;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (nItalic % 2 === 1 && nBold % 2 === 1) {
|
|
54
|
+
const i = firstSingle ?? firstMulti ?? firstSpace;
|
|
55
|
+
if (i !== undefined) {
|
|
56
|
+
arr[i] = `''`;
|
|
57
|
+
arr[i - 1] += `'`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (let i = 1; i < length; i += 2) {
|
|
61
|
+
// @ts-expect-error abstract class
|
|
62
|
+
new quote_1.QuoteToken(arr[i], config, accum);
|
|
63
|
+
arr[i] = `\0${accum.length - 1}q\x7F`;
|
|
64
|
+
}
|
|
65
|
+
return arr.join('');
|
|
66
|
+
};
|
|
67
|
+
exports.parseQuotes = parseQuotes;
|
|
68
|
+
constants_1.parsers['parseQuotes'] = __filename;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSelector = void 0;
|
|
4
|
+
const constants_1 = require("../util/constants");
|
|
5
|
+
const string_1 = require("../util/string");
|
|
6
|
+
const index_1 = require("../index");
|
|
7
|
+
const simplePseudos = new Set([
|
|
8
|
+
'root',
|
|
9
|
+
'first-child',
|
|
10
|
+
'first-of-type',
|
|
11
|
+
'last-child',
|
|
12
|
+
'last-of-type',
|
|
13
|
+
'only-child',
|
|
14
|
+
'only-of-type',
|
|
15
|
+
'empty',
|
|
16
|
+
'parent',
|
|
17
|
+
'header',
|
|
18
|
+
'hidden',
|
|
19
|
+
'visible',
|
|
20
|
+
'only-whitespace',
|
|
21
|
+
'any-link',
|
|
22
|
+
'local-link',
|
|
23
|
+
'invalid',
|
|
24
|
+
'required',
|
|
25
|
+
'optional',
|
|
26
|
+
]);
|
|
27
|
+
const complexPseudos = [
|
|
28
|
+
'is',
|
|
29
|
+
'not',
|
|
30
|
+
'nth-child',
|
|
31
|
+
'nth-of-type',
|
|
32
|
+
'nth-last-child',
|
|
33
|
+
'nth-last-of-type',
|
|
34
|
+
'contains',
|
|
35
|
+
'has',
|
|
36
|
+
'lang',
|
|
37
|
+
'regex',
|
|
38
|
+
];
|
|
39
|
+
const specialChars = [
|
|
40
|
+
['[', '['],
|
|
41
|
+
[']', ']'],
|
|
42
|
+
['(', '('],
|
|
43
|
+
[')', ')'],
|
|
44
|
+
['"', '"'],
|
|
45
|
+
[`'`, '''],
|
|
46
|
+
[':', ':'],
|
|
47
|
+
['\\', '\'],
|
|
48
|
+
['&', '&'],
|
|
49
|
+
];
|
|
50
|
+
const pseudoRegex = new RegExp(`:(${complexPseudos.join('|')})$`, 'u'), regularRegex = /[[(,>+~]|\s+/u, attributeRegex = /^\s*(\w+)\s*(?:([~|^$*!]?=)\s*("[^"]*"|'[^']*'|[^\s[\]]+)(?:\s+(i))?\s*)?\]/u, functionRegex = /^(\s*"[^"]*"\s*|\s*'[^']*'\s*|[^()]*)\)/u, grouping = new Set([',', '>', '+', '~']), combinator = new Set(['>', '+', '~', '']);
|
|
51
|
+
/**
|
|
52
|
+
* 清理转义符号
|
|
53
|
+
* @param selector
|
|
54
|
+
*/
|
|
55
|
+
const sanitize = (selector) => {
|
|
56
|
+
for (const [c, escaped] of specialChars) {
|
|
57
|
+
selector = selector.replace(new RegExp((0, string_1.escapeRegExp)(`\\${c}`), 'gu'), escaped);
|
|
58
|
+
}
|
|
59
|
+
return selector;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* 还原转义符号
|
|
63
|
+
* @param selector
|
|
64
|
+
*/
|
|
65
|
+
const desanitize = (selector) => {
|
|
66
|
+
for (const [c, escaped] of specialChars) {
|
|
67
|
+
selector = selector.replace(new RegExp(escaped, 'gu'), c);
|
|
68
|
+
}
|
|
69
|
+
return selector.trim();
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* 去除首尾的引号
|
|
73
|
+
* @param val 属性值或伪选择器函数的参数
|
|
74
|
+
*/
|
|
75
|
+
const deQuote = (val) => /^(["']).*\1$/u.test(val) ? val.slice(1, -1) : val.trim();
|
|
76
|
+
/**
|
|
77
|
+
* 解析选择器
|
|
78
|
+
* @param selector
|
|
79
|
+
* @throws `SyntaxError` 非法的选择器
|
|
80
|
+
*/
|
|
81
|
+
const parseSelector = (selector) => {
|
|
82
|
+
selector = selector.trim();
|
|
83
|
+
const stack = [[[]]];
|
|
84
|
+
let sanitized = sanitize(selector), regex = regularRegex, mt = regex.exec(sanitized), [condition] = stack, [step] = condition;
|
|
85
|
+
/**
|
|
86
|
+
* 解析简单伪选择器
|
|
87
|
+
* @param index 伪选择器的终点位置
|
|
88
|
+
* @throws `SyntaxError` 非法的选择器
|
|
89
|
+
*/
|
|
90
|
+
const pushSimple = (index) => {
|
|
91
|
+
const str = sanitized.slice(0, index), pieces = str.trim().split(':'),
|
|
92
|
+
// eslint-disable-next-line unicorn/explicit-length-check
|
|
93
|
+
i = pieces.slice(1).findIndex(pseudo => simplePseudos.has(pseudo)) + 1 || pieces.length;
|
|
94
|
+
if (pieces.slice(i).some(pseudo => !simplePseudos.has(pseudo))) {
|
|
95
|
+
throw new SyntaxError(`非法的选择器!\n${str}\n可能需要将':'转义为'\\:'。`);
|
|
96
|
+
}
|
|
97
|
+
step.push(desanitize(pieces.slice(0, i).join(':')), ...pieces.slice(i).map(piece => `:${piece}`));
|
|
98
|
+
};
|
|
99
|
+
while (mt) {
|
|
100
|
+
let { 0: syntax, index } = mt;
|
|
101
|
+
if (syntax.trim() === '') {
|
|
102
|
+
index += syntax.length;
|
|
103
|
+
const char = sanitized[index];
|
|
104
|
+
syntax = grouping.has(char) ? char : '';
|
|
105
|
+
}
|
|
106
|
+
if (syntax === ',') { // 情形1:并列
|
|
107
|
+
pushSimple(index);
|
|
108
|
+
condition = [[]];
|
|
109
|
+
[step] = condition;
|
|
110
|
+
stack.push(condition);
|
|
111
|
+
}
|
|
112
|
+
else if (combinator.has(syntax)) { // 情形2:关系
|
|
113
|
+
pushSimple(index);
|
|
114
|
+
if (!step.some(Boolean)) {
|
|
115
|
+
throw new SyntaxError(`非法的选择器!\n${selector}\n可能需要通用选择器'*'。`);
|
|
116
|
+
}
|
|
117
|
+
step.relation = syntax;
|
|
118
|
+
step = [];
|
|
119
|
+
condition.push(step);
|
|
120
|
+
}
|
|
121
|
+
else if (syntax === '[') { // 情形3:属性开启
|
|
122
|
+
pushSimple(index);
|
|
123
|
+
regex = attributeRegex;
|
|
124
|
+
}
|
|
125
|
+
else if (syntax.endsWith(']')) { // 情形4:属性闭合
|
|
126
|
+
mt[3] &&= desanitize(deQuote(mt[3]));
|
|
127
|
+
step.push(mt.slice(1));
|
|
128
|
+
regex = regularRegex;
|
|
129
|
+
}
|
|
130
|
+
else if (syntax === '(') { // 情形5:伪选择器开启
|
|
131
|
+
const pseudoExec = pseudoRegex.exec(sanitized.slice(0, index));
|
|
132
|
+
if (!pseudoExec) {
|
|
133
|
+
throw new SyntaxError(`非法的选择器!\n${desanitize(sanitized)}\n请检查伪选择器是否存在。`);
|
|
134
|
+
}
|
|
135
|
+
pushSimple(pseudoExec.index);
|
|
136
|
+
step.push(pseudoExec[1]); // 临时存放复杂伪选择器
|
|
137
|
+
regex = functionRegex;
|
|
138
|
+
}
|
|
139
|
+
else { // 情形6:伪选择器闭合
|
|
140
|
+
mt.push(step.pop());
|
|
141
|
+
mt[1] &&= deQuote(mt[1]);
|
|
142
|
+
step.push(mt.slice(1));
|
|
143
|
+
regex = regularRegex;
|
|
144
|
+
}
|
|
145
|
+
sanitized = sanitized.slice(index + syntax.length);
|
|
146
|
+
if (grouping.has(syntax)) {
|
|
147
|
+
sanitized = sanitized.trim();
|
|
148
|
+
}
|
|
149
|
+
mt = regex.exec(sanitized);
|
|
150
|
+
}
|
|
151
|
+
if (regex === regularRegex) {
|
|
152
|
+
pushSimple(Infinity);
|
|
153
|
+
const pseudos = new Set(stack.flat(2).filter((e) => typeof e === 'string' && e.startsWith(':')));
|
|
154
|
+
if (pseudos.size > 0) {
|
|
155
|
+
index_1.default.warn('检测到伪选择器,请确认是否需要将":"转义成"\\:"。', pseudos);
|
|
156
|
+
}
|
|
157
|
+
return stack;
|
|
158
|
+
}
|
|
159
|
+
throw new SyntaxError(`非法的选择器!\n${selector}\n检测到未闭合的'${regex === attributeRegex ? '[' : '('}'`);
|
|
160
|
+
};
|
|
161
|
+
exports.parseSelector = parseSelector;
|
|
162
|
+
constants_1.parsers['parseSelector'] = __filename;
|