wikiparser-node 0.8.0-b → 0.8.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 (87) hide show
  1. package/README.md +39 -0
  2. package/config/default.json +832 -0
  3. package/config/llwiki.json +630 -0
  4. package/config/moegirl.json +728 -0
  5. package/config/zhwiki.json +1269 -0
  6. package/index.js +321 -0
  7. package/lib/element.js +611 -0
  8. package/lib/node.js +772 -0
  9. package/lib/ranges.js +130 -0
  10. package/lib/text.js +215 -0
  11. package/lib/title.js +81 -0
  12. package/mixin/attributeParent.js +117 -0
  13. package/mixin/fixedToken.js +40 -0
  14. package/mixin/hidden.js +21 -0
  15. package/mixin/singleLine.js +31 -0
  16. package/mixin/sol.js +65 -0
  17. package/package.json +11 -12
  18. package/parser/brackets.js +120 -0
  19. package/parser/commentAndExt.js +62 -0
  20. package/parser/converter.js +46 -0
  21. package/parser/externalLinks.js +33 -0
  22. package/parser/hrAndDoubleUnderscore.js +38 -0
  23. package/parser/html.js +42 -0
  24. package/parser/links.js +94 -0
  25. package/parser/list.js +59 -0
  26. package/parser/magicLinks.js +41 -0
  27. package/parser/quotes.js +64 -0
  28. package/parser/selector.js +177 -0
  29. package/parser/table.js +114 -0
  30. package/src/arg.js +203 -0
  31. package/src/atom/hidden.js +13 -0
  32. package/src/atom/index.js +43 -0
  33. package/src/attribute.js +454 -0
  34. package/src/attributes.js +454 -0
  35. package/src/charinsert.js +97 -0
  36. package/src/converter.js +176 -0
  37. package/src/converterFlags.js +284 -0
  38. package/src/converterRule.js +258 -0
  39. package/src/extLink.js +179 -0
  40. package/src/gallery.js +152 -0
  41. package/src/hasNowiki/index.js +44 -0
  42. package/src/hasNowiki/pre.js +40 -0
  43. package/src/heading.js +134 -0
  44. package/src/html.js +248 -0
  45. package/src/imageParameter.js +277 -0
  46. package/src/imagemap.js +199 -0
  47. package/src/imagemapLink.js +41 -0
  48. package/src/index.js +933 -0
  49. package/src/link/category.js +49 -0
  50. package/src/link/file.js +282 -0
  51. package/src/link/galleryImage.js +120 -0
  52. package/src/link/index.js +383 -0
  53. package/src/magicLink.js +149 -0
  54. package/src/nested/choose.js +24 -0
  55. package/src/nested/combobox.js +23 -0
  56. package/src/nested/index.js +96 -0
  57. package/src/nested/references.js +23 -0
  58. package/src/nowiki/comment.js +71 -0
  59. package/src/nowiki/dd.js +59 -0
  60. package/src/nowiki/doubleUnderscore.js +56 -0
  61. package/src/nowiki/hr.js +41 -0
  62. package/src/nowiki/index.js +56 -0
  63. package/src/nowiki/list.js +16 -0
  64. package/src/nowiki/noinclude.js +28 -0
  65. package/src/nowiki/quote.js +69 -0
  66. package/src/onlyinclude.js +64 -0
  67. package/src/paramTag/index.js +89 -0
  68. package/src/paramTag/inputbox.js +35 -0
  69. package/src/parameter.js +239 -0
  70. package/src/syntax.js +91 -0
  71. package/src/table/index.js +984 -0
  72. package/src/table/td.js +339 -0
  73. package/src/table/tr.js +319 -0
  74. package/src/tagPair/ext.js +142 -0
  75. package/src/tagPair/include.js +50 -0
  76. package/src/tagPair/index.js +126 -0
  77. package/src/transclude.js +824 -0
  78. package/tool/index.js +1202 -0
  79. package/util/base.js +17 -0
  80. package/util/debug.js +73 -0
  81. package/util/diff.js +76 -0
  82. package/util/lint.js +54 -0
  83. package/util/string.js +107 -0
  84. package/bundle/bundle.min.js +0 -38
  85. package/extensions/editor.css +0 -60
  86. package/extensions/editor.js +0 -317
  87. package/extensions/ui.css +0 -119
@@ -1,317 +0,0 @@
1
- 'use strict';
2
-
3
- (() => {
4
- const MAX_STAGE = 11;
5
-
6
- /** web worker */
7
- const workerJS = () => {
8
- self.importScripts('https://fastly.jsdelivr.net/gh/bhsd-harry/wikiparser-node@0.7.4-b/bundle/bundle.min.js');
9
- const /** @type {{Parser: Parser}} */ {Parser} = self,
10
- entities = {'&': 'amp', '<': 'lt', '>': 'gt'};
11
-
12
- /**
13
- * @param {{data: ['setConfig', ParserConfig]|['getConfig'|'print'|'lint', number, string, Boolean, number]}}
14
- */
15
- self.onmessage = ({data}) => {
16
- const [command, qid, ...args] = data;
17
- switch (command) {
18
- case 'setConfig':
19
- Parser.config = qid;
20
- break;
21
- case 'getConfig':
22
- self.postMessage([qid, Parser.minConfig]);
23
- break;
24
- case 'lint':
25
- self.postMessage([qid, Parser.parse(...args).lint(), args[0]]);
26
- break;
27
- default: {
28
- const stage = args[2] === undefined ? MAX_STAGE : args[2];
29
- self.postMessage([
30
- qid,
31
- Parser.parse(...args).childNodes.map(child => [
32
- stage,
33
- String(child),
34
- child.type === 'text'
35
- ? String(child).replace(/[&<>]/gu, p => `&${entities[p]};`)
36
- : child.print(),
37
- ]),
38
- ]);
39
- }
40
- }
41
- };
42
- };
43
-
44
- const blob = new Blob([`(${String(workerJS).replace(/MAX_STAGE/gu, MAX_STAGE)})()`], {type: 'text/javascript'}),
45
- url = URL.createObjectURL(blob),
46
- worker = new Worker(url);
47
- URL.revokeObjectURL(url);
48
-
49
- /**
50
- * 生成事件监听函数
51
- * @param {number} qid 输入id
52
- * @param {(res: *) => void} resolve Promise对象的resolve函数
53
- * @param {string} raw 原始文本
54
- */
55
- const getListener = (qid, resolve, raw) => {
56
- const listener = /** @param {{data: [number, *, string]}} e 消息事件 */ ({data: [rid, res, resRaw]}) => {
57
- if (rid === qid && (raw === undefined || raw === resRaw)) {
58
- worker.removeEventListener('message', listener);
59
- resolve(res);
60
- }
61
- };
62
- return listener;
63
- };
64
-
65
- /**
66
- * 更新解析设置
67
- * @param {ParserConfig} config 设置
68
- */
69
- const setConfig = config => {
70
- worker.postMessage(['setConfig', config]);
71
- };
72
-
73
- /**
74
- * 获取Parser.minConfig
75
- * @returns {Promise<ParserConfig>}
76
- */
77
- const getConfig = () => new Promise(resolve => {
78
- worker.addEventListener('message', getListener(-3, resolve));
79
- worker.postMessage(['getConfig', -3]);
80
- });
81
-
82
- /**
83
- * 将解析改为异步执行
84
- * @param {string} wikitext wikitext
85
- * @param {boolean} include 是否嵌入
86
- * @param {number} stage 解析层级
87
- * @param {number} qid Printer编号
88
- * @returns {Promise<[number, string, string][]>}
89
- */
90
- const print = (wikitext, include, stage, qid = -1) => new Promise(resolve => {
91
- worker.addEventListener('message', getListener(qid, resolve));
92
- worker.postMessage(['print', qid, wikitext, include, stage]);
93
- });
94
-
95
- /**
96
- * 将语法分析改为异步执行
97
- * @param {string} wikitext wikitext
98
- * @param {boolean} include 是否嵌入
99
- * @param {number} qid Linter编号,暂时固定为`-2`
100
- * @returns {Promise<LintError[]>}
101
- */
102
- const lint = (wikitext, include, qid = -2) => new Promise(resolve => {
103
- worker.addEventListener('message', getListener(qid, resolve, wikitext));
104
- worker.postMessage(['lint', qid, wikitext, include]);
105
- });
106
-
107
- let id = 0;
108
-
109
- /** 用于打印AST */
110
- class Printer {
111
- /**
112
- * @param {HTMLDivElement} preview 置于下层的代码高亮
113
- * @param {HTMLTextAreaElement} textbox 置于上层的文本框
114
- * @param {boolean} include 是否嵌入
115
- */
116
- constructor(preview, textbox, include) {
117
- this.id = id++;
118
- this.preview = preview;
119
- this.textbox = textbox;
120
- this.include = Boolean(include);
121
- /** @type {[number, string, string][]} */ this.root = [];
122
- /** @type {Promise<void>} */ this.running = undefined;
123
- this.viewportChanged = false;
124
- /** @type {[number, string]} */ this.ticks = [0, undefined];
125
- }
126
-
127
- /** 倒计时 */
128
- tick() {
129
- setTimeout(() => {
130
- const {ticks} = this;
131
- if (ticks[0] > 0) {
132
- ticks[0] -= 500;
133
- this[ticks[0] <= 0 ? ticks[1] : 'tick']();
134
- }
135
- }, 500);
136
- }
137
-
138
- /**
139
- * 用于debounce
140
- * @param {number} delay 延迟
141
- * @param {string} method 方法
142
- */
143
- queue(delay, method) {
144
- const {ticks} = this,
145
- [state] = ticks;
146
- if (state <= 0 || method === 'coarsePrint' || ticks[1] !== 'coarsePrint') {
147
- ticks[0] = delay;
148
- ticks[1] = method;
149
- if (state <= 0) {
150
- this.tick();
151
- }
152
- }
153
- }
154
-
155
- /** 渲染 */
156
- paint() {
157
- this.preview.innerHTML = `<span class="wpb-root">${
158
- this.root.map(([,, printed]) => printed).join('')
159
- }</span> `;
160
- this.preview.scrollTop = this.textbox.scrollTop;
161
- this.preview.classList.remove('active');
162
- this.textbox.style.color = 'transparent';
163
- }
164
-
165
- /** 初步解析 */
166
- async coarsePrint() {
167
- if (this.running) {
168
- return undefined;
169
- }
170
- const {include, textbox: {value}} = this,
171
- parsed = await print(value, include, 2, this.id);
172
- if (this.include !== include || this.textbox.value !== value) {
173
- this.running = undefined;
174
- this.running = this.coarsePrint();
175
- return this.running;
176
- }
177
- this.root = parsed;
178
- this.paint();
179
- this.running = undefined;
180
- this.running = this.finePrint();
181
- return this.running;
182
- }
183
-
184
- /** 根据可见范围精细解析 */
185
- async finePrint() {
186
- if (this.running) {
187
- this.viewportChanged = true;
188
- return undefined;
189
- }
190
- this.viewportChanged = false;
191
- const {
192
- root,
193
- preview: {scrollHeight, offsetHeight: parentHeight, scrollTop, children: [rootNode]},
194
- include,
195
- textbox: {value},
196
- } = this;
197
- let text = value,
198
- start = 0,
199
- {length: end} = root;
200
- if (scrollHeight > parentHeight) {
201
- const /** @type {HTMLElement[]} */ childNodes = [...rootNode.childNodes],
202
- headings = childNodes.filter(({className}) => className === 'wpb-heading'),
203
- {length} = headings;
204
- if (length > 0) {
205
- let i = headings.findIndex(({offsetTop, offsetHeight}) => offsetTop + offsetHeight > scrollTop);
206
- i = i === -1 ? length : i;
207
- let j = headings.slice(i).findIndex(({offsetTop}) => offsetTop >= scrollTop + parentHeight);
208
- j = j === -1 ? length : i + j;
209
- start = i ? childNodes.indexOf(headings[i - 1]) : 0;
210
- while (i <= j && root[start][0] === MAX_STAGE) {
211
- start = childNodes.indexOf(headings[i++]);
212
- }
213
- end = j === length ? end : childNodes.indexOf(headings[j]);
214
- while (i <= j && root[end - 1][0] === MAX_STAGE) {
215
- end = childNodes.indexOf(headings[--j]);
216
- }
217
- text = root.slice(start, end).map(([, str]) => str).join('');
218
- }
219
- }
220
- if (start === end) {
221
- this.running = undefined;
222
- return undefined;
223
- }
224
- const parsed = await print(text, include, MAX_STAGE, this.id);
225
- if (this.include === include && this.textbox.value === value) {
226
- this.root.splice(start, end - start, ...parsed);
227
- this.paint();
228
- this.running = undefined;
229
- if (this.viewportChanged) {
230
- this.running = this.finePrint();
231
- }
232
- } else {
233
- this.running = undefined;
234
- this.running = this.coarsePrint();
235
- }
236
- return this.running;
237
- }
238
- }
239
-
240
- /** 用于语法分析 */
241
- class Linter {
242
- /** @param {boolean} include 是否嵌入 */
243
- constructor(include) {
244
- this.id = id++;
245
- this.include = Boolean(include);
246
- this.wikitext = undefined;
247
- /** @type {Promise<LintError[]>} */ this.running = undefined;
248
- }
249
-
250
- /**
251
- * 提交语法分析
252
- * @param {string} wikitext 待分析的文本
253
- */
254
- queue(wikitext) {
255
- this.wikitext = wikitext;
256
- this.running = this.lint(wikitext);
257
- return this.running;
258
- }
259
-
260
- /**
261
- * 执行语法分析
262
- * @param {string} wikitext 待分析的文本
263
- */
264
- async lint(wikitext) {
265
- const {include} = this,
266
- errors = await lint(wikitext, include, this.id);
267
- return this.include === include && this.wikitext === wikitext ? errors : this.running;
268
- }
269
- }
270
-
271
- /**
272
- * 高亮textarea
273
- * @param {HTMLTextAreaElement} textbox textarea元素
274
- * @param {boolean} include 是否嵌入
275
- * @throws `TypeError` 不是textarea
276
- */
277
- const wikiparse = (textbox, include) => {
278
- if (!(textbox instanceof HTMLTextAreaElement)) {
279
- throw new TypeError('wikiparse方法仅可用于textarea元素!');
280
- }
281
- const preview = document.createElement('div'),
282
- container = document.createElement('div'),
283
- printer = new Printer(preview, textbox, include);
284
- preview.id = 'wikiPretty';
285
- preview.classList.add('wikiparser', 'active');
286
- container.classList.add('wikiparse-container');
287
- textbox.replaceWith(container);
288
- textbox.classList.add('wikiparsed');
289
- container.append(preview, textbox);
290
-
291
- textbox.addEventListener('input', ({isComposing}) => {
292
- if (!isComposing) {
293
- printer.queue(2000, 'coarsePrint');
294
- }
295
- textbox.style.color = '';
296
- preview.classList.add('active');
297
- });
298
- textbox.addEventListener('scroll', () => {
299
- if (preview.scrollHeight > preview.offsetHeight && !preview.classList.contains('active')) {
300
- preview.scrollTop = textbox.scrollTop;
301
- printer.queue(500, 'finePrint');
302
- }
303
- });
304
- textbox.addEventListener('keydown', e => {
305
- if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
306
- e.preventDefault();
307
- printer.ticks[0] = 0;
308
- printer.running = printer.coarsePrint();
309
- }
310
- });
311
- printer.running = printer.coarsePrint();
312
- return printer;
313
- };
314
-
315
- Object.assign(wikiparse, {print, lint, setConfig, getConfig, Printer, Linter});
316
- window.wikiparse = wikiparse;
317
- })();
package/extensions/ui.css DELETED
@@ -1,119 +0,0 @@
1
- .wikiparser {
2
- white-space: pre-wrap;
3
- overflow-wrap: break-word;
4
- font-family: monospace;
5
- }
6
-
7
- .wpb-error {
8
- text-decoration: underline wavy #f00 1px;
9
- }
10
- .wpb-hidden, .wpb-table-inter, .wpb-table-inter span {
11
- color: #f00;
12
- font-weight: normal;
13
- text-decoration: underline wavy 1px;
14
- }
15
-
16
- .wpb-noinclude, .wpb-include, .wpb-comment {
17
- color: #72777d;
18
- font-weight: normal;
19
- }
20
- .wpb-comment {
21
- font-style: italic;
22
- }
23
-
24
- .wpb-ext, .wpb-html {
25
- color: #14866d;
26
- font-weight: bold;
27
- }
28
- .wpb-ext-attrs, .wpb-html-attrs {
29
- font-weight: normal;
30
- }
31
- .wpb-ext-attr > .wpb-attr-value, .wpb-html-attr > .wpb-attr-value {
32
- color: #179b1c;
33
- }
34
- .wpb-ext-inner {
35
- color: initial;
36
- font-weight: normal;
37
- background-color: rgba(0, 0, 0, .03);
38
- }
39
-
40
- .wpb-arg {
41
- color: #ac6600;
42
- font-weight: bold;
43
- }
44
- .wpb-arg-default {
45
- color: #ad9300;
46
- font-weight: normal;
47
- }
48
-
49
- .wpb-template {
50
- color: #80c;
51
- font-weight: bold;
52
- background-color: rgba(119, 0, 170, .03);
53
- }
54
- .wpb-magic-word {
55
- color: #d33;
56
- font-weight: bold;
57
- background-color: rgba(170, 17, 17, .03);
58
- }
59
- .wpb-invoke-module, .wpb-invoke-function {
60
- color: #dd5d33;
61
- font-weight: normal;
62
- }
63
- .wpb-parameter {
64
- color: initial;
65
- font-weight: normal;
66
- }
67
- .wpb-template > .wpb-parameter > .wpb-parameter-key,
68
- .wpb-invoke-function ~ .wpb-parameter > .wpb-parameter-key {
69
- color: #b0c;
70
- }
71
-
72
- .wpb-heading, .wpb-image-parameter {
73
- color: #0076dd;
74
- }
75
- .wpb-heading-title {
76
- color: initial;
77
- font-weight: bold;
78
- }
79
-
80
- .wpb-table, .wpb-tr, .wpb-td {
81
- color: #d08;
82
- font-weight: bold;
83
- }
84
- .wpb-table-attrs {
85
- font-weight: normal;
86
- }
87
- .wpb-table-attr > .wpb-attr-value {
88
- color: #f500d4;
89
- }
90
- .wpb-td-inner {
91
- color: initial;
92
- font-weight: normal;
93
- }
94
-
95
- .wpb-double-underscore, .wpb-hr, .wpb-quote, .wpb-list, .wpb-dd {
96
- color: #0076dd;
97
- font-weight: bold;
98
- background-color: #eee;
99
- }
100
-
101
- .wpb-link, .wpb-category, .wpb-file, .wpb-gallery-image, .wpb-imagemap-image,
102
- .wpb-ext-link, .wpb-free-ext-link {
103
- color: #000aaa;
104
- background-color: rgba(34, 17, 153, .03);
105
- }
106
- .wpb-link-text, .wpb-image-caption, .wpb-ext-link-text {
107
- color: initial;
108
- }
109
-
110
- .wpb-converter {
111
- color: #b68;
112
- font-weight: bold;
113
- }
114
- .wpb-converter-rule {
115
- font-weight: normal;
116
- }
117
- .wpb-converter-rule-from, .wpb-converter-rule-to, .wpb-converter-noconvert {
118
- color: initial;
119
- }