wikiparser-node 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/config/default.json +13 -17
- package/config/llwiki.json +11 -79
- package/config/moegirl.json +7 -1
- package/config/zhwiki.json +1269 -0
- package/index.js +130 -97
- package/lib/element.js +410 -518
- package/lib/node.js +493 -115
- package/lib/ranges.js +27 -19
- package/lib/text.js +175 -0
- package/lib/title.js +14 -6
- package/mixin/attributeParent.js +70 -24
- package/mixin/fixedToken.js +18 -10
- package/mixin/hidden.js +6 -4
- package/mixin/sol.js +39 -12
- package/package.json +17 -4
- package/parser/brackets.js +18 -18
- package/parser/commentAndExt.js +16 -14
- package/parser/converter.js +14 -13
- package/parser/externalLinks.js +12 -11
- package/parser/hrAndDoubleUnderscore.js +24 -14
- package/parser/html.js +8 -7
- package/parser/links.js +13 -13
- package/parser/list.js +12 -11
- package/parser/magicLinks.js +11 -10
- package/parser/quotes.js +6 -5
- package/parser/selector.js +175 -0
- package/parser/table.js +31 -24
- package/src/arg.js +91 -43
- package/src/atom/hidden.js +5 -2
- package/src/atom/index.js +17 -9
- package/src/attribute.js +210 -101
- package/src/converter.js +78 -43
- package/src/converterFlags.js +104 -45
- package/src/converterRule.js +136 -78
- package/src/extLink.js +81 -27
- package/src/gallery.js +63 -20
- package/src/heading.js +58 -20
- package/src/html.js +138 -48
- package/src/imageParameter.js +93 -58
- package/src/index.js +314 -186
- package/src/link/category.js +22 -54
- package/src/link/file.js +83 -32
- package/src/link/galleryImage.js +21 -7
- package/src/link/index.js +170 -81
- package/src/magicLink.js +64 -14
- package/src/nowiki/comment.js +36 -10
- package/src/nowiki/dd.js +37 -22
- package/src/nowiki/doubleUnderscore.js +21 -7
- package/src/nowiki/hr.js +11 -7
- package/src/nowiki/index.js +16 -9
- package/src/nowiki/list.js +2 -2
- package/src/nowiki/noinclude.js +8 -4
- package/src/nowiki/quote.js +38 -7
- package/src/onlyinclude.js +24 -7
- package/src/parameter.js +102 -62
- package/src/syntax.js +23 -20
- package/src/table/index.js +282 -174
- package/src/table/td.js +112 -61
- package/src/table/tr.js +135 -74
- package/src/tagPair/ext.js +30 -23
- package/src/tagPair/include.js +26 -11
- package/src/tagPair/index.js +72 -29
- package/src/transclude.js +235 -127
- package/tool/index.js +42 -32
- package/util/debug.js +21 -18
- package/util/diff.js +76 -0
- package/util/lint.js +40 -0
- package/util/string.js +56 -26
- package/.eslintrc.json +0 -319
- package/errors/README +0 -1
- package/jsconfig.json +0 -7
- package/printed/README +0 -1
- package/typings/element.d.ts +0 -28
- package/typings/index.d.ts +0 -52
- package/typings/node.d.ts +0 -23
- package/typings/parser.d.ts +0 -9
- package/typings/table.d.ts +0 -14
- package/typings/token.d.ts +0 -22
- package/typings/tool.d.ts +0 -10
package/src/link/category.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const Title = require('../../lib/title'),
|
|
4
|
+
Parser = require('../..'),
|
|
5
|
+
LinkToken = require('.');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* 分类
|
|
@@ -10,72 +10,40 @@ const /** @type {Parser} */ Parser = require('../..'),
|
|
|
10
10
|
*/
|
|
11
11
|
class CategoryToken extends LinkToken {
|
|
12
12
|
type = 'category';
|
|
13
|
-
sortkey = '';
|
|
14
13
|
|
|
15
14
|
setLangLink = undefined;
|
|
16
15
|
setFragment = undefined;
|
|
17
16
|
asSelfLink = undefined;
|
|
18
17
|
pipeTrick = undefined;
|
|
19
18
|
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
constructor(link, text, title, config = Parser.getConfig(), accum = []) {
|
|
27
|
-
super(link, text, title, config, accum);
|
|
28
|
-
this.seal(['sortkey', 'setFragment', 'asSelfLink', 'pipeTrick']);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
afterBuild() {
|
|
32
|
-
super.afterBuild();
|
|
33
|
-
this.#updateSortkey();
|
|
34
|
-
const that = this;
|
|
35
|
-
const /** @type {AstListener} */ categoryListener = ({prevTarget}) => {
|
|
36
|
-
if (prevTarget?.type === 'link-text') {
|
|
37
|
-
that.#updateSortkey();
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
this.addEventListener(['remove', 'insert', 'replace', 'text'], categoryListener);
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
#updateSortkey() {
|
|
45
|
-
this.setAttribute('sortkey', this.children[1]?.text()
|
|
46
|
-
?.replace(/&#(\d+);/g, /** @param {string} p1 */ (_, p1) => String.fromCharCode(Number(p1)))
|
|
47
|
-
?.replace(/&#x([\da-f]+);/gi, /** @param {string} p1 */ (_, p1) => String.fromCharCode(parseInt(p1, 16)))
|
|
48
|
-
?.replaceAll('\n', '') ?? '',
|
|
19
|
+
/** 分类排序关键字 */
|
|
20
|
+
get sortkey() {
|
|
21
|
+
return this.childNodes[1]?.text()?.replaceAll(
|
|
22
|
+
/&#(\d+|x[\da-f]+);|\n/gu,
|
|
23
|
+
/** @param {string} p */
|
|
24
|
+
(_, p) => p ? String.fromCodePoint(p[0] === 'x' ? parseInt(p.slice(1), 16) : Number(p)) : '',
|
|
49
25
|
);
|
|
50
26
|
}
|
|
51
27
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (i === 1) {
|
|
55
|
-
this.setAttribute('sortkey', '');
|
|
56
|
-
}
|
|
57
|
-
return super.removeAt(i);
|
|
28
|
+
set sortkey(text) {
|
|
29
|
+
this.setSortkey(text);
|
|
58
30
|
}
|
|
59
31
|
|
|
60
32
|
/**
|
|
61
|
-
* @
|
|
62
|
-
* @param {
|
|
63
|
-
* @param {
|
|
33
|
+
* @param {string} link 分类名
|
|
34
|
+
* @param {string|undefined} text 排序关键字
|
|
35
|
+
* @param {Title} title 分类页面标题对象
|
|
36
|
+
* @param {accum} accum
|
|
64
37
|
*/
|
|
65
|
-
|
|
66
|
-
super
|
|
67
|
-
|
|
68
|
-
this.#updateSortkey();
|
|
69
|
-
}
|
|
70
|
-
return token;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** @returns {string} */
|
|
74
|
-
text() {
|
|
75
|
-
return `[[${this.firstElementChild.text()}]]`;
|
|
38
|
+
constructor(link, text, title, config = Parser.getConfig(), accum = []) {
|
|
39
|
+
super(link, text, title, config, accum);
|
|
40
|
+
this.seal(['setFragment', 'asSelfLink', 'pipeTrick'], true);
|
|
76
41
|
}
|
|
77
42
|
|
|
78
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* 设置排序关键字
|
|
45
|
+
* @param {string} text 排序关键字
|
|
46
|
+
*/
|
|
79
47
|
setSortkey(text) {
|
|
80
48
|
this.setLinkText(text);
|
|
81
49
|
}
|
package/src/link/file.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const Title = require('../../lib/title'),
|
|
4
|
+
{explode, noWrap} = require('../../util/string'),
|
|
4
5
|
{externalUse} = require('../../util/debug'),
|
|
5
|
-
|
|
6
|
+
{generateForChild} = require('../../util/lint'),
|
|
7
|
+
Parser = require('../..'),
|
|
6
8
|
LinkToken = require('.'),
|
|
7
9
|
ImageParameterToken = require('../imageParameter');
|
|
8
10
|
|
|
@@ -21,18 +23,25 @@ class FileToken extends LinkToken {
|
|
|
21
23
|
setLinkText = undefined;
|
|
22
24
|
pipeTrick = undefined;
|
|
23
25
|
|
|
26
|
+
/** 图片链接 */
|
|
24
27
|
get link() {
|
|
25
28
|
return this.getArg('link')?.link;
|
|
26
29
|
}
|
|
30
|
+
|
|
27
31
|
set link(value) {
|
|
28
32
|
this.setValue('link', value);
|
|
29
33
|
}
|
|
34
|
+
|
|
35
|
+
/** 图片大小 */
|
|
30
36
|
get size() {
|
|
31
37
|
return this.getArg('width')?.size;
|
|
32
38
|
}
|
|
39
|
+
|
|
40
|
+
/** 图片宽度 */
|
|
33
41
|
get width() {
|
|
34
42
|
return this.size?.width;
|
|
35
43
|
}
|
|
44
|
+
|
|
36
45
|
set width(width) {
|
|
37
46
|
const arg = this.getArg('width');
|
|
38
47
|
if (arg) {
|
|
@@ -41,9 +50,12 @@ class FileToken extends LinkToken {
|
|
|
41
50
|
this.setValue('width', width);
|
|
42
51
|
}
|
|
43
52
|
}
|
|
53
|
+
|
|
54
|
+
/** 图片高度 */
|
|
44
55
|
get height() {
|
|
45
56
|
return this.size?.height;
|
|
46
57
|
}
|
|
58
|
+
|
|
47
59
|
set height(height) {
|
|
48
60
|
const arg = this.getArg('width');
|
|
49
61
|
if (arg) {
|
|
@@ -54,9 +66,9 @@ class FileToken extends LinkToken {
|
|
|
54
66
|
}
|
|
55
67
|
|
|
56
68
|
/**
|
|
57
|
-
* @param {string} link
|
|
58
|
-
* @param {string|undefined} text
|
|
59
|
-
* @param {Title} title
|
|
69
|
+
* @param {string} link 文件名
|
|
70
|
+
* @param {string|undefined} text 图片参数
|
|
71
|
+
* @param {Title} title 文件标题对象
|
|
60
72
|
* @param {accum} accum
|
|
61
73
|
* @complexity `n`
|
|
62
74
|
*/
|
|
@@ -64,11 +76,32 @@ class FileToken extends LinkToken {
|
|
|
64
76
|
super(link, undefined, title, config, accum);
|
|
65
77
|
this.setAttribute('acceptable', {AtomToken: 0, ImageParameterToken: '1:'});
|
|
66
78
|
this.append(...explode('-{', '}-', '|', text).map(part => new ImageParameterToken(part, config, accum)));
|
|
67
|
-
this.seal(['setLangLink', 'setFragment', 'asSelfLink', 'setLinkText', 'pipeTrick']);
|
|
79
|
+
this.seal(['setLangLink', 'setFragment', 'asSelfLink', 'setLinkText', 'pipeTrick'], true);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @override
|
|
84
|
+
* @param {number} start 起始位置
|
|
85
|
+
*/
|
|
86
|
+
lint(start = 0) {
|
|
87
|
+
const errors = super.lint(start),
|
|
88
|
+
frameArgs = this.getFrameArgs(),
|
|
89
|
+
captions = this.getArgs('caption');
|
|
90
|
+
if (frameArgs.length > 1 || captions.size > 1) {
|
|
91
|
+
const rect = this.getRootNode().posFromIndex(start);
|
|
92
|
+
if (frameArgs.length > 1) {
|
|
93
|
+
errors.push(...frameArgs.map(arg => generateForChild(arg, rect, '重复或冲突的图片框架参数')));
|
|
94
|
+
}
|
|
95
|
+
if (captions.size > 1) {
|
|
96
|
+
errors.push(...[...captions].map(arg => generateForChild(arg, rect, '重复的图片说明')));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return errors;
|
|
68
100
|
}
|
|
69
101
|
|
|
70
102
|
/**
|
|
71
|
-
* @
|
|
103
|
+
* @override
|
|
104
|
+
* @param {number} i 移除位置
|
|
72
105
|
* @complexity `n`
|
|
73
106
|
*/
|
|
74
107
|
removeAt(i) {
|
|
@@ -82,7 +115,9 @@ class FileToken extends LinkToken {
|
|
|
82
115
|
}
|
|
83
116
|
|
|
84
117
|
/**
|
|
85
|
-
* @
|
|
118
|
+
* @override
|
|
119
|
+
* @param {ImageParameterToken} token 待插入的子节点
|
|
120
|
+
* @param {number} i 插入位置
|
|
86
121
|
* @complexity `n`
|
|
87
122
|
*/
|
|
88
123
|
insertAt(token, i = this.childNodes.length) {
|
|
@@ -93,12 +128,18 @@ class FileToken extends LinkToken {
|
|
|
93
128
|
return super.insertAt(token, i);
|
|
94
129
|
}
|
|
95
130
|
|
|
96
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* 获取所有图片参数节点
|
|
133
|
+
* @returns {ImageParameterToken[]}
|
|
134
|
+
*/
|
|
97
135
|
getAllArgs() {
|
|
98
136
|
return this.childNodes.slice(1);
|
|
99
137
|
}
|
|
100
138
|
|
|
101
|
-
/**
|
|
139
|
+
/**
|
|
140
|
+
* 获取图片框架属性参数节点
|
|
141
|
+
* @complexity `n`
|
|
142
|
+
*/
|
|
102
143
|
getFrameArgs() {
|
|
103
144
|
const args = this.getAllArgs()
|
|
104
145
|
.filter(({name}) => ['manualthumb', 'frameless', 'framed', 'thumbnail'].includes(name));
|
|
@@ -109,15 +150,16 @@ class FileToken extends LinkToken {
|
|
|
109
150
|
}
|
|
110
151
|
|
|
111
152
|
/**
|
|
112
|
-
*
|
|
153
|
+
* 获取指定图片参数
|
|
154
|
+
* @param {string} key 参数名
|
|
155
|
+
* @param {boolean} copy 是否返回备份
|
|
113
156
|
* @complexity `n`
|
|
114
157
|
*/
|
|
115
158
|
getArgs(key, copy = true) {
|
|
116
159
|
if (typeof key !== 'string') {
|
|
117
160
|
this.typeError('getArgs', 'String');
|
|
118
|
-
} else if (!copy && !Parser.debugging && externalUse('getArgs')) {
|
|
119
|
-
this.debugOnly('getArgs');
|
|
120
161
|
}
|
|
162
|
+
copy ||= !Parser.debugging && externalUse('getArgs');
|
|
121
163
|
let args = this.#args[key];
|
|
122
164
|
if (!args) {
|
|
123
165
|
args = new Set(this.getAllArgs().filter(({name}) => key === name));
|
|
@@ -127,7 +169,8 @@ class FileToken extends LinkToken {
|
|
|
127
169
|
}
|
|
128
170
|
|
|
129
171
|
/**
|
|
130
|
-
*
|
|
172
|
+
* 是否具有指定图片参数
|
|
173
|
+
* @param {string} key 参数名
|
|
131
174
|
* @complexity `n`
|
|
132
175
|
*/
|
|
133
176
|
hasArg(key) {
|
|
@@ -135,15 +178,17 @@ class FileToken extends LinkToken {
|
|
|
135
178
|
}
|
|
136
179
|
|
|
137
180
|
/**
|
|
138
|
-
*
|
|
181
|
+
* 获取生效的指定图片参数
|
|
182
|
+
* @param {string} key 参数名
|
|
139
183
|
* @complexity `n`
|
|
140
184
|
*/
|
|
141
185
|
getArg(key) {
|
|
142
|
-
return [...this.getArgs(key, false)].sort((a, b) => a.
|
|
186
|
+
return [...this.getArgs(key, false)].sort((a, b) => a.compareDocumentPosition(b)).at(-1);
|
|
143
187
|
}
|
|
144
188
|
|
|
145
189
|
/**
|
|
146
|
-
*
|
|
190
|
+
* 移除指定图片参数
|
|
191
|
+
* @param {string} key 参数名
|
|
147
192
|
* @complexity `n`
|
|
148
193
|
*/
|
|
149
194
|
removeArg(key) {
|
|
@@ -152,10 +197,13 @@ class FileToken extends LinkToken {
|
|
|
152
197
|
}
|
|
153
198
|
}
|
|
154
199
|
|
|
155
|
-
/**
|
|
200
|
+
/**
|
|
201
|
+
* 获取图片参数名
|
|
202
|
+
* @complexity `n`
|
|
203
|
+
*/
|
|
156
204
|
getKeys() {
|
|
157
205
|
const args = this.getAllArgs();
|
|
158
|
-
if (this.#keys.size === 0 && args.length) {
|
|
206
|
+
if (this.#keys.size === 0 && args.length > 0) {
|
|
159
207
|
for (const {name} of args) {
|
|
160
208
|
this.#keys.add(name);
|
|
161
209
|
}
|
|
@@ -164,7 +212,8 @@ class FileToken extends LinkToken {
|
|
|
164
212
|
}
|
|
165
213
|
|
|
166
214
|
/**
|
|
167
|
-
*
|
|
215
|
+
* 获取指定的图片参数值
|
|
216
|
+
* @param {string} key 参数名
|
|
168
217
|
* @complexity `n`
|
|
169
218
|
*/
|
|
170
219
|
getValues(key) {
|
|
@@ -172,22 +221,25 @@ class FileToken extends LinkToken {
|
|
|
172
221
|
}
|
|
173
222
|
|
|
174
223
|
/**
|
|
224
|
+
* 获取生效的指定图片参数值
|
|
175
225
|
* @template {string|undefined} T
|
|
176
|
-
* @param {T} key
|
|
226
|
+
* @param {T} key 参数名
|
|
177
227
|
* @returns {T extends undefined ? Object<string, string> : string|true}
|
|
178
228
|
* @complexity `n`
|
|
179
229
|
*/
|
|
180
230
|
getValue(key) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
return Object.fromEntries(this.getKeys().map(k => [k, this.getValue(k)]));
|
|
231
|
+
return key === undefined
|
|
232
|
+
? Object.fromEntries(this.getKeys().map(k => [k, this.getValue(k)]))
|
|
233
|
+
: this.getArg(key)?.getValue();
|
|
185
234
|
}
|
|
186
235
|
|
|
187
236
|
/**
|
|
188
|
-
*
|
|
189
|
-
* @param {string
|
|
237
|
+
* 设置图片参数
|
|
238
|
+
* @param {string} key 参数名
|
|
239
|
+
* @param {string|boolean} value 参数值
|
|
190
240
|
* @complexity `n`
|
|
241
|
+
* @throws `RangeError` 未定义的图片参数
|
|
242
|
+
* @throws `SyntaxError` 非法的参数
|
|
191
243
|
*/
|
|
192
244
|
setValue(key, value) {
|
|
193
245
|
if (typeof key !== 'string') {
|
|
@@ -220,13 +272,12 @@ class FileToken extends LinkToken {
|
|
|
220
272
|
}
|
|
221
273
|
const wikitext = `[[File:F|${syntax ? syntax.replace('$1', value) : value}]]`,
|
|
222
274
|
root = Parser.parse(wikitext, this.getAttribute('include'), 6, config),
|
|
223
|
-
{childNodes: {length},
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
) {
|
|
275
|
+
{childNodes: {length}, firstChild: file} = root,
|
|
276
|
+
{name, type, childNodes: {length: fileLength}, lastChild: imageParameter} = file;
|
|
277
|
+
if (length !== 1 || type !== 'file' || name !== 'File:F' || fileLength !== 2 || imageParameter.name !== key) {
|
|
227
278
|
throw new SyntaxError(`非法的 ${key} 参数:${noWrap(value)}`);
|
|
228
279
|
}
|
|
229
|
-
this.appendChild(
|
|
280
|
+
this.appendChild(imageParameter);
|
|
230
281
|
}
|
|
231
282
|
}
|
|
232
283
|
|
package/src/link/galleryImage.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const Title = require('../../lib/title'),
|
|
4
|
+
Parser = require('../..'),
|
|
4
5
|
Token = require('..'),
|
|
5
6
|
FileToken = require('./file');
|
|
6
7
|
|
|
@@ -16,9 +17,9 @@ class GalleryImageToken extends FileToken {
|
|
|
16
17
|
height = undefined;
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
|
-
* @param {string} link
|
|
20
|
-
* @param {string|undefined} text
|
|
21
|
-
* @param {Title} title
|
|
20
|
+
* @param {string} link 图片文件名
|
|
21
|
+
* @param {string|undefined} text 图片参数
|
|
22
|
+
* @param {Title} title 图片文件标题对象
|
|
22
23
|
* @param {accum} accum
|
|
23
24
|
*/
|
|
24
25
|
constructor(link, text, title, config = Parser.getConfig(), accum = []) {
|
|
@@ -26,21 +27,34 @@ class GalleryImageToken extends FileToken {
|
|
|
26
27
|
if (text !== undefined) {
|
|
27
28
|
token = new Token(text, config, true, accum);
|
|
28
29
|
token.type = 'temp';
|
|
29
|
-
token.setAttribute('stage', 1);
|
|
30
30
|
for (let n = 1; n < Parser.MAX_STAGE; n++) {
|
|
31
|
-
token.parseOnce();
|
|
31
|
+
token.getAttribute('parseOnce')();
|
|
32
32
|
}
|
|
33
33
|
accum.splice(accum.indexOf(token), 1);
|
|
34
34
|
}
|
|
35
35
|
const newConfig = structuredClone(config);
|
|
36
36
|
newConfig.img = Object.fromEntries(Object.entries(config.img).filter(([, param]) => param !== 'width'));
|
|
37
37
|
super(link, token?.toString(), title, newConfig, accum);
|
|
38
|
-
this.seal(['size', 'width', 'height']);
|
|
38
|
+
this.seal(['size', 'width', 'height'], true);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/** @override */
|
|
41
42
|
getPadding() {
|
|
42
43
|
return 0;
|
|
43
44
|
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @override
|
|
48
|
+
* @param {string} selector
|
|
49
|
+
*/
|
|
50
|
+
toString(selector) {
|
|
51
|
+
return super.toString(selector).replaceAll('\n', ' ');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** @override */
|
|
55
|
+
text() {
|
|
56
|
+
return super.text().replaceAll('\n', ' ');
|
|
57
|
+
}
|
|
44
58
|
}
|
|
45
59
|
|
|
46
60
|
Parser.classes.GalleryImageToken = __filename;
|