wikiparser-node 1.21.1 → 1.21.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/README.md +11 -3
- package/bundle/bundle-es8.min.js +23 -23
- package/bundle/bundle-lsp.min.js +24 -24
- package/bundle/bundle.min.js +23 -23
- package/coverage/badge.svg +1 -1
- package/dist/addon/table.js +5 -5
- package/dist/addon/token.js +116 -7
- package/dist/bin/config.js +3 -3
- package/dist/index.d.ts +7 -0
- package/dist/lib/element.d.ts +1 -0
- package/dist/lib/element.js +1 -0
- package/dist/lib/lsp.d.ts +2 -0
- package/dist/lib/lsp.js +5 -4
- package/dist/lib/node.d.ts +20 -3
- package/dist/lib/node.js +39 -17
- package/dist/lib/text.d.ts +2 -0
- package/dist/lib/text.js +17 -12
- package/dist/lib/title.d.ts +3 -1
- package/dist/lib/title.js +3 -1
- package/dist/mixin/sol.js +1 -1
- package/dist/parser/list.js +6 -3
- package/dist/parser/table.js +2 -2
- package/dist/src/arg.js +1 -1
- package/dist/src/attribute.d.ts +1 -0
- package/dist/src/attribute.js +6 -3
- package/dist/src/attributes.js +1 -1
- package/dist/src/converter.js +1 -1
- package/dist/src/converterFlags.js +1 -1
- package/dist/src/extLink.js +2 -2
- package/dist/src/gallery.d.ts +12 -2
- package/dist/src/gallery.js +12 -2
- package/dist/src/heading.d.ts +6 -1
- package/dist/src/heading.js +7 -2
- package/dist/src/hidden.js +1 -1
- package/dist/src/html.js +1 -1
- package/dist/src/imageParameter.d.ts +1 -0
- package/dist/src/imageParameter.js +3 -2
- package/dist/src/imagemap.js +4 -4
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +14 -6
- package/dist/src/link/base.js +4 -4
- package/dist/src/link/file.d.ts +9 -1
- package/dist/src/link/file.js +13 -5
- package/dist/src/link/galleryImage.js +3 -1
- package/dist/src/link/redirectTarget.d.ts +6 -1
- package/dist/src/link/redirectTarget.js +7 -2
- package/dist/src/magicLink.d.ts +6 -1
- package/dist/src/magicLink.js +7 -2
- package/dist/src/nested.js +1 -1
- package/dist/src/nowiki/comment.js +1 -1
- package/dist/src/nowiki/index.js +1 -1
- package/dist/src/nowiki/listBase.d.ts +6 -1
- package/dist/src/nowiki/listBase.js +7 -2
- package/dist/src/nowiki/quote.d.ts +6 -1
- package/dist/src/nowiki/quote.js +9 -2
- package/dist/src/parameter.js +1 -1
- package/dist/src/redirect.js +1 -1
- package/dist/src/table/index.js +8 -7
- package/dist/src/table/td.js +1 -1
- package/dist/src/table/trBase.js +2 -2
- package/dist/src/transclude.d.ts +21 -8
- package/dist/src/transclude.js +43 -26
- package/dist/util/html.js +3 -6
- package/dist/util/lint.js +6 -3
- package/extensions/dist/base.js +1 -1
- package/i18n/zh-hans.json +1 -1
- package/i18n/zh-hant.json +1 -1
- package/package.json +2 -2
package/coverage/badge.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="98" height="20" role="img" aria-label="Coverage:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="98" height="20" role="img" aria-label="Coverage: 87%"><title>Coverage: 87%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="98" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="63" height="20" fill="#555"/><rect x="63" width="35" height="20" fill="#4c1"/><rect width="98" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">Coverage</text><text x="325" y="140" transform="scale(.1)" fill="#fff" textLength="530">Coverage</text><text aria-hidden="true" x="795" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250">87%</text><text x="795" y="140" transform="scale(.1)" fill="#fff" textLength="250">87%</text></g></svg>
|
package/dist/addon/table.js
CHANGED
|
@@ -211,7 +211,7 @@ index_2.TableToken.prototype.insertTableRow =
|
|
|
211
211
|
// @ts-expect-error abstract class
|
|
212
212
|
const token = debug_1.Shadow.run(() => new tr_1.TrToken('\n|-', undefined, this.getAttribute('config')));
|
|
213
213
|
token.setAttr(attr);
|
|
214
|
-
if (reference?.
|
|
214
|
+
if (reference?.is('table')) { // `row === 0`且表格自身是有效行
|
|
215
215
|
reference = this.prependTableRow();
|
|
216
216
|
}
|
|
217
217
|
this.insertBefore(token, reference);
|
|
@@ -289,7 +289,7 @@ index_2.TableToken.prototype.removeTableRow =
|
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
|
-
const row = rows[y], rowToken = row.
|
|
292
|
+
const row = rows[y], rowToken = row.is('tr') ? row : this.prependTableRow();
|
|
293
293
|
rowToken.remove();
|
|
294
294
|
return rowToken;
|
|
295
295
|
};
|
|
@@ -387,7 +387,7 @@ index_2.TableToken.prototype.replicateTableRow =
|
|
|
387
387
|
/** @implements */
|
|
388
388
|
function (row) {
|
|
389
389
|
let rowToken = this.getNthRow(row);
|
|
390
|
-
if (rowToken.
|
|
390
|
+
if (rowToken.is('table')) {
|
|
391
391
|
rowToken = this.prependTableRow();
|
|
392
392
|
}
|
|
393
393
|
const replicated = this.insertBefore(rowToken.cloneNode(), rowToken);
|
|
@@ -438,7 +438,7 @@ index_2.TableToken.prototype.moveTableRowBefore =
|
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
let beforeToken = this.getNthRow(before);
|
|
441
|
-
if (beforeToken.
|
|
441
|
+
if (beforeToken.is('table')) {
|
|
442
442
|
beforeToken = this.prependTableRow();
|
|
443
443
|
}
|
|
444
444
|
this.insertBefore(rowToken, beforeToken);
|
|
@@ -447,7 +447,7 @@ index_2.TableToken.prototype.moveTableRowBefore =
|
|
|
447
447
|
index_2.TableToken.prototype.moveTableRowAfter =
|
|
448
448
|
/** @implements */
|
|
449
449
|
function (y, after) {
|
|
450
|
-
const layout = this.getLayout(), afterToken = this.getNthRow(after), cells = afterToken.childNodes.filter(child => child.
|
|
450
|
+
const layout = this.getLayout(), afterToken = this.getNthRow(after), cells = afterToken.childNodes.filter(child => child.is('td') && child.subtype !== 'caption');
|
|
451
451
|
try {
|
|
452
452
|
strict_1.default.deepEqual(occupied(layout, y), occupied(layout, after, true, cells));
|
|
453
453
|
}
|
package/dist/addon/token.js
CHANGED
|
@@ -15,7 +15,41 @@ const include_1 = require("../src/tagPair/include");
|
|
|
15
15
|
const ext_1 = require("../src/tagPair/ext");
|
|
16
16
|
const html_1 = require("../src/html");
|
|
17
17
|
const attributes_1 = require("../src/attributes");
|
|
18
|
-
const blockElems = 'table|h1|h2|h3|h4|h5|h6|pre|p|ul|ol|dl', antiBlockElems = 'td|th'
|
|
18
|
+
const blockElems = 'table|h1|h2|h3|h4|h5|h6|pre|p|ul|ol|dl', antiBlockElems = 'td|th', solvedMagicWords = new Set([
|
|
19
|
+
'if',
|
|
20
|
+
'ifeq',
|
|
21
|
+
'ifexist',
|
|
22
|
+
'switch',
|
|
23
|
+
]), expandedMagicWords = new Set([
|
|
24
|
+
'currentmonth',
|
|
25
|
+
'currentmonth1',
|
|
26
|
+
'currentmonthname',
|
|
27
|
+
'currentmonthnamegen',
|
|
28
|
+
'currentmonthabbrev',
|
|
29
|
+
'currentday',
|
|
30
|
+
'currentday2',
|
|
31
|
+
'currentdayname',
|
|
32
|
+
'currentyear',
|
|
33
|
+
'currenttime',
|
|
34
|
+
'currenthour',
|
|
35
|
+
'currentweek',
|
|
36
|
+
'currentdow',
|
|
37
|
+
'currenttimestamp',
|
|
38
|
+
'localmonth',
|
|
39
|
+
'localmonth1',
|
|
40
|
+
'localmonthname',
|
|
41
|
+
'localmonthnamegen',
|
|
42
|
+
'localmonthabbrev',
|
|
43
|
+
'localday',
|
|
44
|
+
'localday2',
|
|
45
|
+
'localdayname',
|
|
46
|
+
'localyear',
|
|
47
|
+
'localtime',
|
|
48
|
+
'localhour',
|
|
49
|
+
'localweek',
|
|
50
|
+
'localdow',
|
|
51
|
+
'localtimestamp',
|
|
52
|
+
]);
|
|
19
53
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
20
54
|
/<(?:table|\/(?:td|th)|\/?(?:tr|caption|dt|dd|li))\b/iu;
|
|
21
55
|
const openRegex = new RegExp(String.raw `<(?:${blockElems}|\/(?:${antiBlockElems})|\/?(?:tr|caption|dt|dd|li))\b`, 'iu');
|
|
@@ -54,11 +88,12 @@ const parseIf = (accum, prev, effective) => {
|
|
|
54
88
|
* @param config
|
|
55
89
|
* @param include
|
|
56
90
|
* @param context 模板调用环境
|
|
91
|
+
* @param now 当前时间
|
|
57
92
|
* @param accum
|
|
58
93
|
* @param stack 模板调用栈
|
|
59
94
|
*/
|
|
60
|
-
const expand = (wikitext, config, include, context, accum = [], stack = []) => {
|
|
61
|
-
const
|
|
95
|
+
const expand = (wikitext, config, include, context, now = index_1.default.now ?? new Date(), accum = [], stack = []) => {
|
|
96
|
+
const n = accum.length, token = new index_2.Token(wikitext, config, accum);
|
|
62
97
|
token.type = 'root';
|
|
63
98
|
token.parseOnce(0, include);
|
|
64
99
|
if (context !== false) {
|
|
@@ -129,9 +164,82 @@ const expand = (wikitext, config, include, context, accum = [], stack = []) => {
|
|
|
129
164
|
else if (stack.includes(title)) {
|
|
130
165
|
return `${prev}<span class="error">Template loop detected: [[${title}]]</span>`;
|
|
131
166
|
}
|
|
132
|
-
return implicitNewLine(expand(index_1.default.templates.get(title), config, true, target, accum, [...stack, title]).toString(), prev);
|
|
167
|
+
return implicitNewLine(expand(index_1.default.templates.get(title), config, true, target, now, accum, [...stack, title]).toString(), prev);
|
|
133
168
|
}
|
|
134
|
-
else if (
|
|
169
|
+
else if (expandedMagicWords.has(name)) {
|
|
170
|
+
if (context === false) {
|
|
171
|
+
return m;
|
|
172
|
+
}
|
|
173
|
+
switch (name) {
|
|
174
|
+
case 'currentyear':
|
|
175
|
+
return `${prev}${now.getUTCFullYear()}`;
|
|
176
|
+
case 'currentmonth':
|
|
177
|
+
return prev + String(now.getUTCMonth() + 1).padStart(2, '0');
|
|
178
|
+
case 'currentmonth1':
|
|
179
|
+
return `${prev}${now.getUTCMonth() + 1}`;
|
|
180
|
+
case 'currentmonthname':
|
|
181
|
+
case 'currentmonthnamegen':
|
|
182
|
+
return prev + now.toLocaleString('default', { month: 'long', timeZone: 'UTC' });
|
|
183
|
+
case 'currentmonthabbrev':
|
|
184
|
+
return prev + now.toLocaleString('default', { month: 'short', timeZone: 'UTC' });
|
|
185
|
+
case 'currentday':
|
|
186
|
+
return `${prev}${now.getUTCDate()}`;
|
|
187
|
+
case 'currentday2':
|
|
188
|
+
return prev + String(now.getUTCDate()).padStart(2, '0');
|
|
189
|
+
case 'currentdow':
|
|
190
|
+
return `${prev}${now.getUTCDay()}`;
|
|
191
|
+
case 'currentdayname':
|
|
192
|
+
return prev + now.toLocaleString('default', { weekday: 'long', timeZone: 'UTC' });
|
|
193
|
+
case 'currenttime':
|
|
194
|
+
return `${prev}${String(now.getUTCHours()).padStart(2, '0')}:${String(now.getUTCMinutes()).padStart(2, '0')}`;
|
|
195
|
+
case 'currenthour':
|
|
196
|
+
return prev + String(now.getUTCHours()).padStart(2, '0');
|
|
197
|
+
case 'currentweek': {
|
|
198
|
+
const firstDay = new Date(Date.UTC(now.getUTCFullYear(), 0, 1));
|
|
199
|
+
return `${prev}${Math.ceil((now.getTime() - firstDay.getTime()) / 1e3 / 60 / 60 / 24 / 7)}`;
|
|
200
|
+
}
|
|
201
|
+
case 'currenttimestamp':
|
|
202
|
+
return prev + now.toISOString().slice(0, 19)
|
|
203
|
+
.replace(/[-:T]/gu, '');
|
|
204
|
+
case 'localyear':
|
|
205
|
+
return `${prev}${now.getFullYear()}`;
|
|
206
|
+
case 'localmonth':
|
|
207
|
+
return prev + String(now.getMonth() + 1).padStart(2, '0');
|
|
208
|
+
case 'localmonth1':
|
|
209
|
+
return `${prev}${now.getMonth() + 1}`;
|
|
210
|
+
case 'localmonthname':
|
|
211
|
+
case 'localmonthnamegen':
|
|
212
|
+
return prev + now.toLocaleString('default', { month: 'long' });
|
|
213
|
+
case 'localmonthabbrev':
|
|
214
|
+
return prev + now.toLocaleString('default', { month: 'short' });
|
|
215
|
+
case 'localday':
|
|
216
|
+
return `${prev}${now.getDate()}`;
|
|
217
|
+
case 'localday2':
|
|
218
|
+
return prev + String(now.getDate()).padStart(2, '0');
|
|
219
|
+
case 'localdow':
|
|
220
|
+
return `${prev}${now.getDay()}`;
|
|
221
|
+
case 'localdayname':
|
|
222
|
+
return prev + now.toLocaleString('default', { weekday: 'long' });
|
|
223
|
+
case 'localtime':
|
|
224
|
+
return `${prev}${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
|
|
225
|
+
case 'localhour':
|
|
226
|
+
return prev + String(now.getHours()).padStart(2, '0');
|
|
227
|
+
case 'localweek': {
|
|
228
|
+
const firstDay = new Date(now.getFullYear(), 0, 1);
|
|
229
|
+
return `${prev}${Math.ceil((now.getTime() - firstDay.getTime()) / 1e3 / 60 / 60 / 24 / 7)}`;
|
|
230
|
+
}
|
|
231
|
+
case 'localtimestamp':
|
|
232
|
+
return prev
|
|
233
|
+
+ String(now.getFullYear())
|
|
234
|
+
+ String(now.getMonth() + 1).padStart(2, '0')
|
|
235
|
+
+ String(now.getDate()).padStart(2, '0')
|
|
236
|
+
+ String(now.getHours()).padStart(2, '0')
|
|
237
|
+
+ String(now.getMinutes()).padStart(2, '0')
|
|
238
|
+
+ String(now.getSeconds()).padStart(2, '0');
|
|
239
|
+
// no default
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
else if (!solvedMagicWords.has(name)) {
|
|
135
243
|
return m;
|
|
136
244
|
}
|
|
137
245
|
else if (length < 3 || name === 'ifeq' && length === 3) {
|
|
@@ -308,8 +416,9 @@ index_2.Token.prototype.createElement = /** @implements */ function (tagName, {
|
|
|
308
416
|
() => new include_1.IncludeToken(tagName, '', undefined, selfClosing ? undefined : tagName, config));
|
|
309
417
|
}
|
|
310
418
|
else if (config.ext.includes(tagName)) {
|
|
419
|
+
return debug_1.Shadow.run(
|
|
311
420
|
// @ts-expect-error abstract class
|
|
312
|
-
|
|
421
|
+
() => new ext_1.ExtToken(tagName, '', undefined, selfClosing ? undefined : '', config, include));
|
|
313
422
|
}
|
|
314
423
|
else if (config.html.some(tags => tags.includes(tagName))) {
|
|
315
424
|
return debug_1.Shadow.run(() => {
|
|
@@ -328,7 +437,7 @@ index_2.Token.prototype.sections = /** @implements */ function () {
|
|
|
328
437
|
return undefined;
|
|
329
438
|
}
|
|
330
439
|
const { childNodes, length } = this, headings = [...childNodes.entries()]
|
|
331
|
-
.filter((entry) => entry[1].
|
|
440
|
+
.filter((entry) => entry[1].is('heading'))
|
|
332
441
|
.map(([i, { level }]) => [i, level]), lastHeading = [-1, -1, -1, -1, -1, -1], sections = headings.map(([i]) => {
|
|
333
442
|
const range = this.createRange();
|
|
334
443
|
range.setStart(this, i);
|
package/dist/bin/config.js
CHANGED
|
@@ -6,7 +6,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const
|
|
9
|
+
const strict_1 = __importDefault(require("assert/strict"));
|
|
10
10
|
const cm_1 = require("@bhsd/common/dist/cm");
|
|
11
11
|
const diff_1 = require("../util/diff");
|
|
12
12
|
/**
|
|
@@ -145,10 +145,10 @@ exports.default = async (site, url, force, internal) => {
|
|
|
145
145
|
const oldConfig = arrToObj(require(file)), newConfig = arrToObj(config);
|
|
146
146
|
for (const [k, v] of Object.entries(newConfig)) {
|
|
147
147
|
try {
|
|
148
|
-
|
|
148
|
+
strict_1.default.deepStrictEqual(oldConfig[k], v);
|
|
149
149
|
}
|
|
150
150
|
catch (e) {
|
|
151
|
-
if (e instanceof
|
|
151
|
+
if (e instanceof strict_1.default.AssertionError) {
|
|
152
152
|
(0, diff_1.error)(`Configuration mismatch for "${k}"`);
|
|
153
153
|
delete e.actual;
|
|
154
154
|
delete e.expected;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,13 @@ declare interface Parser extends ParserBase {
|
|
|
13
13
|
templates: Map<string, string>;
|
|
14
14
|
warning: boolean;
|
|
15
15
|
debugging: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Specify the current time of the parser
|
|
18
|
+
*
|
|
19
|
+
* 指定解析器的当前时间
|
|
20
|
+
* @since v1.21.2
|
|
21
|
+
*/
|
|
22
|
+
now?: Date;
|
|
16
23
|
/**
|
|
17
24
|
* Normalize page title
|
|
18
25
|
*
|
package/dist/lib/element.d.ts
CHANGED
package/dist/lib/element.js
CHANGED
package/dist/lib/lsp.d.ts
CHANGED
|
@@ -127,6 +127,7 @@ export declare class LanguageService implements LanguageServiceBase {
|
|
|
127
127
|
*
|
|
128
128
|
* 提供 CodeLens
|
|
129
129
|
* @param text source Wikitext / 源代码
|
|
130
|
+
* @since v1.16.3
|
|
130
131
|
*/
|
|
131
132
|
provideInlayHints(text: string): Promise<InlayHint[]>;
|
|
132
133
|
/**
|
|
@@ -149,6 +150,7 @@ export declare class LanguageService implements LanguageServiceBase {
|
|
|
149
150
|
* 设置目标维基百科
|
|
150
151
|
* @param wiki Wikipedia URL / 维基百科网址
|
|
151
152
|
* @throws `RangeError` 不是有效的维基百科网址
|
|
153
|
+
* @since v1.18.1
|
|
152
154
|
*/
|
|
153
155
|
setTargetWikipedia(wiki: string): Promise<void>;
|
|
154
156
|
}
|
package/dist/lib/lsp.js
CHANGED
|
@@ -63,7 +63,7 @@ exports.isAttr = isAttr;
|
|
|
63
63
|
* Check if a token is an HTML attribute.
|
|
64
64
|
* @param token
|
|
65
65
|
*/
|
|
66
|
-
const isHtmlAttr = (token) => token.
|
|
66
|
+
const isHtmlAttr = (token) => token.is('html-attr') || token.is('table-attr');
|
|
67
67
|
/**
|
|
68
68
|
* Check if all child nodes are plain text or comments.
|
|
69
69
|
* @param token
|
|
@@ -651,7 +651,7 @@ class LanguageService {
|
|
|
651
651
|
if (t === 'magic-word' && n !== 'invoke') {
|
|
652
652
|
return undefined;
|
|
653
653
|
}
|
|
654
|
-
const key = this.#text.slice(cur.getAbsoluteIndex(), root.indexFromPos(line, character)).trimStart(),
|
|
654
|
+
const key = this.#text.slice(cur.getAbsoluteIndex(), root.indexFromPos(line, character)).trimStart(), { module: mod, function: func } = transclusion;
|
|
655
655
|
return key
|
|
656
656
|
? getCompletion(root.querySelectorAll('parameter').filter(token => {
|
|
657
657
|
if (token === parentNode
|
|
@@ -663,8 +663,7 @@ class LanguageService {
|
|
|
663
663
|
else if (t === 'template') {
|
|
664
664
|
return true;
|
|
665
665
|
}
|
|
666
|
-
|
|
667
|
-
return m === mod && f === func;
|
|
666
|
+
return token.parentNode.module === mod && token.parentNode.function === func;
|
|
668
667
|
}).map(({ name }) => name), 'Variable', key, position, type === 'parameter-value' ? '=' : '')
|
|
669
668
|
: undefined;
|
|
670
669
|
/* NOT FOR BROWSER ONLY */
|
|
@@ -1302,6 +1301,7 @@ class LanguageService {
|
|
|
1302
1301
|
*
|
|
1303
1302
|
* 提供 CodeLens
|
|
1304
1303
|
* @param text source Wikitext / 源代码
|
|
1304
|
+
* @since v1.16.3
|
|
1305
1305
|
*/
|
|
1306
1306
|
async provideInlayHints(text) {
|
|
1307
1307
|
const root = await this.#queue(text);
|
|
@@ -1391,6 +1391,7 @@ class LanguageService {
|
|
|
1391
1391
|
* 设置目标维基百科
|
|
1392
1392
|
* @param wiki Wikipedia URL / 维基百科网址
|
|
1393
1393
|
* @throws `RangeError` 不是有效的维基百科网址
|
|
1394
|
+
* @since v1.18.1
|
|
1394
1395
|
*/
|
|
1395
1396
|
async setTargetWikipedia(wiki) {
|
|
1396
1397
|
const mt = /^https?:\/\/([^./]+)\.wikipedia\.org/iu.exec(wiki);
|
package/dist/lib/node.d.ts
CHANGED
|
@@ -72,11 +72,26 @@ export declare abstract class AstNode implements AstNodeBase {
|
|
|
72
72
|
get style(): Position & Dimension & {
|
|
73
73
|
padding: number;
|
|
74
74
|
};
|
|
75
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* font weigth and style
|
|
77
|
+
*
|
|
78
|
+
* 字体样式
|
|
79
|
+
* @since v.1.8.0
|
|
80
|
+
*/
|
|
76
81
|
get font(): Font;
|
|
77
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* whether to be bold
|
|
84
|
+
*
|
|
85
|
+
* 是否粗体
|
|
86
|
+
* @since v.1.8.0
|
|
87
|
+
*/
|
|
78
88
|
get bold(): boolean;
|
|
79
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* whether to be italic
|
|
91
|
+
*
|
|
92
|
+
* 是否斜体
|
|
93
|
+
* @since v.1.8.0
|
|
94
|
+
*/
|
|
80
95
|
get italic(): boolean;
|
|
81
96
|
constructor();
|
|
82
97
|
/**
|
|
@@ -124,12 +139,14 @@ export declare abstract class AstNode implements AstNodeBase {
|
|
|
124
139
|
*
|
|
125
140
|
* 是否是某种类型的节点
|
|
126
141
|
* @param type token type / 节点类型
|
|
142
|
+
* @since v1.10.0
|
|
127
143
|
*/
|
|
128
144
|
is<T extends Token>(type: TokenTypes): this is T;
|
|
129
145
|
/**
|
|
130
146
|
* Get the text and the start/end positions of all lines
|
|
131
147
|
*
|
|
132
148
|
* 获取所有行的wikitext和起止位置
|
|
149
|
+
* @since v1.16.3
|
|
133
150
|
*/
|
|
134
151
|
getLines(): [string, number, number][];
|
|
135
152
|
/**
|
package/dist/lib/node.js
CHANGED
|
@@ -124,22 +124,37 @@ class AstNode {
|
|
|
124
124
|
get fixed() {
|
|
125
125
|
return false;
|
|
126
126
|
}
|
|
127
|
-
/**
|
|
127
|
+
/**
|
|
128
|
+
* font weigth and style
|
|
129
|
+
*
|
|
130
|
+
* 字体样式
|
|
131
|
+
* @since v.1.8.0
|
|
132
|
+
*/
|
|
128
133
|
get font() {
|
|
129
134
|
const { bold, italic, b = 0, i = 0 } = this.#getFont();
|
|
130
135
|
return { bold: bold && b >= 0, italic: italic && i >= 0 };
|
|
131
136
|
}
|
|
132
|
-
/**
|
|
137
|
+
/**
|
|
138
|
+
* whether to be bold
|
|
139
|
+
*
|
|
140
|
+
* 是否粗体
|
|
141
|
+
* @since v.1.8.0
|
|
142
|
+
*/
|
|
133
143
|
get bold() {
|
|
134
144
|
return this.font.bold;
|
|
135
145
|
}
|
|
136
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* whether to be italic
|
|
148
|
+
*
|
|
149
|
+
* 是否斜体
|
|
150
|
+
* @since v.1.8.0
|
|
151
|
+
*/
|
|
137
152
|
get italic() {
|
|
138
153
|
return this.font.italic;
|
|
139
154
|
}
|
|
140
155
|
constructor() {
|
|
141
|
-
Object.defineProperty(this, 'childNodes', { writable: false });
|
|
142
156
|
if (!index_1.default.viewOnly) {
|
|
157
|
+
Object.defineProperty(this, 'childNodes', { writable: false });
|
|
143
158
|
Object.freeze(this.childNodes);
|
|
144
159
|
}
|
|
145
160
|
}
|
|
@@ -177,16 +192,18 @@ class AstNode {
|
|
|
177
192
|
default:
|
|
178
193
|
/* NOT FOR BROWSER */
|
|
179
194
|
if (Object.hasOwn(this, key)) {
|
|
180
|
-
const descriptor = Object.getOwnPropertyDescriptor(this, key);
|
|
181
|
-
if (
|
|
182
|
-
descriptor.enumerable =
|
|
195
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, key), bool = Boolean(value), optional = this.#optional.has(key) && descriptor.enumerable !== bool;
|
|
196
|
+
if (optional) {
|
|
197
|
+
descriptor.enumerable = bool;
|
|
183
198
|
}
|
|
184
|
-
const oldValue = this[key]
|
|
185
|
-
|
|
186
|
-
if (frozen && typeof value === 'object') {
|
|
199
|
+
const oldValue = this[key];
|
|
200
|
+
if (typeof value === 'object' && typeof oldValue === 'object' && Object.isFrozen(oldValue)) {
|
|
187
201
|
Object.freeze(value);
|
|
188
202
|
}
|
|
189
|
-
|
|
203
|
+
if (optional || !descriptor.writable) {
|
|
204
|
+
Object.defineProperty(this, key, { ...descriptor, value });
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
190
207
|
}
|
|
191
208
|
/* NOT FOR BROWSER END */
|
|
192
209
|
this[key] = value; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
@@ -309,6 +326,7 @@ class AstNode {
|
|
|
309
326
|
*
|
|
310
327
|
* 是否是某种类型的节点
|
|
311
328
|
* @param type token type / 节点类型
|
|
329
|
+
* @since v1.10.0
|
|
312
330
|
*/
|
|
313
331
|
is(type) {
|
|
314
332
|
return this.type === type;
|
|
@@ -317,6 +335,7 @@ class AstNode {
|
|
|
317
335
|
* Get the text and the start/end positions of all lines
|
|
318
336
|
*
|
|
319
337
|
* 获取所有行的wikitext和起止位置
|
|
338
|
+
* @since v1.16.3
|
|
320
339
|
*/
|
|
321
340
|
getLines() {
|
|
322
341
|
return (0, lint_1.cache)(this.#lines, () => {
|
|
@@ -340,12 +359,15 @@ class AstNode {
|
|
|
340
359
|
this.#optional.add(key);
|
|
341
360
|
}
|
|
342
361
|
/* NOT FOR BROWSER END */
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
362
|
+
const enumerable = !permanent && Boolean(this[key]);
|
|
363
|
+
if (!enumerable || !index_1.default.viewOnly) {
|
|
364
|
+
Object.defineProperty(this, key, {
|
|
365
|
+
enumerable,
|
|
366
|
+
configurable: true,
|
|
367
|
+
/* NOT FOR BROWSER */
|
|
368
|
+
writable: index_1.default.viewOnly,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
349
371
|
}
|
|
350
372
|
/* PRINT ONLY END */
|
|
351
373
|
/* NOT FOR BROWSER */
|
package/dist/lib/text.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ export declare class AstText extends AstNode {
|
|
|
72
72
|
* Escape `=` and `|`
|
|
73
73
|
*
|
|
74
74
|
* 转义 `=` 和 `|`
|
|
75
|
+
* @since v1.1.4
|
|
75
76
|
*/
|
|
76
77
|
escape(): void;
|
|
77
78
|
/**
|
|
@@ -79,6 +80,7 @@ export declare class AstText extends AstNode {
|
|
|
79
80
|
*
|
|
80
81
|
* 生成HTML
|
|
81
82
|
* @param nowrap whether to disable line-wrapping / 是否不换行
|
|
83
|
+
* @since v1.10.0
|
|
82
84
|
*/
|
|
83
85
|
toHtml(nowrap?: boolean): string;
|
|
84
86
|
}
|
package/dist/lib/text.js
CHANGED
|
@@ -176,14 +176,16 @@ let AstText = (() => {
|
|
|
176
176
|
/** @param text 包含文本 */
|
|
177
177
|
constructor(text) {
|
|
178
178
|
super();
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
179
|
+
if (index_1.default.viewOnly) {
|
|
180
|
+
this.data = text;
|
|
181
|
+
/* NOT FOR BROWSER */
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
Object.defineProperties(this, {
|
|
185
|
+
data: { value: text, writable: false },
|
|
186
|
+
childNodes: { enumerable: false, configurable: false },
|
|
187
|
+
});
|
|
188
|
+
}
|
|
187
189
|
}
|
|
188
190
|
/** @private */
|
|
189
191
|
toString(skip) {
|
|
@@ -453,6 +455,7 @@ let AstText = (() => {
|
|
|
453
455
|
* Escape `=` and `|`
|
|
454
456
|
*
|
|
455
457
|
* 转义 `=` 和 `|`
|
|
458
|
+
* @since v1.1.4
|
|
456
459
|
*/
|
|
457
460
|
escape() {
|
|
458
461
|
const { TranscludeToken } = require('../src/transclude');
|
|
@@ -479,6 +482,7 @@ let AstText = (() => {
|
|
|
479
482
|
*
|
|
480
483
|
* 生成HTML
|
|
481
484
|
* @param nowrap whether to disable line-wrapping / 是否不换行
|
|
485
|
+
* @since v1.10.0
|
|
482
486
|
*/
|
|
483
487
|
toHtml(nowrap) {
|
|
484
488
|
const { data } = this;
|
|
@@ -489,8 +493,9 @@ let AstText = (() => {
|
|
|
489
493
|
if (/\s$/u.test(this.data)) {
|
|
490
494
|
const spaces = [], mt = /\n[^\S\n]*$/u.exec(this.data);
|
|
491
495
|
let { nextSibling } = this, mt2 = null;
|
|
492
|
-
while (nextSibling
|
|
493
|
-
|
|
496
|
+
while (nextSibling && (nextSibling.is('comment')
|
|
497
|
+
|| nextSibling.is('category')
|
|
498
|
+
|| nextSibling.type === 'text')) {
|
|
494
499
|
if (nextSibling.type === 'text') {
|
|
495
500
|
mt2 = mt && /^[^\S\n]*(?=\n)/u.exec(nextSibling.data);
|
|
496
501
|
if (mt2 || nextSibling.data.trim()) {
|
|
@@ -500,7 +505,7 @@ let AstText = (() => {
|
|
|
500
505
|
spaces.push(nextSibling);
|
|
501
506
|
}
|
|
502
507
|
}
|
|
503
|
-
else if (mt && nextSibling.
|
|
508
|
+
else if (mt && nextSibling.is('category')) {
|
|
504
509
|
const trimmed = this.data.trimEnd();
|
|
505
510
|
if (this.data !== trimmed) {
|
|
506
511
|
const { length } = trimmed;
|
|
@@ -513,7 +518,7 @@ let AstText = (() => {
|
|
|
513
518
|
}
|
|
514
519
|
({ nextSibling } = nextSibling);
|
|
515
520
|
}
|
|
516
|
-
if (mt2 || nextSibling?.
|
|
521
|
+
if (mt2 || nextSibling?.is('table')) {
|
|
517
522
|
if (mt) {
|
|
518
523
|
this.deleteData(mt.index + (mt2 ? 0 : 1));
|
|
519
524
|
if (mt2) {
|
package/dist/lib/title.d.ts
CHANGED
package/dist/lib/title.js
CHANGED
package/dist/mixin/sol.js
CHANGED
|
@@ -20,7 +20,7 @@ const sol = (self) => (constructor) => {
|
|
|
20
20
|
: '\n';
|
|
21
21
|
}
|
|
22
22
|
return parentNode?.type === 'root'
|
|
23
|
-
|| type === 'list' && parentNode?.
|
|
23
|
+
|| type === 'list' && parentNode?.is('list-range')
|
|
24
24
|
|| type !== 'heading' && parentNode?.type === 'ext-inner' && parentNode.name === 'poem'
|
|
25
25
|
? ''
|
|
26
26
|
: '\n';
|
package/dist/parser/list.js
CHANGED
|
@@ -16,17 +16,20 @@ const constants_1 = require("../util/constants");
|
|
|
16
16
|
* @param accum
|
|
17
17
|
*/
|
|
18
18
|
const parseList = (wikitext, state, config, accum) => {
|
|
19
|
-
const mt = /^((?:\0\d+[cno]\x7F)*)([;:*#]
|
|
19
|
+
const mt = /^((?:\0\d+[cno]\x7F)*)([;:*#]+)(\s*)/u.exec(wikitext);
|
|
20
20
|
if (!mt) {
|
|
21
21
|
state.lastPrefix = '';
|
|
22
22
|
return wikitext;
|
|
23
23
|
}
|
|
24
|
-
const [total, comment, prefix] = mt, prefix2 = prefix.replace(/;/gu, ':'), commonPrefixLength = (0, html_1.getCommon)(prefix2, state.lastPrefix), parts = (commonPrefixLength > 1 ? prefix.slice(commonPrefixLength - 1) : prefix)
|
|
24
|
+
const [total, comment, prefix, space] = mt, prefix2 = prefix.replace(/;/gu, ':'), commonPrefixLength = (0, html_1.getCommon)(prefix2, state.lastPrefix), parts = ((commonPrefixLength > 1 ? prefix.slice(commonPrefixLength - 1) : prefix) + space)
|
|
25
|
+
.split(/(?=;)/u), isDt = parts[0].startsWith(';');
|
|
25
26
|
let dt = parts.length - (isDt ? 0 : 1);
|
|
26
27
|
if (commonPrefixLength > 1) {
|
|
27
28
|
const commonPrefix = prefix.slice(0, commonPrefixLength - 1);
|
|
28
29
|
if (isDt) {
|
|
29
|
-
|
|
30
|
+
const commonPrefixes = commonPrefix.split(/(?=;)/u);
|
|
31
|
+
parts.unshift(...commonPrefixes);
|
|
32
|
+
dt += commonPrefix.includes(';') ? commonPrefixes.length : 0;
|
|
30
33
|
}
|
|
31
34
|
else {
|
|
32
35
|
parts[0] = commonPrefix + parts[0];
|
package/dist/parser/table.js
CHANGED
|
@@ -19,7 +19,7 @@ const isTr = (token) => token.lastChild.constructor !== index_1.Token;
|
|
|
19
19
|
* @param top 当前解析的表格或表格行
|
|
20
20
|
* @param stack 表格栈
|
|
21
21
|
*/
|
|
22
|
-
const pop = (top, stack) => top.
|
|
22
|
+
const pop = (top, stack) => top.is('td') ? stack.pop() : top;
|
|
23
23
|
/**
|
|
24
24
|
* 解析表格,注意`tr`和`td`包含开头的换行
|
|
25
25
|
* @param {Token & {firstChild: AstText}} root 根节点
|
|
@@ -92,7 +92,7 @@ const parseTable = ({ firstChild: { data }, type, name }, config, accum) => {
|
|
|
92
92
|
}
|
|
93
93
|
else if (row) {
|
|
94
94
|
top = pop(top, stack);
|
|
95
|
-
if (top.
|
|
95
|
+
if (top.is('tr')) {
|
|
96
96
|
top = stack.pop();
|
|
97
97
|
}
|
|
98
98
|
// @ts-expect-error abstract class
|