wikiparser-node 0.3.1 → 0.5.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 (80) hide show
  1. package/README.md +1 -1
  2. package/config/default.json +13 -17
  3. package/config/llwiki.json +11 -79
  4. package/config/moegirl.json +7 -1
  5. package/config/zhwiki.json +1269 -0
  6. package/index.js +130 -97
  7. package/lib/element.js +410 -518
  8. package/lib/node.js +493 -115
  9. package/lib/ranges.js +27 -19
  10. package/lib/text.js +175 -0
  11. package/lib/title.js +14 -6
  12. package/mixin/attributeParent.js +70 -24
  13. package/mixin/fixedToken.js +18 -10
  14. package/mixin/hidden.js +6 -4
  15. package/mixin/sol.js +39 -12
  16. package/package.json +17 -4
  17. package/parser/brackets.js +18 -18
  18. package/parser/commentAndExt.js +16 -14
  19. package/parser/converter.js +14 -13
  20. package/parser/externalLinks.js +12 -11
  21. package/parser/hrAndDoubleUnderscore.js +24 -14
  22. package/parser/html.js +8 -7
  23. package/parser/links.js +13 -13
  24. package/parser/list.js +12 -11
  25. package/parser/magicLinks.js +11 -10
  26. package/parser/quotes.js +6 -5
  27. package/parser/selector.js +175 -0
  28. package/parser/table.js +31 -24
  29. package/src/arg.js +91 -43
  30. package/src/atom/hidden.js +5 -2
  31. package/src/atom/index.js +17 -9
  32. package/src/attribute.js +210 -101
  33. package/src/converter.js +78 -43
  34. package/src/converterFlags.js +104 -45
  35. package/src/converterRule.js +136 -78
  36. package/src/extLink.js +81 -27
  37. package/src/gallery.js +63 -20
  38. package/src/heading.js +58 -20
  39. package/src/html.js +138 -48
  40. package/src/imageParameter.js +93 -58
  41. package/src/index.js +314 -186
  42. package/src/link/category.js +22 -54
  43. package/src/link/file.js +83 -32
  44. package/src/link/galleryImage.js +21 -7
  45. package/src/link/index.js +170 -81
  46. package/src/magicLink.js +64 -14
  47. package/src/nowiki/comment.js +36 -10
  48. package/src/nowiki/dd.js +37 -22
  49. package/src/nowiki/doubleUnderscore.js +21 -7
  50. package/src/nowiki/hr.js +11 -7
  51. package/src/nowiki/index.js +16 -9
  52. package/src/nowiki/list.js +2 -2
  53. package/src/nowiki/noinclude.js +8 -4
  54. package/src/nowiki/quote.js +38 -7
  55. package/src/onlyinclude.js +24 -7
  56. package/src/parameter.js +102 -62
  57. package/src/syntax.js +23 -20
  58. package/src/table/index.js +282 -174
  59. package/src/table/td.js +112 -61
  60. package/src/table/tr.js +135 -74
  61. package/src/tagPair/ext.js +30 -23
  62. package/src/tagPair/include.js +26 -11
  63. package/src/tagPair/index.js +72 -29
  64. package/src/transclude.js +235 -127
  65. package/tool/index.js +42 -32
  66. package/util/debug.js +21 -18
  67. package/util/diff.js +76 -0
  68. package/util/lint.js +40 -0
  69. package/util/string.js +56 -26
  70. package/.eslintrc.json +0 -319
  71. package/errors/README +0 -1
  72. package/jsconfig.json +0 -7
  73. package/printed/README +0 -1
  74. package/typings/element.d.ts +0 -28
  75. package/typings/index.d.ts +0 -52
  76. package/typings/node.d.ts +0 -23
  77. package/typings/parser.d.ts +0 -9
  78. package/typings/table.d.ts +0 -14
  79. package/typings/token.d.ts +0 -22
  80. package/typings/tool.d.ts +0 -10
package/src/converter.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const {text} = require('../util/string'),
4
- /** @type {Parser} */ Parser = require('..'),
3
+ const {text, print} = require('../util/string'),
4
+ Parser = require('..'),
5
5
  Token = require('.'),
6
6
  ConverterFlagsToken = require('./converterFlags'),
7
7
  ConverterRuleToken = require('./converterRule');
@@ -14,116 +14,151 @@ class ConverterToken extends Token {
14
14
  type = 'converter';
15
15
 
16
16
  /**
17
- * @param {string[]} flags
18
- * @param {string[]} rules
17
+ * 是否无转换
18
+ * @this {ConverterToken & {lastChild: ConverterRuleToken}}
19
+ */
20
+ get noConvert() {
21
+ return this.hasFlag('R') || this.childNodes.length === 2 && !this.lastChild.variant;
22
+ }
23
+
24
+ /**
25
+ * @param {string[]} flags 转换类型标记
26
+ * @param {string[]} rules 转换规则
19
27
  * @param {accum} accum
20
28
  */
21
29
  constructor(flags, rules, config = Parser.getConfig(), accum = []) {
22
30
  super(undefined, config, true, accum);
23
31
  this.append(new ConverterFlagsToken(flags, config, accum));
24
- if (rules.length) {
25
- const [firstRule] = rules,
26
- hasColon = firstRule.includes(':'),
27
- firstRuleToken = new ConverterRuleToken(firstRule, hasColon, config, accum);
28
- if (hasColon && firstRuleToken.childNodes.length === 1) {
29
- this.appendChild(new ConverterRuleToken(rules.join(';'), false, config, accum));
30
- } else {
31
- this.append(
32
- firstRuleToken,
33
- ...rules.slice(1).map(rule => new ConverterRuleToken(rule, true, config, accum)),
34
- );
35
- }
32
+ const [firstRule] = rules,
33
+ hasColon = firstRule.includes(':'),
34
+ firstRuleToken = new ConverterRuleToken(firstRule, hasColon, config, accum);
35
+ if (hasColon && firstRuleToken.childNodes.length === 1) {
36
+ this.appendChild(new ConverterRuleToken(rules.join(';'), false, config, accum));
37
+ } else {
38
+ this.append(
39
+ firstRuleToken,
40
+ ...rules.slice(1).map(rule => new ConverterRuleToken(rule, true, config, accum)),
41
+ );
36
42
  }
37
- this.protectChildren(0);
43
+ this.getAttribute('protectChildren')(0);
38
44
  }
39
45
 
46
+ /** @override */
40
47
  cloneNode() {
41
- const [flags, ...rules] = this.cloneChildren(),
48
+ const [flags, ...rules] = this.cloneChildNodes(),
42
49
  token = Parser.run(() => new ConverterToken([], [], this.getAttribute('config')));
43
- token.firstElementChild.safeReplaceWith(flags);
50
+ token.firstChild.safeReplaceWith(flags);
44
51
  token.append(...rules);
45
52
  return token;
46
53
  }
47
54
 
48
- toString() {
49
- const [flags, ...rules] = this.children;
50
- return `-{${flags.toString()}${flags.childNodes.length ? '|' : ''}${rules.map(String).join(';')}}-`;
55
+ /**
56
+ * @override
57
+ * @param {string} selector
58
+ */
59
+ toString(selector) {
60
+ const {childNodes: [flags, ...rules]} = this;
61
+ return selector && this.matches(selector)
62
+ ? ''
63
+ : `-{${flags.toString(selector)}${flags.childNodes.length > 0 ? '|' : ''}${rules.map(String).join(';')}}-`;
51
64
  }
52
65
 
66
+ /** @override */
53
67
  getPadding() {
54
68
  return 2;
55
69
  }
56
70
 
57
- /** @param {number} i */
71
+ /**
72
+ * /** @override
73
+ * @param {number} i 子节点位置
74
+ */
58
75
  getGaps(i = 0) {
59
76
  i = i < 0 ? i + this.childNodes.length : i;
60
- return i || this.firstElementChild.childNodes.length ? 1 : 0;
77
+ return i || this.firstChild.childNodes.length > 0 ? 1 : 0;
78
+ }
79
+
80
+ /** @override */
81
+ print() {
82
+ const {children: [flags, ...rules]} = this;
83
+ return `<span class="wpb-converter">-{${flags.print()}${
84
+ flags.childNodes.length > 0 ? '|' : ''
85
+ }${print(rules, {sep: ';'})}}-</span>`;
61
86
  }
62
87
 
88
+ /** @override */
63
89
  text() {
64
- const [flags, ...rules] = this.children;
90
+ const {childNodes: [flags, ...rules]} = this;
65
91
  return `-{${flags.text()}|${text(rules, ';')}}-`;
66
92
  }
67
93
 
68
- /** @this {ConverterToken & {firstChild: ConverterFlagsToken}} */
94
+ /**
95
+ * 获取所有转换类型标记
96
+ * @this {{firstChild: ConverterFlagsToken}}
97
+ */
69
98
  getAllFlags() {
70
99
  return this.firstChild.getAllFlags();
71
100
  }
72
101
 
73
- /** @this {ConverterToken & {firstChild: ConverterFlagsToken}} */
102
+ /**
103
+ * 获取有效的转换类型标记
104
+ * @this {{firstChild: ConverterFlagsToken}}
105
+ */
74
106
  getEffectiveFlags() {
75
107
  return this.firstChild.getEffectiveFlags();
76
108
  }
77
109
 
78
- /** @this {ConverterToken & {firstChild: ConverterFlagsToken}} */
110
+ /**
111
+ * 获取未知的转换类型标记
112
+ * @this {{firstChild: ConverterFlagsToken}}
113
+ */
79
114
  getUnknownFlags() {
80
115
  return this.firstChild.getUnknownFlags();
81
116
  }
82
117
 
83
118
  /**
84
- * @this {ConverterToken & {firstChild: ConverterFlagsToken}}
85
- * @param {string} flag
119
+ * 是否具有某转换类型标记
120
+ * @this {{firstChild: ConverterFlagsToken}}
121
+ * @param {string} flag 转换类型标记
86
122
  */
87
123
  hasFlag(flag) {
88
124
  return this.firstChild.hasFlag(flag);
89
125
  }
90
126
 
91
127
  /**
92
- * @this {ConverterToken & {firstChild: ConverterFlagsToken}}
93
- * @param {string} flag
128
+ * 是否具有某有效的转换类型标记
129
+ * @this {{firstChild: ConverterFlagsToken}}
130
+ * @param {string} flag 转换类型标记
94
131
  */
95
132
  hasEffectiveFlag(flag) {
96
133
  return this.firstChild.hasEffectiveFlag(flag);
97
134
  }
98
135
 
99
136
  /**
100
- * @this {ConverterToken & {firstChild: ConverterFlagsToken}}
101
- * @param {string} flag
137
+ * 移除转换类型标记
138
+ * @this {{firstChild: ConverterFlagsToken}}
139
+ * @param {string} flag 转换类型标记
102
140
  */
103
141
  removeFlag(flag) {
104
142
  this.firstChild.removeFlag(flag);
105
143
  }
106
144
 
107
145
  /**
108
- * @this {ConverterToken & {firstChild: ConverterFlagsToken}}
109
- * @param {string} flag
146
+ * 设置转换类型标记
147
+ * @this {{firstChild: ConverterFlagsToken}}
148
+ * @param {string} flag 转换类型标记
110
149
  */
111
150
  setFlag(flag) {
112
151
  this.firstChild.setFlag(flag);
113
152
  }
114
153
 
115
154
  /**
116
- * @this {ConverterToken & {firstChild: ConverterFlagsToken}}
117
- * @param {string} flag
155
+ * 开关某转换类型标记
156
+ * @this {{firstChild: ConverterFlagsToken}}
157
+ * @param {string} flag 转换类型标记
118
158
  */
119
159
  toggleFlag(flag) {
120
160
  this.firstChild.toggleFlag(flag);
121
161
  }
122
-
123
- /** @this {ConverterToken & {children: [ConverterFlagsToken, ConverterRuleToken]}} */
124
- get noConvert() {
125
- return this.childNodes.length < 3 && !this.children[1]?.variant;
126
- }
127
162
  }
128
163
 
129
164
  Parser.classes.ConverterToken = __filename;
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const /** @type {Parser} */ Parser = require('..'),
3
+ const {generateForChild} = require('../util/lint'),
4
+ Parser = require('..'),
4
5
  Token = require('.'),
5
6
  AtomToken = require('./atom');
6
7
 
@@ -13,7 +14,7 @@ class ConverterFlagsToken extends Token {
13
14
  /** @type {string[]} */ #flags;
14
15
 
15
16
  /**
16
- * @param {string[]} flags
17
+ * @param {string[]} flags 转换类型标记
17
18
  * @param {accum} accum
18
19
  */
19
20
  constructor(flags, config = Parser.getConfig(), accum = []) {
@@ -21,30 +22,34 @@ class ConverterFlagsToken extends Token {
21
22
  this.append(...flags.map(flag => new AtomToken(flag, 'converter-flag', config, accum)));
22
23
  }
23
24
 
25
+ /** @override */
24
26
  cloneNode() {
25
- const cloned = this.cloneChildren(),
27
+ const cloned = this.cloneChildNodes(),
26
28
  token = Parser.run(() => new ConverterFlagsToken([], this.getAttribute('config')));
27
29
  token.append(...cloned);
28
30
  token.afterBuild();
29
31
  return token;
30
32
  }
31
33
 
32
- /** @complexity `n` */
34
+ /**
35
+ * @override
36
+ * @complexity `n`
37
+ */
33
38
  afterBuild() {
34
- this.#flags = this.children.map(child => child.text().trim());
35
- const that = this,
36
- /** @type {AstListener} */ converterFlagsListener = ({prevTarget}) => {
37
- if (prevTarget) {
38
- that.#flags[that.childNodes.indexOf(prevTarget)] = prevTarget.text().trim();
39
- }
40
- };
39
+ this.#flags = this.childNodes.map(child => child.text().trim());
40
+ const /** @type {AstListener} */ converterFlagsListener = ({prevTarget}) => {
41
+ if (prevTarget) {
42
+ this.#flags[this.childNodes.indexOf(prevTarget)] = prevTarget.text().trim();
43
+ }
44
+ };
41
45
  this.addEventListener(['remove', 'insert', 'text', 'replace'], converterFlagsListener);
42
46
  return this;
43
47
  }
44
48
 
45
49
  /**
50
+ * @override
46
51
  * @template {string} T
47
- * @param {T} key
52
+ * @param {T} key 属性键
48
53
  * @returns {TokenAttribute<T>}
49
54
  */
50
55
  getAttribute(key) {
@@ -55,7 +60,8 @@ class ConverterFlagsToken extends Token {
55
60
  }
56
61
 
57
62
  /**
58
- * @param {number} i
63
+ * @override
64
+ * @param {number} i 移除位置
59
65
  * @complexity `n`
60
66
  */
61
67
  removeAt(i) {
@@ -65,7 +71,9 @@ class ConverterFlagsToken extends Token {
65
71
  }
66
72
 
67
73
  /**
68
- * @param {AtomToken} token
74
+ * @override
75
+ * @param {AtomToken} token 待插入的子节点
76
+ * @param {number} i 插入位置
69
77
  * @complexity `n`
70
78
  */
71
79
  insertAt(token, i = this.childNodes.length) {
@@ -74,42 +82,92 @@ class ConverterFlagsToken extends Token {
74
82
  return token;
75
83
  }
76
84
 
77
- toString() {
78
- return super.toString(';');
85
+ /**
86
+ * @override
87
+ * @param {string} selector
88
+ */
89
+ toString(selector) {
90
+ return super.toString(selector, ';');
79
91
  }
80
92
 
93
+ /** @override */
81
94
  getGaps() {
82
95
  return 1;
83
96
  }
84
97
 
98
+ /** @override */
99
+ print() {
100
+ return super.print({sep: ';'});
101
+ }
102
+
103
+ /**
104
+ * @override
105
+ * @param {number} start 起始位置
106
+ */
107
+ lint(start = 0) {
108
+ const variantFlags = this.getVariantFlags(),
109
+ unknownFlags = this.getUnknownFlags(),
110
+ emptyFlags = this.#flags.filter(flag => !flag),
111
+ validFlags = this.#flags.filter(flag => ['A', 'T', 'R', 'D', '-', 'H', 'N'].includes(flag)),
112
+ knownFlagCount = this.#flags.length - unknownFlags.length - emptyFlags,
113
+ errors = super.lint(start);
114
+ if (variantFlags.length === knownFlagCount || validFlags.length === knownFlagCount) {
115
+ return errors;
116
+ }
117
+ const rect = this.getRootNode().posFromIndex(start);
118
+ for (const child of this.childNodes) {
119
+ const flag = child.text().trim();
120
+ if (flag && !variantFlags.includes(flag) && !unknownFlags.includes(flag)
121
+ && (variantFlags.length > 0 || !validFlags.includes(flag))
122
+ ) {
123
+ errors.push(generateForChild(child, rect, '无效的转换标记'));
124
+ }
125
+ }
126
+ return errors;
127
+ }
128
+
129
+ /** @override */
85
130
  text() {
86
131
  return super.text(';');
87
132
  }
88
133
 
89
134
  /**
90
- * @param {string} flag
135
+ * 获取转换类型标记节点
136
+ * @param {string} flag 转换类型标记
91
137
  * @returns {AtomToken[]}
92
138
  * @complexity `n`
93
139
  */
94
140
  getFlagToken(flag) {
95
- return this.#flags.includes(flag) ? this.children.filter(child => child.text().trim() === flag) : [];
141
+ return this.#flags.includes(flag) ? this.childNodes.filter(child => child.text().trim() === flag) : [];
96
142
  }
97
143
 
144
+ /** 获取所有转换类型标记 */
98
145
  getAllFlags() {
99
146
  return new Set(this.#flags);
100
147
  }
101
148
 
102
- /** @complexity `n` */
149
+ /**
150
+ * 获取未知转换类型标记
151
+ * @complexity `n`
152
+ */
103
153
  getUnknownFlags() {
104
- return this.#flags.filter(flag => /\{\{[^{}]+\}\}/.test(flag));
154
+ return this.#flags.filter(flag => /\{\{[^{}]+\}\}/u.test(flag));
155
+ }
156
+
157
+ /** 获取指定语言变体的转换标记 */
158
+ getVariantFlags() {
159
+ const {variants} = this.getAttribute('config');
160
+ return this.#flags.filter(flag => variants.includes(flag));
105
161
  }
106
162
 
107
- /** @complexity `n` */
163
+ /**
164
+ * 获取有效转换类型标记
165
+ * @complexity `n`
166
+ */
108
167
  getEffectiveFlags() {
109
- const {variants} = this.getAttribute('config'),
110
- variantFlags = this.#flags.filter(flag => variants.includes(flag)),
168
+ const variantFlags = this.getVariantFlags(),
111
169
  unknownFlags = this.getUnknownFlags();
112
- if (variantFlags.length) {
170
+ if (variantFlags.length > 0) {
113
171
  return new Set([...variantFlags, ...unknownFlags]);
114
172
  }
115
173
  const validFlags = ['A', 'T', 'R', 'D', '-', 'H', 'N'],
@@ -125,10 +183,9 @@ class ConverterFlagsToken extends Token {
125
183
  } else if (flags.has('H')) {
126
184
  const hasT = flags.has('T'),
127
185
  hasD = flags.has('D');
128
- if (hasT && hasD) {
129
- return new Set(['+', 'H', 'T', 'D']);
130
- }
131
- return new Set(['+', 'H', ...hasT ? ['T'] : [], ...hasD ? ['D'] : [], ...unknownFlags]);
186
+ return hasT && hasD
187
+ ? new Set(['+', 'H', 'T', 'D'])
188
+ : new Set(['+', 'H', ...hasT ? ['T'] : [], ...hasD ? ['D'] : [], ...unknownFlags]);
132
189
  }
133
190
  if (flags.size === 1 && flags.has('T')) {
134
191
  flags.add('H');
@@ -143,27 +200,26 @@ class ConverterFlagsToken extends Token {
143
200
  return flags;
144
201
  }
145
202
 
146
- /** @param {string} flag */
203
+ /**
204
+ * 是否具有某转换类型标记
205
+ * @param {string} flag 转换类型标记
206
+ */
147
207
  hasFlag(flag) {
148
- if (typeof flag !== 'string') {
149
- this.typeError('hasFlag', 'String');
150
- }
151
- return this.#flags.includes(flag);
208
+ return typeof flag === 'string' ? this.#flags.includes(flag) : this.typeError('hasFlag', 'String');
152
209
  }
153
210
 
154
211
  /**
155
- * @param {string} flag
212
+ * 是否具有某有效转换类型标记
213
+ * @param {string} flag 转换类型标记
156
214
  * @complexity `n`
157
215
  */
158
216
  hasEffectiveFlag(flag) {
159
- if (typeof flag !== 'string') {
160
- this.typeError('hasFlag', 'String');
161
- }
162
- return this.getEffectiveFlags().has(flag);
217
+ return typeof flag === 'string' ? this.getEffectiveFlags().has(flag) : this.typeError('hasFlag', 'String');
163
218
  }
164
219
 
165
220
  /**
166
- * @param {string} flag
221
+ * 移除某转换类型标记
222
+ * @param {string} flag 转换类型标记
167
223
  * @complexity `n²`
168
224
  */
169
225
  removeFlag(flag) {
@@ -173,7 +229,8 @@ class ConverterFlagsToken extends Token {
173
229
  }
174
230
 
175
231
  /**
176
- * @param {string} flag
232
+ * 添加转换类型标记
233
+ * @param {string} flag 转换类型标记
177
234
  * @complexity `n`
178
235
  */
179
236
  #newFlag(flag) {
@@ -182,7 +239,8 @@ class ConverterFlagsToken extends Token {
182
239
  }
183
240
 
184
241
  /**
185
- * @param {string} flag
242
+ * 设置转换类型标记
243
+ * @param {string} flag 转换类型标记
186
244
  * @complexity `n`
187
245
  */
188
246
  setFlag(flag) {
@@ -194,14 +252,15 @@ class ConverterFlagsToken extends Token {
194
252
  }
195
253
 
196
254
  /**
197
- * @param {string} flag
255
+ * 开关转换类型标记
256
+ * @param {string} flag 转换类型标记
198
257
  * @complexity `n²`
199
258
  */
200
259
  toggleFlag(flag) {
201
- if (!this.#flags.includes(flag)) {
202
- this.#newFlag(flag);
203
- } else {
260
+ if (this.#flags.includes(flag)) {
204
261
  this.removeFlag(flag);
262
+ } else {
263
+ this.#newFlag(flag);
205
264
  }
206
265
  }
207
266
  }