wikilint 2.19.0 → 2.20.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/config/default.json +49 -3
- package/config/minimum.json +5 -1
- package/data/ext/math.json +660 -0
- package/dist/base.d.mts +1 -1
- package/dist/base.d.ts +1 -1
- package/dist/bin/cli.js +19 -6
- package/dist/bin/config.js +26 -8
- package/dist/index.js +10 -1
- package/dist/internal.d.ts +2 -0
- package/dist/lib/document.d.ts +1 -0
- package/dist/lib/document.js +10 -1
- package/dist/lib/element.js +15 -4
- package/dist/lib/lsp.js +87 -57
- package/dist/lib/node.js +0 -7
- package/dist/lib/text.js +3 -7
- package/dist/lib/title.js +1 -6
- package/dist/mixin/attributesParent.js +1 -1
- package/dist/mixin/gapped.d.ts +4 -0
- package/dist/mixin/gapped.js +20 -0
- package/dist/mixin/hidden.js +1 -1
- package/dist/mixin/multiLine.d.ts +4 -0
- package/dist/mixin/multiLine.js +26 -0
- package/dist/mixin/padded.d.ts +5 -0
- package/dist/mixin/padded.js +20 -0
- package/dist/parser/braces.js +8 -12
- package/dist/parser/commentAndExt.js +18 -2
- package/dist/parser/magicLinks.js +1 -1
- package/dist/parser/selector.js +5 -2
- package/dist/src/arg.js +131 -84
- package/dist/src/attribute.js +4 -4
- package/dist/src/attributes.js +2 -2
- package/dist/src/commented.d.ts +19 -0
- package/dist/src/commented.js +41 -0
- package/dist/src/converter.js +90 -43
- package/dist/src/converterFlags.js +113 -66
- package/dist/src/converterRule.d.ts +1 -1
- package/dist/src/extLink.d.ts +2 -3
- package/dist/src/extLink.js +97 -54
- package/dist/src/gallery.d.ts +3 -4
- package/dist/src/gallery.js +114 -72
- package/dist/src/heading.js +10 -10
- package/dist/src/imageParameter.d.ts +1 -1
- package/dist/src/imageParameter.js +4 -3
- package/dist/src/imagemap.d.ts +1 -1
- package/dist/src/imagemap.js +126 -86
- package/dist/src/imagemapLink.d.ts +1 -1
- package/dist/src/index.js +11 -8
- package/dist/src/link/base.d.ts +2 -3
- package/dist/src/link/base.js +149 -105
- package/dist/src/link/file.d.ts +2 -3
- package/dist/src/link/file.js +2 -2
- package/dist/src/link/galleryImage.d.ts +2 -3
- package/dist/src/link/galleryImage.js +89 -47
- package/dist/src/nested.d.ts +1 -1
- package/dist/src/nowiki/comment.js +2 -5
- package/dist/src/nowiki/doubleUnderscore.js +2 -5
- package/dist/src/nowiki/index.d.ts +1 -1
- package/dist/src/nowiki/index.js +2 -1
- package/dist/src/onlyinclude.js +63 -15
- package/dist/src/paramTag/index.d.ts +1 -1
- package/dist/src/paramTag/index.js +89 -47
- package/dist/src/parameter.d.ts +3 -4
- package/dist/src/parameter.js +4 -8
- package/dist/src/pre.d.ts +3 -4
- package/dist/src/pre.js +5 -9
- package/dist/src/syntax.d.ts +1 -1
- package/dist/src/table/base.d.ts +2 -2
- package/dist/src/table/base.js +3 -7
- package/dist/src/table/index.js +1 -1
- package/dist/src/table/td.d.ts +2 -3
- package/dist/src/table/td.js +3 -7
- package/dist/src/table/tr.d.ts +1 -1
- package/dist/src/tagPair/ext.js +34 -31
- package/dist/src/tagPair/index.d.ts +1 -1
- package/dist/src/tagPair/index.js +94 -47
- package/dist/src/tagPair/translate.d.ts +22 -0
- package/dist/src/tagPair/translate.js +48 -0
- package/dist/src/transclude.js +378 -332
- package/dist/util/lint.js +17 -30
- package/dist/util/sharable.js +29 -1
- package/dist/util/sharable.mjs +31 -3
- package/dist/util/string.js +14 -1
- package/package.json +3 -2
package/dist/src/transclude.js
CHANGED
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
2
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
37
|
exports.TranscludeToken = void 0;
|
|
4
38
|
const string_1 = require("../util/string");
|
|
@@ -6,6 +40,7 @@ const lint_1 = require("../util/lint");
|
|
|
6
40
|
const debug_1 = require("../util/debug");
|
|
7
41
|
const constants_1 = require("../util/constants");
|
|
8
42
|
const rect_1 = require("../lib/rect");
|
|
43
|
+
const gapped_1 = require("../mixin/gapped");
|
|
9
44
|
const index_1 = require("./index");
|
|
10
45
|
const parameter_1 = require("./parameter");
|
|
11
46
|
const atom_1 = require("./atom");
|
|
@@ -16,377 +51,388 @@ const syntax_1 = require("./syntax");
|
|
|
16
51
|
* 模板或魔术字
|
|
17
52
|
* @classdesc `{childNodes: [AtomToken|SyntaxToken, ...AtomToken[], ...ParameterToken[]]}`
|
|
18
53
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
*/
|
|
34
|
-
constructor(title, parts, config, accum = []) {
|
|
35
|
-
let heading;
|
|
36
|
-
const m = /^(?:\s|\0\d+[cn]\x7F)*\0(\d+)h\x7F(?:\s|\0\d+[cn]\x7F)*/u.exec(title);
|
|
37
|
-
if (m) {
|
|
38
|
-
heading = Number(m[1]);
|
|
39
|
-
title = title.replace(`\0${heading}h\x7F`, accum[heading].toString().replace(/^\n/u, ''));
|
|
54
|
+
let TranscludeToken = (() => {
|
|
55
|
+
let _classDecorators = [(0, gapped_1.gapped)()];
|
|
56
|
+
let _classDescriptor;
|
|
57
|
+
let _classExtraInitializers = [];
|
|
58
|
+
let _classThis;
|
|
59
|
+
let _classSuper = index_1.Token;
|
|
60
|
+
var TranscludeToken = class extends _classSuper {
|
|
61
|
+
static { _classThis = this; }
|
|
62
|
+
static {
|
|
63
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
64
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
65
|
+
TranscludeToken = _classThis = _classDescriptor.value;
|
|
66
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
67
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
40
68
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
69
|
+
modifier = '';
|
|
70
|
+
#type = 'template';
|
|
71
|
+
#colon = ':';
|
|
72
|
+
#raw = false;
|
|
73
|
+
#args = new Map();
|
|
74
|
+
#title;
|
|
75
|
+
get type() {
|
|
76
|
+
return this.#type;
|
|
46
77
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
78
|
+
/**
|
|
79
|
+
* @param title 模板标题或魔术字
|
|
80
|
+
* @param parts 参数各部分
|
|
81
|
+
* @throws `SyntaxError` 非法的模板名称
|
|
82
|
+
*/
|
|
83
|
+
constructor(title, parts, config, accum = []) {
|
|
84
|
+
let heading;
|
|
85
|
+
const m = /^(?:\s|\0\d+[cn]\x7F)*\0(\d+)h\x7F(?:\s|\0\d+[cn]\x7F)*/u.exec(title);
|
|
86
|
+
if (m) {
|
|
87
|
+
heading = Number(m[1]);
|
|
88
|
+
title = title.replace(`\0${heading}h\x7F`, accum[heading].toString().replace(/^\n/u, ''));
|
|
51
89
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|| !('functionHook' in config) || functionHook.includes(canonicalName), isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
|
|
63
|
-
if (isFunction ? canonicalName && isFunc : isVar) {
|
|
64
|
-
this.setAttribute('name', canonicalName || lcName.replace(/^#|:$/u, ''));
|
|
65
|
-
this.#type = 'magic-word';
|
|
66
|
-
if (fullWidth) {
|
|
67
|
-
this.#colon = ':';
|
|
68
|
-
}
|
|
69
|
-
const token = new syntax_1.SyntaxToken(magicWord, 'magic-word-name', config, accum);
|
|
70
|
-
super.insertAt(token);
|
|
71
|
-
if (arg !== false) {
|
|
72
|
-
parts.unshift([arg]);
|
|
90
|
+
super(undefined, config, accum, {});
|
|
91
|
+
const { parserFunction: [insensitive, sensitive], variable, functionHook } = config, argSubst = /^(?:\s|\0\d+[cn]\x7F)*\0\d+s\x7F/u.exec(title)?.[0];
|
|
92
|
+
if (argSubst) {
|
|
93
|
+
this.setAttribute('modifier', argSubst);
|
|
94
|
+
title = title.slice(argSubst.length);
|
|
95
|
+
}
|
|
96
|
+
else if (title.includes(':')) {
|
|
97
|
+
const [modifier, ...arg] = title.split(':'), [mt] = /^(?:\s|\0\d+[cn]\x7F)*/u.exec(arg[0] ?? '');
|
|
98
|
+
if (this.setModifier(`${modifier}:${mt}`)) {
|
|
99
|
+
title = arg.join(':').slice(mt.length);
|
|
73
100
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
101
|
+
}
|
|
102
|
+
const colon = title.search(/[::]/u), fullWidth = title[colon] === ':', isFunction = colon !== -1;
|
|
103
|
+
if (isFunction || parts.length === 0 && !this.#raw) {
|
|
104
|
+
const magicWord = isFunction ? title.slice(0, colon) : title, arg = isFunction && title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = isFunction
|
|
105
|
+
? cleaned.slice(cleaned.search(/\S/u)) + (fullWidth ? ':' : '')
|
|
106
|
+
: cleaned.trim(), lcName = name.toLowerCase(), isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema
|
|
107
|
+
? sensitive.includes(name)
|
|
108
|
+
: Object.prototype.hasOwnProperty.call(sensitive, name), canonicalName = !isOldSchema && isSensitive
|
|
109
|
+
? sensitive[name]
|
|
110
|
+
: Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName], isFunc = isOldSchema && isSensitive
|
|
111
|
+
|| !('functionHook' in config) || functionHook.includes(canonicalName), isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
|
|
112
|
+
if (isFunction ? canonicalName && isFunc : isVar) {
|
|
113
|
+
this.setAttribute('name', canonicalName || lcName.replace(/^#|:$/u, ''));
|
|
114
|
+
this.#type = 'magic-word';
|
|
115
|
+
if (fullWidth) {
|
|
116
|
+
this.#colon = ':';
|
|
117
|
+
}
|
|
118
|
+
const token = new syntax_1.SyntaxToken(magicWord, 'magic-word-name', config, accum);
|
|
119
|
+
super.insertAt(token);
|
|
120
|
+
if (arg !== false) {
|
|
121
|
+
parts.unshift([arg]);
|
|
122
|
+
}
|
|
123
|
+
if (this.name === 'invoke') {
|
|
124
|
+
for (let i = 0; i < 2; i++) {
|
|
125
|
+
const part = parts.shift();
|
|
126
|
+
if (!part) {
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
const invoke = new atom_1.AtomToken(part.join('='), `invoke-${i ? 'function' : 'module'}`, config, accum);
|
|
130
|
+
super.insertAt(invoke);
|
|
79
131
|
}
|
|
80
|
-
const invoke = new atom_1.AtomToken(part.join('='), `invoke-${i ? 'function' : 'module'}`, config, accum);
|
|
81
|
-
super.insertAt(invoke);
|
|
82
132
|
}
|
|
83
133
|
}
|
|
84
134
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
135
|
+
if (this.type === 'template') {
|
|
136
|
+
const name = (0, string_1.removeComment)(title).trim();
|
|
137
|
+
if (!this.normalizeTitle(name, 10, { halfParsed: true, temporary: true }).valid) {
|
|
138
|
+
accum.pop();
|
|
139
|
+
throw new SyntaxError('Invalid template name');
|
|
140
|
+
}
|
|
141
|
+
const token = new atom_1.AtomToken(title, 'template-name', config, accum, {});
|
|
142
|
+
super.insertAt(token);
|
|
91
143
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (typeof heading === 'number') {
|
|
96
|
-
// @ts-expect-error sparse array
|
|
97
|
-
accum[heading] = undefined;
|
|
98
|
-
}
|
|
99
|
-
const templateLike = this.isTemplate();
|
|
100
|
-
let i = 1;
|
|
101
|
-
for (let j = 0; j < parts.length; j++) {
|
|
102
|
-
const part = parts[j];
|
|
103
|
-
if (!(templateLike || this.name === 'switch' && j > 0 || this.name === 'tag' && j > 1)) {
|
|
104
|
-
part[0] = part.join('=');
|
|
105
|
-
part.length = 1;
|
|
144
|
+
if (typeof heading === 'number') {
|
|
145
|
+
// @ts-expect-error sparse array
|
|
146
|
+
accum[heading] = undefined;
|
|
106
147
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
148
|
+
const templateLike = this.isTemplate();
|
|
149
|
+
let i = 1;
|
|
150
|
+
for (let j = 0; j < parts.length; j++) {
|
|
151
|
+
const part = parts[j];
|
|
152
|
+
if (!(templateLike || this.name === 'switch' && j > 0 || this.name === 'tag' && j > 1)) {
|
|
153
|
+
part[0] = part.join('=');
|
|
154
|
+
part.length = 1;
|
|
155
|
+
}
|
|
156
|
+
if (part.length === 1) {
|
|
157
|
+
part.unshift(i);
|
|
158
|
+
i++;
|
|
159
|
+
}
|
|
160
|
+
// @ts-expect-error abstract class
|
|
161
|
+
this.insertAt(new parameter_1.ParameterToken(...part, config, accum));
|
|
110
162
|
}
|
|
111
|
-
// @ts-expect-error abstract class
|
|
112
|
-
this.insertAt(new parameter_1.ParameterToken(...part, config, accum));
|
|
113
163
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Set the transclusion modifier
|
|
166
|
+
*
|
|
167
|
+
* 设置引用修饰符
|
|
168
|
+
* @param modifier transclusion modifier / 引用修饰符
|
|
169
|
+
*/
|
|
170
|
+
setModifier(modifier) {
|
|
171
|
+
const { parserFunction: [, , raw, subst] } = this.getAttribute('config'), lcModifier = (0, string_1.removeComment)(modifier).trim();
|
|
172
|
+
if (modifier && !lcModifier.endsWith(':')) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
const magicWord = lcModifier.slice(0, -1).toLowerCase(), isRaw = raw.includes(magicWord), isSubst = subst.includes(magicWord);
|
|
176
|
+
if (this.#raw && isRaw
|
|
177
|
+
|| !this.#raw && (isSubst || modifier === '')
|
|
178
|
+
|| (debug_1.Shadow.running || this.length > 1) && (isRaw || isSubst || modifier === '')) {
|
|
179
|
+
this.setAttribute('modifier', modifier);
|
|
180
|
+
this.#raw = isRaw;
|
|
181
|
+
return Boolean(modifier);
|
|
182
|
+
}
|
|
125
183
|
return false;
|
|
126
184
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return
|
|
185
|
+
/**
|
|
186
|
+
* Check if it is a template or a module
|
|
187
|
+
*
|
|
188
|
+
* 是否是模板或模块
|
|
189
|
+
*/
|
|
190
|
+
isTemplate() {
|
|
191
|
+
return this.type === 'template' || this.name === 'invoke';
|
|
134
192
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
*
|
|
140
|
-
* 是否是模板或模块
|
|
141
|
-
*/
|
|
142
|
-
isTemplate() {
|
|
143
|
-
return this.type === 'template' || this.name === 'invoke';
|
|
144
|
-
}
|
|
145
|
-
/** 获取模板或模块名 */
|
|
146
|
-
#getTitle() {
|
|
147
|
-
const isTemplate = this.type === 'template', title = this.normalizeTitle(this.childNodes[isTemplate ? 0 : 1].text(), isTemplate ? 10 : 828, { temporary: true });
|
|
148
|
-
return title;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Get the module name and module function name
|
|
152
|
-
*
|
|
153
|
-
* 获取模块名和模块函数名
|
|
154
|
-
* @throws `Error` 仅用于模块
|
|
155
|
-
*/
|
|
156
|
-
getModule() {
|
|
157
|
-
LSP: { // eslint-disable-line no-unused-labels
|
|
158
|
-
/* istanbul ignore if */
|
|
159
|
-
if (this.type !== 'magic-word' || this.name !== 'invoke') {
|
|
160
|
-
throw new Error('TranscludeToken.getModule method is only for modules!');
|
|
161
|
-
}
|
|
162
|
-
return [
|
|
163
|
-
this.#getTitle().title,
|
|
164
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
165
|
-
this.childNodes[2]?.text().trim(),
|
|
166
|
-
];
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/** @private */
|
|
170
|
-
afterBuild() {
|
|
171
|
-
if (this.modifier.includes('\0')) {
|
|
172
|
-
this.setAttribute('modifier', this.buildFromStr(this.modifier, constants_1.BuildMethod.String));
|
|
193
|
+
/** 获取模板或模块名 */
|
|
194
|
+
#getTitle() {
|
|
195
|
+
const isTemplate = this.type === 'template', title = this.normalizeTitle(this.childNodes[isTemplate ? 0 : 1].text(), isTemplate ? 10 : 828, { temporary: true });
|
|
196
|
+
return title;
|
|
173
197
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Get the module name and module function name
|
|
200
|
+
*
|
|
201
|
+
* 获取模块名和模块函数名
|
|
202
|
+
* @throws `Error` 仅用于模块
|
|
203
|
+
*/
|
|
204
|
+
getModule() {
|
|
205
|
+
LSP: { // eslint-disable-line no-unused-labels
|
|
206
|
+
/* istanbul ignore if */
|
|
207
|
+
if (this.type !== 'magic-word' || this.name !== 'invoke') {
|
|
208
|
+
throw new Error('TranscludeToken.getModule method is only for modules!');
|
|
209
|
+
}
|
|
210
|
+
return [
|
|
211
|
+
this.#getTitle().title,
|
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
213
|
+
this.childNodes[2]?.text().trim(),
|
|
214
|
+
];
|
|
180
215
|
}
|
|
181
216
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
? ''
|
|
196
|
-
: `{{${modifier}${type === 'magic-word'
|
|
197
|
-
? firstChild.text()
|
|
198
|
-
+ (length === 1 ? '' : this.#colon)
|
|
199
|
-
+ (0, string_1.text)(childNodes.slice(1), '|')
|
|
200
|
-
: super.text('|')}}}`;
|
|
201
|
-
}
|
|
202
|
-
/** @private */
|
|
203
|
-
getAttribute(key) {
|
|
204
|
-
switch (key) {
|
|
205
|
-
case 'padding':
|
|
206
|
-
return this.modifier.length + 2;
|
|
207
|
-
case 'title':
|
|
208
|
-
return this.#title;
|
|
209
|
-
case 'colon':
|
|
210
|
-
return this.#colon;
|
|
211
|
-
default:
|
|
212
|
-
return super.getAttribute(key);
|
|
217
|
+
/** @private */
|
|
218
|
+
afterBuild() {
|
|
219
|
+
if (this.modifier.includes('\0')) {
|
|
220
|
+
this.setAttribute('modifier', this.buildFromStr(this.modifier, constants_1.BuildMethod.String));
|
|
221
|
+
}
|
|
222
|
+
super.afterBuild();
|
|
223
|
+
if (this.isTemplate()) {
|
|
224
|
+
const isTemplate = this.type === 'template';
|
|
225
|
+
if (isTemplate) {
|
|
226
|
+
this.#title = this.#getTitle();
|
|
227
|
+
this.setAttribute('name', this.#title.title);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
213
230
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const errors = super.lint(start, re);
|
|
222
|
-
if (!this.isTemplate()) {
|
|
223
|
-
return errors;
|
|
231
|
+
/** @private */
|
|
232
|
+
toString(skip) {
|
|
233
|
+
return `{{${this.modifier}${this.type === 'magic-word'
|
|
234
|
+
? this.firstChild.toString(skip)
|
|
235
|
+
+ (this.length === 1 ? '' : this.#colon)
|
|
236
|
+
+ this.childNodes.slice(1).map(child => child.toString(skip)).join('|')
|
|
237
|
+
: super.toString(skip, '|')}}}`;
|
|
224
238
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
239
|
+
/** @private */
|
|
240
|
+
text() {
|
|
241
|
+
const { childNodes, length, firstChild, modifier, type, name } = this;
|
|
242
|
+
return type === 'magic-word' && name === 'vardefine'
|
|
243
|
+
? ''
|
|
244
|
+
: `{{${modifier}${type === 'magic-word'
|
|
245
|
+
? firstChild.text()
|
|
246
|
+
+ (length === 1 ? '' : this.#colon)
|
|
247
|
+
+ (0, string_1.text)(childNodes.slice(1), '|')
|
|
248
|
+
: super.text('|')}}}`;
|
|
228
249
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
desc: 'remove',
|
|
241
|
-
};
|
|
242
|
-
errors.push(e);
|
|
250
|
+
/** @private */
|
|
251
|
+
getAttribute(key) {
|
|
252
|
+
switch (key) {
|
|
253
|
+
case 'padding':
|
|
254
|
+
return this.modifier.length + 2;
|
|
255
|
+
case 'title':
|
|
256
|
+
return this.#title;
|
|
257
|
+
case 'colon':
|
|
258
|
+
return this.#colon;
|
|
259
|
+
default:
|
|
260
|
+
return super.getAttribute(key);
|
|
243
261
|
}
|
|
244
262
|
}
|
|
245
|
-
|
|
246
|
-
|
|
263
|
+
/** @private */
|
|
264
|
+
lint(start = this.getAbsoluteIndex(), re) {
|
|
265
|
+
const errors = super.lint(start, re);
|
|
266
|
+
if (!this.isTemplate()) {
|
|
267
|
+
return errors;
|
|
268
|
+
}
|
|
269
|
+
const { type, childNodes, length } = this, rect = new rect_1.BoundingRect(this, start), invoke = type === 'magic-word';
|
|
270
|
+
if (invoke && !this.#getTitle().valid) {
|
|
271
|
+
errors.push((0, lint_1.generateForChild)(childNodes[1], rect, 'invalid-invoke', 'illegal module name'));
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
const child = childNodes[invoke ? 1 : 0], i = child.childNodes
|
|
275
|
+
.findIndex(c => c.type === 'text' && (0, string_1.decodeHtml)(c.data).includes('#')), textNode = child.childNodes[i];
|
|
276
|
+
if (textNode) {
|
|
277
|
+
const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', 'useless fragment');
|
|
278
|
+
e.fix = {
|
|
279
|
+
range: [
|
|
280
|
+
e.startIndex + child.getRelativeIndex(i) + textNode.data.indexOf('#'),
|
|
281
|
+
e.endIndex,
|
|
282
|
+
],
|
|
283
|
+
text: '',
|
|
284
|
+
desc: 'remove',
|
|
285
|
+
};
|
|
286
|
+
errors.push(e);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (invoke && length === 2) {
|
|
290
|
+
errors.push((0, lint_1.generateForSelf)(this, rect, 'invalid-invoke', 'missing module function'));
|
|
291
|
+
return errors;
|
|
292
|
+
}
|
|
293
|
+
const duplicatedArgs = this.getDuplicatedArgs()
|
|
294
|
+
.filter(([, parameter]) => !parameter[0].querySelector('ext'));
|
|
295
|
+
if (duplicatedArgs.length > 0) {
|
|
296
|
+
for (const [, args] of duplicatedArgs) {
|
|
297
|
+
errors.push(...args.map(arg => {
|
|
298
|
+
const e = (0, lint_1.generateForChild)(arg, rect, 'no-duplicate', 'duplicated parameter');
|
|
299
|
+
e.suggestions = [{ desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' }];
|
|
300
|
+
return e;
|
|
301
|
+
}));
|
|
302
|
+
}
|
|
303
|
+
}
|
|
247
304
|
return errors;
|
|
248
305
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
306
|
+
/**
|
|
307
|
+
* 处理匿名参数更改
|
|
308
|
+
* @param addedToken 新增的参数
|
|
309
|
+
*/
|
|
310
|
+
#handleAnonArgChange(addedToken) {
|
|
311
|
+
const args = this.getAnonArgs(), added = typeof addedToken !== 'number';
|
|
312
|
+
for (let i = added ? args.indexOf(addedToken) : addedToken - 1; i < args.length; i++) {
|
|
313
|
+
const token = args[i], { name } = token, newName = String(i + 1);
|
|
314
|
+
if (name !== newName || token === addedToken) {
|
|
315
|
+
token.setAttribute('name', newName);
|
|
316
|
+
this.getArgs(newName, false, false).add(token);
|
|
317
|
+
}
|
|
258
318
|
}
|
|
259
319
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const token = args[i], { name } = token, newName = String(i + 1);
|
|
270
|
-
if (name !== newName || token === addedToken) {
|
|
271
|
-
token.setAttribute('name', newName);
|
|
272
|
-
this.getArgs(newName, false, false).add(token);
|
|
320
|
+
/**
|
|
321
|
+
* @override
|
|
322
|
+
* @param token node to be inserted / 待插入的子节点
|
|
323
|
+
* @param i position to be inserted at / 插入位置
|
|
324
|
+
*/
|
|
325
|
+
insertAt(token, i = this.length) {
|
|
326
|
+
super.insertAt(token, i);
|
|
327
|
+
if (token.anon) {
|
|
328
|
+
this.#handleAnonArgChange(token);
|
|
273
329
|
}
|
|
330
|
+
else if (token.name) {
|
|
331
|
+
this.getArgs(token.name, false, false).add(token);
|
|
332
|
+
}
|
|
333
|
+
return token;
|
|
274
334
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
super.insertAt(token, i);
|
|
283
|
-
if (token.anon) {
|
|
284
|
-
this.#handleAnonArgChange(token);
|
|
285
|
-
}
|
|
286
|
-
else if (token.name) {
|
|
287
|
-
this.getArgs(token.name, false, false).add(token);
|
|
335
|
+
/**
|
|
336
|
+
* Get all parameters
|
|
337
|
+
*
|
|
338
|
+
* 获取所有参数
|
|
339
|
+
*/
|
|
340
|
+
getAllArgs() {
|
|
341
|
+
return this.childNodes.filter((0, debug_1.isToken)('parameter'));
|
|
288
342
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
getAllArgs() {
|
|
297
|
-
return this.childNodes.filter((0, debug_1.isToken)('parameter'));
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Get all anonymous parameters
|
|
301
|
-
*
|
|
302
|
-
* 获取所有匿名参数
|
|
303
|
-
*/
|
|
304
|
-
getAnonArgs() {
|
|
305
|
-
return this.getAllArgs().filter(({ anon }) => anon);
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Get parameters with the specified name
|
|
309
|
-
*
|
|
310
|
-
* 获取指定参数
|
|
311
|
-
* @param key parameter name / 参数名
|
|
312
|
-
* @param exact whether to match anonymosity / 是否匹配匿名性
|
|
313
|
-
* @param copy whether to return a copy / 是否返回一个备份
|
|
314
|
-
*/
|
|
315
|
-
getArgs(key, exact, copy = true) {
|
|
316
|
-
const keyStr = String(key)
|
|
317
|
-
.replace(/^[ \t\n\0\v]+|([^ \t\n\0\v])[ \t\n\0\v]+$/gu, '$1');
|
|
318
|
-
let args;
|
|
319
|
-
if (this.#args.has(keyStr)) {
|
|
320
|
-
args = this.#args.get(keyStr);
|
|
343
|
+
/**
|
|
344
|
+
* Get all anonymous parameters
|
|
345
|
+
*
|
|
346
|
+
* 获取所有匿名参数
|
|
347
|
+
*/
|
|
348
|
+
getAnonArgs() {
|
|
349
|
+
return this.getAllArgs().filter(({ anon }) => anon);
|
|
321
350
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
351
|
+
/**
|
|
352
|
+
* Get parameters with the specified name
|
|
353
|
+
*
|
|
354
|
+
* 获取指定参数
|
|
355
|
+
* @param key parameter name / 参数名
|
|
356
|
+
* @param exact whether to match anonymosity / 是否匹配匿名性
|
|
357
|
+
* @param copy whether to return a copy / 是否返回一个备份
|
|
358
|
+
*/
|
|
359
|
+
getArgs(key, exact, copy = true) {
|
|
360
|
+
const keyStr = String(key)
|
|
361
|
+
.replace(/^[ \t\n\0\v]+|([^ \t\n\0\v])[ \t\n\0\v]+$/gu, '$1');
|
|
362
|
+
let args;
|
|
363
|
+
if (this.#args.has(keyStr)) {
|
|
364
|
+
args = this.#args.get(keyStr);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
args = new Set(this.getAllArgs().filter(({ name }) => keyStr === name));
|
|
368
|
+
this.#args.set(keyStr, args);
|
|
369
|
+
}
|
|
370
|
+
return args;
|
|
325
371
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
getDuplicatedArgs() {
|
|
334
|
-
return [...this.#args].filter(([, { size }]) => size > 1).map(([key, args]) => [key, [...args]]);
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Get possible values of some magic words
|
|
338
|
-
*
|
|
339
|
-
* 对特定魔术字获取可能的取值
|
|
340
|
-
* @throws `Error` 不是可接受的魔术字
|
|
341
|
-
*/
|
|
342
|
-
getPossibleValues() {
|
|
343
|
-
const { type, name, childNodes } = this;
|
|
344
|
-
if (type === 'template') {
|
|
345
|
-
throw new Error('TranscludeToken.getPossibleValues method is only for specific magic words!');
|
|
372
|
+
/**
|
|
373
|
+
* Get duplicated parameters
|
|
374
|
+
*
|
|
375
|
+
* 获取重名参数
|
|
376
|
+
*/
|
|
377
|
+
getDuplicatedArgs() {
|
|
378
|
+
return [...this.#args].filter(([, { size }]) => size > 1).map(([key, args]) => [key, [...args]]);
|
|
346
379
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
start = 3;
|
|
357
|
-
break;
|
|
358
|
-
case 'switch': {
|
|
359
|
-
const parameters = childNodes.slice(2), last = parameters[parameters.length - 1];
|
|
360
|
-
queue = [
|
|
361
|
-
...parameters.filter(({ anon }) => !anon),
|
|
362
|
-
...last?.anon ? [last] : [],
|
|
363
|
-
].map(({ lastChild }) => lastChild);
|
|
364
|
-
break;
|
|
365
|
-
}
|
|
366
|
-
default:
|
|
380
|
+
/**
|
|
381
|
+
* Get possible values of some magic words
|
|
382
|
+
*
|
|
383
|
+
* 对特定魔术字获取可能的取值
|
|
384
|
+
* @throws `Error` 不是可接受的魔术字
|
|
385
|
+
*/
|
|
386
|
+
getPossibleValues() {
|
|
387
|
+
const { type, name, childNodes } = this;
|
|
388
|
+
if (type === 'template') {
|
|
367
389
|
throw new Error('TranscludeToken.getPossibleValues method is only for specific magic words!');
|
|
368
|
-
}
|
|
369
|
-
queue ??= childNodes.slice(start, start + 2).map(({ lastChild }) => lastChild);
|
|
370
|
-
for (let i = 0; i < queue.length;) {
|
|
371
|
-
const { length, 0: first } = queue[i].childNodes.filter(child => child.text().trim());
|
|
372
|
-
if (length === 0) {
|
|
373
|
-
queue.splice(i, 1);
|
|
374
390
|
}
|
|
375
|
-
|
|
376
|
-
|
|
391
|
+
let start, queue;
|
|
392
|
+
switch (name) {
|
|
393
|
+
case 'if':
|
|
394
|
+
case 'ifexist':
|
|
395
|
+
case 'ifexpr':
|
|
396
|
+
case 'iferror':
|
|
397
|
+
start = 2;
|
|
398
|
+
break;
|
|
399
|
+
case 'ifeq':
|
|
400
|
+
start = 3;
|
|
401
|
+
break;
|
|
402
|
+
case 'switch': {
|
|
403
|
+
const parameters = childNodes.slice(2), last = parameters[parameters.length - 1];
|
|
404
|
+
queue = [
|
|
405
|
+
...parameters.filter(({ anon }) => !anon),
|
|
406
|
+
...last?.anon ? [last] : [],
|
|
407
|
+
].map(({ lastChild }) => lastChild);
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
default:
|
|
411
|
+
throw new Error('TranscludeToken.getPossibleValues method is only for specific magic words!');
|
|
377
412
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
i
|
|
413
|
+
queue ??= childNodes.slice(start, start + 2).map(({ lastChild }) => lastChild);
|
|
414
|
+
for (let i = 0; i < queue.length;) {
|
|
415
|
+
const { length, 0: first } = queue[i].childNodes.filter(child => child.text().trim());
|
|
416
|
+
if (length === 0) {
|
|
417
|
+
queue.splice(i, 1);
|
|
383
418
|
}
|
|
384
|
-
|
|
419
|
+
else if (length > 1 || first.type !== 'magic-word') {
|
|
385
420
|
i++;
|
|
386
421
|
}
|
|
422
|
+
else {
|
|
423
|
+
try {
|
|
424
|
+
const possibleValues = first.getPossibleValues();
|
|
425
|
+
queue.splice(i, 1, ...possibleValues);
|
|
426
|
+
i += possibleValues.length;
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
i++;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
387
432
|
}
|
|
433
|
+
return queue;
|
|
388
434
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
}
|
|
435
|
+
};
|
|
436
|
+
return TranscludeToken = _classThis;
|
|
437
|
+
})();
|
|
392
438
|
exports.TranscludeToken = TranscludeToken;
|