wikilint 2.16.6 → 2.18.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.
- package/README.md +25 -2
- package/bin/config.js +3 -0
- package/config/.schema.json +7 -3
- package/config/default.json +86 -23
- package/config/enwiki.json +20 -13
- package/config/llwiki.json +99 -7
- package/config/minimum.json +6 -3
- package/config/moegirl.json +12 -12
- package/config/zhwiki.json +52 -21
- package/coverage/badge.svg +1 -1
- package/data/.schema.json +7 -0
- package/data/ext/mapframe.json +4 -0
- package/data/ext/maplink.json +4 -0
- package/data/ext/score.json +1033 -0
- package/data/ext/templatedata.json +184 -0
- package/dist/base.d.mts +4 -2
- package/dist/base.d.ts +4 -2
- package/dist/base.js +2 -0
- package/dist/base.mjs +3 -1
- package/dist/bin/cli.js +224 -47
- package/dist/bin/config.js +112 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -9
- package/dist/lib/document.d.ts +54 -0
- package/dist/lib/document.js +122 -0
- package/dist/lib/element.d.ts +6 -0
- package/dist/lib/element.js +5 -1
- package/dist/lib/lsp.d.ts +7 -7
- package/dist/lib/lsp.js +313 -47
- package/dist/lib/node.js +4 -1
- package/dist/lib/text.js +4 -1
- package/dist/lib/title.js +4 -4
- package/dist/parser/braces.js +0 -1
- package/dist/parser/commentAndExt.js +0 -1
- package/dist/parser/converter.js +0 -1
- package/dist/parser/externalLinks.js +0 -1
- package/dist/parser/hrAndDoubleUnderscore.js +0 -1
- package/dist/parser/html.js +0 -1
- package/dist/parser/links.js +4 -2
- package/dist/parser/list.js +0 -1
- package/dist/parser/magicLinks.js +0 -1
- package/dist/parser/quotes.js +0 -1
- package/dist/parser/redirect.js +4 -2
- package/dist/parser/table.js +0 -1
- package/dist/src/arg.d.ts +2 -3
- package/dist/src/arg.js +10 -7
- package/dist/src/attribute.js +4 -1
- package/dist/src/attributes.d.ts +2 -3
- package/dist/src/attributes.js +5 -2
- package/dist/src/converter.d.ts +2 -2
- package/dist/src/converter.js +3 -4
- package/dist/src/converterFlags.d.ts +2 -3
- package/dist/src/converterFlags.js +5 -6
- package/dist/src/converterRule.js +4 -1
- package/dist/src/extLink.js +4 -1
- package/dist/src/gallery.js +7 -3
- package/dist/src/heading.d.ts +2 -3
- package/dist/src/heading.js +10 -5
- package/dist/src/html.d.ts +0 -3
- package/dist/src/html.js +82 -91
- package/dist/src/imageParameter.d.ts +2 -3
- package/dist/src/imageParameter.js +9 -3
- package/dist/src/imagemap.js +4 -1
- package/dist/src/imagemapLink.d.ts +2 -2
- package/dist/src/imagemapLink.js +5 -6
- package/dist/src/index.js +25 -1
- package/dist/src/link/base.js +4 -1
- package/dist/src/link/file.js +4 -1
- package/dist/src/link/galleryImage.js +4 -1
- package/dist/src/magicLink.js +4 -1
- package/dist/src/nested.d.ts +2 -3
- package/dist/src/nested.js +5 -2
- package/dist/src/nowiki/comment.js +4 -1
- package/dist/src/nowiki/doubleUnderscore.d.ts +2 -2
- package/dist/src/nowiki/doubleUnderscore.js +1 -2
- package/dist/src/nowiki/index.js +4 -1
- package/dist/src/nowiki/quote.js +4 -1
- package/dist/src/paramTag/index.js +5 -1
- package/dist/src/paramTag/inputbox.js +4 -1
- package/dist/src/parameter.js +4 -1
- package/dist/src/pre.js +4 -1
- package/dist/src/redirect.d.ts +2 -3
- package/dist/src/redirect.js +6 -5
- package/dist/src/table/base.js +4 -1
- package/dist/src/table/index.d.ts +8 -0
- package/dist/src/table/index.js +13 -3
- package/dist/src/table/td.js +4 -1
- package/dist/src/tagPair/ext.js +9 -2
- package/dist/src/tagPair/include.js +4 -1
- package/dist/src/transclude.d.ts +2 -3
- package/dist/src/transclude.js +8 -8
- package/dist/util/diff.js +20 -6
- package/dist/util/lint.js +4 -1
- package/dist/util/string.js +5 -2
- package/package.json +20 -14
- package/dist/util/sharable.d.ts +0 -1
package/dist/lib/lsp.js
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.LanguageService = exports.tasks = void 0;
|
|
4
|
-
const path = require("path");
|
|
5
7
|
const common_1 = require("@bhsd/common");
|
|
6
8
|
const sharable_1 = require("../util/sharable");
|
|
7
9
|
const lint_1 = require("../util/lint");
|
|
8
10
|
const string_1 = require("../util/string");
|
|
9
|
-
const index_1 = require("../index");
|
|
11
|
+
const index_1 = __importDefault(require("../index"));
|
|
12
|
+
/* NOT FOR BROWSER ONLY */
|
|
13
|
+
const fs_1 = __importDefault(require("fs"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const util_1 = __importDefault(require("util"));
|
|
16
|
+
const child_process_1 = require("child_process");
|
|
17
|
+
const crypto_1 = require("crypto");
|
|
18
|
+
const stylelint_1 = require("@bhsd/common/dist/stylelint");
|
|
19
|
+
const document_1 = require("./document");
|
|
20
|
+
/** @see https://www.npmjs.com/package/stylelint-config-recommended */
|
|
21
|
+
const cssRules = {
|
|
22
|
+
'block-no-empty': null,
|
|
23
|
+
'property-no-unknown': null,
|
|
24
|
+
}, jsonSelector = document_1.jsonTags.map(s => `ext-inner#${s}`).join(), scores = new Map();
|
|
10
25
|
/* NOT FOR BROWSER ONLY END */
|
|
11
26
|
exports.tasks = new WeakMap();
|
|
12
27
|
const refTags = new Set(['ref']), referencesTags = new Set(['ref', 'references']), nameAttrs = new Set(['name', 'extends', 'follow']), groupAttrs = new Set(['group']), renameTypes = new Set([
|
|
@@ -23,7 +38,7 @@ const refTags = new Set(['ref']), referencesTags = new Set(['ref', 'references']
|
|
|
23
38
|
'heading-title',
|
|
24
39
|
'heading',
|
|
25
40
|
...renameTypes,
|
|
26
|
-
]), plainTypes = new Set(['text', 'comment', 'noinclude', 'include']);
|
|
41
|
+
]), plainTypes = new Set(['text', 'comment', 'noinclude', 'include']), cssSelector = ['ext', 'html', 'table'].map(s => `${s}-attr#style`).join();
|
|
27
42
|
/**
|
|
28
43
|
* Check if all child nodes are plain text or comments.
|
|
29
44
|
* @param childNodes child nodes
|
|
@@ -68,28 +83,39 @@ const createNodeRange = (token) => {
|
|
|
68
83
|
* @param pos.line line number
|
|
69
84
|
* @param pos.character character number
|
|
70
85
|
* @param extra extra text
|
|
86
|
+
* @param getDoc documentation method
|
|
71
87
|
*/
|
|
72
|
-
const getCompletion = (words, kind, mt, { line, character }, extra) => [...new Set(words)].map((w) =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
const getCompletion = (words, kind, mt, { line, character }, extra, getDoc) => [...new Set(words)].map((w) => {
|
|
89
|
+
const doc = getDoc?.(w)?.description;
|
|
90
|
+
return {
|
|
91
|
+
label: w,
|
|
92
|
+
kind,
|
|
93
|
+
textEdit: {
|
|
94
|
+
range: {
|
|
95
|
+
start: { line, character: character - mt.length },
|
|
96
|
+
end: { line, character },
|
|
97
|
+
},
|
|
98
|
+
newText: w + (extra ?? ''),
|
|
79
99
|
},
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
100
|
+
...doc && {
|
|
101
|
+
documentation: {
|
|
102
|
+
kind: 'markdown',
|
|
103
|
+
value: doc,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
});
|
|
83
108
|
/**
|
|
84
109
|
* Get the caret position at the position from a word.
|
|
85
110
|
* @param root root token
|
|
111
|
+
* @param text source code
|
|
86
112
|
* @param pos position
|
|
87
113
|
* @param pos.line line number
|
|
88
114
|
* @param pos.character character number
|
|
89
115
|
*/
|
|
90
|
-
const caretPositionFromWord = (root, { line, character }) => {
|
|
116
|
+
const caretPositionFromWord = (root, text, { line, character }) => {
|
|
91
117
|
const index = root.indexFromPos(line, character);
|
|
92
|
-
return root.caretPositionFromIndex(index + Number(/\w/u.test(
|
|
118
|
+
return root.caretPositionFromIndex(index + Number(/\w/u.test(text.charAt(index))));
|
|
93
119
|
};
|
|
94
120
|
/**
|
|
95
121
|
* Get the attribute of a `<ref>` tag.
|
|
@@ -141,7 +167,6 @@ const getName = (token) => {
|
|
|
141
167
|
return parentNode.name;
|
|
142
168
|
}
|
|
143
169
|
};
|
|
144
|
-
/* NOT FOR BROWSER ONLY */
|
|
145
170
|
/**
|
|
146
171
|
* Get the quick fix data.
|
|
147
172
|
* @param root root token
|
|
@@ -154,6 +179,55 @@ const getQuickFix = (root, fix, preferred = false) => ({
|
|
|
154
179
|
title: `${preferred ? 'Fix' : 'Suggestion'}: ${fix.desc}`,
|
|
155
180
|
fix: preferred,
|
|
156
181
|
});
|
|
182
|
+
/* NOT FOR BROWSER ONLY */
|
|
183
|
+
/**
|
|
184
|
+
* Correct the position of an error.
|
|
185
|
+
* @param height
|
|
186
|
+
* @param width
|
|
187
|
+
* @param line 0-based line number
|
|
188
|
+
* @param column 0-based column number
|
|
189
|
+
*/
|
|
190
|
+
const adjustPos = (height, width, line, column) => {
|
|
191
|
+
if (line === 0) {
|
|
192
|
+
line = 1;
|
|
193
|
+
column = 0;
|
|
194
|
+
}
|
|
195
|
+
else if (line === height + 1) {
|
|
196
|
+
line = height;
|
|
197
|
+
column = width;
|
|
198
|
+
}
|
|
199
|
+
return [line, column];
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Get the position of a Stylelint error.
|
|
203
|
+
* @param rect bounding client rect of the token
|
|
204
|
+
* @param bottom bottom of the style block
|
|
205
|
+
* @param line line number
|
|
206
|
+
* @param column column number
|
|
207
|
+
*/
|
|
208
|
+
const getStylelintPos = (rect, bottom, line, column) => {
|
|
209
|
+
const { top, left, height, width } = rect, start = bottom - height - 1;
|
|
210
|
+
line -= start;
|
|
211
|
+
[line, column] = adjustPos(height, width, line, column);
|
|
212
|
+
return (0, lint_1.getEndPos)(top, left, line, column);
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Convert LilyPond errors to VSCode diagnostics.
|
|
216
|
+
* @param token `<score>` extension token
|
|
217
|
+
* @param errors LilyPond errors
|
|
218
|
+
*/
|
|
219
|
+
const getLilyPondDiagnostics = (token, errors) => {
|
|
220
|
+
const { top, left } = token.lastChild.getBoundingClientRect();
|
|
221
|
+
return errors.map(({ line, col, message }) => {
|
|
222
|
+
const pos = (0, lint_1.getEndPos)(top, left, line, col);
|
|
223
|
+
return {
|
|
224
|
+
range: { start: pos, end: pos },
|
|
225
|
+
severity: 1,
|
|
226
|
+
source: 'LilyPond',
|
|
227
|
+
message,
|
|
228
|
+
};
|
|
229
|
+
});
|
|
230
|
+
};
|
|
157
231
|
/**
|
|
158
232
|
* Get the end position of a section.
|
|
159
233
|
* @param section section
|
|
@@ -176,22 +250,47 @@ class LanguageService {
|
|
|
176
250
|
#done;
|
|
177
251
|
#done2;
|
|
178
252
|
#config;
|
|
179
|
-
#
|
|
253
|
+
#include;
|
|
180
254
|
#completionConfig;
|
|
255
|
+
include = true;
|
|
181
256
|
/** @private */
|
|
182
257
|
data;
|
|
258
|
+
/* NOT FOR BROWSER ONLY */
|
|
259
|
+
lilypond;
|
|
260
|
+
lilypondData;
|
|
261
|
+
/* NOT FOR BROWSER ONLY END */
|
|
183
262
|
/** @param uri 任务标识 */
|
|
184
263
|
constructor(uri) {
|
|
185
264
|
exports.tasks.set(uri, this);
|
|
186
265
|
/* NOT FOR BROWSER ONLY */
|
|
187
|
-
Object.
|
|
188
|
-
|
|
189
|
-
|
|
266
|
+
Object.defineProperties(this, {
|
|
267
|
+
data: {
|
|
268
|
+
value: require(path_1.default.join('..', '..', 'data', 'signatures')),
|
|
269
|
+
enumerable: false,
|
|
270
|
+
},
|
|
271
|
+
lilypondData: {
|
|
272
|
+
value: require(path_1.default.join('..', '..', 'data', 'ext', 'score')),
|
|
273
|
+
enumerable: false,
|
|
274
|
+
},
|
|
190
275
|
});
|
|
191
276
|
}
|
|
192
277
|
/** @implements */
|
|
193
278
|
destroy() {
|
|
194
279
|
Object.setPrototypeOf(this, null);
|
|
280
|
+
/* NOT FOR BROWSER ONLY */
|
|
281
|
+
const dir = path_1.default.join(__dirname, 'lilypond');
|
|
282
|
+
if (fs_1.default.existsSync(dir)) {
|
|
283
|
+
for (const file of fs_1.default.readdirSync(dir)) {
|
|
284
|
+
try {
|
|
285
|
+
void fs_1.default.promises.unlink(path_1.default.join(dir, file));
|
|
286
|
+
}
|
|
287
|
+
catch { }
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/** 检查解析设置有无更新 */
|
|
292
|
+
#checkConfig() {
|
|
293
|
+
return this.#config === index_1.default.config && this.#include === this.include;
|
|
195
294
|
}
|
|
196
295
|
/**
|
|
197
296
|
* 提交解析任务
|
|
@@ -203,7 +302,7 @@ class LanguageService {
|
|
|
203
302
|
*/
|
|
204
303
|
async #queue(text) {
|
|
205
304
|
text = (0, string_1.tidy)(text);
|
|
206
|
-
if (this.#
|
|
305
|
+
if (!this.#running && this.#checkConfig() && this.#text === text) {
|
|
207
306
|
return this.#done;
|
|
208
307
|
}
|
|
209
308
|
this.#text = text;
|
|
@@ -219,8 +318,9 @@ class LanguageService {
|
|
|
219
318
|
async #parse() {
|
|
220
319
|
const config = index_1.default.getConfig();
|
|
221
320
|
this.#config = index_1.default.config;
|
|
222
|
-
|
|
223
|
-
|
|
321
|
+
this.#include = this.include;
|
|
322
|
+
const text = this.#text, root = await index_1.default.partialParse(text, () => this.#text, this.include, config);
|
|
323
|
+
if (this.#checkConfig() && this.#text === text) {
|
|
224
324
|
this.#done = root;
|
|
225
325
|
this.#running = undefined;
|
|
226
326
|
return root;
|
|
@@ -240,7 +340,7 @@ class LanguageService {
|
|
|
240
340
|
*/
|
|
241
341
|
async #queueSignature(text) {
|
|
242
342
|
text = (0, string_1.tidy)(text);
|
|
243
|
-
if (this.#
|
|
343
|
+
if (!this.#running2 && this.#checkConfig() && this.#text2 === text) {
|
|
244
344
|
return this.#done2;
|
|
245
345
|
}
|
|
246
346
|
this.#text2 = text;
|
|
@@ -255,9 +355,10 @@ class LanguageService {
|
|
|
255
355
|
*/
|
|
256
356
|
async #parseSignature() {
|
|
257
357
|
const config = index_1.default.getConfig();
|
|
258
|
-
this.#
|
|
259
|
-
|
|
260
|
-
|
|
358
|
+
this.#config = index_1.default.config;
|
|
359
|
+
this.#include = this.include;
|
|
360
|
+
const text = this.#text2, root = await index_1.default.partialParse(text, () => this.#text2, this.include, config);
|
|
361
|
+
if (this.#checkConfig() && this.#text2 === text) {
|
|
261
362
|
this.#done2 = root;
|
|
262
363
|
this.#running2 = undefined;
|
|
263
364
|
return root;
|
|
@@ -370,7 +471,7 @@ class LanguageService {
|
|
|
370
471
|
return getCompletion(allTags, 'Class', mt[1].slice(closing ? 1 : 0), position, closing && !curLine?.slice(character).trim().startsWith('>') ? '>' : '');
|
|
371
472
|
}
|
|
372
473
|
else if (mt?.[4]) { // behavior switch
|
|
373
|
-
return getCompletion(switches, 'Constant', mt[4], position);
|
|
474
|
+
return getCompletion(switches, 'Constant', mt[4], position, '', name => this.data && this.#getBehaviorSwitch(name.slice(2, -2)));
|
|
374
475
|
}
|
|
375
476
|
else if (mt?.[5] !== undefined) { // protocol
|
|
376
477
|
return getCompletion(protocols, 'Reference', mt[5], position);
|
|
@@ -389,7 +490,7 @@ class LanguageService {
|
|
|
389
490
|
? getCompletion(// link
|
|
390
491
|
root.querySelectorAll('link,file,category,redirect-target').filter(token => token !== cur).map(({ name }) => name), 'Folder', str, position)
|
|
391
492
|
: [
|
|
392
|
-
...getCompletion(functions, 'Function', match, position),
|
|
493
|
+
...getCompletion(functions, 'Function', match, position, '', name => this.data && this.#getParserFunction(name.replace(/^#/u, '').toLowerCase())),
|
|
393
494
|
...match.startsWith('#')
|
|
394
495
|
? []
|
|
395
496
|
: getCompletion(root.querySelectorAll('template').filter(token => token !== cur)
|
|
@@ -423,7 +524,8 @@ class LanguageService {
|
|
|
423
524
|
];
|
|
424
525
|
}
|
|
425
526
|
else if (mt?.[7] !== undefined || type === 'attr-key') { // attribute key
|
|
426
|
-
const tag = mt?.[7]?.toLowerCase() ?? parentNode.tag, key = mt?.[9]
|
|
527
|
+
const tag = mt?.[7]?.toLowerCase() ?? parentNode.tag, key = mt?.[9]
|
|
528
|
+
?? cur.toString().slice(0, character - root.posFromIndex(cur.getAbsoluteIndex()).left);
|
|
427
529
|
if (!tags.has(tag)) {
|
|
428
530
|
return undefined;
|
|
429
531
|
}
|
|
@@ -448,7 +550,7 @@ class LanguageService {
|
|
|
448
550
|
if (t === 'magic-word' && n !== 'invoke') {
|
|
449
551
|
return undefined;
|
|
450
552
|
}
|
|
451
|
-
const key = cur.
|
|
553
|
+
const index = root.indexFromPos(line, character), key = this.#text.slice(cur.getAbsoluteIndex(), index).trimStart(), [module, func] = t === 'magic-word' ? transclusion.getModule() : [];
|
|
452
554
|
return key
|
|
453
555
|
? getCompletion(root.querySelectorAll('parameter').filter(token => {
|
|
454
556
|
if (token === parentNode
|
|
@@ -464,6 +566,43 @@ class LanguageService {
|
|
|
464
566
|
return m === module && f === func;
|
|
465
567
|
}).map(({ name }) => name), 'Variable', key, position, type === 'parameter-value' ? '=' : '')
|
|
466
568
|
: undefined;
|
|
569
|
+
/* NOT FOR BROWSER ONLY */
|
|
570
|
+
}
|
|
571
|
+
else if (document_1.cssLSP && type === 'attr-value' && parentNode.name === 'style' && cur.length === 1) {
|
|
572
|
+
const textDoc = new document_1.EmbeddedCSSDocument(root, cur);
|
|
573
|
+
return document_1.cssLSP.doComplete(textDoc, position, textDoc.styleSheet).items.map((item) => ({
|
|
574
|
+
...item,
|
|
575
|
+
textEdit: {
|
|
576
|
+
range: item.textEdit.range,
|
|
577
|
+
newText: item.textEdit.newText.replace(/\s/gu, ''),
|
|
578
|
+
},
|
|
579
|
+
}));
|
|
580
|
+
}
|
|
581
|
+
else if (document_1.jsonLSP && type === 'ext-inner' && document_1.jsonTags.includes(cur.name)) {
|
|
582
|
+
const textDoc = new document_1.EmbeddedJSONDocument(root, cur);
|
|
583
|
+
return (await document_1.jsonLSP.doComplete(textDoc, position, textDoc.jsonDoc))?.items;
|
|
584
|
+
}
|
|
585
|
+
else if (type === 'ext-inner' && cur.name === 'score') {
|
|
586
|
+
const lang = parentNode.getAttr('lang');
|
|
587
|
+
if (lang !== undefined && lang !== 'lilypond') {
|
|
588
|
+
return undefined;
|
|
589
|
+
}
|
|
590
|
+
const j = root.indexFromPos(line, character), i = cur.getAbsoluteIndex(), before = this.#text.slice(i, j), comment = before.lastIndexOf('%');
|
|
591
|
+
if (comment !== -1
|
|
592
|
+
&& (before.charAt(comment + 1) === '{' || !before.slice(comment).includes('\n'))) {
|
|
593
|
+
return undefined;
|
|
594
|
+
}
|
|
595
|
+
const word = /\\?\b(?:\w|\b(?:->?|\.)|\bly:)+$/u.exec(curLine.slice(0, character))?.[0];
|
|
596
|
+
if (word) {
|
|
597
|
+
const { lilypondData } = this;
|
|
598
|
+
return word.startsWith('\\')
|
|
599
|
+
? getCompletion(lilypondData.filter(w => w.startsWith('\\')), 'Function', word, position)
|
|
600
|
+
: [
|
|
601
|
+
...getCompletion(lilypondData.filter(w => /^[a-z]/u.test(w)), 'Variable', word, position),
|
|
602
|
+
...getCompletion(lilypondData.filter(w => /^[A-Z]/u.test(w)), 'Class', word, position),
|
|
603
|
+
];
|
|
604
|
+
}
|
|
605
|
+
/* NOT FOR BROWSER ONLY END */
|
|
467
606
|
}
|
|
468
607
|
return undefined;
|
|
469
608
|
}
|
|
@@ -475,23 +614,124 @@ class LanguageService {
|
|
|
475
614
|
* @param warning whether to include warnings / 是否包含警告
|
|
476
615
|
*/
|
|
477
616
|
async provideDiagnostics(text, warning = true) {
|
|
478
|
-
const root = await this.#queue(text), errors = root.lint()
|
|
479
|
-
|
|
480
|
-
|
|
617
|
+
const root = await this.#queue(text), errors = root.lint(), diagnostics = (warning ? errors : errors.filter(({ severity }) => severity === 'error')).map(({ startLine, startCol, endLine, endCol, severity, rule, message, fix, suggestions,
|
|
618
|
+
/* NOT FOR BROWSER ONLY */
|
|
619
|
+
code, }) => ({
|
|
481
620
|
range: {
|
|
482
621
|
start: { line: startLine, character: startCol },
|
|
483
622
|
end: { line: endLine, character: endCol },
|
|
484
623
|
},
|
|
485
624
|
severity: severity === 'error' ? 1 : 2,
|
|
486
|
-
source:
|
|
487
|
-
|
|
625
|
+
source:
|
|
626
|
+
/* eslint-disable @stylistic/operator-linebreak */
|
|
627
|
+
rule === 'invalid-css' ?
|
|
628
|
+
'css' :
|
|
629
|
+
'WikiLint',
|
|
630
|
+
code: code ??
|
|
631
|
+
/* eslint-enable @stylistic/operator-linebreak */
|
|
632
|
+
rule,
|
|
488
633
|
message,
|
|
489
|
-
/* NOT FOR BROWSER ONLY */
|
|
490
634
|
data: [
|
|
491
635
|
...fix ? [getQuickFix(root, fix, true)] : [],
|
|
492
636
|
...suggestions ? suggestions.map(suggestion => getQuickFix(root, suggestion)) : [],
|
|
493
637
|
],
|
|
494
|
-
}))
|
|
638
|
+
})),
|
|
639
|
+
/* eslint-disable @stylistic/operator-linebreak */
|
|
640
|
+
cssDiagnostics = await document_1.stylelint ?
|
|
641
|
+
await (async () => {
|
|
642
|
+
const tokens = this.findStyleTokens();
|
|
643
|
+
if (tokens.length === 0) {
|
|
644
|
+
return [];
|
|
645
|
+
}
|
|
646
|
+
const cssErrors = await (0, stylelint_1.styleLint)((await document_1.stylelint), tokens.map(({ type, tag, lastChild }, i) => `${type === 'ext-attr' ? 'div' : tag}#${i}{\n${(0, common_1.sanitizeInlineStyle)(lastChild.toString())}\n}`).join('\n'), cssRules);
|
|
647
|
+
if (cssErrors.length === 0) {
|
|
648
|
+
return [];
|
|
649
|
+
}
|
|
650
|
+
const rects = tokens.map(({ lastChild }) => lastChild.getBoundingClientRect());
|
|
651
|
+
let acc = 0;
|
|
652
|
+
const bottoms = rects.map(({ height }) => {
|
|
653
|
+
acc += height + 2;
|
|
654
|
+
return acc;
|
|
655
|
+
});
|
|
656
|
+
return cssErrors.map(({ rule, text: msg, severity, line, column, endLine = line, endColumn = column, }) => {
|
|
657
|
+
const i = bottoms.findIndex(bottom => bottom >= line);
|
|
658
|
+
return {
|
|
659
|
+
range: {
|
|
660
|
+
start: getStylelintPos(rects[i], bottoms[i], line, column - 1),
|
|
661
|
+
end: getStylelintPos(rects[i], bottoms[i], endLine, endColumn - 1),
|
|
662
|
+
},
|
|
663
|
+
severity: severity === 'error' ? 1 : 2,
|
|
664
|
+
source: 'Stylelint',
|
|
665
|
+
code: rule,
|
|
666
|
+
message: msg.slice(0, msg.lastIndexOf('(') - 1),
|
|
667
|
+
};
|
|
668
|
+
});
|
|
669
|
+
})() :
|
|
670
|
+
[], jsonDiagnostics = document_1.jsonLSP ?
|
|
671
|
+
await Promise.all(root.querySelectorAll(jsonSelector).map(async (token) => {
|
|
672
|
+
const textDoc = new document_1.EmbeddedJSONDocument(root, token), severityLevel = token.name === 'templatedata' ? 'error' : 'ignore', e = (await document_1.jsonLSP.doValidation(textDoc, textDoc.jsonDoc, {
|
|
673
|
+
comments: severityLevel,
|
|
674
|
+
trailingCommas: severityLevel,
|
|
675
|
+
})).map((error) => ({
|
|
676
|
+
...error,
|
|
677
|
+
source: 'json',
|
|
678
|
+
}));
|
|
679
|
+
return warning ? e : e.filter(({ severity }) => severity === 1);
|
|
680
|
+
})) :
|
|
681
|
+
[];
|
|
682
|
+
/* eslint-enable @stylistic/operator-linebreak */
|
|
683
|
+
/* NOT FOR BROWSER ONLY */
|
|
684
|
+
let lilypondDiagnostics = [];
|
|
685
|
+
if (this.lilypond) {
|
|
686
|
+
const tokens = root.querySelectorAll('ext#score').filter(token => {
|
|
687
|
+
const lang = token.getAttr('lang');
|
|
688
|
+
return (lang === undefined || lang === 'lilypond') && token.innerText;
|
|
689
|
+
});
|
|
690
|
+
if (tokens.length > 0) {
|
|
691
|
+
const dir = path_1.default.join(__dirname, 'lilypond');
|
|
692
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
693
|
+
fs_1.default.mkdirSync(dir);
|
|
694
|
+
}
|
|
695
|
+
lilypondDiagnostics = await Promise.all(tokens.map(async (token) => {
|
|
696
|
+
const { innerText } = token, score = `showLastLength = R1${token.getAttr('raw') === undefined ? ` \\score {\n${innerText}\n}` : `\n${innerText}`}`;
|
|
697
|
+
if (scores.has(score)) {
|
|
698
|
+
return getLilyPondDiagnostics(token, scores.get(score));
|
|
699
|
+
}
|
|
700
|
+
const hash = (0, crypto_1.createHash)('sha256');
|
|
701
|
+
hash.update(score);
|
|
702
|
+
const file = path_1.default.join(dir, `${hash.digest('hex')}.ly`);
|
|
703
|
+
fs_1.default.writeFileSync(file, score);
|
|
704
|
+
try {
|
|
705
|
+
await util_1.default.promisify(child_process_1.execFile)(this.lilypond, ['-s', '-o', dir, file]);
|
|
706
|
+
scores.set(score, []);
|
|
707
|
+
}
|
|
708
|
+
catch (e) {
|
|
709
|
+
const { stderr } = e;
|
|
710
|
+
if (stderr) {
|
|
711
|
+
const re = new RegExp(String.raw `^${file}:(\d+):(\d+): error: (.+)$`, 'gmu'), lilypondErrors = [...stderr.matchAll(re)].map(([, line, col, msg]) => {
|
|
712
|
+
const { offsetHeight, offsetWidth } = token.lastChild, pos = adjustPos(offsetHeight, offsetWidth, Number(line) - 1, Number(col) - 1);
|
|
713
|
+
return {
|
|
714
|
+
line: pos[0],
|
|
715
|
+
col: pos[1],
|
|
716
|
+
message: msg,
|
|
717
|
+
};
|
|
718
|
+
});
|
|
719
|
+
scores.set(score, lilypondErrors);
|
|
720
|
+
return getLilyPondDiagnostics(token, lilypondErrors);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
return [];
|
|
724
|
+
}));
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
/* NOT FOR BROWSER ONLY END */
|
|
728
|
+
return [
|
|
729
|
+
diagnostics,
|
|
730
|
+
cssDiagnostics,
|
|
731
|
+
jsonDiagnostics,
|
|
732
|
+
/* NOT FOR BROWSER ONLY */
|
|
733
|
+
lilypondDiagnostics,
|
|
734
|
+
].flat(2);
|
|
495
735
|
}
|
|
496
736
|
/**
|
|
497
737
|
* Provide folding ranges
|
|
@@ -507,7 +747,7 @@ class LanguageService {
|
|
|
507
747
|
for (const token of tokens) {
|
|
508
748
|
const { offsetHeight } = token;
|
|
509
749
|
if (token.type === 'heading-title' || offsetHeight > 2) {
|
|
510
|
-
const { top } = token.
|
|
750
|
+
const { top } = root.posFromIndex(token.getAbsoluteIndex());
|
|
511
751
|
if (token.type === 'heading-title') {
|
|
512
752
|
const { level } = token.parentNode;
|
|
513
753
|
for (let i = level - 1; i < 6; i++) {
|
|
@@ -541,6 +781,13 @@ class LanguageService {
|
|
|
541
781
|
});
|
|
542
782
|
}
|
|
543
783
|
}
|
|
784
|
+
/* NOT FOR BROWSER ONLY */
|
|
785
|
+
if (document_1.jsonLSP) {
|
|
786
|
+
for (const token of root.querySelectorAll(jsonSelector)) {
|
|
787
|
+
ranges.push(...document_1.jsonLSP.getFoldingRanges(new document_1.EmbeddedJSONDocument(root, token)));
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
/* NOT FOR BROWSER ONLY END */
|
|
544
791
|
return ranges;
|
|
545
792
|
}
|
|
546
793
|
/**
|
|
@@ -637,7 +884,7 @@ class LanguageService {
|
|
|
637
884
|
* @param position 位置
|
|
638
885
|
*/
|
|
639
886
|
async provideReferences(text, position) {
|
|
640
|
-
const root = await this.#queue(text), { offsetNode, offset } = caretPositionFromWord(root, position), element = offsetNode.type === 'text' ? offsetNode.parentNode : offsetNode, node = offset === 0 && (element.type === 'ext-attr-dirty' || element.type === 'html-attr-dirty')
|
|
887
|
+
const root = await this.#queue(text), { offsetNode, offset } = caretPositionFromWord(root, this.#text, position), element = offsetNode.type === 'text' ? offsetNode.parentNode : offsetNode, node = offset === 0 && (element.type === 'ext-attr-dirty' || element.type === 'html-attr-dirty')
|
|
641
888
|
? element.parentNode.parentNode
|
|
642
889
|
: element, { type } = node, refName = getRefName(node), refGroup = getRefGroup(node);
|
|
643
890
|
if (!refName && !refGroup && !referenceTypes.has(type)) {
|
|
@@ -717,6 +964,13 @@ class LanguageService {
|
|
|
717
964
|
},
|
|
718
965
|
};
|
|
719
966
|
}
|
|
967
|
+
/**
|
|
968
|
+
* 检索状态开关
|
|
969
|
+
* @param name 魔术字名
|
|
970
|
+
*/
|
|
971
|
+
#getBehaviorSwitch(name) {
|
|
972
|
+
return this.data.behaviorSwitches.find(({ aliases }) => aliases.includes(name));
|
|
973
|
+
}
|
|
720
974
|
/**
|
|
721
975
|
* 检索解析器函数
|
|
722
976
|
* @param name 函数名
|
|
@@ -737,17 +991,17 @@ class LanguageService {
|
|
|
737
991
|
if (!this.data) {
|
|
738
992
|
return undefined;
|
|
739
993
|
}
|
|
740
|
-
const root = await this.#queue(text), { offsetNode, offset } = caretPositionFromWord(root, position), token = offsetNode.type === 'text' ? offsetNode.parentNode : offsetNode, { type, parentNode, length, name } = token;
|
|
994
|
+
const root = await this.#queue(text), { offsetNode, offset } = caretPositionFromWord(root, this.#text, position), token = offsetNode.type === 'text' ? offsetNode.parentNode : offsetNode, { type, parentNode, length, name } = token;
|
|
741
995
|
let info, f, range;
|
|
742
996
|
if (token.is('double-underscore') && offset > 0) {
|
|
743
|
-
info = this
|
|
997
|
+
info = this.#getBehaviorSwitch(token.innerText.toLowerCase());
|
|
744
998
|
}
|
|
745
999
|
else if (type === 'magic-word-name') {
|
|
746
1000
|
info = this.#getParserFunction(parentNode.name);
|
|
747
1001
|
f = token.toString(true).trim();
|
|
748
1002
|
}
|
|
749
1003
|
else if (token.is('magic-word') && !token.modifier && length === 1
|
|
750
|
-
&& (offset > 0 || token.
|
|
1004
|
+
&& (offset > 0 || root.posFromIndex(token.getAbsoluteIndex()).left === position.character)) {
|
|
751
1005
|
info = this.#getParserFunction(name);
|
|
752
1006
|
f = token.firstChild.toString(true).trim();
|
|
753
1007
|
}
|
|
@@ -762,6 +1016,16 @@ class LanguageService {
|
|
|
762
1016
|
end: positionAt(root, aIndex + token.modifier.trimEnd().length + 1),
|
|
763
1017
|
};
|
|
764
1018
|
}
|
|
1019
|
+
/* NOT FOR BROWSER ONLY */
|
|
1020
|
+
}
|
|
1021
|
+
else if (document_1.cssLSP && type === 'attr-value' && length === 1 && parentNode.name === 'style') {
|
|
1022
|
+
const textDoc = new document_1.EmbeddedCSSDocument(root, token);
|
|
1023
|
+
return document_1.cssLSP.doHover(textDoc, position, textDoc.styleSheet) ?? undefined;
|
|
1024
|
+
}
|
|
1025
|
+
else if (document_1.jsonLSP && type === 'ext-inner' && document_1.jsonTags.includes(name)) {
|
|
1026
|
+
const textDoc = new document_1.EmbeddedJSONDocument(root, token);
|
|
1027
|
+
return await document_1.jsonLSP.doHover(textDoc, position, textDoc.jsonDoc) ?? undefined;
|
|
1028
|
+
/* NOT FOR BROWSER ONLY END */
|
|
765
1029
|
}
|
|
766
1030
|
return info && {
|
|
767
1031
|
contents: {
|
|
@@ -842,6 +1106,11 @@ class LanguageService {
|
|
|
842
1106
|
}
|
|
843
1107
|
return hints;
|
|
844
1108
|
}
|
|
1109
|
+
/** @private */
|
|
1110
|
+
findStyleTokens() {
|
|
1111
|
+
return this.#done.querySelectorAll(cssSelector)
|
|
1112
|
+
.filter(({ lastChild: { length, firstChild } }) => length === 1 && firstChild.type === 'text');
|
|
1113
|
+
}
|
|
845
1114
|
/* NOT FOR BROWSER ONLY */
|
|
846
1115
|
/**
|
|
847
1116
|
* Provide quick fixes
|
|
@@ -851,7 +1120,7 @@ class LanguageService {
|
|
|
851
1120
|
*/
|
|
852
1121
|
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
853
1122
|
provideCodeAction(diagnostics) {
|
|
854
|
-
return diagnostics.flatMap(diagnostic => diagnostic.data.map((data) => ({
|
|
1123
|
+
return diagnostics.filter((diagnostic) => diagnostic.data).flatMap(diagnostic => diagnostic.data.map((data) => ({
|
|
855
1124
|
title: data.title,
|
|
856
1125
|
kind: 'quickfix',
|
|
857
1126
|
diagnostics: [diagnostic],
|
|
@@ -869,9 +1138,6 @@ class LanguageService {
|
|
|
869
1138
|
*/
|
|
870
1139
|
async provideDocumentSymbols(text) {
|
|
871
1140
|
const root = await this.#queue(text), lines = root.getLines(), { length } = lines, symbols = [], names = new Set(), sections = new Array(6), tokens = root.querySelectorAll('heading-title');
|
|
872
|
-
for (const token of [...tokens].reverse()) { // 提高 getBoundingClientRect 的性能
|
|
873
|
-
token.getRelativeIndex();
|
|
874
|
-
}
|
|
875
1141
|
for (const token of tokens) {
|
|
876
1142
|
const { top, height, left, width } = token.getBoundingClientRect(), { level } = token.parentNode;
|
|
877
1143
|
for (let i = level - 1; i < 6; i++) {
|
package/dist/lib/node.js
CHANGED
|
@@ -180,7 +180,10 @@ class AstNode {
|
|
|
180
180
|
*/
|
|
181
181
|
getBoundingClientRect() {
|
|
182
182
|
// eslint-disable-next-line no-unused-labels
|
|
183
|
-
LSP: return {
|
|
183
|
+
LSP: return {
|
|
184
|
+
...this.#getDimension(),
|
|
185
|
+
...this.getRootNode().posFromIndex(this.getAbsoluteIndex()),
|
|
186
|
+
};
|
|
184
187
|
}
|
|
185
188
|
/** @private */
|
|
186
189
|
seal(key, permanent) {
|
package/dist/lib/text.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.AstText = void 0;
|
|
4
7
|
const string_1 = require("../util/string");
|
|
5
8
|
const lint_1 = require("../util/lint");
|
|
6
|
-
const index_1 = require("../index");
|
|
9
|
+
const index_1 = __importDefault(require("../index"));
|
|
7
10
|
const node_1 = require("./node");
|
|
8
11
|
const sp = String.raw `[${string_1.zs}\t]*`, source = String.raw `<\s*(?:/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])|((?:^|\])[^[]*?)\]+|(?:rfc|pmid)(?=[-::]?${sp}\d)|isbn(?=[-::]?${sp}(?:\d(?:${sp}|-)){6})`;
|
|
9
12
|
const errorSyntax = new RegExp(String.raw `${source}|https?[:/]/+`, 'giu');
|
package/dist/lib/title.js
CHANGED
|
@@ -145,11 +145,11 @@ class Title {
|
|
|
145
145
|
const { title, fragment } = this;
|
|
146
146
|
if (title) {
|
|
147
147
|
return this.#path.replace('$1', encodeURIComponent(title)
|
|
148
|
-
+ (fragment
|
|
149
|
-
?
|
|
150
|
-
: `#${encodeURIComponent(
|
|
148
|
+
+ (fragment
|
|
149
|
+
? `#${encodeURIComponent(
|
|
151
150
|
// eslint-disable-next-line @stylistic/comma-dangle
|
|
152
|
-
fragment)}`
|
|
151
|
+
fragment)}`
|
|
152
|
+
: ''));
|
|
153
153
|
}
|
|
154
154
|
return fragment === undefined ? '' : `#${encodeURIComponent(fragment)}`;
|
|
155
155
|
}
|
package/dist/parser/braces.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseBraces = void 0;
|
|
4
|
-
/* istanbul ignore file */
|
|
5
4
|
const string_1 = require("../util/string");
|
|
6
5
|
const heading_1 = require("../src/heading");
|
|
7
6
|
const transclude_1 = require("../src/transclude");
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseCommentAndExt = void 0;
|
|
4
|
-
/* istanbul ignore file */
|
|
5
4
|
const onlyinclude_1 = require("../src/onlyinclude");
|
|
6
5
|
const noinclude_1 = require("../src/nowiki/noinclude");
|
|
7
6
|
const include_1 = require("../src/tagPair/include");
|
package/dist/parser/converter.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseExternalLinks = void 0;
|
|
4
|
-
/* istanbul ignore file */
|
|
5
4
|
const string_1 = require("../util/string");
|
|
6
5
|
const extLink_1 = require("../src/extLink");
|
|
7
6
|
const magicLink_1 = require("../src/magicLink");
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseHrAndDoubleUnderscore = void 0;
|
|
4
|
-
/* istanbul ignore file */
|
|
5
4
|
const hr_1 = require("../src/nowiki/hr");
|
|
6
5
|
const doubleUnderscore_1 = require("../src/nowiki/doubleUnderscore");
|
|
7
6
|
const heading_1 = require("../src/heading");
|