wikiparser-node 0.11.0-m → 0.11.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 (141) hide show
  1. package/config/.schema.json +7 -0
  2. package/config/default.json +1 -0
  3. package/config/llwiki.json +35 -0
  4. package/config/moegirl.json +44 -0
  5. package/config/zhwiki.json +466 -0
  6. package/dist/index.d.ts +4 -0
  7. package/dist/lib/element.d.ts +116 -2
  8. package/dist/lib/node.d.ts +193 -10
  9. package/dist/lib/ranges.d.ts +37 -0
  10. package/dist/lib/text.d.ts +35 -1
  11. package/dist/lib/title.d.ts +6 -0
  12. package/dist/mixin/attributeParent.d.ts +9 -0
  13. package/dist/mixin/fixedToken.d.ts +8 -0
  14. package/dist/mixin/singleLine.d.ts +8 -0
  15. package/dist/mixin/sol.d.ts +8 -0
  16. package/dist/parser/selector.d.ts +12 -0
  17. package/dist/src/arg.d.ts +30 -1
  18. package/dist/src/atom/index.d.ts +2 -1
  19. package/dist/src/attribute.d.ts +24 -1
  20. package/dist/src/attributes.d.ts +79 -0
  21. package/dist/src/charinsert.d.ts +32 -0
  22. package/dist/src/converter.d.ts +75 -1
  23. package/dist/src/converterFlags.d.ts +57 -1
  24. package/dist/src/converterRule.d.ts +47 -1
  25. package/dist/src/extLink.d.ts +41 -1
  26. package/dist/src/gallery.d.ts +15 -1
  27. package/dist/src/heading.d.ts +22 -2
  28. package/dist/src/html.d.ts +25 -2
  29. package/dist/src/imageParameter.d.ts +43 -1
  30. package/dist/src/imagemap.d.ts +12 -1
  31. package/dist/src/imagemapLink.d.ts +5 -0
  32. package/dist/src/index.d.ts +136 -3
  33. package/dist/src/link/category.d.ts +8 -0
  34. package/dist/src/link/file.d.ts +58 -0
  35. package/dist/src/link/index.d.ts +61 -2
  36. package/dist/src/magicLink.d.ts +22 -0
  37. package/dist/src/nested/index.d.ts +3 -5
  38. package/dist/src/nowiki/comment.d.ts +13 -1
  39. package/dist/src/nowiki/dd.d.ts +9 -0
  40. package/dist/src/nowiki/doubleUnderscore.d.ts +11 -1
  41. package/dist/src/nowiki/index.d.ts +11 -2
  42. package/dist/src/nowiki/quote.d.ts +0 -7
  43. package/dist/src/onlyinclude.d.ts +8 -1
  44. package/dist/src/paramTag/index.d.ts +8 -3
  45. package/dist/src/parameter.d.ts +48 -1
  46. package/dist/src/syntax.d.ts +6 -1
  47. package/dist/src/table/index.d.ts +257 -0
  48. package/dist/src/table/td.d.ts +67 -6
  49. package/dist/src/table/tr.d.ts +74 -0
  50. package/dist/src/tagPair/ext.d.ts +2 -1
  51. package/dist/src/tagPair/include.d.ts +9 -0
  52. package/dist/src/tagPair/index.d.ts +14 -1
  53. package/dist/src/transclude.d.ts +125 -1
  54. package/dist/tool/index.d.ts +420 -0
  55. package/dist/util/base.d.ts +10 -0
  56. package/dist/util/debug.d.ts +20 -0
  57. package/dist/util/diff.d.ts +8 -0
  58. package/dist/util/string.d.ts +24 -0
  59. package/index.js +256 -4
  60. package/lib/element.js +488 -6
  61. package/lib/node.js +495 -6
  62. package/lib/ranges.js +130 -0
  63. package/lib/text.js +96 -1
  64. package/lib/title.js +28 -1
  65. package/mixin/attributeParent.js +117 -0
  66. package/mixin/fixedToken.js +40 -0
  67. package/mixin/hidden.js +3 -0
  68. package/mixin/singleLine.js +31 -0
  69. package/mixin/sol.js +54 -0
  70. package/package.json +5 -2
  71. package/parser/brackets.js +1 -0
  72. package/parser/commentAndExt.js +1 -0
  73. package/parser/converter.js +1 -0
  74. package/parser/externalLinks.js +1 -0
  75. package/parser/hrAndDoubleUnderscore.js +1 -0
  76. package/parser/html.js +1 -0
  77. package/parser/links.js +5 -4
  78. package/parser/list.js +1 -0
  79. package/parser/magicLinks.js +1 -0
  80. package/parser/quotes.js +1 -0
  81. package/parser/selector.js +180 -0
  82. package/parser/table.js +1 -0
  83. package/src/arg.js +116 -2
  84. package/src/atom/hidden.js +2 -0
  85. package/src/atom/index.js +17 -0
  86. package/src/attribute.js +189 -3
  87. package/src/attributes.js +307 -4
  88. package/src/charinsert.js +97 -0
  89. package/src/converter.js +108 -2
  90. package/src/converterFlags.js +187 -0
  91. package/src/converterRule.js +183 -1
  92. package/src/extLink.js +121 -1
  93. package/src/gallery.js +54 -0
  94. package/src/hasNowiki/index.js +12 -0
  95. package/src/hasNowiki/pre.js +12 -0
  96. package/src/heading.js +54 -3
  97. package/src/html.js +118 -3
  98. package/src/imageParameter.js +164 -2
  99. package/src/imagemap.js +61 -2
  100. package/src/imagemapLink.js +13 -1
  101. package/src/index.js +530 -3
  102. package/src/link/category.js +32 -1
  103. package/src/link/file.js +157 -2
  104. package/src/link/galleryImage.js +60 -2
  105. package/src/link/index.js +270 -1
  106. package/src/magicLink.js +83 -0
  107. package/src/nested/choose.js +1 -0
  108. package/src/nested/combobox.js +1 -0
  109. package/src/nested/index.js +27 -0
  110. package/src/nested/references.js +1 -0
  111. package/src/nowiki/comment.js +25 -1
  112. package/src/nowiki/dd.js +47 -1
  113. package/src/nowiki/doubleUnderscore.js +31 -1
  114. package/src/nowiki/hr.js +20 -1
  115. package/src/nowiki/index.js +23 -1
  116. package/src/nowiki/list.js +5 -2
  117. package/src/nowiki/noinclude.js +14 -0
  118. package/src/nowiki/quote.js +14 -0
  119. package/src/onlyinclude.js +26 -1
  120. package/src/paramTag/index.js +24 -1
  121. package/src/paramTag/inputbox.js +4 -1
  122. package/src/parameter.js +147 -5
  123. package/src/syntax.js +68 -0
  124. package/src/table/index.js +941 -2
  125. package/src/table/td.js +230 -5
  126. package/src/table/tr.js +247 -2
  127. package/src/tagPair/ext.js +21 -1
  128. package/src/tagPair/include.js +24 -0
  129. package/src/tagPair/index.js +56 -2
  130. package/src/transclude.js +512 -5
  131. package/tool/index.js +1209 -0
  132. package/typings/array.d.ts +29 -0
  133. package/typings/event.d.ts +22 -0
  134. package/typings/index.d.ts +67 -0
  135. package/typings/node.d.ts +19 -0
  136. package/typings/parser.d.ts +7 -0
  137. package/typings/table.d.ts +10 -0
  138. package/typings/token.d.ts +3 -0
  139. package/typings/tool.d.ts +6 -0
  140. package/util/debug.js +73 -0
  141. package/util/string.js +51 -0
package/index.js CHANGED
@@ -1,11 +1,127 @@
1
1
  'use strict';
2
2
 
3
+ const fs = require('fs'),
4
+ path = require('path');
5
+
3
6
  const /** @type {import('./typings')} */ Parser = {
4
7
  config: './config/default',
5
8
  i18n: undefined,
6
9
 
7
10
  MAX_STAGE: 11,
8
11
 
12
+ warning: true,
13
+ debugging: false,
14
+ running: false,
15
+
16
+ classes: {},
17
+ mixins: {},
18
+ parsers: {},
19
+ tool: {},
20
+
21
+ aliases: [
22
+ ['AstText'],
23
+ ['CommentToken', 'ExtToken', 'IncludeToken', 'NoincludeToken'],
24
+ ['ArgToken', 'TranscludeToken', 'HeadingToken'],
25
+ ['HtmlToken'],
26
+ ['TableToken'],
27
+ ['HrToken', 'DoubleUnderscoreToken'],
28
+ ['LinkToken', 'FileToken', 'CategoryToken'],
29
+ ['QuoteToken'],
30
+ ['ExtLinkToken'],
31
+ ['MagicLinkToken'],
32
+ ['ListToken', 'DdToken'],
33
+ ['ConverterToken'],
34
+ ],
35
+ typeAliases: {
36
+ text: ['string', 'str'],
37
+ plain: ['regular', 'normal'],
38
+ // comment and extension
39
+ onlyinclude: ['only-include'],
40
+ noinclude: ['no-include'],
41
+ include: ['includeonly', 'include-only'],
42
+ comment: undefined,
43
+ ext: ['extension'],
44
+ 'ext-attrs': ['extension-attrs', 'ext-attributes', 'extension-attributes'],
45
+ 'ext-attr-dirty': ['extension-attr-dirty', 'ext-attribute-dirty', 'extension-attribute-dirty'],
46
+ 'ext-attr': ['extension-attr', 'ext-attribute', 'extension-attribute'],
47
+ 'attr-key': ['attribute-key'],
48
+ 'attr-value': ['attribute-value', 'attr-val', 'attribute-val'],
49
+ 'ext-inner': ['extension-inner'],
50
+ // triple brackets
51
+ arg: ['argument'],
52
+ 'arg-name': ['argument-name'],
53
+ 'arg-default': ['argument-default'],
54
+ hidden: ['arg-redundant'],
55
+ // double brackets
56
+ 'magic-word': ['parser-function', 'parser-func'],
57
+ 'magic-word-name': ['parser-function-name', 'parser-func-name'],
58
+ 'invoke-function': ['invoke-func', 'lua-function', 'lua-func', 'module-function', 'module-func'],
59
+ 'invoke-module': ['lua-module'],
60
+ template: undefined,
61
+ 'template-name': undefined,
62
+ parameter: ['param'],
63
+ 'parameter-key': ['param-key'],
64
+ 'parameter-value': ['parameter-val', 'param-value', 'param-val'],
65
+ // heading
66
+ heading: ['header'],
67
+ 'heading-title': ['header-title'],
68
+ 'heading-trail': ['header-trail'],
69
+ // html
70
+ html: undefined,
71
+ 'html-attrs': ['html-attributes'],
72
+ 'html-attr-dirty': ['html-attribute-dirty'],
73
+ 'html-attr': ['html-attribute'],
74
+ // table
75
+ table: undefined,
76
+ tr: ['table-row'],
77
+ td: ['table-cell', 'table-data'],
78
+ 'table-syntax': undefined,
79
+ 'table-attrs': ['tr-attrs', 'td-attrs', 'table-attributes', 'tr-attributes', 'td-attributes'],
80
+ 'table-attr-dirty':
81
+ ['tr-attr-dirty', 'td-attr-dirty', 'table-attribute-dirty', 'tr-attribute-dirty', 'td-attribute-dirty'],
82
+ 'table-attr': ['tr-attr', 'td-attr', 'table-attribute', 'tr-attribute', 'td-attribute'],
83
+ 'table-inter': undefined,
84
+ 'td-inner': ['table-cell-inner', 'table-data-inner'],
85
+ // hr and double-underscore
86
+ hr: ['horizontal'],
87
+ 'double-underscore': ['underscore', 'behavior-switch', 'behaviour-switch'],
88
+ // link
89
+ link: ['wikilink'],
90
+ 'link-target': ['wikilink-target'],
91
+ 'link-text': ['wikilink-text'],
92
+ category: ['category-link', 'cat', 'cat-link'],
93
+ file: ['file-link', 'image', 'image-link', 'img', 'img-link'],
94
+ 'gallery-image': ['gallery-file', 'gallery-img'],
95
+ 'imagemap-image': ['imagemap-file', 'imagemap-img', 'image-map-image', 'image-map-file', 'image-map-img'],
96
+ 'image-parameter': ['img-parameter', 'image-param', 'img-param'],
97
+ // quotes
98
+ quote: ['quotes', 'quot', 'apostrophe', 'apostrophes', 'apos'],
99
+ // external link
100
+ 'ext-link': ['external-link'],
101
+ 'ext-link-text': ['external-link-text'],
102
+ 'ext-link-url': ['external-link-url'],
103
+ // magic link
104
+ 'free-ext-link': ['free-external-link', 'magic-link'],
105
+ // list
106
+ list: ['ol', 'ordered-list', 'ul', 'unordered-list', 'dl', 'description-list'],
107
+ dd: ['indent', 'indentation'],
108
+ // converter
109
+ converter: ['convert', 'conversion'],
110
+ 'converter-flags': ['convert-flags', 'conversion-flags'],
111
+ 'converter-flag': ['convert-flag', 'conversion-flag'],
112
+ 'converter-rule': ['convert-rule', 'conversion-rule'],
113
+ 'converter-rule-noconvert': ['convert-rule-noconvert', 'conversion-rule-noconvert'],
114
+ 'converter-rule-variant': ['convert-rule-variant', 'conversion-rule-variant'],
115
+ 'converter-rule-to': ['convert-rule-to', 'conversion-rule-to'],
116
+ 'converter-rule-from': ['convert-rule-from', 'conversion-rule-from'],
117
+ // specific extensions
118
+ 'param-line': ['parameter-line'],
119
+ 'charinsert-line': undefined,
120
+ 'imagemap-link': ['image-map-link'],
121
+ },
122
+
123
+ promises: [Promise.resolve()],
124
+
9
125
  getConfig() {
10
126
  if (typeof this.config === 'string') {
11
127
  this.config = require(this.config);
@@ -43,6 +159,22 @@ const /** @type {import('./typings')} */ Parser = {
43
159
  }
44
160
  const Title = require('./lib/title');
45
161
  const titleObj = new Title(String(title), defaultNs, config, decode, selfLink);
162
+ if (token) {
163
+ /**
164
+ * 重建部分属性值
165
+ * @param {string[]} keys 属性键
166
+ */
167
+ const build = keys => {
168
+ for (const key of keys) {
169
+ if (titleObj[key]?.includes('\0')) {
170
+ titleObj[key] = token.getAttribute('buildFromStr')(titleObj[key], 'text');
171
+ }
172
+ }
173
+ };
174
+ this.run(() => {
175
+ build(['title', 'main', 'fragment']);
176
+ });
177
+ }
46
178
  return titleObj;
47
179
  },
48
180
 
@@ -56,19 +188,139 @@ const /** @type {import('./typings')} */ Parser = {
56
188
  token = new Token(wikitext, config);
57
189
  try {
58
190
  token.parse(maxStage, include);
59
- } catch {}
191
+ } catch (e) {
192
+ if (e instanceof Error) {
193
+ const file = path.join(__dirname, 'errors', new Date().toISOString()),
194
+ stage = token.getAttribute('stage');
195
+ fs.writeFileSync(file, stage === this.MAX_STAGE ? wikitext : String(token));
196
+ fs.writeFileSync(`${file}.err`, e.stack);
197
+ fs.writeFileSync(`${file}.json`, JSON.stringify({
198
+ stage, include: token.getAttribute('include'), config: this.config,
199
+ }, null, '\t'));
200
+ }
201
+ throw e;
202
+ }
60
203
  });
204
+ if (this.debugging) {
205
+ let restored = String(token),
206
+ process = '解析';
207
+ if (restored === wikitext) {
208
+ const entities = {lt: '<', gt: '>', amp: '&'};
209
+ restored = token.print().replace(
210
+ /<[^<]+?>|&([lg]t|amp);/gu,
211
+ /** @param {string} s */ (_, s) => s ? entities[s] : '',
212
+ );
213
+ process = '渲染HTML';
214
+ }
215
+ if (restored !== wikitext) {
216
+ const diff = require('./util/diff');
217
+ const {promises: {0: cur, length}} = this;
218
+ this.promises.unshift((async () => {
219
+ await cur;
220
+ this.error(`${process}过程中不可逆地修改了原始文本!`);
221
+ return diff(wikitext, restored, length);
222
+ })());
223
+ }
224
+ }
61
225
  return token;
62
226
  },
63
227
 
64
228
  run(callback) {
65
- return callback();
229
+ const {running} = this;
230
+ this.running = true;
231
+ try {
232
+ const result = callback();
233
+ this.running = running;
234
+ return result;
235
+ } catch (e) {
236
+ this.running = running;
237
+ throw e;
238
+ }
239
+ },
240
+
241
+ warn(msg, ...args) {
242
+ if (this.warning) {
243
+ console.warn('\x1B[33m%s\x1B[0m', msg, ...args);
244
+ }
245
+ },
246
+ debug(msg, ...args) {
247
+ if (this.debugging) {
248
+ console.debug('\x1B[34m%s\x1B[0m', msg, ...args);
249
+ }
250
+ },
251
+ error(msg, ...args) {
252
+ console.error('\x1B[31m%s\x1B[0m', msg, ...args);
253
+ },
254
+ info(msg, ...args) {
255
+ console.info('\x1B[32m%s\x1B[0m', msg, ...args);
256
+ },
257
+
258
+ log(f) {
259
+ if (typeof f === 'function') {
260
+ console.log(String(f));
261
+ }
262
+ },
263
+
264
+ clearCache() {
265
+ const entries = [
266
+ ...Object.entries(this.classes),
267
+ ...Object.entries(this.mixins),
268
+ ...Object.entries(this.parsers),
269
+ ...Object.entries(this.tool),
270
+ ];
271
+ for (const [, filePath] of entries) {
272
+ try {
273
+ delete require.cache[require.resolve(filePath)];
274
+ } catch {}
275
+ }
276
+ for (const [name, filePath] of entries) {
277
+ if (name in global) {
278
+ global[name] = require(filePath);
279
+ }
280
+ }
281
+ },
282
+
283
+ isInterwiki(title, {interwiki} = Parser.getConfig()) {
284
+ title = String(title);
285
+ return new RegExp(`^(${interwiki.join('|')})\\s*:`, 'iu')
286
+ .exec(title.replaceAll('_', ' ').replace(/^\s*:?\s*/u, ''));
287
+ },
288
+
289
+ reparse(date) {
290
+ const main = fs.readdirSync(path.join(__dirname, 'errors'))
291
+ .find(name => name.startsWith(date) && name.endsWith('Z'));
292
+ if (!main) {
293
+ throw new RangeError(`找不到对应时间戳的错误记录:${date}`);
294
+ }
295
+ const file = path.join(__dirname, 'errors', main),
296
+ wikitext = fs.readFileSync(file, 'utf8');
297
+ const {stage, include, config} = require(`${file}.json`),
298
+ Token = require('./src');
299
+ this.config = config;
300
+ return this.run(() => {
301
+ const halfParsed = stage < this.MAX_STAGE,
302
+ token = new Token(wikitext, this.getConfig(), halfParsed);
303
+ if (halfParsed) {
304
+ token.setAttribute('stage', stage).getAttribute('parseOnce')(stage, include);
305
+ } else {
306
+ token.parse(undefined, include);
307
+ }
308
+ fs.unlinkSync(file);
309
+ fs.unlinkSync(`${file}.err`);
310
+ fs.unlinkSync(`${file}.json`);
311
+ return token;
312
+ });
313
+ },
314
+
315
+ getTool() {
316
+ delete require.cache[require.resolve('./tool')];
317
+ return require('./tool');
66
318
  },
67
319
  };
68
320
 
69
321
  const /** @type {PropertyDescriptorMap} */ def = {},
70
- immutable = new Set(['MAX_STAGE']),
71
- enumerable = new Set(['config', 'normalizeTitle', 'parse']);
322
+ immutable = new Set(['MAX_STAGE', 'aliases', 'typeAliases', 'promises']),
323
+ enumerable = new Set(['config', 'normalizeTitle', 'parse', 'isInterwiki', 'getTool']);
72
324
  for (const key in Parser) {
73
325
  if (immutable.has(key)) {
74
326
  def[key] = {enumerable: false, writable: false};