wikiparser-node 1.16.1 → 1.16.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.
Files changed (60) hide show
  1. package/bundle/bundle.es7.js +26 -29
  2. package/data/signatures.json +82 -4
  3. package/dist/addon/table.js +9 -3
  4. package/dist/addon/token.js +73 -90
  5. package/dist/addon/transclude.js +3 -3
  6. package/dist/base.d.mts +10 -2
  7. package/dist/base.d.ts +10 -2
  8. package/dist/index.d.ts +0 -1
  9. package/dist/index.js +6 -6
  10. package/dist/lib/attributes.d.ts +24 -0
  11. package/dist/lib/attributes.js +67 -0
  12. package/dist/lib/element.js +9 -9
  13. package/dist/lib/lsp.d.ts +16 -2
  14. package/dist/lib/lsp.js +159 -148
  15. package/dist/lib/node.d.ts +2 -0
  16. package/dist/lib/node.js +93 -50
  17. package/dist/lib/ranges.d.ts +4 -8
  18. package/dist/lib/ranges.js +12 -19
  19. package/dist/lib/text.js +6 -4
  20. package/dist/lib/title.js +3 -1
  21. package/dist/parser/braces.js +3 -3
  22. package/dist/parser/commentAndExt.js +2 -3
  23. package/dist/parser/hrAndDoubleUnderscore.js +1 -2
  24. package/dist/parser/links.js +1 -2
  25. package/dist/parser/magicLinks.js +4 -2
  26. package/dist/parser/selector.js +37 -30
  27. package/dist/src/html.js +6 -4
  28. package/dist/src/imageParameter.js +12 -13
  29. package/dist/src/imagemap.js +3 -3
  30. package/dist/src/index.d.ts +23 -19
  31. package/dist/src/index.js +74 -48
  32. package/dist/src/link/file.js +1 -2
  33. package/dist/src/magicLink.js +8 -6
  34. package/dist/src/nested.js +4 -1
  35. package/dist/src/nowiki/index.js +3 -3
  36. package/dist/src/nowiki/list.js +1 -1
  37. package/dist/src/redirect.js +1 -2
  38. package/dist/src/table/index.js +10 -4
  39. package/dist/src/table/td.js +47 -55
  40. package/dist/src/transclude.js +5 -5
  41. package/dist/util/constants.js +2 -0
  42. package/dist/util/debug.js +14 -18
  43. package/dist/util/html.js +2 -0
  44. package/dist/util/lint.js +24 -4
  45. package/dist/util/string.js +9 -5
  46. package/extensions/es7/base.js +22 -4
  47. package/extensions/es7/lint.js +20 -11
  48. package/extensions/typings.d.ts +1 -2
  49. package/package.json +4 -3
  50. package/bundle/bundle.lsp.js +0 -42
  51. package/bundle/bundle.min.js +0 -38
  52. package/extensions/dist/base.js +0 -268
  53. package/extensions/dist/codejar.js +0 -56
  54. package/extensions/dist/editor.js +0 -159
  55. package/extensions/dist/highlight.js +0 -30
  56. package/extensions/dist/lint.js +0 -72
  57. package/extensions/dist/lsp.js +0 -67
  58. package/extensions/dist/test-page.js +0 -89
  59. package/extensions/editor.css +0 -59
  60. package/extensions/ui.css +0 -162
@@ -764,7 +764,7 @@
764
764
  }
765
765
  ]
766
766
  ],
767
- "description": "The unexpanded wikitext is rendered (more or less, for details see [Help:Templates](https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Templates#Usage))."
767
+ "description": "The unexpanded wikitext is rendered (more or less, for details see [help](https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Templates#Usage))."
768
768
  },
769
769
  {
770
770
  "aliases": [
@@ -848,7 +848,7 @@
848
848
  }
849
849
  ]
850
850
  ],
851
- "description": "Alias for XML-style MediaWiki parser tags or extension tags. It allows a [pre-save transform of wiki code](https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Tag_extensions#How_do_I_render_wikitext_in_my_extension?) and [Extension:ParserFunctions](https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:ParserFunctions) within tags before the tag is processed. It also prevents parsing of tags in conditional paths that aren't executed (like in `#if` statements). Content between tags is passed as the first parameter, and any attributes for the tags can be passed as subsequent parameters."
851
+ "description": "Alias for XML-style MediaWiki parser tags or extension tags. It allows a [pre-save transform of wiki code](https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Tag_extensions#How_do_I_render_wikitext_in_my_extension?) and parser functions within tags before the tag is processed. It also prevents parsing of tags in conditional paths that aren't executed (like in `#if` statements). Content between tags is passed as the first parameter, and any attributes for the tags can be passed as subsequent parameters."
852
852
  },
853
853
  {
854
854
  "aliases": [
@@ -1550,6 +1550,84 @@
1550
1550
  ],
1551
1551
  "description": "This function will output the final, last value a variable has at the end of the page rendering. Naturally, the value will be inserted after the parser went over the entire wiki markup, so this function can't be used in other functions, expecting the right value is being used.\n\nThe `default value` will be used if the variable doesn't exist at the final page rendering stage or if its value is an empty string. The default will be expanded right where the function is used, so the parameter will be expanded, even if it won't be needed."
1552
1552
  },
1553
+ {
1554
+ "aliases": [
1555
+ "#lst",
1556
+ "#section"
1557
+ ],
1558
+ "signatures": [
1559
+ [
1560
+ {
1561
+ "label": "article"
1562
+ },
1563
+ {
1564
+ "label": "chapter"
1565
+ }
1566
+ ]
1567
+ ],
1568
+ "description": "Transclude a section called *chapter* from a page called *article*. The target article defines the location of the section."
1569
+ },
1570
+ {
1571
+ "aliases": [
1572
+ "#lstx",
1573
+ "#section-x"
1574
+ ],
1575
+ "signatures": [
1576
+ [
1577
+ {
1578
+ "label": "article"
1579
+ },
1580
+ {
1581
+ "label": "chapter"
1582
+ }
1583
+ ],
1584
+ [
1585
+ {
1586
+ "label": "article"
1587
+ },
1588
+ {
1589
+ "label": "chapter"
1590
+ },
1591
+ {
1592
+ "label": "replacement text"
1593
+ }
1594
+ ]
1595
+ ],
1596
+ "description": "Transclude a page, but exclude a specified section. Optionally, you may add replacement text to the excluded section. The replacement text will appear in the area where the section is skipped (excluded)."
1597
+ },
1598
+ {
1599
+ "aliases": [
1600
+ "#lsth",
1601
+ "#section-h"
1602
+ ],
1603
+ "signatures": [
1604
+ [
1605
+ {
1606
+ "label": "article"
1607
+ }
1608
+ ],
1609
+ [
1610
+ {
1611
+ "label": "article"
1612
+ },
1613
+ {
1614
+ "label": "section X"
1615
+ }
1616
+ ],
1617
+ [
1618
+ {
1619
+ "label": "article"
1620
+ },
1621
+ {
1622
+ "label": "section X"
1623
+ },
1624
+ {
1625
+ "label": "section Y"
1626
+ }
1627
+ ]
1628
+ ],
1629
+ "description": "Transclude the introduction of a page (i.e. the content before the first heading), or the whole content of the first occurrence of the *section X* (which includes all its sub-sections but excludes the heading of *section X* itself), or the content from the first occurrence of *section X* (excluding the heading of *section X* itself) until it reaches the next occurrence of *section Y*. Note that *section Y* acts as a stop point so the transclusion doesn't contain the content of *section Y*."
1630
+ },
1553
1631
  {
1554
1632
  "aliases": [
1555
1633
  "currentyear",
@@ -2637,13 +2715,13 @@
2637
2715
  "aliases": [
2638
2716
  "!"
2639
2717
  ],
2640
- "description": "Used to include a vertical bar (pipe).\n\nSee [Help:Extension:ParserFunctions#Escaping pipe characters in tables](https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Extension:ParserFunctions#Escaping_pipe_characters_in_tables) for further explanation."
2718
+ "description": "Used to include a vertical bar (pipe).\n\nSee [help](https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Extension:ParserFunctions#Escaping_pipe_characters_in_tables) for further explanation."
2641
2719
  },
2642
2720
  {
2643
2721
  "aliases": [
2644
2722
  "="
2645
2723
  ],
2646
- "description": "Used to include an equal sign.\n\nSee [Help:Extension:ParserFunctions#Raw equal signs](https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Extension:ParserFunctions#Raw_equal_signs) for further explanation."
2724
+ "description": "Used to include an equal sign.\n\nSee [help](https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Extension:ParserFunctions#Raw_equal_signs) for further explanation."
2647
2725
  },
2648
2726
  {
2649
2727
  "aliases": [
@@ -9,6 +9,12 @@ const tr_1 = require("../src/table/tr");
9
9
  const index_2 = require("../src/table/index");
10
10
  const td_1 = require("../src/table/td");
11
11
  const trBase_1 = require("../src/table/trBase");
12
+ /**
13
+ * 比较两个数
14
+ * @param a
15
+ * @param b
16
+ */
17
+ const compare = (a, b) => a - b;
12
18
  /**
13
19
  * 检查坐标形式
14
20
  * @param coords 坐标
@@ -75,7 +81,7 @@ const format = (cells, attr = {}, multi) => {
75
81
  * @param token 待填充的单元格
76
82
  */
77
83
  const fill = (y, rowToken, layout, maxCol, token) => {
78
- const rowLayout = layout[y], childNodes = [...rowToken.childNodes].reverse(), index = childNodes.findIndex(child => child instanceof td_1.TdToken && child.subtype !== 'caption'), pos = index > 0 ? childNodes.length - index : undefined;
84
+ const rowLayout = layout[y], index = rowToken.childNodes.findLastIndex(child => child instanceof td_1.TdToken && child.subtype !== 'caption'), pos = index > 0 ? index + 1 : undefined;
79
85
  debug_1.Shadow.run(() => {
80
86
  for (let i = 0; i < maxCol; i++) {
81
87
  if (!rowLayout[i]) {
@@ -104,7 +110,7 @@ index_2.TableToken.prototype.toRawCoords =
104
110
  }
105
111
  else if (rowLayout || y > 0) {
106
112
  return x === rowLayout?.length
107
- ? { row: y, column: (rowLayout.reverse().find(({ row }) => row === y)?.column ?? -1) + 1, start: true }
113
+ ? { row: y, column: (rowLayout.findLast(({ row }) => row === y)?.column ?? -1) + 1, start: true }
108
114
  : undefined;
109
115
  }
110
116
  return { row: 0, column: 0, start: true };
@@ -280,7 +286,7 @@ index_2.TableToken.prototype.removeTableCol =
280
286
  index_2.TableToken.prototype.mergeCells =
281
287
  /** @implements */
282
288
  function (xlim, ylim) {
283
- const layout = this.getLayout(), maxCol = Math.max(...layout.map(({ length }) => length)), [xmin, xmax] = xlim.map(x => x < 0 ? x + maxCol : x).sort(debug_1.compare), [ymin, ymax] = ylim.map(y => y < 0 ? y + layout.length : y).sort(debug_1.compare), set = new Set(layout.slice(ymin, ymax).flatMap(rowLayout => rowLayout.slice(xmin, xmax)));
289
+ const layout = this.getLayout(), maxCol = Math.max(...layout.map(({ length }) => length)), [xmin, xmax] = xlim.map(x => x < 0 ? x + maxCol : x).sort(compare), [ymin, ymax] = ylim.map(y => y < 0 ? y + layout.length : y).sort(compare), set = new Set(layout.slice(ymin, ymax).flatMap(rowLayout => rowLayout.slice(xmin, xmax)));
284
290
  if ([...layout[ymin - 1] ?? [], ...layout[ymax] ?? []].some(coords => set.has(coords))
285
291
  || layout.some(rowLayout => set.has(rowLayout[xmin - 1]) || set.has(rowLayout[xmax]))) {
286
292
  throw new RangeError('The area to be merged overlaps with the outer area!');
@@ -40,36 +40,6 @@ index_2.Token.prototype.createElement = /** @implements */ function (tagName, {
40
40
  /* istanbul ignore next */
41
41
  throw new RangeError(`Invalid tag name: ${tagName}`);
42
42
  };
43
- index_2.Token.prototype.caretPositionFromIndex = /** @implements */ function (index) {
44
- if (index === undefined) {
45
- return undefined;
46
- }
47
- const { length } = this.toString();
48
- if (index >= length || index < -length) {
49
- return undefined;
50
- }
51
- index += index < 0 ? length : 0;
52
- let self = this, acc = 0, start = 0;
53
- while (self.type !== 'text') {
54
- const { childNodes } = self;
55
- acc += self.getAttribute('padding');
56
- for (let i = 0; acc <= index && i < childNodes.length; i++) {
57
- const cur = childNodes[i], l = cur.toString().length;
58
- acc += l;
59
- if (acc > index) {
60
- self = cur;
61
- acc -= l;
62
- start = acc;
63
- break;
64
- }
65
- acc += self.getGaps(i);
66
- }
67
- if (self.childNodes === childNodes) {
68
- return { offsetNode: self, offset: index - start };
69
- }
70
- }
71
- return { offsetNode: self, offset: index - start };
72
- };
73
43
  index_2.Token.prototype.sections = /** @implements */ function () {
74
44
  if (this.type !== 'root') {
75
45
  return undefined;
@@ -322,75 +292,88 @@ index_2.Token.prototype.solveConst = /** @implements */ function () {
322
292
  return debug_1.Shadow.run(() => expand(this.toString(), this.getAttribute('config'), this.getAttribute('include'), false).parse());
323
293
  };
324
294
  index_2.Token.prototype.toHtml = /** @implements */ function () {
325
- if (this.type !== 'root') {
326
- return this.cloneNode().toHtmlInternal();
327
- }
328
- const expanded = this.expand();
329
- constants_1.states.set(expanded, { headings: new Set() });
330
- const lines = expanded.toHtmlInternal().split('\n'), blockElems = 'table|h1|h2|h3|h4|h5|h6|pre|p|ul|ol|dl', antiBlockElems = 'td|th', openRegex = new RegExp(String.raw `<(?:${blockElems}|\/(?:${antiBlockElems})|\/?(?:tr|caption|dt|dd|li))\b`, 'iu'), closeRegex = new RegExp(String.raw `<(?:\/(?:${blockElems})|${antiBlockElems}|\/?(?:center|blockquote|div|hr|figure))\b`, 'iu');
331
- let output = '', inBlockElem = false, pendingPTag = false, inBlockquote = false, lastParagraph = '';
332
- const /** @ignore */ closeParagraph = () => {
333
- if (lastParagraph) {
334
- const result = `</${lastParagraph}>\n`;
335
- lastParagraph = '';
336
- return result;
337
- }
338
- return '';
339
- };
340
- for (let line of lines) {
341
- const openMatch = openRegex.test(line), closeMatch = closeRegex.test(line);
342
- if (openMatch || closeMatch) {
343
- const blockquote = /<(\/?)blockquote[\s>](?!.*<\/?blockquote[\s>])/iu.exec(line)?.[1];
344
- inBlockquote = blockquote === undefined ? inBlockquote : blockquote === '';
345
- pendingPTag = false;
346
- output += closeParagraph();
347
- inBlockElem = !closeMatch;
348
- }
349
- else if (!inBlockElem) {
350
- if (line.startsWith(' ') && (lastParagraph === 'pre' || line.trim()) && !inBlockquote) {
351
- if (lastParagraph !== 'pre') {
352
- pendingPTag = false;
353
- output += `${closeParagraph()}<pre>`;
354
- lastParagraph = 'pre';
355
- }
356
- line = line.slice(1);
295
+ const { viewOnly } = index_1.default;
296
+ index_1.default.viewOnly = false;
297
+ let html;
298
+ if (this.type === 'root') {
299
+ const expanded = this.expand();
300
+ constants_1.states.set(expanded, { headings: new Set() });
301
+ const lines = expanded.toHtmlInternal().split('\n'), blockElems = 'table|h1|h2|h3|h4|h5|h6|pre|p|ul|ol|dl', antiBlockElems = 'td|th';
302
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
303
+ /<(?:table|\/(?:td|th)|\/?(?:tr|caption|dt|dd|li))\b/iu;
304
+ const openRegex = new RegExp(String.raw `<(?:${blockElems}|\/(?:${antiBlockElems})|\/?(?:tr|caption|dt|dd|li))\b`, 'iu');
305
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
306
+ /<(?:\/(?:h1|h2)|td|th|\/?(?:center|blockquote|div|hr|figure))\b/iu;
307
+ const closeRegex = new RegExp(String.raw `<(?:\/(?:${blockElems})|${antiBlockElems}|\/?(?:center|blockquote|div|hr|figure))\b`, 'iu');
308
+ let output = '', inBlockElem = false, pendingPTag = false, inBlockquote = false, lastParagraph = '';
309
+ const /** @ignore */ closeParagraph = () => {
310
+ if (lastParagraph) {
311
+ const result = `</${lastParagraph}>\n`;
312
+ lastParagraph = '';
313
+ return result;
357
314
  }
358
- else if (/^(?:<link\b[^>]*>\s*)+$/iu.test(line)) {
359
- if (pendingPTag) {
360
- output += closeParagraph();
361
- pendingPTag = false;
362
- }
315
+ return '';
316
+ };
317
+ for (let line of lines) {
318
+ const openMatch = openRegex.test(line), closeMatch = closeRegex.test(line);
319
+ if (openMatch || closeMatch) {
320
+ const blockquote = /<(\/?)blockquote[\s>](?!.*<\/?blockquote[\s>])/iu.exec(line)?.[1];
321
+ inBlockquote = blockquote === undefined ? inBlockquote : blockquote === '';
322
+ pendingPTag = false;
323
+ output += closeParagraph();
324
+ inBlockElem = !closeMatch;
363
325
  }
364
- else if (!line.trim()) {
365
- if (pendingPTag) {
366
- output += `${pendingPTag}<br>`;
326
+ else if (!inBlockElem) {
327
+ if (line.startsWith(' ') && (lastParagraph === 'pre' || line.trim()) && !inBlockquote) {
328
+ if (lastParagraph !== 'pre') {
329
+ pendingPTag = false;
330
+ output += `${closeParagraph()}<pre>`;
331
+ lastParagraph = 'pre';
332
+ }
333
+ line = line.slice(1);
334
+ }
335
+ else if (/^(?:<link\b[^>]*>\s*)+$/iu.test(line)) {
336
+ if (pendingPTag) {
337
+ output += closeParagraph();
338
+ pendingPTag = false;
339
+ }
340
+ }
341
+ else if (!line.trim()) {
342
+ if (pendingPTag) {
343
+ output += `${pendingPTag}<br>`;
344
+ pendingPTag = false;
345
+ lastParagraph = 'p';
346
+ }
347
+ else if (lastParagraph === 'p') {
348
+ pendingPTag = '</p><p>';
349
+ }
350
+ else {
351
+ output += closeParagraph();
352
+ pendingPTag = '<p>';
353
+ }
354
+ }
355
+ else if (pendingPTag) {
356
+ output += pendingPTag;
367
357
  pendingPTag = false;
368
358
  lastParagraph = 'p';
369
359
  }
370
- else if (lastParagraph === 'p') {
371
- pendingPTag = '</p><p>';
372
- }
373
- else {
374
- output += closeParagraph();
375
- pendingPTag = '<p>';
360
+ else if (lastParagraph !== 'p') {
361
+ output += `${closeParagraph()}<p>`;
362
+ lastParagraph = 'p';
376
363
  }
377
364
  }
378
- else if (pendingPTag) {
379
- output += pendingPTag;
380
- pendingPTag = false;
381
- lastParagraph = 'p';
382
- }
383
- else if (lastParagraph !== 'p') {
384
- output += `${closeParagraph()}<p>`;
385
- lastParagraph = 'p';
365
+ if (!pendingPTag) {
366
+ output += `${line}\n`;
386
367
  }
387
368
  }
388
- if (!pendingPTag) {
389
- output += `${line}\n`;
390
- }
369
+ output += closeParagraph();
370
+ constants_1.states.delete(expanded);
371
+ html = output.trimEnd();
372
+ }
373
+ else {
374
+ html = this.cloneNode().toHtmlInternal();
391
375
  }
392
- output += closeParagraph();
393
- constants_1.states.delete(expanded);
394
- return output.trimEnd();
376
+ index_1.default.viewOnly = viewOnly;
377
+ return html;
395
378
  };
396
379
  constants_1.classes['ExtendedToken'] = __filename;
@@ -133,9 +133,9 @@ transclude_1.TranscludeToken.prototype.fixDuplication =
133
133
  }
134
134
  else if (aggressive && (anonCount ? /\D\d+$/u : /(?:^|\D)\d+$/u).test(key)) {
135
135
  let last;
136
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
137
- /^a\d+$/u;
138
- const str = key.slice(0, -/(?<!\d)\d+$/u.exec(key)[0].length), regex = new RegExp(String.raw `^${(0, string_1.escapeRegExp)(str)}\d+$`, 'u'), series = this.getAllArgs().filter(({ name }) => regex.test(name)), ordered = series.every(({ name }, i) => {
136
+ const str = key.slice(0, -/(?<!\d)\d+$/u.exec(key)[0].length);
137
+ /^a\d+$/u; // eslint-disable-line @typescript-eslint/no-unused-expressions
138
+ const regex = new RegExp(String.raw `^${(0, string_1.escapeRegExp)(str)}\d+$`, 'u'), series = this.getAllArgs().filter(({ name }) => regex.test(name)), ordered = series.every(({ name }, i) => {
139
139
  const j = Number(name.slice(str.length)), cmp = j <= i + 1 && (i === 0 || j >= last || name === key);
140
140
  last = j;
141
141
  return cmp;
package/dist/base.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Range, Position, ColorInformation, ColorPresentation, CompletionItem as CompletionItemBase, CompletionItemKind, FoldingRange, DocumentLink, Location, WorkspaceEdit, Diagnostic, Hover, DocumentSymbol, CodeAction, SignatureHelp } from 'vscode-languageserver-types';
1
+ import type { Range, Position, ColorInformation, ColorPresentation, CompletionItem as CompletionItemBase, CompletionItemKind, FoldingRange, DocumentLink, Location, WorkspaceEdit, Diagnostic, Hover, SignatureHelp, InlayHint, DocumentSymbol, CodeAction } from 'vscode-languageserver-types';
2
2
  export interface Config {
3
3
  ext: string[];
4
4
  readonly html: [string[], string[], string[]];
@@ -95,6 +95,8 @@ interface Token extends AstNode {
95
95
  querySelectorAll<T = Token>(selector: string): T[];
96
96
  /** 保存为JSON */
97
97
  json(): AST;
98
+ /** 生成HTML */
99
+ toHtml(): string;
98
100
  }
99
101
  interface SignatureParameter {
100
102
  label: string;
@@ -138,7 +140,7 @@ export interface LanguageService {
138
140
  * 提供语法检查
139
141
  * @param wikitext 源代码
140
142
  */
141
- provideDiagnostics(wikitext: string): Promise<Diagnostic[]>;
143
+ provideDiagnostics(wikitext: string, warning?: boolean): Promise<Diagnostic[]>;
142
144
  /**
143
145
  * 提供折叠范围
144
146
  * @param text 源代码
@@ -186,6 +188,11 @@ export interface LanguageService {
186
188
  * @param position 位置
187
189
  */
188
190
  provideSignatureHelp(text: string, position: Position): Promise<SignatureHelp | undefined>;
191
+ /**
192
+ * 提供 CodeLens
193
+ * @param text 源代码
194
+ */
195
+ provideInlayHints(text: string): Promise<InlayHint[]>;
189
196
  /**
190
197
  * 提供快速修复建议
191
198
  * @param diagnostics 语法诊断信息
@@ -200,6 +207,7 @@ export interface LanguageService {
200
207
  export interface Parser {
201
208
  config: Config | string;
202
209
  i18n: Record<string, string> | string | undefined;
210
+ viewOnly: boolean;
203
211
  /** 获取当前的解析设置 */
204
212
  getConfig(): Config;
205
213
  /**
package/dist/base.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Range, Position, ColorInformation, ColorPresentation, CompletionItem as CompletionItemBase, CompletionItemKind, FoldingRange, DocumentLink, Location, WorkspaceEdit, Diagnostic, Hover, DocumentSymbol, CodeAction, SignatureHelp } from 'vscode-languageserver-types';
1
+ import type { Range, Position, ColorInformation, ColorPresentation, CompletionItem as CompletionItemBase, CompletionItemKind, FoldingRange, DocumentLink, Location, WorkspaceEdit, Diagnostic, Hover, SignatureHelp, InlayHint, DocumentSymbol, CodeAction } from 'vscode-languageserver-types';
2
2
  export interface Config {
3
3
  ext: string[];
4
4
  readonly html: [string[], string[], string[]];
@@ -95,6 +95,8 @@ interface Token extends AstNode {
95
95
  querySelectorAll<T = Token>(selector: string): T[];
96
96
  /** 保存为JSON */
97
97
  json(): AST;
98
+ /** 生成HTML */
99
+ toHtml(): string;
98
100
  }
99
101
  interface SignatureParameter {
100
102
  label: string;
@@ -138,7 +140,7 @@ export interface LanguageService {
138
140
  * 提供语法检查
139
141
  * @param wikitext 源代码
140
142
  */
141
- provideDiagnostics(wikitext: string): Promise<Diagnostic[]>;
143
+ provideDiagnostics(wikitext: string, warning?: boolean): Promise<Diagnostic[]>;
142
144
  /**
143
145
  * 提供折叠范围
144
146
  * @param text 源代码
@@ -186,6 +188,11 @@ export interface LanguageService {
186
188
  * @param position 位置
187
189
  */
188
190
  provideSignatureHelp(text: string, position: Position): Promise<SignatureHelp | undefined>;
191
+ /**
192
+ * 提供 CodeLens
193
+ * @param text 源代码
194
+ */
195
+ provideInlayHints(text: string): Promise<InlayHint[]>;
189
196
  /**
190
197
  * 提供快速修复建议
191
198
  * @param diagnostics 语法诊断信息
@@ -200,6 +207,7 @@ export interface LanguageService {
200
207
  export interface Parser {
201
208
  config: Config | string;
202
209
  i18n: Record<string, string> | string | undefined;
210
+ viewOnly: boolean;
203
211
  /** 获取当前的解析设置 */
204
212
  getConfig(): Config;
205
213
  /**
package/dist/index.d.ts CHANGED
@@ -4,7 +4,6 @@ import type { LanguageService } from './lib/lsp';
4
4
  import type { Token } from './internal';
5
5
  declare interface Parser extends ParserBase {
6
6
  rules: readonly LintError.Rule[];
7
- viewOnly: boolean;
8
7
  conversionTable: Map<string, string>;
9
8
  redirects: Map<string, string>;
10
9
  templateDir?: string;
package/dist/index.js CHANGED
@@ -251,12 +251,12 @@ const Parser = {
251
251
  },
252
252
  /** @implements */
253
253
  isInterwiki(title, { interwiki } = Parser.getConfig()) {
254
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
255
- /^(zh|en)\s*:/diu;
256
- return interwiki.length > 0
257
- ? new RegExp(String.raw `^(${interwiki.join('|')})\s*:`, 'diu')
258
- .exec(title.replaceAll('_', ' ').replace(/^\s*:?\s*/u, ''))
259
- : null;
254
+ if (interwiki.length > 0) {
255
+ /^(zh|en)\s*:/diu; // eslint-disable-line @typescript-eslint/no-unused-expressions
256
+ const re = new RegExp(String.raw `^(${interwiki.join('|')})\s*:`, 'diu');
257
+ return re.exec(title.replaceAll('_', ' ').replace(/^\s*:?\s*/u, ''));
258
+ }
259
+ return null;
260
260
  },
261
261
  /* istanbul ignore next */
262
262
  /** @implements */
@@ -0,0 +1,24 @@
1
+ import type { TokenTypes } from '../base';
2
+ import type { Title } from '../lib/title';
3
+ import type { Token } from '../internal';
4
+ declare type Target = Token & {
5
+ link?: string | Title;
6
+ };
7
+ /** 用于选择器的属性 */
8
+ export declare class Attributes {
9
+ #private;
10
+ token: Target;
11
+ type: TokenTypes;
12
+ constructor(token: Token);
13
+ get link(): string | Title | undefined;
14
+ get invalid(): boolean;
15
+ get siblings(): Token[] | undefined;
16
+ get siblingsOfType(): Token[] | undefined;
17
+ get siblingsCount(): number;
18
+ get siblingsCountOfType(): number;
19
+ get index(): number;
20
+ get indexOfType(): number;
21
+ get lastIndex(): number;
22
+ get lastIndexOfType(): number;
23
+ }
24
+ export {};
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Attributes = void 0;
4
+ /* eslint-disable jsdoc/require-jsdoc */
5
+ const constants_1 = require("../util/constants");
6
+ /** 用于选择器的属性 */
7
+ class Attributes {
8
+ token;
9
+ type;
10
+ #link;
11
+ #invalid;
12
+ #siblings;
13
+ #siblingsOfType;
14
+ #siblingsCount;
15
+ #siblingsCountOfType;
16
+ #index;
17
+ #indexOfType;
18
+ #lastIndex;
19
+ #lastIndexOfType;
20
+ constructor(token) {
21
+ this.token = token;
22
+ this.type = token.type;
23
+ }
24
+ get link() {
25
+ this.#link ??= this.token.link;
26
+ return this.#link;
27
+ }
28
+ get invalid() {
29
+ this.#invalid ??= this.type === 'table-inter'
30
+ || this.type === 'image-parameter' && this.token.name === 'invalid';
31
+ return this.#invalid;
32
+ }
33
+ get siblings() {
34
+ this.#siblings ??= this.token.parentNode?.children;
35
+ return this.#siblings;
36
+ }
37
+ get siblingsOfType() {
38
+ this.#siblingsOfType ??= this.siblings?.filter(({ type }) => type === this.type);
39
+ return this.#siblingsOfType;
40
+ }
41
+ get siblingsCount() {
42
+ this.#siblingsCount ??= this.siblings?.length ?? 1;
43
+ return this.#siblingsCount;
44
+ }
45
+ get siblingsCountOfType() {
46
+ this.#siblingsCountOfType ??= this.siblingsOfType?.length ?? 1;
47
+ return this.#siblingsCountOfType;
48
+ }
49
+ get index() {
50
+ this.#index ??= (this.siblings?.indexOf(this.token) ?? 0) + 1;
51
+ return this.#index;
52
+ }
53
+ get indexOfType() {
54
+ this.#indexOfType ??= (this.siblingsOfType?.indexOf(this.token) ?? 0) + 1;
55
+ return this.#indexOfType;
56
+ }
57
+ get lastIndex() {
58
+ this.#lastIndex ??= this.siblingsCount - this.index + 1;
59
+ return this.#lastIndex;
60
+ }
61
+ get lastIndexOfType() {
62
+ this.#lastIndexOfType ??= this.siblingsCountOfType - this.indexOfType + 1;
63
+ return this.#lastIndexOfType;
64
+ }
65
+ }
66
+ exports.Attributes = Attributes;
67
+ constants_1.classes['Attributes'] = __filename;
@@ -34,7 +34,7 @@ class AstElement extends node_1.AstNode {
34
34
  }
35
35
  /** 末位非文本子节点 */
36
36
  get lastElementChild() {
37
- return this.children[this.childElementCount - 1];
37
+ return this.childNodes.findLast((child) => child.type !== 'text');
38
38
  }
39
39
  /** 非文本子节点总数 */
40
40
  get childElementCount() {
@@ -55,16 +55,12 @@ class AstElement extends node_1.AstNode {
55
55
  /** 内部高度 */
56
56
  get clientHeight() {
57
57
  const { innerText } = this;
58
- return typeof innerText === 'string' ? innerText.split('\n').length : undefined;
58
+ return innerText?.split('\n').length;
59
59
  }
60
60
  /** 内部宽度 */
61
61
  get clientWidth() {
62
62
  const { innerText } = this;
63
- if (typeof innerText === 'string') {
64
- const lines = innerText.split('\n');
65
- return lines.at(-1).length;
66
- }
67
- return undefined;
63
+ return innerText?.split('\n').pop().length;
68
64
  }
69
65
  constructor() {
70
66
  super();
@@ -83,12 +79,16 @@ class AstElement extends node_1.AstNode {
83
79
  * @param i 移除位置
84
80
  */
85
81
  const remove = (i) => {
82
+ /* NOT FOR BROWSER */
86
83
  childNodes[i].setAttribute('parentNode', undefined);
84
+ /* NOT FOR BROWSER END */
87
85
  childNodes.splice(i, 1);
86
+ childNodes[i - 1]?.setAttribute('nextSibling', childNodes[i]);
87
+ childNodes[i]?.setAttribute('previousSibling', childNodes[i - 1]);
88
88
  };
89
89
  for (let i = childNodes.length - 1; i >= 0; i--) {
90
90
  const { type, data } = childNodes[i];
91
- if (type !== 'text' || this.getGaps(i - 1)) {
91
+ if (type !== 'text' || childNodes.length === 1 || this.getGaps(i - (i && 1))) {
92
92
  //
93
93
  }
94
94
  else if (data === '') {
@@ -128,7 +128,7 @@ class AstElement extends node_1.AstNode {
128
128
  if (node.contains(this)) {
129
129
  throw new RangeError('Cannot insert an ancestor node!');
130
130
  }
131
- else if (this.childNodes.includes(node)) {
131
+ else if (node.parentNode === this) {
132
132
  throw new RangeError('Cannot insert its own child node!');
133
133
  }
134
134
  this.verifyChild(i, 1);