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/table/td.js
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
const fixedToken = require('../../mixin/fixedToken'),
|
|
4
4
|
{externalUse, typeError} = require('../../util/debug'),
|
|
5
|
-
|
|
5
|
+
Parser = require('../..'),
|
|
6
6
|
Token = require('..'),
|
|
7
7
|
TrToken = require('./tr');
|
|
8
8
|
|
|
9
|
+
const aliases = {td: '\n|', th: '\n!', caption: '\n|+'},
|
|
10
|
+
openingPattern = /^(?:\n[\S\n]*(?:[|!]|\|\+|\{\{\s*!\s*\}\}\+?)|(?:\||\{\{\s*!\s*\}\}){2}|!!|\{\{\s*!!\s*\}\})$/u;
|
|
11
|
+
|
|
9
12
|
/**
|
|
10
13
|
* `<td>`、`<th>`和`<caption>`
|
|
11
14
|
* @classdesc `{childNodes: [SyntaxToken, AttributeToken, Token]}`
|
|
@@ -14,54 +17,73 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
14
17
|
type = 'td';
|
|
15
18
|
#innerSyntax = '';
|
|
16
19
|
|
|
17
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* 单元格类型
|
|
22
|
+
* @complexity `n`
|
|
23
|
+
*/
|
|
18
24
|
get subtype() {
|
|
19
25
|
return this.getSyntax().subtype;
|
|
20
26
|
}
|
|
27
|
+
|
|
21
28
|
set subtype(subtype) {
|
|
22
29
|
this.setSyntax(subtype);
|
|
23
30
|
}
|
|
24
31
|
|
|
32
|
+
/** rowspan */
|
|
25
33
|
get rowspan() {
|
|
26
34
|
return this.getAttr('rowspan');
|
|
27
35
|
}
|
|
36
|
+
|
|
28
37
|
set rowspan(rowspan) {
|
|
29
38
|
this.setAttr('rowspan', rowspan);
|
|
30
39
|
}
|
|
40
|
+
|
|
41
|
+
/** colspan */
|
|
31
42
|
get colspan() {
|
|
32
43
|
return this.getAttr('colspan');
|
|
33
44
|
}
|
|
45
|
+
|
|
34
46
|
set colspan(colspan) {
|
|
35
47
|
this.setAttr('colspan', colspan);
|
|
36
48
|
}
|
|
37
49
|
|
|
50
|
+
/** 内部wikitext */
|
|
51
|
+
get innerText() {
|
|
52
|
+
return this.lastChild.text();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** 是否位于行首 */
|
|
38
56
|
isIndependent() {
|
|
39
|
-
return this.
|
|
57
|
+
return this.firstChild.text()[0] === '\n';
|
|
40
58
|
}
|
|
41
59
|
|
|
42
60
|
/**
|
|
61
|
+
* 获取单元格语法信息
|
|
43
62
|
* @returns {{subtype: 'td'|'th'|'caption', escape: boolean, correction: boolean}}
|
|
44
63
|
* @complexity `n`
|
|
45
64
|
*/
|
|
46
65
|
getSyntax() {
|
|
47
|
-
const syntax = this.
|
|
48
|
-
esc = syntax.includes('{{')
|
|
66
|
+
const syntax = this.firstChild.text(),
|
|
67
|
+
esc = syntax.includes('{{'),
|
|
68
|
+
char = syntax.at(-1);
|
|
49
69
|
let subtype = 'td';
|
|
50
|
-
if (
|
|
70
|
+
if (char === '!') {
|
|
51
71
|
subtype = 'th';
|
|
52
|
-
} else if (
|
|
72
|
+
} else if (char === '+') {
|
|
53
73
|
subtype = 'caption';
|
|
54
74
|
}
|
|
55
75
|
if (this.isIndependent()) {
|
|
56
76
|
return {subtype, escape: esc, correction: false};
|
|
57
77
|
}
|
|
58
|
-
const {
|
|
59
|
-
if (
|
|
78
|
+
const {previousSibling} = this;
|
|
79
|
+
if (previousSibling?.type !== 'td') {
|
|
60
80
|
return {subtype, escape: esc, correction: true};
|
|
61
81
|
}
|
|
62
|
-
const result =
|
|
82
|
+
const result = previousSibling.getSyntax();
|
|
63
83
|
result.escape ||= esc;
|
|
64
|
-
result.correction =
|
|
84
|
+
result.correction = previousSibling.lastChild
|
|
85
|
+
.toString('comment, ext, include, noinclude, arg, template, magic-word, html')
|
|
86
|
+
.includes('\n');
|
|
65
87
|
if (subtype === 'th' && result.subtype !== 'th') {
|
|
66
88
|
result.subtype = 'th';
|
|
67
89
|
result.correction = true;
|
|
@@ -69,26 +91,23 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
69
91
|
return result;
|
|
70
92
|
}
|
|
71
93
|
|
|
72
|
-
static openingPattern
|
|
73
|
-
= /^(?:\n[\S\n]*(?:[|!]|\|\+|\{\{\s*!\s*\}\}\+?)|(?:\||\{\{\s*!\s*\}\}){2}|!!|\{\{\s*!!\s*\}\})$/;
|
|
74
|
-
|
|
75
94
|
getRowCount = undefined;
|
|
76
95
|
getNthCol = undefined;
|
|
77
96
|
insertTableCell = undefined;
|
|
78
97
|
|
|
79
98
|
/**
|
|
80
|
-
* @param {string} syntax
|
|
81
|
-
* @param {string} inner
|
|
99
|
+
* @param {string} syntax 单元格语法
|
|
100
|
+
* @param {string} inner 内部wikitext
|
|
82
101
|
* @param {accum} accum
|
|
83
102
|
*/
|
|
84
103
|
constructor(syntax, inner, config = Parser.getConfig(), accum = []) {
|
|
85
|
-
let innerSyntax = /\||\0\d+!\
|
|
104
|
+
let innerSyntax = inner?.match(/\||\0\d+!\x7F/u),
|
|
86
105
|
attr = innerSyntax ? inner.slice(0, innerSyntax.index) : '';
|
|
87
|
-
if (/\[\[|-\{
|
|
106
|
+
if (/\[\[|-\{/u.test(attr)) {
|
|
88
107
|
innerSyntax = null;
|
|
89
108
|
attr = '';
|
|
90
109
|
}
|
|
91
|
-
super(syntax, attr, config, accum,
|
|
110
|
+
super(syntax, attr, config, accum, openingPattern);
|
|
92
111
|
if (innerSyntax) {
|
|
93
112
|
[this.#innerSyntax] = innerSyntax;
|
|
94
113
|
}
|
|
@@ -96,9 +115,11 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
96
115
|
const innerToken = new Token(inner?.slice(innerSyntax?.index + this.#innerSyntax.length), config, true, accum);
|
|
97
116
|
innerToken.type = 'td-inner';
|
|
98
117
|
this.setAttribute('acceptable', {SyntaxToken: 0, AttributeToken: 1, Token: 2})
|
|
99
|
-
.seal(['getRowCount', 'getNthCol', 'insertTableCell']
|
|
118
|
+
.seal(['getRowCount', 'getNthCol', 'insertTableCell'], true)
|
|
119
|
+
.appendChild(innerToken.setAttribute('stage', 4));
|
|
100
120
|
}
|
|
101
121
|
|
|
122
|
+
/** @override */
|
|
102
123
|
cloneNode() {
|
|
103
124
|
const /** @type {TdToken} */ token = super.cloneNode();
|
|
104
125
|
token.setAttribute('innerSyntax', this.#innerSyntax);
|
|
@@ -106,21 +127,24 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
106
127
|
}
|
|
107
128
|
|
|
108
129
|
/**
|
|
109
|
-
*
|
|
110
|
-
* @param {
|
|
111
|
-
* @param {
|
|
130
|
+
* 创建新的单元格
|
|
131
|
+
* @param {string|Token} inner 内部wikitext
|
|
132
|
+
* @param {'td'|'th'|'caption'} subtype 单元格类型
|
|
133
|
+
* @param {Record<string, string>} attr 单元格属性
|
|
134
|
+
* @param {boolean} include 是否嵌入
|
|
135
|
+
* @throws `RangeError` 非法的单元格类型
|
|
112
136
|
*/
|
|
113
137
|
static create(inner, subtype = 'td', attr = {}, include = false, config = Parser.getConfig()) {
|
|
114
138
|
if (typeof inner !== 'string' && (!(inner instanceof Token) || !inner.isPlain()) || typeof attr !== 'object') {
|
|
115
139
|
typeError(this, 'create', 'String', 'Token', 'Object');
|
|
116
|
-
} else if (
|
|
140
|
+
} else if (subtype !== 'td' && subtype !== 'th' && subtype !== 'caption') {
|
|
117
141
|
throw new RangeError('单元格的子类型只能为 "td"、"th" 或 "caption"!');
|
|
118
142
|
} else if (typeof inner === 'string') {
|
|
119
143
|
inner = Parser.parse(inner, include, undefined, config);
|
|
120
144
|
}
|
|
121
145
|
const token = Parser.run(() => new TdToken('\n|', undefined, config));
|
|
122
146
|
token.setSyntax(subtype);
|
|
123
|
-
token.
|
|
147
|
+
token.lastChild.safeReplaceWith(inner);
|
|
124
148
|
for (const [k, v] of Object.entries(attr)) {
|
|
125
149
|
token.setAttr(k, v);
|
|
126
150
|
}
|
|
@@ -128,22 +152,22 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
128
152
|
}
|
|
129
153
|
|
|
130
154
|
/**
|
|
155
|
+
* @override
|
|
131
156
|
* @template {string} T
|
|
132
|
-
* @param {T} key
|
|
157
|
+
* @param {T} key 属性键
|
|
133
158
|
* @returns {TokenAttribute<T>}
|
|
134
159
|
*/
|
|
135
160
|
getAttribute(key) {
|
|
136
|
-
|
|
137
|
-
return this.#innerSyntax;
|
|
138
|
-
}
|
|
139
|
-
return super.getAttribute(key);
|
|
161
|
+
return key === 'innerSyntax' ? this.#innerSyntax : super.getAttribute(key);
|
|
140
162
|
}
|
|
141
163
|
|
|
142
164
|
/**
|
|
165
|
+
* @override
|
|
143
166
|
* @template {string} T
|
|
144
|
-
* @param {T} key
|
|
145
|
-
* @param {TokenAttribute<T>} value
|
|
146
|
-
* @
|
|
167
|
+
* @param {T} key 属性键
|
|
168
|
+
* @param {TokenAttribute<T>} value 属性值
|
|
169
|
+
* @returns {this}
|
|
170
|
+
* @throws `RangeError` 仅用于代码调试
|
|
147
171
|
*/
|
|
148
172
|
setAttribute(key, value) {
|
|
149
173
|
if (key !== 'innerSyntax') {
|
|
@@ -155,102 +179,129 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
155
179
|
return this;
|
|
156
180
|
}
|
|
157
181
|
|
|
182
|
+
/** @override */
|
|
158
183
|
afterBuild() {
|
|
159
184
|
if (this.#innerSyntax.includes('\0')) {
|
|
160
|
-
this.#innerSyntax = this.buildFromStr(this.#innerSyntax).map(String).join('');
|
|
185
|
+
this.#innerSyntax = this.getAttribute('buildFromStr')(this.#innerSyntax).map(String).join('');
|
|
161
186
|
}
|
|
162
187
|
return this;
|
|
163
188
|
}
|
|
164
189
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
190
|
+
/**
|
|
191
|
+
* @override
|
|
192
|
+
* @param {string} syntax 表格语法
|
|
193
|
+
* @param {boolean} esc 是否需要转义
|
|
194
|
+
*/
|
|
195
|
+
setSyntax(syntax, esc) {
|
|
196
|
+
super.setSyntax(aliases[syntax] ?? syntax, esc);
|
|
170
197
|
}
|
|
171
198
|
|
|
172
|
-
/**
|
|
199
|
+
/**
|
|
200
|
+
* 修复\<td\>语法
|
|
201
|
+
* @complexity `n`
|
|
202
|
+
*/
|
|
173
203
|
#correct() {
|
|
174
|
-
if (this.
|
|
204
|
+
if (String(this.childNodes[1])) {
|
|
175
205
|
this.#innerSyntax ||= '|';
|
|
176
206
|
}
|
|
177
|
-
const {subtype, escape
|
|
207
|
+
const {subtype, escape, correction} = this.getSyntax();
|
|
178
208
|
if (correction) {
|
|
179
|
-
this.setSyntax(subtype,
|
|
209
|
+
this.setSyntax(subtype, escape);
|
|
180
210
|
}
|
|
181
211
|
}
|
|
182
212
|
|
|
183
|
-
/**
|
|
213
|
+
/**
|
|
214
|
+
* 改为独占一行
|
|
215
|
+
* @complexity `n`
|
|
216
|
+
*/
|
|
184
217
|
independence() {
|
|
185
218
|
if (!this.isIndependent()) {
|
|
186
|
-
const {subtype, escape
|
|
187
|
-
this.setSyntax(subtype,
|
|
219
|
+
const {subtype, escape} = this.getSyntax();
|
|
220
|
+
this.setSyntax(subtype, escape);
|
|
188
221
|
}
|
|
189
222
|
}
|
|
190
223
|
|
|
191
224
|
/**
|
|
225
|
+
* @override
|
|
226
|
+
* @param {string} selector
|
|
192
227
|
* @returns {string}
|
|
193
228
|
* @complexity `n`
|
|
194
229
|
*/
|
|
195
|
-
toString() {
|
|
230
|
+
toString(selector) {
|
|
196
231
|
this.#correct();
|
|
197
|
-
const [syntax, attr, inner] = this
|
|
198
|
-
return
|
|
232
|
+
const {childNodes: [syntax, attr, inner]} = this;
|
|
233
|
+
return selector && this.matches(selector)
|
|
234
|
+
? ''
|
|
235
|
+
: `${syntax.toString(selector)}${attr.toString(selector)}${this.#innerSyntax}${inner.toString(selector)}`;
|
|
199
236
|
}
|
|
200
237
|
|
|
238
|
+
/**
|
|
239
|
+
* @override
|
|
240
|
+
* @param {number} i 子节点位置
|
|
241
|
+
*/
|
|
201
242
|
getGaps(i = 0) {
|
|
202
243
|
i = i < 0 ? i + this.childNodes.length : i;
|
|
203
|
-
if (i
|
|
204
|
-
|
|
244
|
+
if (i === 1) {
|
|
245
|
+
this.#correct();
|
|
246
|
+
return this.#innerSyntax.length;
|
|
205
247
|
}
|
|
206
|
-
|
|
207
|
-
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** @override */
|
|
252
|
+
print() {
|
|
253
|
+
const {childNodes: [syntax, attr, inner]} = this;
|
|
254
|
+
return `<span class="wpb-td">${syntax.print()}${attr.print()}${this.#innerSyntax}${inner.print()}</span>`;
|
|
208
255
|
}
|
|
209
256
|
|
|
210
257
|
/**
|
|
258
|
+
* @override
|
|
211
259
|
* @returns {string}
|
|
212
260
|
* @complexity `n`
|
|
213
261
|
*/
|
|
214
262
|
text() {
|
|
215
263
|
this.#correct();
|
|
216
|
-
const [syntax, attr, inner] = this
|
|
264
|
+
const {childNodes: [syntax, attr, inner]} = this;
|
|
217
265
|
return `${syntax.text()}${attr.text()}${this.#innerSyntax}${inner.text()}`;
|
|
218
266
|
}
|
|
219
267
|
|
|
220
268
|
/**
|
|
269
|
+
* 获取单元格属性
|
|
221
270
|
* @template {string} T
|
|
222
|
-
* @param {T} key
|
|
271
|
+
* @param {T} key 属性键
|
|
223
272
|
* @returns {T extends 'rowspan'|'colspan' ? number : Record<string, string|true>}
|
|
224
273
|
*/
|
|
225
274
|
getAttr(key) {
|
|
226
275
|
const /** @type {string|true} */ value = super.getAttr(key);
|
|
227
276
|
key = key?.toLowerCase()?.trim();
|
|
228
|
-
return
|
|
277
|
+
return key === 'rowspan' || key === 'colspan' ? Number(value) || 1 : value;
|
|
229
278
|
}
|
|
230
279
|
|
|
231
280
|
/**
|
|
281
|
+
* 设置单元格属性
|
|
232
282
|
* @template {string} T
|
|
233
|
-
* @param {T} key
|
|
234
|
-
* @param {T extends 'rowspan'|'colspan' ? number : string|boolean} value
|
|
283
|
+
* @param {T} key 属性键
|
|
284
|
+
* @param {T extends 'rowspan'|'colspan' ? number : string|boolean} value 属性值
|
|
235
285
|
*/
|
|
236
286
|
setAttr(key, value) {
|
|
237
287
|
if (typeof key !== 'string') {
|
|
238
288
|
this.typeError('setAttr', 'String');
|
|
239
289
|
}
|
|
240
290
|
key = key.toLowerCase().trim();
|
|
241
|
-
if (typeof value === 'number' &&
|
|
291
|
+
if (typeof value === 'number' && (key === 'rowspan' || key === 'colspan')) {
|
|
242
292
|
value = value === 1 ? false : String(value);
|
|
243
293
|
}
|
|
244
294
|
const /** @type {boolean} */ result = super.setAttr(key, value);
|
|
245
|
-
if (!this.
|
|
295
|
+
if (!String(this.childNodes[1])) {
|
|
246
296
|
this.#innerSyntax = '';
|
|
247
297
|
}
|
|
248
298
|
return result;
|
|
249
299
|
}
|
|
250
300
|
|
|
301
|
+
/** @override */
|
|
251
302
|
escape() {
|
|
252
303
|
super.escape();
|
|
253
|
-
if (this.
|
|
304
|
+
if (String(this.childNodes[1])) {
|
|
254
305
|
this.#innerSyntax ||= '{{!}}';
|
|
255
306
|
}
|
|
256
307
|
if (this.#innerSyntax === '|') {
|