wikiparser-node 0.3.0 → 0.4.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 (81) hide show
  1. package/.eslintrc.json +472 -34
  2. package/README.md +1 -1
  3. package/config/default.json +58 -30
  4. package/config/llwiki.json +22 -90
  5. package/config/moegirl.json +51 -13
  6. package/config/zhwiki.json +1269 -0
  7. package/index.js +114 -104
  8. package/lib/element.js +448 -440
  9. package/lib/node.js +335 -115
  10. package/lib/ranges.js +27 -18
  11. package/lib/text.js +146 -0
  12. package/lib/title.js +13 -5
  13. package/mixin/attributeParent.js +70 -24
  14. package/mixin/fixedToken.js +14 -6
  15. package/mixin/hidden.js +6 -4
  16. package/mixin/sol.js +27 -10
  17. package/package.json +9 -3
  18. package/parser/brackets.js +22 -17
  19. package/parser/commentAndExt.js +18 -16
  20. package/parser/converter.js +14 -13
  21. package/parser/externalLinks.js +12 -11
  22. package/parser/hrAndDoubleUnderscore.js +23 -14
  23. package/parser/html.js +10 -9
  24. package/parser/links.js +15 -14
  25. package/parser/list.js +12 -11
  26. package/parser/magicLinks.js +12 -11
  27. package/parser/quotes.js +6 -5
  28. package/parser/selector.js +175 -0
  29. package/parser/table.js +25 -18
  30. package/printed/example.json +120 -0
  31. package/src/arg.js +56 -32
  32. package/src/atom/hidden.js +5 -2
  33. package/src/atom/index.js +17 -9
  34. package/src/attribute.js +182 -100
  35. package/src/converter.js +68 -41
  36. package/src/converterFlags.js +67 -45
  37. package/src/converterRule.js +117 -65
  38. package/src/extLink.js +66 -18
  39. package/src/gallery.js +42 -15
  40. package/src/heading.js +34 -15
  41. package/src/html.js +97 -35
  42. package/src/imageParameter.js +83 -54
  43. package/src/index.js +299 -178
  44. package/src/link/category.js +20 -52
  45. package/src/link/file.js +59 -28
  46. package/src/link/galleryImage.js +21 -7
  47. package/src/link/index.js +146 -60
  48. package/src/magicLink.js +34 -12
  49. package/src/nowiki/comment.js +22 -10
  50. package/src/nowiki/dd.js +37 -22
  51. package/src/nowiki/doubleUnderscore.js +16 -7
  52. package/src/nowiki/hr.js +11 -7
  53. package/src/nowiki/index.js +16 -9
  54. package/src/nowiki/list.js +2 -2
  55. package/src/nowiki/noinclude.js +8 -4
  56. package/src/nowiki/quote.js +11 -7
  57. package/src/onlyinclude.js +19 -7
  58. package/src/parameter.js +65 -38
  59. package/src/syntax.js +26 -20
  60. package/src/table/index.js +260 -165
  61. package/src/table/td.js +98 -52
  62. package/src/table/tr.js +102 -58
  63. package/src/tagPair/ext.js +27 -19
  64. package/src/tagPair/include.js +16 -11
  65. package/src/tagPair/index.js +64 -29
  66. package/src/transclude.js +170 -93
  67. package/test/api.js +83 -0
  68. package/test/real.js +133 -0
  69. package/test/test.js +28 -0
  70. package/test/util.js +80 -0
  71. package/tool/index.js +41 -31
  72. package/typings/api.d.ts +13 -0
  73. package/typings/array.d.ts +28 -0
  74. package/typings/event.d.ts +24 -0
  75. package/typings/index.d.ts +46 -4
  76. package/typings/node.d.ts +15 -9
  77. package/typings/parser.d.ts +7 -0
  78. package/typings/tool.d.ts +3 -2
  79. package/util/debug.js +21 -18
  80. package/util/string.js +40 -27
  81. package/typings/element.d.ts +0 -28
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const attributeParent = require('../../mixin/attributeParent'),
4
- /** @type {Parser} */ Parser = require('../..'),
4
+ Parser = require('../..'),
5
5
  TagPairToken = require('.');
6
6
 
7
7
  /**
@@ -11,35 +11,46 @@ const attributeParent = require('../../mixin/attributeParent'),
11
11
  class ExtToken extends attributeParent(TagPairToken) {
12
12
  type = 'ext';
13
13
 
14
+ /** @override */
15
+ get closed() {
16
+ return super.closed;
17
+ }
18
+
14
19
  /**
15
- * @param {string} name
16
- * @param {string|undefined} closing
20
+ * @param {string} name 标签名
21
+ * @param {string} attr 标签属性
22
+ * @param {string} inner 内部wikitext
23
+ * @param {string|undefined} closed 是否封闭
17
24
  * @param {accum} accum
18
25
  */
19
- constructor(name, attr = '', inner = '', closing = undefined, config = Parser.getConfig(), accum = []) {
20
- attr = !attr || /^\s/.test(attr) ? attr : ` ${attr}`;
26
+ constructor(name, attr = '', inner = '', closed = undefined, config = Parser.getConfig(), accum = []) {
27
+ attr = !attr || attr.trimStart() !== attr ? attr : ` ${attr}`;
28
+ const AttributeToken = require('../attribute');
21
29
  const lcName = name.toLowerCase(),
22
- AttributeToken = require('../attribute'),
23
30
  attrToken = new AttributeToken(attr, 'ext-attr', lcName, config, accum),
24
31
  newConfig = structuredClone(config),
25
32
  ext = new Set(newConfig.ext);
26
33
  let /** @type {acceptable} */ acceptable, /** @type {Token} */ innerToken;
27
34
  switch (lcName) {
28
35
  case 'choose':
29
- ext.add('option');
30
- // fall through
31
- case 'ref':
32
36
  case 'option':
37
+ case 'ref':
33
38
  case 'poem':
34
39
  case 'indicator':
35
40
  case 'tab':
36
41
  case 'tabs':
37
- case 'pre': {
42
+ case 'pre':
43
+ case 'combobox':
44
+ case 'combooption': {
38
45
  ext.delete(lcName);
39
- newConfig.ext = [...ext];
46
+ newConfig.ext = [
47
+ ...ext,
48
+ ...lcName === 'choose' ? ['option'] : [],
49
+ ...lcName === 'combobox' ? ['combooption'] : [],
50
+ ];
40
51
  const Token = require('..');
41
52
  acceptable = {AttributeToken: 0, Token: 1};
42
- innerToken = new Token(inner, newConfig, false, accum);
53
+ innerToken = new Token(inner, newConfig, true, accum);
43
54
  break;
44
55
  }
45
56
  case 'gallery': {
@@ -50,6 +61,7 @@ class ExtToken extends attributeParent(TagPairToken) {
50
61
  innerToken = new GalleryToken(inner, newConfig, accum);
51
62
  break;
52
63
  }
64
+
53
65
  /*
54
66
  * 更多定制扩展的代码示例:
55
67
  * ```
@@ -74,23 +86,19 @@ class ExtToken extends attributeParent(TagPairToken) {
74
86
  if (lcName === 'pre') {
75
87
  innerToken.setAttribute('stage', Parser.MAX_STAGE - 1);
76
88
  }
77
- super(name, attrToken, innerToken, closing, config, accum, acceptable);
78
- Object.defineProperty(this, 'closed', {value: true, enumerable: false, writable: false, configurable: false});
89
+ super(name, attrToken, innerToken, closed, config, accum, acceptable);
79
90
  }
80
91
 
92
+ /** @override */
81
93
  cloneNode() {
82
94
  const inner = this.lastElementChild.cloneNode(),
83
95
  tags = this.getAttribute('tags'),
84
96
  config = this.getAttribute('config'),
85
- attr = this.firstElementChild.toString(),
97
+ attr = String(this.firstElementChild),
86
98
  token = Parser.run(() => new ExtToken(tags[0], attr, '', this.selfClosing ? undefined : tags[1], config));
87
99
  token.lastElementChild.safeReplaceWith(inner);
88
100
  return token;
89
101
  }
90
-
91
- get innerText() {
92
- return this.selfClosing ? '' : this.lastElementChild.text();
93
- }
94
102
  }
95
103
 
96
104
  Parser.classes.ExtToken = __filename;
@@ -1,41 +1,46 @@
1
1
  'use strict';
2
2
 
3
3
  const hidden = require('../../mixin/hidden'),
4
- /** @type {Parser} */ Parser = require('../..'),
4
+ Parser = require('../..'),
5
5
  TagPairToken = require('.');
6
6
 
7
7
  /**
8
8
  * `<includeonly>`或`<noinclude>`
9
- * @classdesc `{childNodes: [string, string]}`
9
+ * @classdesc `{childNodes: [AstText, AstText]}`
10
10
  */
11
11
  class IncludeToken extends hidden(TagPairToken) {
12
12
  type = 'include';
13
13
 
14
14
  /**
15
- * @param {string} name
16
- * @param {string|undefined} inner
17
- * @param {string|undefined} closing
15
+ * @param {string} name 标签名
16
+ * @param {string} attr 标签属性
17
+ * @param {string|undefined} inner 内部wikitext
18
+ * @param {string|undefined} closed 是否封闭
18
19
  * @param {accum} accum
19
20
  */
20
- constructor(name, attr = '', inner = undefined, closing = undefined, config = Parser.getConfig(), accum = []) {
21
- super(name, attr, inner ?? '', inner !== undefined ? closing ?? '' : closing, config, accum, {String: [0, 1]});
21
+ constructor(name, attr = '', inner = undefined, closed = undefined, config = Parser.getConfig(), accum = []) {
22
+ super(name, attr, inner ?? '', inner === undefined ? closed : closed ?? '', config, accum, {AstText: [0, 1]});
22
23
  }
23
24
 
24
- /** @this {IncludeToken & {firstChild: string, lastChild: string}} */
25
+ /** @override */
25
26
  cloneNode() {
26
27
  const tags = this.getAttribute('tags'),
27
28
  config = this.getAttribute('config'),
28
- inner = this.selfClosing ? undefined : this.lastChild,
29
+ inner = this.selfClosing ? undefined : String(this.lastChild),
29
30
  closing = this.selfClosing || !this.closed ? undefined : tags[1],
30
- token = Parser.run(() => new IncludeToken(tags[0], this.firstChild, inner, closing, config));
31
+ token = Parser.run(() => new IncludeToken(tags[0], String(this.firstChild), inner, closing, config));
31
32
  return token;
32
33
  }
33
34
 
34
- /** @param {string} str */
35
+ /**
36
+ * @override
37
+ * @param {string} str 新文本
38
+ */
35
39
  setText(str) {
36
40
  return super.setText(str, 1);
37
41
  }
38
42
 
43
+ /** 清除标签属性 */
39
44
  removeAttr() {
40
45
  super.setText('', 0);
41
46
  }
@@ -1,30 +1,57 @@
1
1
  'use strict';
2
2
 
3
3
  const fixedToken = require('../../mixin/fixedToken'),
4
- /** @type {Parser} */ Parser = require('../..'),
4
+ Parser = require('../..'),
5
5
  Token = require('..');
6
6
 
7
7
  /**
8
8
  * 成对标签
9
- * @classdesc `{childNodes: [string|AttributeToken, string|Token]}`
9
+ * @classdesc `{childNodes: [AstText|AttributeToken, AstText|Token]}`
10
10
  */
11
11
  class TagPairToken extends fixedToken(Token) {
12
- selfClosing;
13
- closed;
12
+ #selfClosing;
13
+ #closed;
14
14
  #tags;
15
15
 
16
+ /** getter */
17
+ get selfClosing() {
18
+ return this.#selfClosing;
19
+ }
20
+
21
+ set selfClosing(value) {
22
+ value = Boolean(value);
23
+ if (value !== this.#selfClosing && this.lastChild.text()) {
24
+ Parser.warn(`<${this.name}>标签内部的${value ? '文本将被隐藏' : '原有文本将再次可见'}!`);
25
+ }
26
+ this.#selfClosing = value;
27
+ }
28
+
29
+ /** getter */
30
+ get closed() {
31
+ return this.#closed;
32
+ }
33
+
34
+ set closed(value) {
35
+ this.#closed ||= Boolean(value);
36
+ }
37
+
38
+ /** 内部wikitext */
39
+ get innerText() {
40
+ return this.#selfClosing ? undefined : this.lastChild.text();
41
+ }
42
+
16
43
  /**
17
- * @param {string} name
18
- * @param {string|Token} attr
19
- * @param {string|Token} inner
20
- * @param {string|undefined} closing - 约定`undefined`表示自闭合,`''`表示未闭合
44
+ * @param {string} name 标签名
45
+ * @param {string|Token} attr 标签属性
46
+ * @param {string|Token} inner 内部wikitext
47
+ * @param {string|undefined} closed 是否封闭;约定`undefined`表示自闭合,`''`表示未闭合
21
48
  * @param {accum} accum
22
49
  */
23
- constructor(name, attr, inner, closing, config = Parser.getConfig(), accum = []) {
50
+ constructor(name, attr, inner, closed, config = Parser.getConfig(), accum = []) {
24
51
  super(undefined, config, true);
25
- this.setAttribute('name', name.toLowerCase()).#tags = [name, closing || name];
26
- this.selfClosing = closing === undefined;
27
- this.closed = closing !== '';
52
+ this.setAttribute('name', name.toLowerCase()).#tags = [name, closed || name];
53
+ this.#selfClosing = closed === undefined;
54
+ this.#closed = closed !== '';
28
55
  this.append(attr, inner);
29
56
  let index = accum.indexOf(attr);
30
57
  if (index === -1) {
@@ -37,44 +64,52 @@ class TagPairToken extends fixedToken(Token) {
37
64
  }
38
65
 
39
66
  /**
67
+ * @override
40
68
  * @template {string} T
41
- * @param {T} key
69
+ * @param {T} key 属性键
42
70
  * @returns {TokenAttribute<T>}
43
71
  */
44
72
  getAttribute(key) {
45
- if (key === 'tags') {
46
- return [...this.#tags];
47
- }
48
- return super.getAttribute(key);
73
+ return key === 'tags' ? [...this.#tags] : super.getAttribute(key);
49
74
  }
50
75
 
51
- toString() {
52
- const {closed, firstChild, lastChild, nextSibling, name, selfClosing} = this,
76
+ /**
77
+ * @override
78
+ * @param {string} selector
79
+ */
80
+ toString(selector) {
81
+ const {firstChild, lastChild, nextSibling, name} = this,
53
82
  [opening, closing] = this.#tags;
54
- if (!closed && nextSibling) {
83
+ if (selector && this.matches(selector)) {
84
+ return '';
85
+ } else if (!this.#closed && nextSibling) {
55
86
  Parser.error(`自动闭合 <${name}>`, lastChild);
56
- this.closed = true;
87
+ this.#closed = true;
57
88
  }
58
- return selfClosing
89
+ return this.#selfClosing
59
90
  ? `<${opening}${String(firstChild)}/>`
60
- : `<${opening}${String(firstChild)}>${String(lastChild)}${this.closed ? `</${closing}>` : ''}`;
91
+ : `<${opening}${String(firstChild)}>${String(lastChild)}${this.#closed ? `</${closing}>` : ''}`;
61
92
  }
62
93
 
94
+ /** @override */
63
95
  getPadding() {
64
96
  return this.#tags[0].length + 1;
65
97
  }
66
98
 
99
+ /** @override */
67
100
  getGaps() {
68
101
  return 1;
69
102
  }
70
103
 
71
- /** @returns {string} */
104
+ /**
105
+ * @override
106
+ * @returns {string}
107
+ */
72
108
  text() {
73
- const {closed, firstChild, selfClosing} = this,
74
- [opening, closing] = this.#tags;
75
- return selfClosing
76
- ? `<${opening}${typeof firstChild === 'string' ? firstChild : firstChild.text()}/>`
77
- : `<${opening}${super.text('>')}${closed ? `</${closing}>` : ''}`;
109
+ const [opening, closing] = this.#tags;
110
+ return this.#selfClosing
111
+ ? `<${opening}${this.firstChild.text()}/>`
112
+ : `<${opening}${super.text('>')}${this.#closed ? `</${closing}>` : ''}`;
78
113
  }
79
114
  }
80
115