wikiparser-node 1.31.0 → 1.33.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 (111) hide show
  1. package/README.md +5 -0
  2. package/bundle/bundle-es8.min.js +28 -29
  3. package/bundle/bundle-lsp.min.js +31 -31
  4. package/bundle/bundle.min.js +24 -24
  5. package/coverage/badge.svg +1 -1
  6. package/dist/addon/attribute.js +186 -0
  7. package/dist/addon/link.js +91 -0
  8. package/dist/addon/table.js +150 -105
  9. package/dist/addon/token.js +8 -304
  10. package/dist/addon/transclude.js +9 -6
  11. package/dist/base.d.mts +9 -1
  12. package/dist/base.d.ts +9 -1
  13. package/dist/bin/config.js +1 -1
  14. package/dist/index.d.ts +24 -5
  15. package/dist/index.js +71 -92
  16. package/dist/internal.d.ts +4 -0
  17. package/dist/lib/document.d.ts +9 -7
  18. package/dist/lib/document.js +91 -66
  19. package/dist/lib/element.d.ts +7 -7
  20. package/dist/lib/element.js +48 -50
  21. package/dist/lib/lintConfig.js +3 -1
  22. package/dist/lib/lsp.js +127 -56
  23. package/dist/lib/node.js +20 -14
  24. package/dist/lib/text.js +6 -6
  25. package/dist/lib/title.d.ts +11 -0
  26. package/dist/lib/title.js +37 -13
  27. package/dist/mixin/elementLike.js +2 -3
  28. package/dist/mixin/syntax.js +13 -7
  29. package/dist/parser/commentAndExt.js +3 -3
  30. package/dist/parser/selector.js +16 -41
  31. package/dist/render/expand.js +216 -0
  32. package/dist/render/extension.js +141 -0
  33. package/dist/render/html.js +91 -0
  34. package/dist/{addon → render}/magicWords.js +48 -7
  35. package/dist/render/syntaxhighlight.js +415 -0
  36. package/dist/src/arg.js +1 -1
  37. package/dist/src/attribute.d.ts +9 -5
  38. package/dist/src/attribute.js +68 -108
  39. package/dist/src/attributes.d.ts +7 -1
  40. package/dist/src/attributes.js +22 -51
  41. package/dist/src/converter.js +4 -2
  42. package/dist/src/converterFlags.js +8 -6
  43. package/dist/src/converterRule.js +19 -15
  44. package/dist/src/extLink.js +1 -1
  45. package/dist/src/heading.d.ts +1 -1
  46. package/dist/src/heading.js +5 -3
  47. package/dist/src/imageParameter.d.ts +7 -4
  48. package/dist/src/imageParameter.js +47 -28
  49. package/dist/src/index.d.ts +13 -5
  50. package/dist/src/index.js +67 -42
  51. package/dist/src/link/base.d.ts +1 -1
  52. package/dist/src/link/base.js +26 -38
  53. package/dist/src/link/category.d.ts +7 -0
  54. package/dist/src/link/category.js +101 -37
  55. package/dist/src/link/categorytree.d.ts +27 -0
  56. package/dist/src/link/categorytree.js +115 -0
  57. package/dist/src/link/file.d.ts +3 -2
  58. package/dist/src/link/file.js +23 -9
  59. package/dist/src/link/galleryImage.js +7 -9
  60. package/dist/src/link/index.d.ts +1 -1
  61. package/dist/src/link/index.js +10 -31
  62. package/dist/src/multiLine/gallery.d.ts +1 -4
  63. package/dist/src/multiLine/gallery.js +1 -11
  64. package/dist/src/multiLine/imagemap.d.ts +0 -1
  65. package/dist/src/multiLine/imagemap.js +98 -152
  66. package/dist/src/multiLine/index.d.ts +1 -0
  67. package/dist/src/multiLine/index.js +77 -22
  68. package/dist/src/multiLine/inputbox.d.ts +3 -3
  69. package/dist/src/multiLine/inputbox.js +3 -7
  70. package/dist/src/multiLine/paramTag.d.ts +3 -4
  71. package/dist/src/multiLine/paramTag.js +6 -48
  72. package/dist/src/nowiki/comment.js +1 -1
  73. package/dist/src/nowiki/doubleUnderscore.js +4 -2
  74. package/dist/src/nowiki/index.js +34 -31
  75. package/dist/src/nowiki/listBase.d.ts +2 -1
  76. package/dist/src/nowiki/listBase.js +22 -8
  77. package/dist/src/nowiki/quote.d.ts +1 -1
  78. package/dist/src/nowiki/quote.js +1 -1
  79. package/dist/src/onlyinclude.js +1 -1
  80. package/dist/src/paramLine.d.ts +3 -0
  81. package/dist/src/paramLine.js +45 -7
  82. package/dist/src/parameter.js +1 -1
  83. package/dist/src/redirect.js +1 -1
  84. package/dist/src/table/base.d.ts +1 -1
  85. package/dist/src/table/base.js +4 -2
  86. package/dist/src/table/index.d.ts +2 -7
  87. package/dist/src/table/index.js +7 -54
  88. package/dist/src/table/td.js +9 -5
  89. package/dist/src/table/tr.d.ts +1 -1
  90. package/dist/src/tag/index.js +1 -1
  91. package/dist/src/tagPair/ext.js +33 -48
  92. package/dist/src/tagPair/index.js +6 -4
  93. package/dist/src/tagPair/translate.js +2 -2
  94. package/dist/src/transclude.d.ts +0 -6
  95. package/dist/src/transclude.js +16 -33
  96. package/dist/util/constants.js +5 -1
  97. package/dist/util/debug.js +81 -7
  98. package/dist/util/diff.js +17 -15
  99. package/dist/util/html.js +5 -3
  100. package/dist/util/selector.js +37 -0
  101. package/dist/util/sharable.d.mts +5 -1
  102. package/dist/util/sharable.js +69 -8
  103. package/dist/util/sharable.mjs +69 -7
  104. package/dist/util/string.js +31 -12
  105. package/extensions/dist/base.js +1 -1
  106. package/extensions/typings.d.ts +40 -0
  107. package/extensions/ui.css +1 -1
  108. package/i18n/en.json +2 -0
  109. package/i18n/zh-hans.json +31 -29
  110. package/i18n/zh-hant.json +32 -30
  111. package/package.json +19 -15
@@ -97,14 +97,20 @@ let ExtToken = (() => {
97
97
  };
98
98
  let innerToken;
99
99
  switch (lcName) {
100
- case 'tab':
101
- newConfig.ext = newConfig.ext.filter(e => e !== 'tabs');
100
+ case 'pre':
101
+ if (attrToken.getAttr('format') !== 'wikitext') {
102
+ const { PreToken } = require('../pre');
103
+ // @ts-expect-error abstract class
104
+ innerToken = new PreToken(inner, newConfig, accum);
105
+ break;
106
+ }
102
107
  // fall through
103
108
  case 'indicator':
104
109
  case 'poem':
105
110
  case 'ref':
106
111
  case 'option':
107
112
  case 'combooption':
113
+ case 'tab':
108
114
  case 'tabs':
109
115
  case 'poll':
110
116
  case 'seo':
@@ -113,24 +119,21 @@ let ExtToken = (() => {
113
119
  if (lcName === 'poem') {
114
120
  newConfig.excludes.push('heading');
115
121
  }
122
+ else if (lcName === 'tab') {
123
+ newConfig.ext = newConfig.ext.filter(e => e !== 'tabs');
124
+ }
116
125
  innerToken = new index_2.Token(inner, newConfig, accum);
117
126
  break;
118
- case 'pre': {
119
- const { PreToken } = require('../pre');
120
- // @ts-expect-error abstract class
121
- innerToken = new PreToken(inner, newConfig, accum);
122
- break;
123
- }
124
127
  case 'dynamicpagelist': {
125
128
  const { ParamTagToken } = require('../multiLine/paramTag');
126
129
  // @ts-expect-error abstract class
127
- innerToken = new ParamTagToken(include, inner, newConfig, accum);
130
+ innerToken = new ParamTagToken(lcName, include, inner, newConfig, accum);
128
131
  break;
129
132
  }
130
133
  case 'inputbox': {
131
134
  const { InputboxToken } = require('../multiLine/inputbox');
132
135
  // @ts-expect-error abstract class
133
- innerToken = new InputboxToken(include, inner, newConfig, accum);
136
+ innerToken = new InputboxToken(lcName, include, inner, newConfig, accum);
134
137
  break;
135
138
  }
136
139
  case 'references': {
@@ -173,6 +176,12 @@ let ExtToken = (() => {
173
176
  innerToken = new CommentedToken(inner, newConfig, accum);
174
177
  break;
175
178
  }
179
+ case 'categorytree': {
180
+ const { CategorytreeToken } = require('../link/categorytree');
181
+ // @ts-expect-error abstract class
182
+ innerToken = new CategorytreeToken(inner, undefined, newConfig, accum);
183
+ break;
184
+ }
176
185
  // 更多定制扩展的代码示例:
177
186
  // ```
178
187
  // case 'extensionName': {
@@ -234,46 +243,22 @@ let ExtToken = (() => {
234
243
  /** @private */
235
244
  toHtmlInternal(opt) {
236
245
  const { name, firstChild, lastChild } = this;
237
- if (index_1.default.tagHooks.has(name)) {
238
- return index_1.default.tagHooks.get(name)(this);
246
+ if (constants_1.tagHooks.has(name)) {
247
+ return constants_1.tagHooks.get(name)(this);
239
248
  }
240
- switch (name) {
241
- case 'nowiki': {
242
- const html = lastChild.toHtmlInternal();
243
- return this.closest('ext-inner')?.name === 'poem' ? html : (0, string_1.newline)(html);
244
- }
245
- case 'pre': {
246
- const html = lastChild.toHtmlInternal({
247
- ...opt,
248
- nowrap: false,
249
- });
250
- return `<pre${firstChild.toHtmlInternal()}>${this.closest('ext-inner')?.name === 'poem' ? html : (0, string_1.newline)(html)}</pre>`;
251
- }
252
- case 'poem': {
253
- const padding = firstChild.hasAttr('compact') ? '' : '\n';
254
- firstChild.classList.add('poem');
255
- return `<div${firstChild.toHtmlInternal()}>${padding}${lastChild.toHtmlInternal({ ...opt, nowrap: false })
256
- .replace(/(?<!^|<hr>)\n(?!$)/gu, '<br>\n')
257
- .replace(/^ +/gmu, p => '&nbsp;'.repeat(p.length))
258
- .trim()}${padding}</div>`;
259
- }
260
- case 'gallery': {
261
- const caption = firstChild.getAttrToken('caption'), perrow = parseInt(String(firstChild.getAttr('perrow'))), mode = firstChild.getAttr('mode'), nolines = typeof mode === 'string' && mode.toLowerCase() === 'nolines', padding = nolines ? 9 : 43;
262
- firstChild.classList.add('gallery');
263
- if (nolines) {
264
- firstChild.classList.add('mw-gallery-nolines');
265
- }
266
- if (perrow > 0) {
267
- const style = firstChild.getAttr('style');
268
- firstChild.setAttr('style', `max-width: ${(lastChild.widths + padding) * perrow}px;${typeof style === 'string' ? style : ''}`);
269
- }
270
- return `<ul${firstChild.toHtmlInternal()}>\n${caption
271
- ? `\t<li class="gallerycaption">${caption.lastChild.toHtmlInternal({ nowrap: true })}</li>\n`
272
- : ''}${lastChild.toHtmlInternal()}\n</ul>`;
273
- }
274
- default:
275
- return '';
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>`;
276
259
  }
260
+ const { renderExt } = require('../../render/extension');
261
+ return renderExt(this, opt);
277
262
  }
278
263
  };
279
264
  return ExtToken = _classThis;
@@ -123,10 +123,12 @@ let TagPairToken = (() => {
123
123
  }
124
124
  /** @private */
125
125
  print() {
126
- const [opening, closing] = this.#tags;
127
- return super.print(this.selfClosing
128
- ? { pre: `&lt;${opening}`, post: '/&gt;' }
129
- : { pre: `&lt;${opening}`, sep: '&gt;', post: this.closed ? `&lt;/${closing}&gt;` : '' });
126
+ PRINT: {
127
+ const [opening, closing] = this.#tags;
128
+ return super.print(this.selfClosing
129
+ ? { pre: `&lt;${opening}`, post: '/&gt;' }
130
+ : { pre: `&lt;${opening}`, sep: '&gt;', post: this.closed ? `&lt;/${closing}&gt;` : '' });
131
+ }
130
132
  }
131
133
  };
132
134
  return TagPairToken = _classThis;
@@ -102,11 +102,11 @@ let TranslateToken = (() => {
102
102
  /* PRINT ONLY */
103
103
  /** 是否有nowrap属性 */
104
104
  #isNowrap() {
105
- return this.firstChild.toString() === ' nowrap';
105
+ PRINT: return this.firstChild.toString() === ' nowrap';
106
106
  }
107
107
  /** @private */
108
108
  print() {
109
- return `<span class="wpb-ext">&lt;translate${this.#isNowrap()
109
+ PRINT: return `<span class="wpb-ext">&lt;translate${this.#isNowrap()
110
110
  ? '<span class="wpb-ext-attrs"> <span class="wpb-ext-attr">'
111
111
  + '<span class="wpb-attr-key">nowrap</span>'
112
112
  + '</span></span>'
@@ -8,12 +8,6 @@ declare interface Frame {
8
8
  parent?: Frame | undefined;
9
9
  title: string;
10
10
  }
11
- /**
12
- * 获取魔术字的规范名称
13
- * @param name 魔术字
14
- * @param parserFunction 解析设置中的parserFunction属性
15
- */
16
- export declare const getCanonicalName: (name: string, parserFunction: Config["parserFunction"]) => [string, boolean, boolean, string | false];
17
11
  /**
18
12
  * template or magic word
19
13
  *
@@ -37,7 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
38
38
  };
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
- exports.TranscludeToken = exports.getCanonicalName = void 0;
40
+ exports.TranscludeToken = void 0;
41
41
  const string_1 = require("../util/string");
42
42
  const lint_1 = require("../util/lint");
43
43
  const debug_1 = require("../util/debug");
@@ -52,25 +52,7 @@ const atom_1 = require("./atom");
52
52
  const syntax_1 = require("./syntax");
53
53
  /* NOT FOR BROWSER */
54
54
  const cached_1 = require("../mixin/cached");
55
- const basicMagicWords = new Map([['=', '='], ['!', '|']]);
56
55
  /* NOT FOR BROWSER END */
57
- /**
58
- * 获取魔术字的规范名称
59
- * @param name 魔术字
60
- * @param parserFunction 解析设置中的parserFunction属性
61
- */
62
- const getCanonicalName = (name, parserFunction) => {
63
- const lcName = name.toLowerCase(), [insensitive, sensitive] = parserFunction, isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema ? sensitive.includes(name) : Object.prototype.hasOwnProperty.call(sensitive, name);
64
- return [
65
- lcName,
66
- isOldSchema,
67
- isSensitive,
68
- !isOldSchema && isSensitive
69
- ? sensitive[name]
70
- : Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName],
71
- ];
72
- };
73
- exports.getCanonicalName = getCanonicalName;
74
56
  /**
75
57
  * template or magic word
76
58
  *
@@ -170,10 +152,9 @@ let TranscludeToken = (() => {
170
152
  if (isFunction || parts.length === 0 && !this.#raw) {
171
153
  const magicWord = isFunction ? title.slice(0, colon) : title, arg = isFunction && title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = isFunction
172
154
  ? cleaned.slice(cleaned.search(/\S/u)) + (fullWidth ? ':' : '')
173
- : cleaned.trim(), [lcName, isOldSchema, isSensitive, canonicalName] = (0, exports.getCanonicalName)(name, parserFunction), isFunc = isOldSchema && isSensitive
174
- || !('functionHook' in config) || functionHook.includes(canonicalName), isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
155
+ : cleaned.trim(), [, isSensitive, canonicalName] = (0, debug_1.getMagicWordInfo)(name, parserFunction), isFunc = !('functionHook' in config) || functionHook.includes(canonicalName), isVar = variable.includes(canonicalName);
175
156
  if (isFunction ? canonicalName && isFunc : isVar) {
176
- this.setAttribute('name', canonicalName || lcName.replace(/^#|:$/u, ''));
157
+ this.setAttribute('name', canonicalName);
177
158
  this.#type = 'magic-word';
178
159
  if (fullWidth) {
179
160
  this.#colon = ':';
@@ -269,7 +250,7 @@ let TranscludeToken = (() => {
269
250
  }
270
251
  /** 获取模板或模块名 */
271
252
  #getTitle() {
272
- const isTemplate = this.type === 'template', title = this.normalizeTitle((isTemplate ? '' : 'Module:') + this.childNodes[isTemplate ? 0 : 1].text(), 10, { temporary: true, ...!isTemplate && { page: '' } });
253
+ const isTemplate = this.type === 'template', title = this.normalizeTitle((isTemplate ? '' : 'Module:') + (0, string_1.removeComment)(this.childNodes[isTemplate ? 0 : 1].text()), 10, { temporary: true, ...!isTemplate && { page: '' } });
273
254
  /* NOT FOR BROWSER */
274
255
  title.fragment = undefined;
275
256
  /* NOT FOR BROWSER END */
@@ -347,7 +328,7 @@ let TranscludeToken = (() => {
347
328
  return this.#colon;
348
329
  /* PRINT ONLY */
349
330
  case 'invalid':
350
- return (this.type === 'magic-word' && this.name === 'invoke'
331
+ PRINT: return (this.type === 'magic-word' && this.name === 'invoke'
351
332
  && (this.length === 2 || !this.#getTitle().valid));
352
333
  /* PRINT ONLY END */
353
334
  /* NOT FOR BROWSER */
@@ -572,14 +553,16 @@ let TranscludeToken = (() => {
572
553
  }
573
554
  /** @private */
574
555
  print() {
575
- const { childNodes, length, firstChild, modifier, type } = this;
576
- return `<span class="wpb-${type}${this.getAttribute('invalid') ? ' wpb-invalid' : ''}">{{${type === 'magic-word'
577
- ? (0, string_1.escape)(modifier)
578
- + firstChild.print()
579
- + (length === 1 ? '' : this.#colon)
580
- + (0, string_1.print)(childNodes.slice(1), { sep: '|' })
581
- : (modifier ? `<span class="wpb-magic-word">${(0, string_1.escape)(modifier)}</span>` : '')
582
- + (0, string_1.print)(childNodes, { sep: '|' })}}}</span>`;
556
+ PRINT: {
557
+ const { childNodes, length, firstChild, modifier, type } = this;
558
+ return `<span class="wpb-${type}${this.getAttribute('invalid') ? ' wpb-invalid' : ''}">{{${type === 'magic-word'
559
+ ? (0, string_1.escape)(modifier)
560
+ + firstChild.print()
561
+ + (length === 1 ? '' : this.#colon)
562
+ + (0, string_1.print)(childNodes.slice(1), { sep: '|' })
563
+ : (modifier ? `<span class="wpb-magic-word">${(0, string_1.escape)(modifier)}</span>` : '')
564
+ + (0, string_1.print)(childNodes, { sep: '|' })}}}</span>`;
565
+ }
583
566
  }
584
567
  /* NOT FOR BROWSER */
585
568
  cloneNode() {
@@ -846,7 +829,7 @@ let TranscludeToken = (() => {
846
829
  const str = this.text();
847
830
  return opt?.nowrap ? str.replaceAll('\n', ' ') : str;
848
831
  }
849
- return basicMagicWords.has(name) ? basicMagicWords.get(name) : '';
832
+ return '';
850
833
  }
851
834
  };
852
835
  return TranscludeToken = _classThis;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /* NOT FOR BROWSER */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.states = exports.aliases = exports.parsers = exports.mixins = exports.classes = exports.mathTags = exports.enMsg = exports.BuildMethod = exports.MAX_STAGE = void 0;
4
+ exports.tagHooks = exports.functionHooks = exports.states = exports.aliases = exports.parsers = exports.mixins = exports.classes = exports.mathTags = exports.extensions = exports.galleryParams = exports.enMsg = exports.BuildMethod = exports.MAX_STAGE = void 0;
5
5
  /* NOT FOR BROWSER END */
6
6
  exports.MAX_STAGE = 11;
7
7
  var BuildMethod;
@@ -13,6 +13,8 @@ exports.enMsg = (() => {
13
13
  // eslint-disable-next-line n/no-missing-require
14
14
  LSP: return require('../../i18n/en.json');
15
15
  })();
16
+ exports.galleryParams = new Set(['alt', 'link', 'lang', 'page', 'caption']);
17
+ exports.extensions = new Set(['tiff', 'tif', 'png', 'gif', 'jpg', 'jpeg', 'webp', 'xcf', 'pdf', 'svg', 'djvu']);
16
18
  /* NOT FOR BROWSER ONLY */
17
19
  exports.mathTags = new Set(['math', 'chem', 'ce']);
18
20
  /* NOT FOR BROWSER ONLY END */
@@ -33,3 +35,5 @@ exports.aliases = [
33
35
  ['ConverterToken'],
34
36
  ];
35
37
  exports.states = new WeakMap();
38
+ exports.functionHooks = new Map();
39
+ exports.tagHooks = new Map();
@@ -1,26 +1,52 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.undo = exports.mixin = exports.setChildNodes = exports.isToken = exports.Shadow = void 0;
3
+ exports.getCanonicalName = exports.undo = exports.mixin = exports.emptyArray = exports.getMagicWordInfo = exports.setChildNodes = exports.isLink = exports.isRowEnd = exports.isToken = exports.Shadow = void 0;
4
4
  exports.Shadow = {
5
5
  running: false,
6
6
  /** @private */
7
- run(callback) {
7
+ run(callback, Parser) {
8
8
  const { running } = this;
9
9
  this.running = true;
10
+ /* PRINT ONLY */
11
+ const internal = Parser?.internal;
12
+ if (Parser) {
13
+ Parser.internal = true;
14
+ }
15
+ /* PRINT ONLY END */
16
+ /** restore state before exit */
17
+ const finish = () => {
18
+ this.running = running;
19
+ /* PRINT ONLY */
20
+ if (Parser) {
21
+ Parser.internal = internal;
22
+ }
23
+ };
10
24
  try {
11
- const { Token: AnyToken } = require('../src/index');
25
+ const { Token } = require('../src/index');
12
26
  const result = callback();
13
- if (result instanceof AnyToken && !result.getAttribute('built')) {
27
+ if (result instanceof Token && !result.getAttribute('built')) {
14
28
  result.afterBuild();
15
29
  }
16
- this.running = running;
30
+ finish();
17
31
  return result;
18
32
  }
19
33
  catch (e) /* istanbul ignore next */ {
20
- this.running = running;
34
+ finish();
21
35
  throw e;
22
36
  }
23
37
  },
38
+ /** @private */
39
+ internal(callback, Parser) {
40
+ /* PRINT ONLY */
41
+ const { internal } = Parser;
42
+ Parser.internal = true;
43
+ /* PRINT ONLY END */
44
+ const result = callback();
45
+ /* PRINT ONLY */
46
+ Parser.internal = internal;
47
+ /* PRINT ONLY END */
48
+ return result;
49
+ },
24
50
  rev: 0,
25
51
  };
26
52
  /**
@@ -29,6 +55,19 @@ exports.Shadow = {
29
55
  */
30
56
  const isToken = (type) => (node) => node.type === type;
31
57
  exports.isToken = isToken;
58
+ /**
59
+ * 是否是行尾
60
+ * @param token 节点
61
+ * @param token.type 节点类型
62
+ */
63
+ const isRowEnd = ({ type }) => type === 'tr' || type === 'table-syntax';
64
+ exports.isRowEnd = isRowEnd;
65
+ /**
66
+ * 是否为普通内链
67
+ * @param type 节点类型
68
+ */
69
+ const isLink = (type) => type === 'redirect-target' || type === 'link';
70
+ exports.isLink = isLink;
32
71
  /**
33
72
  * 更新chldNodes
34
73
  * @param parent 父节点
@@ -56,12 +95,37 @@ const setChildNodes = (parent, position, deleteCount, inserted = []) => {
56
95
  parent.setAttribute('childNodes', nodes);
57
96
  /* NOT FOR BROWSER */
58
97
  for (const node of removed) {
59
- node.setAttribute('parentNode', undefined);
98
+ if (node.parentNode === parent) {
99
+ node.setAttribute('parentNode', undefined);
100
+ }
60
101
  }
61
102
  /* NOT FOR BROWSER END */
62
103
  return removed;
63
104
  };
64
105
  exports.setChildNodes = setChildNodes;
106
+ /**
107
+ * 获取魔术字的信息
108
+ * @param name 魔术字
109
+ * @param parserFunction 解析设置中的parserFunction属性
110
+ */
111
+ const getMagicWordInfo = (name, parserFunction) => {
112
+ const lcName = name.toLowerCase(), [insensitive, sensitive] = parserFunction, isSensitive = Object.prototype.hasOwnProperty.call(sensitive, name);
113
+ return [
114
+ lcName,
115
+ isSensitive,
116
+ isSensitive
117
+ ? sensitive[name]
118
+ : Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName],
119
+ ];
120
+ };
121
+ exports.getMagicWordInfo = getMagicWordInfo;
122
+ /**
123
+ * 生成一个指定长度的空数组
124
+ * @param length 数组长度
125
+ * @param callback 回调函数
126
+ */
127
+ const emptyArray = (length, callback) => Array.from({ length }, (_, i) => callback(i));
128
+ exports.emptyArray = emptyArray;
65
129
  /* NOT FOR BROWSER ONLY */
66
130
  /**
67
131
  * 同步混入的类名
@@ -101,3 +165,13 @@ const undo = (e, data) => {
101
165
  }
102
166
  };
103
167
  exports.undo = undo;
168
+ /**
169
+ * 获取魔术字的规范名称
170
+ * @param name 魔术字
171
+ * @param parserFunction 解析设置中的parserFunction属性
172
+ */
173
+ const getCanonicalName = (name, parserFunction) => {
174
+ const [lcName, , canonicalName] = (0, exports.getMagicWordInfo)(name, parserFunction);
175
+ return [canonicalName || lcName, canonicalName];
176
+ };
177
+ exports.getCanonicalName = getCanonicalName;
package/dist/util/diff.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.info = exports.error = exports.diff = exports.cmd = void 0;
6
+ exports.info = exports.error = exports.loadChalk = exports.diff = exports.cmd = void 0;
7
7
  const promises_1 = __importDefault(require("fs/promises"));
8
8
  const child_process_1 = require("child_process");
9
9
  /* istanbul ignore next */
@@ -76,27 +76,29 @@ const diff = async (oldStr, newStr, uid) => {
76
76
  await Promise.allSettled([promises_1.default.unlink(oldFile), promises_1.default.unlink(newFile)]);
77
77
  };
78
78
  exports.diff = diff;
79
+ let chalk;
80
+ /* istanbul ignore next */
81
+ const loadChalk = () => {
82
+ if (chalk === undefined) {
83
+ try {
84
+ chalk = require('chalk');
85
+ }
86
+ catch {
87
+ chalk = null;
88
+ }
89
+ }
90
+ return chalk;
91
+ };
92
+ exports.loadChalk = loadChalk;
79
93
  /* istanbul ignore next */
80
94
  /** @implements */
81
95
  const error = (msg, ...args) => {
82
- try {
83
- const chalk = require('chalk');
84
- console.error(chalk.red(msg), ...args);
85
- }
86
- catch {
87
- console.error(msg, ...args);
88
- }
96
+ console.error((0, exports.loadChalk)()?.red(msg) ?? msg, ...args);
89
97
  };
90
98
  exports.error = error;
91
99
  /* istanbul ignore next */
92
100
  /** @implements */
93
101
  const info = (msg, ...args) => {
94
- try {
95
- const chalk = require('chalk');
96
- console.info(chalk.green(msg), ...args);
97
- }
98
- catch {
99
- console.info(msg, ...args);
100
- }
102
+ console.info((0, exports.loadChalk)()?.green(msg) ?? msg, ...args);
101
103
  };
102
104
  exports.info = info;
package/dist/util/html.js CHANGED
@@ -11,6 +11,7 @@ const string_1 = require("./string");
11
11
  */
12
12
  const getCommon = (prefix, lastPrefix) => prefix.startsWith(lastPrefix) ? lastPrefix.length : [...lastPrefix].findIndex((ch, i) => ch !== prefix[i]);
13
13
  exports.getCommon = getCommon;
14
+ /* NOT FOR BROWSER */
14
15
  /**
15
16
  * get next list item
16
17
  * @param char list syntax
@@ -82,9 +83,10 @@ const openList = (chars, { dt }) => {
82
83
  * @param separator delimiter between nodes
83
84
  * @param opt options
84
85
  */
85
- const html = (childNodes, separator, opt) => {
86
+ const html = (childNodes, separator, opt = {}) => {
86
87
  let lastPrefix = '';
87
- const results = [], state = { dt: [] };
88
+ const results = [], { removeBlank } = opt, state = { dt: [] };
89
+ delete opt.removeBlank;
88
90
  for (let j = 0; j < childNodes.length; j++) {
89
91
  const child = childNodes[j];
90
92
  let result = child.toHtmlInternal(opt);
@@ -135,7 +137,7 @@ const html = (childNodes, separator, opt) => {
135
137
  }
136
138
  results.push(result);
137
139
  }
138
- return results.join(separator);
140
+ return (removeBlank ? results.filter(result => result !== '') : results).join(separator);
139
141
  };
140
142
  exports.html = html;
141
143
  /**
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCondition = exports.basic = void 0;
4
+ /**
5
+ * type和name选择器
6
+ * @param selector
7
+ */
8
+ const basic = (selector) => {
9
+ if (selector.includes('#')) {
10
+ const i = selector.indexOf('#'), targetType = selector.slice(0, i), targetName = selector.slice(i + 1);
11
+ return (type, name) => (i === 0 || type === targetType) && name === targetName;
12
+ }
13
+ return type => type === selector;
14
+ };
15
+ exports.basic = basic;
16
+ /**
17
+ * 将选择器转化为类型谓词
18
+ * @param selector 选择器
19
+ * @param scope 作用对象
20
+ * @param has `:has()`伪选择器
21
+ */
22
+ const getCondition = (selector, scope, has) => {
23
+ selector = selector.trim();
24
+ /* NOT FOR BROWSER */
25
+ if (/[^a-z\-,#\s]|(?<![\s,])\s+(?![\s,])/u.test(selector)) {
26
+ const { checkToken } = require('../parser/selector');
27
+ return checkToken(selector, scope, has);
28
+ }
29
+ /* NOT FOR BROWSER END */
30
+ /* istanbul ignore if */
31
+ if (!selector) {
32
+ return (() => true);
33
+ }
34
+ const parts = selector.split(',').map(str => str.trim()).filter(str => str !== '').map(exports.basic);
35
+ return (({ type, name }) => parts.some(condition => condition(type, name)));
36
+ };
37
+ exports.getCondition = getCondition;
@@ -1 +1,5 @@
1
- export declare const commonHtmlAttrs: Set<string>, htmlAttrs: Record<string, Set<string>>, extAttrs: Record<string, Set<string>>, obsoleteAttrs: Record<string, Set<string>>;
1
+ export declare const commonHtmlAttrs: Set<string>;
2
+ export declare const htmlAttrs: Record<string, Set<string>>;
3
+ export declare const extAttrs: Record<string, Set<string>>;
4
+ export declare const obsoleteAttrs: Record<string, Set<string>>;
5
+ export declare const extParams: Record<string, string[]>;