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/imageParameter.js
CHANGED
|
@@ -1,41 +1,39 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {text, noWrap, extUrlChar} = require('../util/string'),
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const {text, noWrap, print, extUrlChar} = require('../util/string'),
|
|
4
|
+
Parser = require('..'),
|
|
5
|
+
Token = require('.'),
|
|
6
|
+
AstText = require('../lib/text');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* 图片参数
|
|
10
|
-
* @classdesc `{childNodes: ...(
|
|
10
|
+
* @classdesc `{childNodes: ...(AstText|Token)}`
|
|
11
11
|
*/
|
|
12
12
|
class ImageParameterToken extends Token {
|
|
13
|
-
|
|
14
|
-
#syntax = '';
|
|
15
|
-
|
|
16
|
-
static #noLink = Symbol('no-link');
|
|
13
|
+
static noLink = Symbol('no-link'); // 这个Symbol需要公开
|
|
17
14
|
|
|
18
15
|
/**
|
|
16
|
+
* 检查图片参数是否合法
|
|
19
17
|
* @template {string} T
|
|
20
|
-
* @param {T} key
|
|
21
|
-
* @param {string} value
|
|
18
|
+
* @param {T} key 参数名
|
|
19
|
+
* @param {string} value 参数值
|
|
22
20
|
* @returns {T extends 'link' ? string|Symbol : boolean}
|
|
23
21
|
*/
|
|
24
|
-
static #validate(key, value, config = Parser.getConfig()) {
|
|
25
|
-
value = value.
|
|
22
|
+
static #validate(key, value, config = Parser.getConfig(), halfParsed = false) {
|
|
23
|
+
value = value.replaceAll(/\0\d+t\x7F/gu, '').trim();
|
|
26
24
|
if (key === 'width') {
|
|
27
|
-
return /^\d*(?:x\d*)
|
|
25
|
+
return /^\d*(?:x\d*)?$/u.test(value);
|
|
28
26
|
} else if (['alt', 'class', 'manualthumb', 'frameless', 'framed', 'thumbnail'].includes(key)) {
|
|
29
27
|
return true;
|
|
30
28
|
} else if (key === 'link') {
|
|
31
29
|
if (!value) {
|
|
32
|
-
return this
|
|
30
|
+
return this.noLink;
|
|
33
31
|
}
|
|
34
|
-
const regex = RegExp(`(?:${config.protocol}|//)${extUrlChar}(?=\0\\d+t\
|
|
32
|
+
const regex = new RegExp(`(?:${config.protocol}|//)${extUrlChar}(?=\0\\d+t\x7F|$)`, 'iu');
|
|
35
33
|
if (regex.test(value)) {
|
|
36
34
|
return value;
|
|
37
35
|
}
|
|
38
|
-
if (
|
|
36
|
+
if (value.startsWith('[[') && value.endsWith(']]')) {
|
|
39
37
|
value = value.slice(2, -2);
|
|
40
38
|
}
|
|
41
39
|
if (value.includes('%')) {
|
|
@@ -43,24 +41,39 @@ class ImageParameterToken extends Token {
|
|
|
43
41
|
value = decodeURIComponent(value);
|
|
44
42
|
} catch {}
|
|
45
43
|
}
|
|
46
|
-
const
|
|
47
|
-
return valid &&
|
|
44
|
+
const title = Parser.normalizeTitle(value, 0, false, config, halfParsed);
|
|
45
|
+
return title.valid && String(title);
|
|
48
46
|
}
|
|
49
47
|
return !isNaN(value);
|
|
50
48
|
}
|
|
51
49
|
|
|
50
|
+
type = 'image-parameter';
|
|
51
|
+
#syntax = '';
|
|
52
|
+
|
|
53
|
+
/** getValue()的getter */
|
|
54
|
+
get value() {
|
|
55
|
+
return this.getValue();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
set value(value) {
|
|
59
|
+
this.setValue(value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** 图片链接 */
|
|
52
63
|
get link() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return undefined;
|
|
64
|
+
return this.name === 'link'
|
|
65
|
+
? ImageParameterToken.#validate('link', this.getValue(), this.getAttribute('config'))
|
|
66
|
+
: undefined;
|
|
57
67
|
}
|
|
68
|
+
|
|
58
69
|
set link(value) {
|
|
59
70
|
if (this.name === 'link') {
|
|
60
|
-
value = value === ImageParameterToken
|
|
71
|
+
value = value === ImageParameterToken.noLink ? '' : value;
|
|
61
72
|
this.setValue(value);
|
|
62
73
|
}
|
|
63
74
|
}
|
|
75
|
+
|
|
76
|
+
/** 图片大小 */
|
|
64
77
|
get size() {
|
|
65
78
|
if (this.name === 'width') {
|
|
66
79
|
const /** @type {string} */ size = this.getValue().trim();
|
|
@@ -68,30 +81,36 @@ class ImageParameterToken extends Token {
|
|
|
68
81
|
const [width, height = ''] = size.split('x');
|
|
69
82
|
return {width, height};
|
|
70
83
|
}
|
|
71
|
-
const token = Parser.parse(size, false, 2, this.getAttribute('config')),
|
|
72
|
-
|
|
73
|
-
|
|
84
|
+
const /** @type {{childNodes: AstText[]}} */ token = Parser.parse(size, false, 2, this.getAttribute('config')),
|
|
85
|
+
i = token.childNodes.findIndex(({type, data}) => type === 'text' && data.includes('x')),
|
|
86
|
+
str = token.childNodes[i];
|
|
74
87
|
if (i === -1) {
|
|
75
88
|
return {width: size, height: ''};
|
|
76
89
|
}
|
|
77
|
-
|
|
78
|
-
|
|
90
|
+
str.splitText(str.data.indexOf('x'));
|
|
91
|
+
str.nextSibling.splitText(1);
|
|
79
92
|
return {width: text(token.childNodes.slice(0, i + 1)), height: text(token.childNodes.slice(i + 2))};
|
|
80
93
|
}
|
|
81
94
|
return undefined;
|
|
82
95
|
}
|
|
96
|
+
|
|
97
|
+
/** 图片宽度 */
|
|
83
98
|
get width() {
|
|
84
99
|
return this.size?.width;
|
|
85
100
|
}
|
|
101
|
+
|
|
86
102
|
set width(width) {
|
|
87
103
|
if (this.name === 'width') {
|
|
88
104
|
const {height} = this;
|
|
89
105
|
this.setValue(`${String(width || '')}${height && 'x'}${height}`);
|
|
90
106
|
}
|
|
91
107
|
}
|
|
108
|
+
|
|
109
|
+
/** 图片高度 */
|
|
92
110
|
get height() {
|
|
93
111
|
return this.size?.height;
|
|
94
112
|
}
|
|
113
|
+
|
|
95
114
|
set height(height) {
|
|
96
115
|
height = String(height || '');
|
|
97
116
|
if (this.name === 'width') {
|
|
@@ -100,20 +119,18 @@ class ImageParameterToken extends Token {
|
|
|
100
119
|
}
|
|
101
120
|
|
|
102
121
|
/**
|
|
103
|
-
* @param {string} str
|
|
122
|
+
* @param {string} str 图片参数
|
|
104
123
|
* @param {accum} accum
|
|
105
124
|
*/
|
|
106
125
|
constructor(str, config = Parser.getConfig(), accum = []) {
|
|
107
126
|
const regexes = Object.entries(config.img).map(
|
|
108
127
|
/** @returns {[string, string, RegExp]} */
|
|
109
|
-
([syntax, param]) => [syntax, param, RegExp(`^(\\s*)${syntax.replace('$1', '(.*)')}(\\s*)
|
|
128
|
+
([syntax, param]) => [syntax, param, new RegExp(`^(\\s*)${syntax.replace('$1', '(.*)')}(\\s*)$`, 'u')],
|
|
110
129
|
),
|
|
111
130
|
param = regexes.find(([,, regex]) => regex.test(str));
|
|
112
131
|
if (param) {
|
|
113
132
|
const mt = param[2].exec(str);
|
|
114
|
-
if (mt.length
|
|
115
|
-
// pass
|
|
116
|
-
} else {
|
|
133
|
+
if (mt.length !== 4 || ImageParameterToken.#validate(param[1], mt[2], config, true)) {
|
|
117
134
|
if (mt.length === 3) {
|
|
118
135
|
super(undefined, config, true, accum);
|
|
119
136
|
this.#syntax = str;
|
|
@@ -129,8 +146,9 @@ class ImageParameterToken extends Token {
|
|
|
129
146
|
this.setAttribute('name', 'caption').setAttribute('stage', 7);
|
|
130
147
|
}
|
|
131
148
|
|
|
149
|
+
/** @override */
|
|
132
150
|
cloneNode() {
|
|
133
|
-
const cloned = this.
|
|
151
|
+
const cloned = this.cloneChildNodes(),
|
|
134
152
|
config = this.getAttribute('config'),
|
|
135
153
|
token = Parser.run(() => new ImageParameterToken(this.#syntax.replace('$1', ''), config));
|
|
136
154
|
token.replaceChildren(...cloned);
|
|
@@ -138,47 +156,59 @@ class ImageParameterToken extends Token {
|
|
|
138
156
|
}
|
|
139
157
|
|
|
140
158
|
/**
|
|
159
|
+
* @override
|
|
141
160
|
* @template {string} T
|
|
142
|
-
* @param {T} key
|
|
161
|
+
* @param {T} key 属性键
|
|
143
162
|
* @returns {TokenAttribute<T>}
|
|
144
163
|
*/
|
|
145
164
|
getAttribute(key) {
|
|
146
|
-
|
|
147
|
-
return this.#syntax;
|
|
148
|
-
}
|
|
149
|
-
return super.getAttribute(key);
|
|
165
|
+
return key === 'syntax' ? this.#syntax : super.getAttribute(key);
|
|
150
166
|
}
|
|
151
167
|
|
|
168
|
+
/** @override */
|
|
152
169
|
isPlain() {
|
|
153
170
|
return true;
|
|
154
171
|
}
|
|
155
172
|
|
|
173
|
+
/** 是否是不可变参数 */
|
|
156
174
|
#isVoid() {
|
|
157
175
|
return this.#syntax && !this.#syntax.includes('$1');
|
|
158
176
|
}
|
|
159
177
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
178
|
+
/**
|
|
179
|
+
* @override
|
|
180
|
+
* @param {string} selector
|
|
181
|
+
*/
|
|
182
|
+
toString(selector) {
|
|
183
|
+
return this.#syntax && !(selector && this.matches(selector))
|
|
184
|
+
? this.#syntax.replace('$1', super.toString(selector))
|
|
185
|
+
: super.toString(selector);
|
|
165
186
|
}
|
|
166
187
|
|
|
188
|
+
/** @override */
|
|
167
189
|
getPadding() {
|
|
168
190
|
return Math.max(0, this.#syntax.indexOf('$1'));
|
|
169
191
|
}
|
|
170
192
|
|
|
193
|
+
/** @override */
|
|
194
|
+
print() {
|
|
195
|
+
return this.#syntax
|
|
196
|
+
? `<span class="wpb-image-parameter">${this.#syntax.replace('$1', print(this.childNodes))}</span>`
|
|
197
|
+
: super.print({class: 'image-caption'});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** @override */
|
|
171
201
|
text() {
|
|
172
|
-
|
|
173
|
-
return super.text().trim();
|
|
174
|
-
}
|
|
175
|
-
return this.#syntax.replace('$1', super.text()).trim();
|
|
202
|
+
return this.#syntax ? this.#syntax.replace('$1', super.text()).trim() : super.text().trim();
|
|
176
203
|
}
|
|
177
204
|
|
|
178
205
|
/**
|
|
179
|
-
* @
|
|
180
|
-
* @
|
|
206
|
+
* @override
|
|
207
|
+
* @template {Token} T
|
|
208
|
+
* @param {T} token 待插入的子节点
|
|
209
|
+
* @param {number} i 插入位置
|
|
181
210
|
* @complexity `n`
|
|
211
|
+
* @throws `Error` 不接受自定义输入的图片参数
|
|
182
212
|
*/
|
|
183
213
|
insertAt(token, i = this.childNodes.length) {
|
|
184
214
|
if (!Parser.running && this.#isVoid()) {
|
|
@@ -187,14 +217,19 @@ class ImageParameterToken extends Token {
|
|
|
187
217
|
return super.insertAt(token, i);
|
|
188
218
|
}
|
|
189
219
|
|
|
190
|
-
/**
|
|
220
|
+
/**
|
|
221
|
+
* 获取参数值
|
|
222
|
+
* @complexity `n`
|
|
223
|
+
*/
|
|
191
224
|
getValue() {
|
|
192
225
|
return this.#isVoid() || super.text();
|
|
193
226
|
}
|
|
194
227
|
|
|
195
228
|
/**
|
|
196
|
-
*
|
|
229
|
+
* 设置参数值
|
|
230
|
+
* @param {string|boolean} value 参数值
|
|
197
231
|
* @complexity `n`
|
|
232
|
+
* @throws SyntaxError` 非法的参数值
|
|
198
233
|
*/
|
|
199
234
|
setValue(value) {
|
|
200
235
|
if (this.#isVoid()) {
|
|
@@ -210,14 +245,14 @@ class ImageParameterToken extends Token {
|
|
|
210
245
|
const root = Parser.parse(`[[File:F|${
|
|
211
246
|
this.#syntax ? this.#syntax.replace('$1', value) : value
|
|
212
247
|
}]]`, this.getAttribute('include'), 6, this.getAttribute('config')),
|
|
213
|
-
{childNodes: {length},
|
|
214
|
-
|
|
215
|
-
if (length !== 1 ||
|
|
216
|
-
||
|
|
248
|
+
{childNodes: {length}, firstChild: file} = root,
|
|
249
|
+
{lastChild: imageParameter, type, name, childNodes: {length: fileLength}} = file;
|
|
250
|
+
if (length !== 1 || type !== 'file' || name !== 'File:F' || fileLength !== 2
|
|
251
|
+
|| imageParameter.name !== this.name
|
|
217
252
|
) {
|
|
218
253
|
throw new SyntaxError(`非法的 ${this.name} 参数:${noWrap(value)}`);
|
|
219
254
|
}
|
|
220
|
-
this.replaceChildren(...
|
|
255
|
+
this.replaceChildren(...imageParameter.childNodes);
|
|
221
256
|
}
|
|
222
257
|
}
|
|
223
258
|
|