wikiparser-node 1.5.1 → 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/default.json +1 -2
- package/config/enwiki.json +1 -2
- package/dist/lib/element.js +0 -4
- package/dist/lib/text.js +11 -1
- package/dist/lib/title.d.ts +3 -3
- package/dist/lib/title.js +13 -11
- package/dist/parser/list.js +27 -9
- package/dist/src/attribute.d.ts +2 -0
- package/dist/src/attribute.js +1 -1
- package/dist/src/imageParameter.d.ts +1 -1
- package/dist/src/imageParameter.js +11 -5
- package/dist/src/link/file.d.ts +2 -0
- package/dist/src/link/file.js +9 -2
- package/dist/src/table/td.d.ts +0 -6
- package/dist/src/table/td.js +1 -5
- package/package.json +1 -1
package/config/default.json
CHANGED
package/config/enwiki.json
CHANGED
package/dist/lib/element.js
CHANGED
package/dist/lib/text.js
CHANGED
|
@@ -121,8 +121,18 @@ class AstText extends node_1.AstNode {
|
|
|
121
121
|
throw new Error('无法对孤立文本节点进行语法分析!');
|
|
122
122
|
/* NOT FOR BROWSER END */
|
|
123
123
|
}
|
|
124
|
+
const { type, name, parentNode: grandparent } = parentNode, nowiki = name === 'nowiki' || name === 'pre';
|
|
125
|
+
let isHtmlAttrVal = false;
|
|
126
|
+
if (type === 'attr-value') {
|
|
127
|
+
const { type: grandType, name: grandName, tag } = grandparent;
|
|
128
|
+
if (grandType !== 'ext-attr') {
|
|
129
|
+
isHtmlAttrVal = true;
|
|
130
|
+
}
|
|
131
|
+
else if (tag === 'choose' && (grandName === 'before' || grandName === 'after')) {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
124
135
|
const { NowikiToken } = require('../src/nowiki');
|
|
125
|
-
const { type, name } = parentNode, nowiki = name === 'nowiki' || name === 'pre', isHtmlAttrVal = type === 'attr-value' && parentNode.parentNode.type !== 'ext-attr';
|
|
126
136
|
let errorRegex;
|
|
127
137
|
if (type === 'ext-inner' && (name === 'pre' || parentNode instanceof NowikiToken)) {
|
|
128
138
|
errorRegex = new RegExp(`<\\s*(?:\\/\\s*)${nowiki ? '' : '?'}(${name})\\b`, 'giu');
|
package/dist/lib/title.d.ts
CHANGED
|
@@ -9,13 +9,13 @@ export declare class Title {
|
|
|
9
9
|
/** 不含命名空间的标题主体部分 */
|
|
10
10
|
get main(): string;
|
|
11
11
|
set main(title: string);
|
|
12
|
+
/** 扩展名 */
|
|
13
|
+
get extension(): string | undefined;
|
|
14
|
+
set extension(extension: string | undefined);
|
|
12
15
|
/** 命名空间前缀 */
|
|
13
16
|
get prefix(): string;
|
|
14
17
|
/** 完整标题 */
|
|
15
18
|
get title(): string;
|
|
16
|
-
/** 扩展名 */
|
|
17
|
-
get extension(): string | undefined;
|
|
18
|
-
set extension(extension: string | undefined);
|
|
19
19
|
/**
|
|
20
20
|
* @param title 标题(含或不含命名空间前缀)
|
|
21
21
|
* @param defaultNs 命名空间
|
package/dist/lib/title.js
CHANGED
|
@@ -11,14 +11,15 @@ class Title {
|
|
|
11
11
|
fragment;
|
|
12
12
|
/** @private */
|
|
13
13
|
encoded = false;
|
|
14
|
+
#main;
|
|
14
15
|
/* NOT FOR BROWSER */
|
|
15
16
|
#namespaces;
|
|
16
|
-
#main;
|
|
17
17
|
interwiki = '';
|
|
18
18
|
/** @private */
|
|
19
19
|
conversionTable = new Map();
|
|
20
20
|
/** @private */
|
|
21
21
|
redirects = new Map();
|
|
22
|
+
/* NOT FOR BROWSER END */
|
|
22
23
|
/** 不含命名空间的标题主体部分 */
|
|
23
24
|
get main() {
|
|
24
25
|
return this.#main;
|
|
@@ -27,6 +28,16 @@ class Title {
|
|
|
27
28
|
title = title.replace(/_/gu, ' ').trim();
|
|
28
29
|
this.#main = title && `${title[0].toUpperCase()}${title.slice(1)}`;
|
|
29
30
|
}
|
|
31
|
+
/** 扩展名 */
|
|
32
|
+
get extension() {
|
|
33
|
+
const { main } = this, i = main.lastIndexOf('.');
|
|
34
|
+
return i === -1 ? undefined : main.slice(i + 1).toLowerCase();
|
|
35
|
+
}
|
|
36
|
+
/* NOT FOR BROWSER */
|
|
37
|
+
set extension(extension) {
|
|
38
|
+
const { main } = this, i = main.lastIndexOf('.');
|
|
39
|
+
this.main = `${i === -1 ? main : main.slice(0, i)}.${extension}`;
|
|
40
|
+
}
|
|
30
41
|
/** 命名空间前缀 */
|
|
31
42
|
get prefix() {
|
|
32
43
|
const namespace = this.#namespaces[this.ns];
|
|
@@ -44,15 +55,6 @@ class Title {
|
|
|
44
55
|
title = `${prefix}${this.main}`.replace(/ /gu, '_');
|
|
45
56
|
return this.redirects.get(title) ?? title;
|
|
46
57
|
}
|
|
47
|
-
/** 扩展名 */
|
|
48
|
-
get extension() {
|
|
49
|
-
const { main } = this, i = main.lastIndexOf('.');
|
|
50
|
-
return i === -1 ? undefined : main.slice(i + 1).toLowerCase();
|
|
51
|
-
}
|
|
52
|
-
set extension(extension) {
|
|
53
|
-
const { main } = this, i = main.lastIndexOf('.');
|
|
54
|
-
this.main = `${i === -1 ? main : main.slice(0, i)}.${extension}`;
|
|
55
|
-
}
|
|
56
58
|
/* NOT FOR BROWSER END */
|
|
57
59
|
/**
|
|
58
60
|
* @param title 标题(含或不含命名空间前缀)
|
|
@@ -112,9 +114,9 @@ class Title {
|
|
|
112
114
|
}
|
|
113
115
|
this.valid = Boolean(title || this.interwiki || selfLink && this.fragment !== undefined)
|
|
114
116
|
&& !/^:|\0\d+[eh!+-]\x7F|[<>[\]{}|]|%[\da-f]{2}/iu.test(title);
|
|
117
|
+
this.main = title;
|
|
115
118
|
/* NOT FOR BROWSER */
|
|
116
119
|
this.#namespaces = config.namespaces;
|
|
117
|
-
this.main = title;
|
|
118
120
|
Object.defineProperties(this, {
|
|
119
121
|
valid: { writable: false },
|
|
120
122
|
encoded: { enumerable: false, writable: false },
|
package/dist/parser/list.js
CHANGED
|
@@ -23,8 +23,8 @@ const parseList = (wikitext, config = index_1.default.getConfig(), accum = []) =
|
|
|
23
23
|
if (!dt) {
|
|
24
24
|
return text;
|
|
25
25
|
}
|
|
26
|
-
const { html: [normalTags] } = config, fullRegex = /:+|-\{|\0\d+
|
|
27
|
-
let regex = fullRegex, ex = regex.exec(text), lt = 0, lc = 0;
|
|
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
28
|
/**
|
|
29
29
|
* 创建`DdToken`
|
|
30
30
|
* @param syntax `:`
|
|
@@ -35,6 +35,18 @@ const parseList = (wikitext, config = index_1.default.getConfig(), accum = []) =
|
|
|
35
35
|
new dd_1.DdToken(syntax, config, accum);
|
|
36
36
|
return `${text.slice(0, index)}\0${accum.length - 1}d\x7F${text.slice(index + syntax.length)}`;
|
|
37
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
|
+
};
|
|
38
50
|
while (ex && dt) {
|
|
39
51
|
const { 0: syntax, index } = ex;
|
|
40
52
|
if (syntax === '-{') {
|
|
@@ -53,15 +65,21 @@ const parseList = (wikitext, config = index_1.default.getConfig(), accum = []) =
|
|
|
53
65
|
regex.lastIndex = lastIndex;
|
|
54
66
|
}
|
|
55
67
|
}
|
|
56
|
-
else if (syntax.
|
|
68
|
+
else if (syntax.endsWith('x\x7F')) {
|
|
57
69
|
const { name, closing, selfClosing } = accum[Number(syntax.slice(1, -2))];
|
|
58
70
|
if (!selfClosing || normalTags.includes(name)) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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;
|
|
65
83
|
}
|
|
66
84
|
}
|
|
67
85
|
else if (lt === 0) { // syntax === ':'
|
package/dist/src/attribute.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export declare abstract class AttributeToken extends Token {
|
|
|
24
24
|
abstract get parentElement(): AttributesToken | undefined;
|
|
25
25
|
abstract get nextElementSibling(): AtomToken | this | undefined;
|
|
26
26
|
abstract get previousElementSibling(): AtomToken | this | undefined;
|
|
27
|
+
/** 标签名 */
|
|
28
|
+
get tag(): string;
|
|
27
29
|
/** 引号是否匹配 */
|
|
28
30
|
get balanced(): boolean;
|
|
29
31
|
set balanced(value: boolean);
|
package/dist/src/attribute.js
CHANGED
|
@@ -37,7 +37,7 @@ export declare abstract class ImageParameterToken extends Token {
|
|
|
37
37
|
get height(): string | undefined;
|
|
38
38
|
set height(height: string | undefined);
|
|
39
39
|
/** @param str 图片参数 */
|
|
40
|
-
constructor(str: string, config?: Parser.Config, accum?: Token[]);
|
|
40
|
+
constructor(str: string, extension: string | undefined, config?: Parser.Config, accum?: Token[]);
|
|
41
41
|
/** @override */
|
|
42
42
|
text(): string;
|
|
43
43
|
/** @override */
|
|
@@ -8,7 +8,7 @@ const constants_1 = require("../util/constants");
|
|
|
8
8
|
const index_1 = require("../index");
|
|
9
9
|
const index_2 = require("./index");
|
|
10
10
|
exports.galleryParams = new Set(['alt', 'link', 'lang', 'page', 'caption']);
|
|
11
|
-
function validate(key, val, config
|
|
11
|
+
function validate(key, val, config, halfParsed = false, ext) {
|
|
12
12
|
val = val.trim();
|
|
13
13
|
let value = val.replace(/\0\d+t\x7F/gu, '').trim();
|
|
14
14
|
switch (key) {
|
|
@@ -31,11 +31,13 @@ function validate(key, val, config = index_1.default.getConfig(), halfParsed = f
|
|
|
31
31
|
return title.valid && title;
|
|
32
32
|
}
|
|
33
33
|
case 'lang':
|
|
34
|
-
return
|
|
34
|
+
return (ext === 'svg' || ext === 'svgz') && !/[^a-z\d-]/u.test(value);
|
|
35
35
|
case 'alt':
|
|
36
36
|
case 'class':
|
|
37
37
|
case 'manualthumb':
|
|
38
38
|
return true;
|
|
39
|
+
case 'page':
|
|
40
|
+
return (ext === 'djvu' || ext === 'djv') && Number(value) > 0;
|
|
39
41
|
default:
|
|
40
42
|
return !Number.isNaN(Number(value));
|
|
41
43
|
}
|
|
@@ -44,6 +46,7 @@ function validate(key, val, config = index_1.default.getConfig(), halfParsed = f
|
|
|
44
46
|
class ImageParameterToken extends index_2.Token {
|
|
45
47
|
type = 'image-parameter';
|
|
46
48
|
#syntax = '';
|
|
49
|
+
#extension;
|
|
47
50
|
/* NOT FOR BROWSER END */
|
|
48
51
|
/** 图片链接 */
|
|
49
52
|
get link() {
|
|
@@ -106,7 +109,7 @@ class ImageParameterToken extends index_2.Token {
|
|
|
106
109
|
}
|
|
107
110
|
/* NOT FOR BROWSER END */
|
|
108
111
|
/** @param str 图片参数 */
|
|
109
|
-
constructor(str, config = index_1.default.getConfig(), accum = []) {
|
|
112
|
+
constructor(str, extension, config = index_1.default.getConfig(), accum = []) {
|
|
110
113
|
let mt;
|
|
111
114
|
const regexes = Object.entries(config.img).map(([syntax, param]) => [
|
|
112
115
|
syntax,
|
|
@@ -115,7 +118,8 @@ class ImageParameterToken extends index_2.Token {
|
|
|
115
118
|
]), param = regexes.find(([, key, regex]) => {
|
|
116
119
|
mt = regex.exec(str);
|
|
117
120
|
return mt
|
|
118
|
-
&& (mt.length !== 4
|
|
121
|
+
&& (mt.length !== 4
|
|
122
|
+
|| validate(key, mt[2], config, true, extension) !== false);
|
|
119
123
|
});
|
|
120
124
|
// @ts-expect-error mt already assigned
|
|
121
125
|
if (param && mt) {
|
|
@@ -135,6 +139,8 @@ class ImageParameterToken extends index_2.Token {
|
|
|
135
139
|
super(str, { ...config, excludes: [...config.excludes ?? [], 'list'] }, accum);
|
|
136
140
|
this.setAttribute('name', 'caption');
|
|
137
141
|
this.setAttribute('stage', 7);
|
|
142
|
+
/* NOT FOR BROWSER */
|
|
143
|
+
this.#extension = extension;
|
|
138
144
|
}
|
|
139
145
|
/** @private */
|
|
140
146
|
afterBuild() {
|
|
@@ -201,7 +207,7 @@ class ImageParameterToken extends index_2.Token {
|
|
|
201
207
|
const cloned = this.cloneChildNodes(), config = this.getAttribute('config');
|
|
202
208
|
return debug_1.Shadow.run(() => {
|
|
203
209
|
// @ts-expect-error abstract class
|
|
204
|
-
const token = new ImageParameterToken(this.#syntax.replace('$1', ''), config);
|
|
210
|
+
const token = new ImageParameterToken(this.#syntax.replace('$1', ''), this.#extension, config);
|
|
205
211
|
token.replaceChildren(...cloned);
|
|
206
212
|
token.setAttribute('name', this.name);
|
|
207
213
|
token.setAttribute('syntax', this.#syntax);
|
package/dist/src/link/file.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export declare abstract class FileToken extends LinkBaseToken {
|
|
|
15
15
|
abstract get lastChild(): AtomToken | ImageParameterToken;
|
|
16
16
|
abstract get children(): [AtomToken, ...ImageParameterToken[]];
|
|
17
17
|
abstract get lastElementChild(): AtomToken | ImageParameterToken;
|
|
18
|
+
/** 扩展名 */
|
|
19
|
+
get extension(): string | undefined;
|
|
18
20
|
/** 图片链接 */
|
|
19
21
|
get link(): string | Title;
|
|
20
22
|
set link(value: string);
|
package/dist/src/link/file.js
CHANGED
|
@@ -42,6 +42,12 @@ const explode = (start, end, separator, str) => {
|
|
|
42
42
|
*/
|
|
43
43
|
class FileToken extends base_1.LinkBaseToken {
|
|
44
44
|
type = 'file';
|
|
45
|
+
/* NOT FOR BROWSER END */
|
|
46
|
+
/** 扩展名 */
|
|
47
|
+
get extension() {
|
|
48
|
+
return this.getTitle().extension;
|
|
49
|
+
}
|
|
50
|
+
/* NOT FOR BROWSER */
|
|
45
51
|
/** 图片链接 */
|
|
46
52
|
get link() {
|
|
47
53
|
return this.getArg('link')?.link ?? super.link;
|
|
@@ -93,9 +99,10 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
93
99
|
/* NOT FOR BROWSER */
|
|
94
100
|
this.setAttribute('acceptable', { AtomToken: 0, ImageParameterToken: '1:' });
|
|
95
101
|
/* NOT FOR BROWSER END */
|
|
102
|
+
const { extension } = this;
|
|
96
103
|
this.append(...explode('-{', '}-', '|', text).map(
|
|
97
104
|
// @ts-expect-error abstract class
|
|
98
|
-
part => new imageParameter_1.ImageParameterToken(part, config, accum)));
|
|
105
|
+
part => new imageParameter_1.ImageParameterToken(part, extension, config, accum)));
|
|
99
106
|
}
|
|
100
107
|
/** @override */
|
|
101
108
|
lint(start = this.getAbsoluteIndex()) {
|
|
@@ -245,7 +252,7 @@ class FileToken extends base_1.LinkBaseToken {
|
|
|
245
252
|
}
|
|
246
253
|
const parameter = debug_1.Shadow.run(
|
|
247
254
|
// @ts-expect-error abstract class
|
|
248
|
-
() => new imageParameter_1.ImageParameterToken(syntax.replace('$1', ''), config));
|
|
255
|
+
() => new imageParameter_1.ImageParameterToken(syntax.replace('$1', ''), this.extension, config));
|
|
249
256
|
if (free) {
|
|
250
257
|
const { childNodes } = index_1.default.parse(value, this.getAttribute('include'), undefined, config);
|
|
251
258
|
parameter.replaceChildren(...childNodes);
|
package/dist/src/table/td.d.ts
CHANGED
|
@@ -54,12 +54,6 @@ export declare abstract class TdToken extends TableBaseToken {
|
|
|
54
54
|
isIndependent(): boolean;
|
|
55
55
|
/** @override */
|
|
56
56
|
cloneNode(): this;
|
|
57
|
-
/**
|
|
58
|
-
* @override
|
|
59
|
-
* @param syntax 表格语法
|
|
60
|
-
* @param esc 是否需要转义
|
|
61
|
-
*/
|
|
62
|
-
setSyntax(syntax: string, esc?: boolean): void;
|
|
63
57
|
/** 改为独占一行 */
|
|
64
58
|
independence(): void;
|
|
65
59
|
/**
|
package/dist/src/table/td.js
CHANGED
|
@@ -251,11 +251,7 @@ let TdToken = (() => {
|
|
|
251
251
|
super.setAttribute(key, value);
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
|
-
/**
|
|
255
|
-
* @override
|
|
256
|
-
* @param syntax 表格语法
|
|
257
|
-
* @param esc 是否需要转义
|
|
258
|
-
*/
|
|
254
|
+
/** @private */
|
|
259
255
|
setSyntax(syntax, esc = false) {
|
|
260
256
|
const aliases = { td: '\n|', th: '\n!', caption: '\n|+' };
|
|
261
257
|
super.setSyntax(aliases[syntax] ?? syntax, esc);
|