wikiparser-node 1.39.0 → 1.40.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.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/bundle/bundle-es8.min.js +30 -29
  3. package/bundle/bundle-lsp.min.js +30 -30
  4. package/bundle/bundle.min.js +19 -19
  5. package/config/.schema.json +1 -1
  6. package/config/default.json +10 -1
  7. package/config/enwiki.json +88 -87
  8. package/config/jawiki.json +162 -153
  9. package/config/minimum.json +5 -81
  10. package/config/zhwiki.json +125 -124
  11. package/data/signatures.json +1 -1
  12. package/dist/addon/attribute.js +1 -1
  13. package/dist/addon/table.js +1 -1
  14. package/dist/addon/transclude.js +3 -1
  15. package/dist/base.d.mts +6 -6
  16. package/dist/base.d.ts +6 -6
  17. package/dist/base.js +1 -0
  18. package/dist/base.mjs +1 -0
  19. package/dist/bin/config.js +1 -1
  20. package/dist/index.d.ts +5 -5
  21. package/dist/index.js +5 -1
  22. package/dist/lib/lintConfig.js +12 -0
  23. package/dist/lib/lsp.js +6 -12
  24. package/dist/lib/node.js +5 -2
  25. package/dist/lib/text.js +4 -1
  26. package/dist/lib/title.js +8 -4
  27. package/dist/mixin/elementLike.js +2 -2
  28. package/dist/parser/commentAndExt.js +2 -1
  29. package/dist/render/expand.js +3 -3
  30. package/dist/render/extension.js +15 -3
  31. package/dist/render/magicWords.js +7 -7
  32. package/dist/src/attribute.d.ts +4 -1
  33. package/dist/src/attribute.js +4 -3
  34. package/dist/src/attributes.js +27 -5
  35. package/dist/src/heading.js +8 -3
  36. package/dist/src/link/base.d.ts +1 -1
  37. package/dist/src/link/base.js +10 -6
  38. package/dist/src/link/file.js +2 -2
  39. package/dist/src/magicLink.js +20 -16
  40. package/dist/src/multiLine/gallery.d.ts +5 -3
  41. package/dist/src/multiLine/gallery.js +6 -4
  42. package/dist/src/nowiki/base.d.ts +1 -1
  43. package/dist/src/parameter.js +5 -2
  44. package/dist/src/table/tr.js +1 -1
  45. package/dist/src/tagPair/ext.js +12 -18
  46. package/dist/src/tagPair/index.d.ts +1 -1
  47. package/dist/src/transclude.d.ts +6 -1
  48. package/dist/src/transclude.js +27 -19
  49. package/dist/util/constants.js +2 -1
  50. package/extensions/dist/base.js +3 -2
  51. package/i18n/en.json +1 -0
  52. package/i18n/zh-hans.json +1 -0
  53. package/i18n/zh-hant.json +1 -0
  54. package/package.json +11 -23
package/dist/lib/node.js CHANGED
@@ -200,7 +200,10 @@ let AstNode = (() => {
200
200
  /** @private */
201
201
  getChildNodes() {
202
202
  const { childNodes } = this;
203
- return Object.isFrozen(childNodes) ? [...childNodes] : childNodes;
203
+ if (Object.isFrozen(childNodes)) {
204
+ return [...childNodes];
205
+ }
206
+ return childNodes;
204
207
  }
205
208
  /** @private */
206
209
  getAttribute(key) {
@@ -636,7 +639,7 @@ let AstNode = (() => {
636
639
  if (this.getRootNode() !== other.getRootNode()) {
637
640
  throw new RangeError('Nodes to be compared are not in the same document!');
638
641
  }
639
- const aAncestors = [...this.getAncestors().reverse(), this], bAncestors = [...other.getAncestors().reverse(), other], depth = aAncestors.findIndex((ancestor, i) => bAncestors[i] !== ancestor), { childNodes } = aAncestors[depth - 1];
642
+ const aAncestors = [...this.getAncestors().toReversed(), this], bAncestors = [...other.getAncestors().toReversed(), other], depth = aAncestors.findIndex((ancestor, i) => bAncestors[i] !== ancestor), { childNodes } = aAncestors[depth - 1];
640
643
  return childNodes.indexOf(aAncestors[depth]) - childNodes.indexOf(bAncestors[depth]);
641
644
  }
642
645
  /** 获取当前节点的相对位置 */
package/dist/lib/text.js CHANGED
@@ -186,7 +186,10 @@ let AstText = (() => {
186
186
  }
187
187
  /** @private */
188
188
  toString(skip) {
189
- return skip && !this.parentNode?.getAttribute('built') ? (0, string_1.removeComment)(this.data) : this.data;
189
+ if (skip && !this.parentNode?.getAttribute('built')) {
190
+ return (0, string_1.removeComment)(this.data);
191
+ }
192
+ return this.data;
190
193
  }
191
194
  /** @private */
192
195
  text() {
package/dist/lib/title.js CHANGED
@@ -136,7 +136,8 @@ class Title {
136
136
  catch /* c8 ignore next */ { }
137
137
  }
138
138
  title = (0, string_1.decodeHtml)(title).replace(/[_ ]+/gu, ' ').trim();
139
- if (subpage || page && trimmed.startsWith('/')) {
139
+ if (subpage
140
+ || page && trimmed.startsWith('/')) {
140
141
  this.#ns = 0;
141
142
  }
142
143
  else {
@@ -206,7 +207,9 @@ class Title {
206
207
  #getTitle(prefix, redirect = true) {
207
208
  let title = (prefix + this.main).replace(/ /gu, '_');
208
209
  if (title.startsWith('/')) {
209
- title = (this.page ?? '') + title.replace(/(.)\/$/u, '$1');
210
+ title =
211
+ (this.page ?? '') +
212
+ title.replace(/(.)\/$/u, '$1');
210
213
  }
211
214
  else if (title.startsWith('../') && this.page?.includes('/')) {
212
215
  const [level, sub] = resolve(title), dirs = this.page.split('/');
@@ -237,7 +240,7 @@ class Title {
237
240
  getRedirection() {
238
241
  const { prefix,
239
242
  /* NOT FOR BROWSER */
240
- main, interwiki, } = this, pre = interwiki + (interwiki && ':') + // eslint-disable-line @stylistic/operator-linebreak
243
+ main, interwiki, } = this, pre = interwiki + (interwiki && ':') +
241
244
  prefix, result = this.#getTitle(pre);
242
245
  /* NOT FOR BROWSER */
243
246
  if (result[0]) {
@@ -338,7 +341,8 @@ class Title {
338
341
  autoConvert() {
339
342
  const { conversionTable } = this;
340
343
  if (conversionTable.size > 0) {
341
- const regex = new RegExp([...conversionTable.keys()].sort((a, b) => b.localeCompare(a)).map(string_1.escapeRegExp).join('|'), 'gu');
344
+ const regex = new RegExp([...conversionTable.keys()].toSorted((a, b) => b.localeCompare(a)).map(string_1.escapeRegExp)
345
+ .join('|'), 'gu');
342
346
  this.main = this.main.replace(regex, p => conversionTable.get(p));
343
347
  }
344
348
  }
@@ -25,9 +25,9 @@ const elementLike = (constructor) => {
25
25
  /* NOT FOR BROWSER END */
26
26
  #getCondition(selector) {
27
27
  return (0, selector_1.getCondition)(selector,
28
- // eslint-disable-next-line unicorn/no-negated-condition, @stylistic/operator-linebreak
28
+ // eslint-disable-next-line unicorn/no-negated-condition
29
29
  !('type' in this) ?
30
- undefined : // eslint-disable-line @stylistic/operator-linebreak
30
+ undefined :
31
31
  this);
32
32
  }
33
33
  getElementBy(condition) {
@@ -96,7 +96,8 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
96
96
  ch = 'c';
97
97
  const closed = substr.endsWith('-->');
98
98
  // @ts-expect-error abstract class
99
- new comment_1.CommentToken((0, string_1.restore)(substr, accum, 1).slice(4, closed ? -3 : undefined), closed, config, accum);
99
+ new comment_1.CommentToken((0, string_1.restore)(substr, accum, 1)
100
+ .slice(4, closed ? -3 : undefined), closed, config, accum);
100
101
  }
101
102
  else if (include) {
102
103
  // @ts-expect-error abstract class
@@ -99,7 +99,7 @@ const expand = (wikitext, page, callPage, config, include, context, now = index_
99
99
  if (!/\0\d+g\x7F/u.test(data)) {
100
100
  continue;
101
101
  }
102
- const expanded = data.replace(/\0(\d+)g\x7F/gu, (_, i) => {
102
+ const expanded = data.replaceAll(/\0(\d+)g\x7F/gu, (_, i) => {
103
103
  const target = accum[i];
104
104
  if (target.type === 'onlyinclude') {
105
105
  clean(accum, target);
@@ -107,7 +107,7 @@ const expand = (wikitext, page, callPage, config, include, context, now = index_
107
107
  }
108
108
  const { lastChild } = target;
109
109
  clean(accum, lastChild);
110
- return lastChild.firstChild.toString().replace(/\0(\d+)c\x7F[\n ]|\0(\d+)n\x7F|^\n|\n$/gu, (m, p1, p2) => {
110
+ return lastChild.firstChild.toString().replaceAll(/\0(\d+)c\x7F[\n ]|\0(\d+)n\x7F|^\n|\n$/gu, (m, p1, p2) => {
111
111
  if (p1 !== undefined) {
112
112
  const { innerText } = accum[p1];
113
113
  return /^T:[^_/\n<>~]+$/u.test(innerText) ? '' : m;
@@ -132,7 +132,7 @@ const expand = (wikitext, page, callPage, config, include, context, now = index_
132
132
  if (!/\0\d+[tm!{}+~-]\x7F/u.test(data)) {
133
133
  continue;
134
134
  }
135
- const expanded = data.replace(/([^\x7F]?)\0(\d+)[tm!{}+~-]\x7F/gu, (m, prev, i) => {
135
+ const expanded = data.replaceAll(/([^\x7F]?)\0(\d+)[tm!{}+~-]\x7F/gu, (m, prev, i) => {
136
136
  const target = accum[i], { type, name, length, firstChild: f, childNodes } = target, isTemplate = type === 'template', args = childNodes.slice(1);
137
137
  if (type === 'arg') {
138
138
  const arg = (0, string_1.removeCommentLine)(f.toString()).trim();
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- /* eslint @stylistic/operator-linebreak: [2, "before", {overrides: {"=": "after"}}] */
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.renderExt = void 0;
5
4
  const constants_1 = require("../util/constants");
@@ -12,12 +11,25 @@ const string_1 = require("../util/string");
12
11
  const renderExt = (token, opt) => {
13
12
  const { name, firstChild, lastChild } = token;
14
13
  switch (name) {
14
+ case 'nowiki': {
15
+ const html = lastChild.toHtmlInternal();
16
+ return token.closest('ext-inner')?.name === 'poem' ? html : (0, string_1.newline)(html);
17
+ }
18
+ case 'pre': {
19
+ const html = lastChild.toHtmlInternal({
20
+ ...opt,
21
+ nowrap: false,
22
+ });
23
+ return `<pre${firstChild.toHtmlInternal()}>${token.closest('ext-inner')?.name === 'poem' ? html : (0, string_1.newline)(html)}</pre>`;
24
+ }
25
+ case 'langconvert':
26
+ return lastChild.toHtmlInternal({ ...opt, nowrap: true });
15
27
  case 'poem': {
16
28
  const padding = firstChild.hasAttr('compact') ? '' : '\n';
17
29
  firstChild.classList.add('poem');
18
30
  return `<div${firstChild.toHtmlInternal()}>${padding}${lastChild.toHtmlInternal({ ...opt, nowrap: false })
19
- .replace(/(?<!^|<hr>)\n(?!$)/gu, '<br>\n')
20
- .replace(/^ +/gmu, p => '&nbsp;'.repeat(p.length))
31
+ .replaceAll(/(?<!^|<hr>)\n(?!$)/gu, '<br>\n')
32
+ .replaceAll(/^ +/gmu, p => '&nbsp;'.repeat(p.length))
21
33
  .trim()}${padding}</div>`;
22
34
  }
23
35
  case 'gallery': {
@@ -153,7 +153,7 @@ function urlFunction(config, args, local) {
153
153
  const link = title.getUrl(config.testArticlePath), protocol = link.startsWith('//') ? 'https:' : '';
154
154
  try {
155
155
  const url = new URL(protocol + link);
156
- url.search = query ? `?${query.replace(/\s/gu, '_')}` : '';
156
+ url.search = query ? `?${query.replaceAll(/\s/gu, '_')}` : '';
157
157
  return local ? url : [url, protocol];
158
158
  }
159
159
  catch (e) {
@@ -197,8 +197,8 @@ const parseUrl = ({ testServer = '', articlePath = testServer }) => {
197
197
  '3B': ';',
198
198
  40: '@',
199
199
  '7E': '~',
200
- }, strip = (s) => s.replace(/\0\d+.\x7F/gu, ''), wfUrlencode = (s) => encodeURIComponent(s.replaceAll(' ', '_'))
201
- .replace(/%(2[01489ACF]|3B|40|7E)/gu, (_, p) => dictUrl[p]), localurl = (config, args) => {
200
+ }, strip = (s) => s.replaceAll(/\0\d+.\x7F/gu, ''), wfUrlencode = (s) => encodeURIComponent(s.replaceAll(' ', '_'))
201
+ .replaceAll(/%(2[01489ACF]|3B|40|7E)/gu, (_, p) => dictUrl[p]), localurl = (config, args) => {
202
202
  const url = urlFunction(config, args, true);
203
203
  return typeof url === 'string' ? url : url.pathname + url.search;
204
204
  }, fullurl = (config, args) => {
@@ -246,7 +246,7 @@ const parseUrl = ({ testServer = '', articlePath = testServer }) => {
246
246
  if (!text) {
247
247
  return '';
248
248
  }
249
- let output = `\n${text}`.replace(/["&'=;_]|!!|__|:\/\/|~{3}|\n(?:[!#*:]|-{4})|(?:ISBN|PMID|RFC) /gu, m => dictHtml1[m]).slice(1);
249
+ let output = `\n${text}`.replaceAll(/["&'=;_]|!!|__|:\/\/|~{3}|\n(?:[!#*:]|-{4})|(?:ISBN|PMID|RFC) /gu, m => dictHtml1[m]).slice(1);
250
250
  output = output.charAt(0).replace(/[+_~-]/u, m => dictHtml2[m])
251
251
  + output.slice(1);
252
252
  output = output.slice(0, -1)
@@ -334,7 +334,7 @@ const expandMagicWord = (name, args, page = '', config = index_1.default.getConf
334
334
  case 'currentweek':
335
335
  return currentWeek(now, new Date(Date.UTC(now.getUTCFullYear(), 0, 1)));
336
336
  case 'currenttimestamp':
337
- return now.toISOString().slice(0, 19).replace(/[-:T]/gu, '');
337
+ return now.toISOString().slice(0, 19).replaceAll(/[-:T]/gu, '');
338
338
  case 'localyear':
339
339
  return localYear(now);
340
340
  case 'localmonth':
@@ -552,10 +552,10 @@ const expandMagicWord = (name, args, page = '', config = index_1.default.getConf
552
552
  case 'padright':
553
553
  return pad(args, 'padEnd');
554
554
  case 'anchorencode':
555
- return anchorencode((0, html_1.getId)(strip(arg0).replace(/\[\[([^[]+?)\]\]/gu, (_, p) => {
555
+ return anchorencode((0, html_1.getId)(strip(arg0).replaceAll(/\[\[([^[]+?)\]\]/gu, (_, p) => {
556
556
  const i = p.indexOf('|');
557
557
  return i <= 0 || i === p.length - 1 ? p : p.slice(i + 1);
558
- }))).replace(/%(?=[\da-f]{2})/giu, '%25');
558
+ }))).replaceAll(/%(?=[\da-f]{2})/giu, '%25');
559
559
  case 'special':
560
560
  return special(target, config);
561
561
  case 'speciale':
@@ -17,7 +17,10 @@ export type AttributeTypes = 'ext-attr' | 'html-attr' | 'table-attr';
17
17
  export declare abstract class AttributeToken extends Token {
18
18
  #private;
19
19
  readonly name: string;
20
- readonly childNodes: readonly [AtomToken, Token];
20
+ readonly childNodes: readonly [
21
+ AtomToken,
22
+ Token
23
+ ];
21
24
  abstract get firstChild(): AtomToken;
22
25
  abstract get lastChild(): Token;
23
26
  abstract get parentNode(): AttributesToken | undefined;
@@ -162,9 +162,10 @@ let AttributeToken = (() => {
162
162
  valueToken.setAttribute('stage', 1);
163
163
  }
164
164
  else {
165
- valueToken = new atom_1.AtomToken(value, 'attr-value', config, accum, {
166
- [`Stage-${exports.stages[type]}`]: ':',
167
- });
165
+ valueToken =
166
+ new atom_1.AtomToken(value, 'attr-value', config, accum, {
167
+ [`Stage-${exports.stages[type]}`]: ':',
168
+ });
168
169
  }
169
170
  super(undefined, config, accum);
170
171
  this.#type = type;
@@ -73,6 +73,15 @@ const wordRegex = /* #__PURE__ */ (() => {
73
73
  }
74
74
  /* c8 ignore stop */
75
75
  })();
76
+ const required = new Map([
77
+ ['indicator', ['name']],
78
+ ['langconvert', ['from', 'to']],
79
+ ['mapframe', ['width', 'height']],
80
+ ['maplink', ['width', 'height']],
81
+ ['phonos', [['ipa', 'file', 'wikibase']]],
82
+ ['section', [['begin', 'end']]],
83
+ ['templatestyles', ['src']],
84
+ ]);
76
85
  /**
77
86
  * attributes of extension and HTML tags
78
87
  *
@@ -174,16 +183,15 @@ let AttributesToken = (() => {
174
183
  let out = '', mt = regex.exec(attr), lastIndex = 0;
175
184
  const insertDirty = /** 插入无效属性 */ () => {
176
185
  if (out) {
177
- super.insertAt(new atom_1.AtomToken(out, toDirty(type), config, accum, {
178
- [`Stage-${stages[type]}`]: ':',
179
- }));
186
+ super.insertAt(new atom_1.AtomToken(out, toDirty(type), config, accum, { [`Stage-${stages[type]}`]: ':' }));
180
187
  out = '';
181
188
  }
182
189
  };
183
190
  while (mt) {
184
191
  const { index, 0: full, 1: key, 2: equal, 3: quoteStart, 4: quoted, 5: quoteEnd, 6: unquoted } = mt;
185
192
  out += attr.slice(lastIndex, index);
186
- if (/^(?:[\w:]|\0\d+t\x7F)(?:[\w:.-]|\0\d+t\x7F)*$/u.test((0, string_1.removeComment)(key).trim())) {
193
+ if (/^(?:[\w:]|\0\d+t\x7F)(?:[\w:.-]|\0\d+t\x7F)*$/u
194
+ .test((0, string_1.removeComment)(key).trim())) {
187
195
  const value = quoted ?? unquoted, quotes = [quoteStart, quoteEnd],
188
196
  // @ts-expect-error abstract class
189
197
  token = new attribute_1.AttributeToken((0, exports.toAttributeType)(type), name, key, quotes, config, equal, value, accum);
@@ -255,7 +263,7 @@ let AttributesToken = (() => {
255
263
  /** @private */
256
264
  lint(start = this.getAbsoluteIndex(), re) {
257
265
  LINT: {
258
- const errors = super.lint(start, re), { parentNode, childNodes } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start), rules = ['no-ignored', 'no-duplicate'], { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, s = ['closingTag', 'invalidAttributes', 'nonWordAttributes']
266
+ const errors = super.lint(start, re), { parentNode, childNodes, type, name: tag } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start), rules = ['no-ignored', 'no-duplicate', 'required-attr'], { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, s = ['closingTag', 'invalidAttributes', 'nonWordAttributes']
259
267
  .map(k => lintConfig.getSeverity(rules[0], k));
260
268
  if (s[0] && this.#lint()) {
261
269
  const e = (0, lint_1.generateForSelf)(this, rect, rules[0], 'attributes-of-closing-tag', s[0]);
@@ -290,6 +298,20 @@ let AttributesToken = (() => {
290
298
  }
291
299
  }
292
300
  }
301
+ if (type === 'ext-attrs' && required.has(tag)) {
302
+ const severity = lintConfig.getSeverity(rules[2], tag);
303
+ if (severity) {
304
+ for (const key of required.get(tag)) {
305
+ const keys = typeof key === 'string' ? [key] : key, missing = keys.every(k => {
306
+ const value = this.getAttr(k);
307
+ return value === true || !value;
308
+ });
309
+ if (missing) {
310
+ errors.push((0, lint_1.generateForSelf)(this, rect, rules[2], index_1.default.msg('required-attribute', keys.join('/')), severity));
311
+ }
312
+ }
313
+ }
314
+ }
293
315
  const severity = lintConfig.getSeverity(rules[1], 'attribute');
294
316
  if (severity && duplicated.size > 0) {
295
317
  for (const key of duplicated) {
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  };
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
40
  exports.HeadingToken = void 0;
41
+ const common_1 = require("@bhsd/common");
41
42
  const lint_1 = require("../util/lint");
42
43
  const debug_1 = require("../util/debug");
43
44
  const rect_1 = require("../lib/rect");
@@ -170,10 +171,14 @@ let HeadingToken = (() => {
170
171
  //
171
172
  }
172
173
  else if (unbalancedStart) {
173
- const [extra] = /^=+/u.exec(innerStr), newLevel = level + extra.length;
174
- e.suggestions = [{ desc: `h${level}`, range: [e.startIndex, e.startIndex + extra.length], text: '' }];
174
+ const extra = (0, common_1.numLeadingSpaces)(innerStr, /[^=]|$/u), newLevel = level + extra;
175
+ e.suggestions = [{ desc: `h${level}`, range: [e.startIndex, e.startIndex + extra], text: '' }];
175
176
  if (newLevel < 7) {
176
- e.suggestions.push({ desc: `h${newLevel}`, range: [e.endIndex, e.endIndex], text: extra });
177
+ e.suggestions.push({
178
+ desc: `h${newLevel}`,
179
+ range: [e.endIndex, e.endIndex],
180
+ text: '='.repeat(extra),
181
+ });
177
182
  }
178
183
  }
179
184
  else {
@@ -12,7 +12,7 @@ import type { Title } from '../../lib/title';
12
12
  export declare abstract class LinkBaseToken extends Token {
13
13
  #private;
14
14
  readonly name: string;
15
- abstract get type(): 'link' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'redirect-target' | 'ext-inner';
15
+ abstract get type(): 'gallery-image' | 'link' | 'category' | 'file' | 'redirect-target' | 'ext-inner' | 'imagemap-image';
16
16
  readonly childNodes: readonly [AtomToken, ...Token[]];
17
17
  abstract get firstChild(): AtomToken;
18
18
  abstract get lastChild(): Token;
@@ -83,7 +83,7 @@ let LinkBaseToken = (() => {
83
83
  /* NOT FOR BROWSER END */
84
84
  /** full link / 完整链接 */
85
85
  get link() {
86
- LSP: return this.#title;
86
+ LINT: return this.#title;
87
87
  }
88
88
  /* PRINT ONLY */
89
89
  /** 片段标识符 */
@@ -123,9 +123,7 @@ let LinkBaseToken = (() => {
123
123
  super(undefined, config, accum, {
124
124
  AtomToken: 0, Token: 1,
125
125
  });
126
- this.insertAt(new atom_1.AtomToken(link, 'link-target', config, accum, {
127
- 'Stage-2': ':', '!ExtToken': '', '!HeadingToken': '',
128
- }));
126
+ this.insertAt(new atom_1.AtomToken(link, 'link-target', config, accum, { 'Stage-2': ':', '!ExtToken': '', '!HeadingToken': '' }));
129
127
  if (linkText !== undefined) {
130
128
  const inner = new index_2.Token(linkText, { ...config, excludes: [...config.excludes, 'list'] }, accum, { 'Stage-5': ':', QuoteToken: ':', ConverterToken: ':' });
131
129
  inner.type = 'link-text';
@@ -198,12 +196,18 @@ let LinkBaseToken = (() => {
198
196
  /** @private */
199
197
  toString(skip) {
200
198
  const str = super.toString(skip, this.#delimiter);
201
- return this.#bracket ? `[[${str}]]` : str;
199
+ if (this.#bracket) {
200
+ return `[[${str}]]`;
201
+ }
202
+ return str;
202
203
  }
203
204
  /** @private */
204
205
  text() {
205
206
  const str = super.text('|');
206
- return this.#bracket ? `[[${str}]]` : str;
207
+ if (this.#bracket) {
208
+ return `[[${str}]]`;
209
+ }
210
+ return str;
207
211
  }
208
212
  /** @private */
209
213
  getAttribute(key) {
@@ -183,9 +183,9 @@ let FileToken = (() => {
183
183
  /* NOT FOR BROWSER END */
184
184
  const { extension } = this.getTitle(true, true);
185
185
  /-\{|\}-|\|/gu; // eslint-disable-line @typescript-eslint/no-unused-expressions
186
- this.safeAppend(explode(text).map(
186
+ this.safeAppend(explode(text).map((part) =>
187
187
  // @ts-expect-error abstract class
188
- (part) => new imageParameter_1.ImageParameterToken(part, extension, type, config, accum)));
188
+ new imageParameter_1.ImageParameterToken(part, extension, type, config, accum)));
189
189
  }
190
190
  /** @private */
191
191
  lint(start = this.getAbsoluteIndex(), re) {
@@ -191,7 +191,7 @@ let MagicLinkToken = (() => {
191
191
  let rule = 'invalid-url', severity = lintConfig.getSeverity(rule);
192
192
  if (severity && !this.querySelector('magic-word')) {
193
193
  try {
194
- this.getUrl();
194
+ this.#getUrl();
195
195
  }
196
196
  catch {
197
197
  errors.push((0, lint_1.generateForSelf)(this, rect, rule, 'invalid-url', severity));
@@ -219,6 +219,16 @@ let MagicLinkToken = (() => {
219
219
  return errors;
220
220
  }
221
221
  }
222
+ /** 获取自由外链的 URL */
223
+ #getUrl() {
224
+ LINT: {
225
+ let { link } = this;
226
+ if (link.startsWith('//')) {
227
+ link = `https:${link}`;
228
+ }
229
+ return new URL(link);
230
+ }
231
+ }
222
232
  /**
223
233
  * Get the URL
224
234
  *
@@ -227,22 +237,16 @@ let MagicLinkToken = (() => {
227
237
  */
228
238
  getUrl(articlePath) {
229
239
  LSP: {
230
- const { type } = this;
231
- let { link } = this;
232
- if (type === 'magic-link') {
233
- if (link.startsWith('ISBN')) {
234
- return this
235
- .normalizeTitle(`BookSources/${link.slice(5)}`, -1, { temporary: true })
236
- .getUrl(articlePath);
237
- }
238
- link = link.startsWith('RFC')
239
- ? `https://datatracker.ietf.org/doc/html/rfc${link.slice(4)}`
240
- : `https://pubmed.ncbi.nlm.nih.gov/${link.slice(5)}`;
241
- }
242
- else if (link.startsWith('//')) {
243
- link = `https:${link}`;
240
+ if (this.type !== 'magic-link') {
241
+ return this.#getUrl();
244
242
  }
245
- return new URL(link);
243
+ const { link } = this;
244
+ return link.startsWith('ISBN')
245
+ ? this.normalizeTitle(`BookSources/${link.slice(5)}`, -1, { temporary: true })
246
+ .getUrl(articlePath)
247
+ : new URL(link.startsWith('RFC')
248
+ ? `https://datatracker.ietf.org/doc/html/rfc${link.slice(4)}`
249
+ : `https://pubmed.ncbi.nlm.nih.gov/${link.slice(5)}`);
246
250
  }
247
251
  }
248
252
  /* PRINT ONLY */
@@ -3,6 +3,7 @@ import { GalleryImageToken } from '../link/galleryImage';
3
3
  import { CommentLineToken } from '../nowiki/commentLine';
4
4
  import type { Config, LintError, AST } from '../../base';
5
5
  import type { AstText, Token, AstNodes } from '../../internal';
6
+ declare type Child = GalleryImageToken | CommentLineToken | AstText;
6
7
  /**
7
8
  * `<gallery>`
8
9
  * @classdesc `{childNodes: (GalleryImageToken|CommentLineToken|AstText)[]}`
@@ -10,9 +11,9 @@ import type { AstText, Token, AstNodes } from '../../internal';
10
11
  export declare abstract class GalleryToken extends MultiLineToken {
11
12
  #private;
12
13
  readonly name: 'gallery';
13
- readonly childNodes: readonly (GalleryImageToken | CommentLineToken | AstText)[];
14
- abstract get firstChild(): GalleryImageToken | CommentLineToken | AstText | undefined;
15
- abstract get lastChild(): GalleryImageToken | CommentLineToken | AstText | undefined;
14
+ readonly childNodes: readonly Child[];
15
+ abstract get firstChild(): Child | undefined;
16
+ abstract get lastChild(): Child | undefined;
16
17
  abstract get children(): (GalleryImageToken | CommentLineToken)[];
17
18
  abstract get firstElementChild(): GalleryImageToken | CommentLineToken | undefined;
18
19
  abstract get lastElementChild(): GalleryImageToken | CommentLineToken | undefined;
@@ -44,3 +45,4 @@ export declare abstract class GalleryToken extends MultiLineToken {
44
45
  */
45
46
  insertImage(file: string, i?: number): GalleryImageToken;
46
47
  }
48
+ export {};
@@ -48,7 +48,6 @@ const debug_1 = require("../../util/debug");
48
48
  const constants_1 = require("../../util/constants");
49
49
  const html_1 = require("../../util/html");
50
50
  const cached_1 = require("../../mixin/cached");
51
- /* NOT FOR BROWSER END */
52
51
  /**
53
52
  * `<gallery>`
54
53
  * @classdesc `{childNodes: (GalleryImageToken|CommentLineToken|AstText)[]}`
@@ -98,8 +97,10 @@ let GalleryToken = (() => {
98
97
  for (const line of inner?.split('\n') ?? []) {
99
98
  const matches = /^([^|]+)(?:\|(.*))?/u.exec(line);
100
99
  if (!matches) {
101
- // @ts-expect-error abstract class
102
- super.insertAt((line.trim() ? new commentLine_1.CommentLineToken(line, config, accum) : line));
100
+ super.insertAt((line.trim()
101
+ // @ts-expect-error abstract class
102
+ ? new commentLine_1.CommentLineToken(line, config, accum)
103
+ : line));
103
104
  continue;
104
105
  }
105
106
  const [, file, alt] = matches;
@@ -108,8 +109,9 @@ let GalleryToken = (() => {
108
109
  super.insertAt(new galleryImage_1.GalleryImageToken('gallery', file, alt, config, accum));
109
110
  }
110
111
  else {
112
+ super.insertAt(
111
113
  // @ts-expect-error abstract class
112
- super.insertAt(new commentLine_1.CommentLineToken(line, config, accum));
114
+ new commentLine_1.CommentLineToken(line, config, accum));
113
115
  }
114
116
  }
115
117
  }
@@ -1,7 +1,7 @@
1
1
  import { Token } from '../index';
2
2
  import type { Config } from '../../base';
3
3
  import type { AstText } from '../../internal';
4
- declare type NowikiTypes = 'ext-inner' | 'comment' | 'dd' | 'double-underscore' | 'hr' | 'list' | 'noinclude' | 'quote';
4
+ declare type NowikiTypes = 'ext-inner' | 'comment' | 'dd' | 'double-underscore' | 'hr' | 'list' | 'quote' | 'noinclude';
5
5
  /**
6
6
  * text-only token that will not be parsed
7
7
  *
@@ -130,7 +130,9 @@ let ParameterToken = (() => {
130
130
  }
131
131
  /** @private */
132
132
  trimName(name, set = true) {
133
- const trimmed = (typeof name === 'string' ? name : name.toString(true))
133
+ const trimmed = (typeof name === 'string'
134
+ ? name :
135
+ name.toString(true))
134
136
  .replace(/^[ \t\n\0\v]+|([^ \t\n\0\v])[ \t\n\0\v]+$/gu, '$1');
135
137
  if (set) {
136
138
  this.setAttribute('name', trimmed);
@@ -245,7 +247,8 @@ let ParameterToken = (() => {
245
247
  */
246
248
  setValue(value) {
247
249
  const { childNodes } = index_1.default.parseWithRef(value, this);
248
- this.lastChild.safeReplaceChildren(childNodes);
250
+ this.lastChild
251
+ .safeReplaceChildren(childNodes);
249
252
  }
250
253
  /**
251
254
  * Rename the parameter
@@ -61,7 +61,7 @@ class TrToken extends trBase_1.TrBaseToken {
61
61
  * 获取前一行
62
62
  */
63
63
  getPreviousRow() {
64
- return this.#getSiblingRow((childNodes, index) => childNodes.slice(0, index).reverse());
64
+ return this.#getSiblingRow((childNodes, index) => childNodes.slice(0, index).toReversed());
65
65
  }
66
66
  }
67
67
  exports.TrToken = TrToken;
@@ -48,7 +48,6 @@ const attributes_1 = require("../attributes");
48
48
  /* NOT FOR BROWSER */
49
49
  const debug_1 = require("../../util/debug");
50
50
  const constants_1 = require("../../util/constants");
51
- const string_1 = require("../../util/string");
52
51
  const cached_1 = require("../../mixin/cached");
53
52
  /**
54
53
  * extension tag
@@ -116,11 +115,17 @@ let ExtToken = (() => {
116
115
  case 'seo':
117
116
  case 'langconvert':
118
117
  case 'phonos':
119
- if (lcName === 'poem') {
120
- newConfig.excludes.push('heading');
121
- }
122
- else if (lcName === 'tab') {
123
- newConfig.ext = newConfig.ext.filter(e => e !== 'tabs');
118
+ switch (lcName) {
119
+ case 'poem':
120
+ newConfig.excludes.push('heading');
121
+ break;
122
+ case 'langconvert':
123
+ newConfig.excludes.push('list');
124
+ break;
125
+ case 'tab':
126
+ newConfig.ext = newConfig.ext.filter(e => e !== 'tabs');
127
+ break;
128
+ // No default
124
129
  }
125
130
  innerToken = new index_2.Token(inner, newConfig, accum);
126
131
  break;
@@ -242,21 +247,10 @@ let ExtToken = (() => {
242
247
  }
243
248
  /** @private */
244
249
  toHtmlInternal(opt) {
245
- const { name, firstChild, lastChild } = this;
250
+ const { name } = this;
246
251
  if (constants_1.tagHooks.has(name)) {
247
252
  return constants_1.tagHooks.get(name)(this);
248
253
  }
249
- else if (name === 'nowiki') {
250
- const html = lastChild.toHtmlInternal();
251
- return this.closest('ext-inner')?.name === 'poem' ? html : (0, string_1.newline)(html);
252
- }
253
- else if (name === 'pre') {
254
- const html = lastChild.toHtmlInternal({
255
- ...opt,
256
- nowrap: false,
257
- });
258
- return `<pre${firstChild.toHtmlInternal()}>${this.closest('ext-inner')?.name === 'poem' ? html : (0, string_1.newline)(html)}</pre>`;
259
- }
260
254
  const { renderExt } = require('../../render/extension');
261
255
  return renderExt(this, opt);
262
256
  }
@@ -10,7 +10,7 @@ export declare abstract class TagPairToken extends Token {
10
10
  #private;
11
11
  readonly name: string;
12
12
  closed: boolean;
13
- abstract get type(): 'ext' | 'include' | 'translate';
13
+ abstract get type(): 'ext' | 'translate' | 'include';
14
14
  readonly childNodes: readonly [AstNodes, AstNodes];
15
15
  abstract get firstChild(): AstNodes;
16
16
  abstract get lastChild(): AstNodes;
@@ -18,7 +18,12 @@ export declare abstract class TranscludeToken extends Token {
18
18
  #private;
19
19
  readonly modifier: string;
20
20
  readonly name: string;
21
- readonly childNodes: readonly [AtomToken | SyntaxToken, ...ParameterToken[]] | readonly [SyntaxToken, AtomToken, AtomToken, ...ParameterToken[]];
21
+ readonly childNodes: readonly [
22
+ SyntaxToken,
23
+ AtomToken,
24
+ AtomToken,
25
+ ...ParameterToken[]
26
+ ] | readonly [AtomToken | SyntaxToken, ...ParameterToken[]];
22
27
  abstract get firstChild(): AtomToken | SyntaxToken;
23
28
  abstract get lastChild(): AtomToken | SyntaxToken | ParameterToken;
24
29
  abstract get children(): [AtomToken | SyntaxToken, ...ParameterToken[]] | [SyntaxToken, AtomToken, AtomToken, ...ParameterToken[]];