wikiparser-node 1.21.3 → 1.22.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 (64) hide show
  1. package/README.md +6 -0
  2. package/bundle/bundle-es8.min.js +24 -24
  3. package/bundle/bundle-lsp.min.js +26 -26
  4. package/bundle/bundle.min.js +24 -24
  5. package/config/default.json +15 -11
  6. package/config/enwiki.json +1 -1
  7. package/config/jawiki.json +1 -1
  8. package/config/minimum.json +2 -3
  9. package/config/moegirl.json +152 -15
  10. package/config/zhwiki.json +1 -1
  11. package/dist/addon/token.js +3 -0
  12. package/dist/base.d.mts +10 -8
  13. package/dist/base.d.ts +10 -8
  14. package/dist/bin/config.js +23 -11
  15. package/dist/index.d.ts +31 -2
  16. package/dist/index.js +27 -1
  17. package/dist/lib/element.d.ts +4 -4
  18. package/dist/lib/element.js +4 -4
  19. package/dist/lib/lintConfig.js +123 -6
  20. package/dist/lib/lsp.d.ts +7 -7
  21. package/dist/lib/lsp.js +12 -16
  22. package/dist/lib/node.d.ts +1 -1
  23. package/dist/lib/node.js +1 -1
  24. package/dist/lib/range.d.ts +2 -2
  25. package/dist/lib/range.js +2 -2
  26. package/dist/lib/text.js +72 -62
  27. package/dist/lib/title.d.ts +11 -4
  28. package/dist/lib/title.js +16 -6
  29. package/dist/parser/commentAndExt.js +6 -4
  30. package/dist/parser/converter.js +1 -1
  31. package/dist/src/arg.js +11 -10
  32. package/dist/src/attribute.js +31 -19
  33. package/dist/src/attributes.js +10 -8
  34. package/dist/src/commented.js +1 -1
  35. package/dist/src/converterRule.js +2 -2
  36. package/dist/src/gallery.js +26 -19
  37. package/dist/src/heading.js +32 -36
  38. package/dist/src/html.js +64 -51
  39. package/dist/src/index.d.ts +2 -2
  40. package/dist/src/index.js +10 -8
  41. package/dist/src/link/base.d.ts +1 -1
  42. package/dist/src/link/base.js +22 -15
  43. package/dist/src/link/file.js +22 -14
  44. package/dist/src/link/index.d.ts +1 -1
  45. package/dist/src/link/index.js +1 -1
  46. package/dist/src/magicLink.js +16 -12
  47. package/dist/src/nowiki/index.js +1 -1
  48. package/dist/src/nowiki/quote.js +19 -38
  49. package/dist/src/table/index.js +33 -27
  50. package/dist/src/table/td.d.ts +1 -1
  51. package/dist/src/table/td.js +27 -25
  52. package/dist/src/table/trBase.js +13 -10
  53. package/dist/src/tagPair/ext.js +6 -3
  54. package/dist/src/tagPair/index.js +2 -3
  55. package/dist/src/transclude.d.ts +15 -1
  56. package/dist/src/transclude.js +43 -13
  57. package/dist/util/lint.js +3 -5
  58. package/dist/util/sharable.js +1 -1
  59. package/dist/util/sharable.mjs +2 -2
  60. package/extensions/dist/base.js +8 -1
  61. package/extensions/typings.d.ts +2 -1
  62. package/i18n/zh-hans.json +1 -1
  63. package/i18n/zh-hant.json +1 -1
  64. package/package.json +7 -2
package/dist/lib/lsp.js CHANGED
@@ -18,7 +18,7 @@ const path_1 = __importDefault(require("path"));
18
18
  const util_1 = __importDefault(require("util"));
19
19
  const child_process_1 = require("child_process");
20
20
  const crypto_1 = require("crypto");
21
- const stylelint_1 = require("@bhsd/common/dist/stylelint");
21
+ const stylelint_util_1 = require("@bhsd/stylelint-util");
22
22
  const document_1 = require("./document");
23
23
  /** @see https://www.npmjs.com/package/stylelint-config-recommended */
24
24
  const cssRules = {
@@ -534,7 +534,7 @@ class LanguageService {
534
534
  *
535
535
  * 提供自动补全
536
536
  * @param text source Wikitext / 源代码
537
- * @param position 位置
537
+ * @param position position / 位置
538
538
  */
539
539
  async provideCompletionItems(text, position) {
540
540
  const { re, allTags, functions, switches, protocols, params, tags, ext } = this.#prepareCompletionConfig(), { line, character } = position, curLine = text.split(/\r?\n/u, line + 1)[line], mt = re.exec(curLine?.slice(0, character) ?? ''), [, , iAlias = {}, sAlias = {}] = this.config.doubleUnderscore;
@@ -762,7 +762,7 @@ class LanguageService {
762
762
  if (tokens.length === 0) {
763
763
  return [];
764
764
  }
765
- const cssErrors = await (0, stylelint_1.styleLint)((await document_1.stylelint), tokens.map(({ type, tag, lastChild }, i) => `${type === 'ext-attr' ? 'div' : tag}#${i}{\n${(0, common_1.sanitizeInlineStyle)(lastChild.toString())}\n}`).join('\n'), cssRules);
765
+ const cssErrors = await (0, stylelint_util_1.styleLint)((await document_1.stylelint), tokens.map(({ type, tag, lastChild }, i) => `${type === 'ext-attr' ? 'div' : tag}#${i}{\n${(0, common_1.sanitizeInlineStyle)(lastChild.toString())}\n}`).join('\n'), cssRules);
766
766
  if (cssErrors.length === 0) {
767
767
  return [];
768
768
  }
@@ -1056,7 +1056,7 @@ class LanguageService {
1056
1056
  *
1057
1057
  * 提供引用
1058
1058
  * @param text source Wikitext / 源代码
1059
- * @param position 位置
1059
+ * @param position position / 位置
1060
1060
  */
1061
1061
  async provideReferences(text, position) {
1062
1062
  const root = await this.#queue(text), { offsetNode, offset } = caretPositionFromWord(root, this.#text, position), element = offsetNode.type === 'text' ? offsetNode.parentNode : offsetNode, node = offset === 0 && (element.type === 'ext-attr-dirty' || element.type === 'html-attr-dirty')
@@ -1077,7 +1077,7 @@ class LanguageService {
1077
1077
  *
1078
1078
  * 提供定义
1079
1079
  * @param text source Wikitext / 源代码
1080
- * @param position 位置
1080
+ * @param position position / 位置
1081
1081
  */
1082
1082
  async provideDefinition(text, position) {
1083
1083
  const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line), ext = node.is('ext') && node.name === 'ref'
@@ -1098,7 +1098,7 @@ class LanguageService {
1098
1098
  *
1099
1099
  * 提供变量更名准备
1100
1100
  * @param text source Wikitext / 源代码
1101
- * @param position 位置
1101
+ * @param position position / 位置
1102
1102
  */
1103
1103
  async resolveRenameLocation(text, position) {
1104
1104
  const root = await this.#queue(text), node = root.elementFromPoint(position.character, position.line), { type } = node, refName = getRefName(node), refGroup = getRefGroup(node);
@@ -1113,7 +1113,7 @@ class LanguageService {
1113
1113
  *
1114
1114
  * 变量更名
1115
1115
  * @param text source Wikitext / 源代码
1116
- * @param position 位置
1116
+ * @param position position / 位置
1117
1117
  * @param newName new name / 新名称
1118
1118
  */
1119
1119
  async provideRenameEdits(text, position, newName) {
@@ -1159,7 +1159,7 @@ class LanguageService {
1159
1159
  *
1160
1160
  * 提供悬停信息
1161
1161
  * @param text source Wikitext / 源代码
1162
- * @param position 位置
1162
+ * @param position position / 位置
1163
1163
  */
1164
1164
  async provideHover(text, position) {
1165
1165
  /* istanbul ignore next */
@@ -1255,7 +1255,7 @@ class LanguageService {
1255
1255
  *
1256
1256
  * 提供魔术字帮助
1257
1257
  * @param text source Wikitext / 源代码
1258
- * @param position 位置
1258
+ * @param position position / 位置
1259
1259
  */
1260
1260
  async provideSignatureHelp(text, position) {
1261
1261
  /* istanbul ignore next */
@@ -1396,19 +1396,15 @@ class LanguageService {
1396
1396
  * @since v1.18.1
1397
1397
  */
1398
1398
  async setTargetWikipedia(wiki) {
1399
- const mt = /^https?:\/\/([^./]+)\.wikipedia\.org/iu.exec(wiki);
1400
- if (!mt) {
1401
- throw new RangeError('Invalid Wikipedia URL!');
1402
- }
1403
- const site = `${mt[1].toLowerCase()}wiki`;
1399
+ const [site, host] = index_1.default.getWMFSite(wiki);
1404
1400
  try {
1405
1401
  const config = require(path_1.default.join('..', '..', 'config', site));
1406
1402
  this.config = index_1.default.getConfig(config);
1407
1403
  }
1408
1404
  catch {
1409
- this.config = await index_1.default.fetchConfig(site, `${mt[0]}/w`);
1405
+ this.config = await index_1.default.fetchConfig(site, `${host}/w`);
1410
1406
  }
1411
- Object.assign(this.config, { articlePath: `${mt[0]}/wiki/` });
1407
+ Object.assign(this.config, { articlePath: `${host}/wiki/` });
1412
1408
  }
1413
1409
  }
1414
1410
  exports.LanguageService = LanguageService;
@@ -197,7 +197,7 @@ export declare abstract class AstNode implements AstNodeBase {
197
197
  * 添加事件监听
198
198
  * @param types event type / 事件类型
199
199
  * @param listener listener function / 监听函数
200
- * @param options 选项
200
+ * @param options options / 选项
201
201
  * @param options.once to be executed only once / 仅执行一次
202
202
  */
203
203
  addEventListener(types: string | string[], listener: (...args: any[]) => void, options?: {
package/dist/lib/node.js CHANGED
@@ -514,7 +514,7 @@ let AstNode = (() => {
514
514
  * 添加事件监听
515
515
  * @param types event type / 事件类型
516
516
  * @param listener listener function / 监听函数
517
- * @param options 选项
517
+ * @param options options / 选项
518
518
  * @param options.once to be executed only once / 仅执行一次
519
519
  */
520
520
  addEventListener(types, listener, options) {
@@ -99,7 +99,7 @@ export declare class AstRange {
99
99
  *
100
100
  * 比较端点和Range的位置
101
101
  * @param referenceNode node container / 端点容器
102
- * @param offset 端点位置
102
+ * @param offset node offset / 端点位置
103
103
  * @throws `RangeError` 不在同一个文档
104
104
  */
105
105
  comparePoint(referenceNode: AstNodes, offset: number): -1 | 0 | 1;
@@ -108,7 +108,7 @@ export declare class AstRange {
108
108
  *
109
109
  * 端点是否在Range中
110
110
  * @param referenceNode node container / 端点容器
111
- * @param offset 端点位置
111
+ * @param offset node offset / 端点位置
112
112
  */
113
113
  isPointInRange(referenceNode: AstNodes, offset: number): boolean;
114
114
  /**
package/dist/lib/range.js CHANGED
@@ -277,7 +277,7 @@ class AstRange {
277
277
  *
278
278
  * 比较端点和Range的位置
279
279
  * @param referenceNode node container / 端点容器
280
- * @param offset 端点位置
280
+ * @param offset node offset / 端点位置
281
281
  * @throws `RangeError` 不在同一个文档
282
282
  */
283
283
  comparePoint(referenceNode, offset) {
@@ -297,7 +297,7 @@ class AstRange {
297
297
  *
298
298
  * 端点是否在Range中
299
299
  * @param referenceNode node container / 端点容器
300
- * @param offset 端点位置
300
+ * @param offset node offset / 端点位置
301
301
  */
302
302
  isPointInRange(referenceNode, offset) {
303
303
  return this.comparePoint(referenceNode, offset) === 0;
package/dist/lib/text.js CHANGED
@@ -63,16 +63,6 @@ const errorSyntaxUrl = new RegExp(source, 'giu'), noLinkTypes = new Set(['attr-v
63
63
  '{': /[{}]/u,
64
64
  ']': /[[\]](?=[^[\]]*$)/u,
65
65
  '}': /[{}](?=[^{}]*$)/u,
66
- }, ruleMap = {
67
- '<': 'tag-like',
68
- '[': 'lonely-bracket',
69
- '{': 'lonely-bracket',
70
- ']': 'lonely-bracket',
71
- '}': 'lonely-bracket',
72
- h: 'lonely-http',
73
- r: 'lonely-http',
74
- p: 'lonely-http',
75
- i: 'lonely-http',
76
66
  }, disallowedTags = new Set([
77
67
  'html',
78
68
  'base',
@@ -210,13 +200,9 @@ let AstText = (() => {
210
200
  throw new Error('An isolated text node cannot be linted!');
211
201
  }
212
202
  const { type, name, parentNode: grandparent } = parentNode;
213
- let isHtmlAttrVal = false;
214
203
  if (type === 'attr-value') {
215
- const { type: grandType, name: grandName, tag } = grandparent;
216
- if (grandType !== 'ext-attr') {
217
- isHtmlAttrVal = true;
218
- }
219
- else if (tag === 'ref' && (grandName === 'name' || grandName === 'extends' || grandName === 'follow')
204
+ const { name: grandName, tag } = grandparent;
205
+ if (tag === 'ref' && (grandName === 'name' || grandName === 'extends' || grandName === 'follow')
220
206
  || grandName === 'group' && (tag === 'ref' || tag === 'references')
221
207
  || tag === 'choose' && (grandName === 'before' || grandName === 'after')) {
222
208
  return [];
@@ -226,7 +212,7 @@ let AstText = (() => {
226
212
  || type === 'ext-link-url'
227
213
  || type === 'ext-link-text'
228
214
  || type === 'image-parameter' && name === 'link'
229
- || isHtmlAttrVal
215
+ || type === 'attr-value'
230
216
  ? errorSyntaxUrl
231
217
  : errorSyntax;
232
218
  if (data.search(errorRegex) === -1) {
@@ -252,72 +238,95 @@ let AstText = (() => {
252
238
  error = error.slice(length);
253
239
  }
254
240
  error = error.toLowerCase();
255
- const [char] = error, magicLink = char === 'r' || char === 'p' || char === 'i';
241
+ const [char] = error, magicLink = char === 'r' || char === 'p' || char === 'i', lbrace = char === '{', rbrace = char === '}', lbrack = char === '[', rbrack = char === ']';
256
242
  let { length } = error;
257
243
  if (char === '<' && !tags.has(tag.toLowerCase())
258
- || char === '[' && type === 'ext-link-text' && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
244
+ || lbrack && type === 'ext-link-text' && (/&(?:rbrack|#93|#x5[Dd];);/u.test(data.slice(index + 1))
259
245
  || nextSibling?.is('ext') && nextName === 'nowiki'
260
246
  && nextSibling.innerText?.includes(']'))
261
247
  || magicLink && (!parentNode.isPlain() || noLinkTypes.has(type))) {
262
248
  continue;
263
249
  }
264
- else if (char === ']' && (index || length > 1)) {
250
+ else if (rbrack && (index || length > 1)) {
265
251
  errorRegex.lastIndex--;
266
252
  }
267
- let startIndex = start + index, endIndex = startIndex + length;
268
- const nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1];
269
- let severity = length > 1 && !(char === '<' && (/^<\s/u.test(error) || !/[\s/>]/u.test(nextChar ?? '') || disallowedTags.has(tag))
270
- || isHtmlAttrVal && (char === '[' || char === ']')
271
- || magicLink && type === 'parameter-value'
272
- || /^(?:rfc|pmid|isbn)$/iu.test(error))
273
- || char === '{' && (nextChar === char || previousChar === '-' && variants.length > 0)
274
- || char === '}' && (previousChar === char || nextChar === '-' && variants.length > 0)
275
- || char === '[' && (type === 'ext-link-text' || nextType === 'free-ext-link' && !data.slice(index + 1).trim())
276
- || char === ']' && previousType === 'free-ext-link'
277
- && !data.slice(0, index).includes(']')
278
- ? 'error'
279
- : 'warning';
280
- const leftBracket = char === '{' || char === '[', rightBracket = char === ']' || char === '}';
281
- if (severity === 'warning' && (leftBracket || rightBracket)) {
282
- const regex = regexes[char], remains = leftBracket ? data.slice(index + 1) : data.slice(0, index);
283
- if (char === '{' && regex.exec(remains)?.[0] === '}'
284
- || char === '}' && regex.exec(remains)?.[0] === '{') {
285
- continue;
286
- }
287
- else if (!remains.includes(char)) {
288
- const sibling = leftBracket ? 'nextSibling' : 'previousSibling';
289
- let cur = this[sibling];
290
- while (cur && (cur.type !== 'text' || !regex.test(cur.data))) {
291
- cur = cur[sibling];
292
- }
293
- if (cur && regex.exec(cur.data)[0] !== char) {
294
- continue;
295
- }
296
- }
297
- }
253
+ // Rule & Severity
254
+ let startIndex = start + index, endIndex = startIndex + length, rule, severity;
255
+ const nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], leftBracket = lbrace || lbrack, lConverter = lbrace && previousChar === '-' && variants.length > 0, rConverter = rbrace && nextChar === '-' && variants.length > 0, brokenExtLink = lbrack && nextType === 'free-ext-link' && !data.slice(index + 1).trim()
256
+ || rbrack && previousType === 'free-ext-link'
257
+ && !data.slice(0, index).includes(']');
298
258
  if (magicLink) {
259
+ rule = 'lonely-http';
299
260
  error = error.toUpperCase();
261
+ severity = index_1.default.lintConfig.getSeverity(rule, error);
300
262
  }
301
- else if (error === '{' && previousChar === '-' && severity === 'error') {
302
- severity = 'warning';
303
- if (index > 0) {
263
+ else if (char === '<') {
264
+ rule = 'tag-like';
265
+ let key;
266
+ if (/^<\s/u.test(error) || !/[\s/>]/u.test(nextChar ?? '')) {
267
+ key = 'invalid';
268
+ }
269
+ else if (disallowedTags.has(tag)) {
270
+ key = 'disallowed';
271
+ }
272
+ severity = index_1.default.lintConfig.getSeverity(rule, key);
273
+ }
274
+ else if (lConverter || rConverter) {
275
+ rule = 'lonely-bracket';
276
+ severity = index_1.default.lintConfig.getSeverity(rule, 'converter');
277
+ if (lConverter && index > 0) {
304
278
  error = '-{';
305
279
  index--;
306
280
  startIndex--;
307
281
  length = 2;
308
282
  }
309
- }
310
- else if (error === '}' && nextChar === '-' && severity === 'error') {
311
- severity = 'warning';
312
- if (index < data.length - 1) {
283
+ else if (rConverter && index < data.length - 1) {
313
284
  error = '}-';
314
285
  endIndex++;
315
286
  length = 2;
316
287
  }
317
288
  }
289
+ else if (brokenExtLink) {
290
+ rule = 'lonely-bracket';
291
+ severity = index_1.default.lintConfig.getSeverity(rule, 'extLink');
292
+ }
293
+ else if (leftBracket || rbrace || rbrack) {
294
+ rule = 'lonely-bracket';
295
+ if (length > 1 || lbrace && nextChar === char || rbrace && previousChar === char) {
296
+ severity = index_1.default.lintConfig.getSeverity(rule, 'double');
297
+ }
298
+ else {
299
+ if (!lbrack || type !== 'ext-link-text') {
300
+ const regex = regexes[char], remains = leftBracket ? data.slice(index + 1) : data.slice(0, index);
301
+ if (lbrace && regex.exec(remains)?.[0] === '}'
302
+ || rbrace && regex.exec(remains)?.[0] === '{') {
303
+ continue;
304
+ }
305
+ else if (!remains.includes(char)) {
306
+ const sibling = leftBracket ? 'nextSibling' : 'previousSibling';
307
+ let cur = this[sibling];
308
+ while (cur && (cur.type !== 'text' || !regex.test(cur.data))) {
309
+ cur = cur[sibling];
310
+ }
311
+ if (cur && regex.exec(cur.data)[0] !== char) {
312
+ continue;
313
+ }
314
+ }
315
+ }
316
+ severity = index_1.default.lintConfig.getSeverity(rule, 'single');
317
+ }
318
+ }
319
+ else {
320
+ rule = 'lonely-http';
321
+ severity = index_1.default.lintConfig.getSeverity(rule);
322
+ }
323
+ if (!severity) {
324
+ continue;
325
+ }
326
+ // LintError
318
327
  const pos = this.posFromIndex(index), { line: startLine, character: startCol } = (0, lint_1.getEndPos)(top, left, pos.top + 1, pos.left), e = {
319
- rule: ruleMap[char],
320
- message: index_1.default.msg('lonely "$1"', magicLink || char === 'h' || error === '-{' || error === '}-' ? error : char),
328
+ rule,
329
+ message: index_1.default.msg('lonely "$1"', magicLink || char === 'h' || lConverter || rConverter ? error : char),
321
330
  severity,
322
331
  startIndex,
323
332
  endIndex,
@@ -326,17 +335,18 @@ let AstText = (() => {
326
335
  startCol,
327
336
  endCol: startCol + length,
328
337
  };
338
+ // Suggestions
329
339
  if (char === '<') {
330
340
  e.suggestions = [{ desc: 'escape', range: [startIndex, startIndex + 1], text: '&lt;' }];
331
341
  }
332
342
  else if (char === 'h' && type !== 'link-text' && wordRegex.test(previousChar || '')) {
333
343
  e.suggestions = [{ desc: 'whitespace', range: [startIndex, startIndex], text: ' ' }];
334
344
  }
335
- else if (char === '[' && type === 'ext-link-text') {
345
+ else if (lbrack && type === 'ext-link-text') {
336
346
  const i = parentNode.getAbsoluteIndex() + parentNode.toString().length;
337
347
  e.suggestions = [{ desc: 'escape', range: [i, i + 1], text: '&#93;' }];
338
348
  }
339
- else if (char === ']' && previousType === 'free-ext-link' && severity === 'error') {
349
+ else if (rbrack && brokenExtLink) {
340
350
  const i = start - previousSibling.toString().length;
341
351
  e.suggestions = [{ desc: 'left bracket', range: [i, i], text: '[' }];
342
352
  }
@@ -36,6 +36,13 @@ export declare class Title {
36
36
  /** @throws `RangeError` undefined namespace */
37
37
  set ns(ns: number);
38
38
  set fragment(fragment: string | undefined);
39
+ /**
40
+ * display title
41
+ *
42
+ * 用于显示的标题
43
+ * @since v1.22.0
44
+ */
45
+ get displayTitle(): string;
39
46
  /**
40
47
  * @see MediaWikiTitleCodec::splitTitleString
41
48
  *
@@ -75,14 +82,14 @@ export declare class Title {
75
82
  * 转换为主页面
76
83
  * @since v1.1.0
77
84
  */
78
- toSubjectPage(): void;
85
+ toSubjectPage(): this;
79
86
  /**
80
87
  * Get the title of its talk page
81
88
  *
82
89
  * 转换为讨论页面
83
90
  * @since v1.1.0
84
91
  */
85
- toTalkPage(): void;
92
+ toTalkPage(): this;
86
93
  /**
87
94
  * Check if the title is a talk page
88
95
  *
@@ -96,12 +103,12 @@ export declare class Title {
96
103
  * 转换为上一级页面
97
104
  * @since v1.1.0
98
105
  */
99
- toBasePage(): void;
106
+ toBasePage(): this;
100
107
  /**
101
108
  * Get the title of its root page
102
109
  *
103
110
  * 转换为根页面
104
111
  * @since v1.1.0
105
112
  */
106
- toRootPage(): void;
113
+ toRootPage(): this;
107
114
  }
package/dist/lib/title.js CHANGED
@@ -94,6 +94,15 @@ class Title {
94
94
  .replaceAll(' ', '_');
95
95
  }
96
96
  }
97
+ /**
98
+ * display title
99
+ *
100
+ * 用于显示的标题
101
+ * @since v1.22.0
102
+ */
103
+ get displayTitle() {
104
+ return this.title.replaceAll('_', ' ');
105
+ }
97
106
  /* NOT FOR BROWSER END */
98
107
  /**
99
108
  * @see MediaWikiTitleCodec::splitTitleString
@@ -236,12 +245,9 @@ class Title {
236
245
  /* NOT FOR BROWSER */
237
246
  /** @private */
238
247
  toString(display) {
239
- return (display ? this.title.replace(/_/gu, ' ') : this.title)
240
- + (this.#fragment === undefined
241
- && this.#redirectFragment === undefined
242
- ? ''
243
- : `#${this.#fragment
244
- ?? this.#redirectFragment}`);
248
+ return (display ? this.displayTitle : this.title) + (this.#fragment === undefined && this.#redirectFragment === undefined
249
+ ? ''
250
+ : `#${this.#fragment ?? this.#redirectFragment}`);
245
251
  }
246
252
  /**
247
253
  * 处理重定向
@@ -283,6 +289,7 @@ class Title {
283
289
  if (this.isTalkPage()) {
284
290
  this.#ns--;
285
291
  }
292
+ return this;
286
293
  }
287
294
  /**
288
295
  * Get the title of its talk page
@@ -294,6 +301,7 @@ class Title {
294
301
  if (!this.isTalkPage()) {
295
302
  this.#ns++;
296
303
  }
304
+ return this;
297
305
  }
298
306
  /**
299
307
  * Check if the title is a talk page
@@ -312,6 +320,7 @@ class Title {
312
320
  */
313
321
  toBasePage() {
314
322
  this.main = this.main.replace(/\/[^/]*$/u, '');
323
+ return this;
315
324
  }
316
325
  /**
317
326
  * Get the title of its root page
@@ -321,6 +330,7 @@ class Title {
321
330
  */
322
331
  toRootPage() {
323
332
  this.main = this.main.replace(/\/.*/u, '');
333
+ return this;
324
334
  }
325
335
  /** @private */
326
336
  getTitleAttr() {
@@ -16,7 +16,9 @@ const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', {
16
16
  const noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly';
17
17
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
18
18
  /<!--[\s\S]*?(?:-->|$)|<foo(?:\s[^>]*)?\/?>|<\/foo\s*>|<(bar)(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/(\1\s*)>)|<(baz)(\s[^>]*?)?(?:\/>|>([\s\S]*?)(?:<\/(baz\s*)>|$))/giu;
19
- return (0, common_1.getObjRegex)(ext => new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext.join('|')})(\s[^>]*?)?(?:/>|>([\s\S]*?)</(\1\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))`, 'giu'));
19
+ return (0, common_1.getObjRegex)(ext => new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext.filter(tag => tag !== 'img').join('|')
20
+ // eslint-disable-next-line unicorn/prefer-string-raw
21
+ })(\s[^>]*?)?(?:/>|>([\s\S]*?)</(${'\\1'}\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))${ext.includes('img') ? String.raw `|<img(\s[^>]*?)?(/?)>` : ''}`, 'giu'));
20
22
  });
21
23
  /**
22
24
  * 更新`<onlyinclude>`和`</onlyinclude>`的位置
@@ -77,13 +79,13 @@ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => {
77
79
  });
78
80
  wikitext = (0, string_1.restore)(wikitext, stack);
79
81
  }
80
- return wikitext.replace(getRegex[includeOnly ? 1 : 0](newExt), (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => {
82
+ return wikitext.replace(getRegex[includeOnly ? 1 : 0](newExt), (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing, imgAttr, imgClosing) => {
81
83
  const l = accum.length;
82
84
  let ch = 'n';
83
- if (name) {
85
+ if (name || newExt.includes('img') && imgClosing !== undefined) {
84
86
  ch = 'e';
85
87
  // @ts-expect-error abstract class
86
- new ext_1.ExtToken(name, attr, inner, closing, newConfig, include, accum);
88
+ new ext_1.ExtToken(name ?? 'img', name ? attr : imgAttr, inner, name ? closing : imgClosing && undefined, newConfig, include, accum);
87
89
  }
88
90
  else if (substr.startsWith('<!--')) {
89
91
  ch = 'c';
@@ -14,7 +14,7 @@ const constants_1 = require("../util/constants");
14
14
  const parseConverter = (text, config, accum) => {
15
15
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
16
16
  /;(?=(?:[^;]*?=>)?\s*zh\s*:|(?:\s|\0\d+[cn]\x7F)*$)/u;
17
- config.regexConverter ??= new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*(?:${config.variants.join('|')})\s*:|(?:\s|\0\d+[cn]\x7F)*$)`, 'u');
17
+ config.regexConverter ??= new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*(?:${config.variants.join('|')})\s*:|(?:\s|\0\d+[cn]\x7F)*$)`, 'iu');
18
18
  const regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, stack = [];
19
19
  let regex = regex1, mt = regex.exec(text);
20
20
  while (mt) {
package/dist/src/arg.js CHANGED
@@ -43,7 +43,8 @@ const lint_1 = require("../util/lint");
43
43
  const rect_1 = require("../lib/rect");
44
44
  const padded_1 = require("../mixin/padded");
45
45
  const gapped_1 = require("../mixin/gapped");
46
- const index_1 = require("./index");
46
+ const index_1 = __importDefault(require("../index"));
47
+ const index_2 = require("./index");
47
48
  const atom_1 = require("./atom");
48
49
  const hidden_1 = require("./hidden");
49
50
  /* NOT FOR BROWSER */
@@ -51,7 +52,6 @@ const constants_1 = require("../util/constants");
51
52
  const debug_1 = require("../util/debug");
52
53
  const noEscape_1 = require("../mixin/noEscape");
53
54
  const cached_1 = require("../mixin/cached");
54
- const index_2 = __importDefault(require("../index"));
55
55
  /* NOT FOR BROWSER END */
56
56
  /**
57
57
  * argument wrapped in `{{{}}}`
@@ -64,7 +64,7 @@ let ArgToken = (() => {
64
64
  let _classDescriptor;
65
65
  let _classExtraInitializers = [];
66
66
  let _classThis;
67
- let _classSuper = index_1.Token;
67
+ let _classSuper = index_2.Token;
68
68
  let _instanceExtraInitializers = [];
69
69
  let _toHtmlInternal_decorators;
70
70
  var ArgToken = class extends _classSuper {
@@ -110,7 +110,7 @@ let ArgToken = (() => {
110
110
  super.insertAt(token);
111
111
  }
112
112
  else {
113
- const token = new index_1.Token(part, config, accum);
113
+ const token = new index_2.Token(part, config, accum);
114
114
  token.type = 'arg-default';
115
115
  token.setAttribute('stage', 2);
116
116
  super.insertAt(token);
@@ -158,10 +158,11 @@ let ArgToken = (() => {
158
158
  errors.push(...childErrors);
159
159
  }
160
160
  }
161
- if (rest.length > 0) {
161
+ const rules = ['no-ignored', 'no-arg'], s = rules.map(rule => index_1.default.lintConfig.getSeverity(rule, 'arg'));
162
+ if (s[0] && rest.length > 0) {
162
163
  const rect = new rect_1.BoundingRect(this, start);
163
164
  errors.push(...rest.map(child => {
164
- const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', 'invisible content inside triple braces');
165
+ const e = (0, lint_1.generateForChild)(child, rect, rules[0], 'invisible content inside triple braces', s[0]);
165
166
  e.startIndex--;
166
167
  e.startCol--;
167
168
  e.suggestions = [
@@ -171,8 +172,8 @@ let ArgToken = (() => {
171
172
  return e;
172
173
  }));
173
174
  }
174
- if (!this.getAttribute('include')) {
175
- const e = (0, lint_1.generateForSelf)(this, { start }, 'no-arg', 'unexpected template argument', 'warning');
175
+ if (s[1] && !this.getAttribute('include')) {
176
+ const e = (0, lint_1.generateForSelf)(this, { start }, rules[1], 'unexpected template argument', s[1]);
176
177
  if (argDefault) {
177
178
  e.suggestions = [{ desc: 'expand', range: [start, e.endIndex], text: argDefault.text() }];
178
179
  }
@@ -252,7 +253,7 @@ let ArgToken = (() => {
252
253
  * @param name new argument name / 新参数名
253
254
  */
254
255
  setName(name) {
255
- const { childNodes } = index_2.default
256
+ const { childNodes } = index_1.default
256
257
  .parse(name, this.getAttribute('include'), 2, this.getAttribute('config'));
257
258
  this.firstChild.safeReplaceChildren(childNodes);
258
259
  }
@@ -267,7 +268,7 @@ let ArgToken = (() => {
267
268
  this.removeAt(1);
268
269
  return;
269
270
  }
270
- const root = index_2.default
271
+ const root = index_1.default
271
272
  .parse(value, this.getAttribute('include'), undefined, this.getAttribute('config')), { childNodes: [, oldDefault] } = this;
272
273
  if (oldDefault) {
273
274
  oldDefault.safeReplaceChildren(root.childNodes);