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.
Files changed (83) hide show
  1. package/config/default.json +49 -3
  2. package/config/minimum.json +5 -1
  3. package/data/ext/math.json +660 -0
  4. package/dist/base.d.mts +1 -1
  5. package/dist/base.d.ts +1 -1
  6. package/dist/bin/cli.js +19 -6
  7. package/dist/bin/config.js +26 -8
  8. package/dist/index.js +10 -1
  9. package/dist/internal.d.ts +2 -0
  10. package/dist/lib/document.d.ts +1 -0
  11. package/dist/lib/document.js +10 -1
  12. package/dist/lib/element.js +15 -4
  13. package/dist/lib/lsp.js +87 -57
  14. package/dist/lib/node.js +0 -7
  15. package/dist/lib/text.js +3 -7
  16. package/dist/lib/title.js +1 -6
  17. package/dist/mixin/attributesParent.js +1 -1
  18. package/dist/mixin/gapped.d.ts +4 -0
  19. package/dist/mixin/gapped.js +20 -0
  20. package/dist/mixin/hidden.js +1 -1
  21. package/dist/mixin/multiLine.d.ts +4 -0
  22. package/dist/mixin/multiLine.js +26 -0
  23. package/dist/mixin/padded.d.ts +5 -0
  24. package/dist/mixin/padded.js +20 -0
  25. package/dist/parser/braces.js +8 -12
  26. package/dist/parser/commentAndExt.js +18 -2
  27. package/dist/parser/magicLinks.js +1 -1
  28. package/dist/parser/selector.js +5 -2
  29. package/dist/src/arg.js +131 -84
  30. package/dist/src/attribute.js +4 -4
  31. package/dist/src/attributes.js +2 -2
  32. package/dist/src/commented.d.ts +19 -0
  33. package/dist/src/commented.js +41 -0
  34. package/dist/src/converter.js +90 -43
  35. package/dist/src/converterFlags.js +113 -66
  36. package/dist/src/converterRule.d.ts +1 -1
  37. package/dist/src/extLink.d.ts +2 -3
  38. package/dist/src/extLink.js +97 -54
  39. package/dist/src/gallery.d.ts +3 -4
  40. package/dist/src/gallery.js +114 -72
  41. package/dist/src/heading.js +10 -10
  42. package/dist/src/imageParameter.d.ts +1 -1
  43. package/dist/src/imageParameter.js +4 -3
  44. package/dist/src/imagemap.d.ts +1 -1
  45. package/dist/src/imagemap.js +126 -86
  46. package/dist/src/imagemapLink.d.ts +1 -1
  47. package/dist/src/index.js +11 -8
  48. package/dist/src/link/base.d.ts +2 -3
  49. package/dist/src/link/base.js +149 -105
  50. package/dist/src/link/file.d.ts +2 -3
  51. package/dist/src/link/file.js +2 -2
  52. package/dist/src/link/galleryImage.d.ts +2 -3
  53. package/dist/src/link/galleryImage.js +89 -47
  54. package/dist/src/nested.d.ts +1 -1
  55. package/dist/src/nowiki/comment.js +2 -5
  56. package/dist/src/nowiki/doubleUnderscore.js +2 -5
  57. package/dist/src/nowiki/index.d.ts +1 -1
  58. package/dist/src/nowiki/index.js +2 -1
  59. package/dist/src/onlyinclude.js +63 -15
  60. package/dist/src/paramTag/index.d.ts +1 -1
  61. package/dist/src/paramTag/index.js +89 -47
  62. package/dist/src/parameter.d.ts +3 -4
  63. package/dist/src/parameter.js +4 -8
  64. package/dist/src/pre.d.ts +3 -4
  65. package/dist/src/pre.js +5 -9
  66. package/dist/src/syntax.d.ts +1 -1
  67. package/dist/src/table/base.d.ts +2 -2
  68. package/dist/src/table/base.js +3 -7
  69. package/dist/src/table/index.js +1 -1
  70. package/dist/src/table/td.d.ts +2 -3
  71. package/dist/src/table/td.js +3 -7
  72. package/dist/src/table/tr.d.ts +1 -1
  73. package/dist/src/tagPair/ext.js +34 -31
  74. package/dist/src/tagPair/index.d.ts +1 -1
  75. package/dist/src/tagPair/index.js +94 -47
  76. package/dist/src/tagPair/translate.d.ts +22 -0
  77. package/dist/src/tagPair/translate.js +48 -0
  78. package/dist/src/transclude.js +378 -332
  79. package/dist/util/lint.js +17 -30
  80. package/dist/util/sharable.js +29 -1
  81. package/dist/util/sharable.mjs +31 -3
  82. package/dist/util/string.js +14 -1
  83. package/package.json +3 -2
@@ -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
- class TranscludeToken extends index_1.Token {
20
- modifier = '';
21
- #type = 'template';
22
- #colon = ':';
23
- #raw = false;
24
- #args = new Map();
25
- #title;
26
- get type() {
27
- return this.#type;
28
- }
29
- /**
30
- * @param title 模板标题或魔术字
31
- * @param parts 参数各部分
32
- * @throws `SyntaxError` 非法的模板名称
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
- super(undefined, config, accum, {});
42
- const { parserFunction: [insensitive, sensitive], variable, functionHook } = config, argSubst = /^(?:\s|\0\d+[cn]\x7F)*\0\d+s\x7F/u.exec(title)?.[0];
43
- if (argSubst) {
44
- this.setAttribute('modifier', argSubst);
45
- title = title.slice(argSubst.length);
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
- else if (title.includes(':')) {
48
- const [modifier, ...arg] = title.split(':'), [mt] = /^(?:\s|\0\d+[cn]\x7F)*/u.exec(arg[0] ?? '');
49
- if (this.setModifier(`${modifier}:${mt}`)) {
50
- title = arg.join(':').slice(mt.length);
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
- const colon = title.search(/[::]/u), fullWidth = title[colon] === ':', isFunction = colon !== -1;
54
- if (isFunction || parts.length === 0 && !this.#raw) {
55
- const magicWord = isFunction ? title.slice(0, colon) : title, arg = isFunction && title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = isFunction
56
- ? cleaned.slice(cleaned.search(/\S/u)) + (fullWidth ? ':' : '')
57
- : cleaned.trim(), lcName = name.toLowerCase(), isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema
58
- ? sensitive.includes(name)
59
- : Object.prototype.hasOwnProperty.call(sensitive, name), canonicalName = !isOldSchema && isSensitive
60
- ? sensitive[name]
61
- : Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName], isFunc = isOldSchema && isSensitive
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
- if (this.name === 'invoke') {
75
- for (let i = 0; i < 2; i++) {
76
- const part = parts.shift();
77
- if (!part) {
78
- break;
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
- if (this.type === 'template') {
87
- const name = (0, string_1.removeComment)(title).trim();
88
- if (!this.normalizeTitle(name, 10, { halfParsed: true, temporary: true }).valid) {
89
- accum.pop();
90
- throw new SyntaxError('Invalid template name');
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
- const token = new atom_1.AtomToken(title, 'template-name', config, accum, {});
93
- super.insertAt(token);
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
- if (part.length === 1) {
108
- part.unshift(i);
109
- i++;
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
- this.seal('modifier');
115
- }
116
- /**
117
- * Set the transclusion modifier
118
- *
119
- * 设置引用修饰符
120
- * @param modifier transclusion modifier / 引用修饰符
121
- */
122
- setModifier(modifier) {
123
- const { parserFunction: [, , raw, subst] } = this.getAttribute('config'), lcModifier = (0, string_1.removeComment)(modifier).trim();
124
- if (modifier && !lcModifier.endsWith(':')) {
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
- const magicWord = lcModifier.slice(0, -1).toLowerCase(), isRaw = raw.includes(magicWord), isSubst = subst.includes(magicWord);
128
- if (this.#raw && isRaw
129
- || !this.#raw && (isSubst || modifier === '')
130
- || (debug_1.Shadow.running || this.length > 1) && (isRaw || isSubst || modifier === '')) {
131
- this.setAttribute('modifier', modifier);
132
- this.#raw = isRaw;
133
- return Boolean(modifier);
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
- return false;
136
- }
137
- /**
138
- * Check if it is a template or a module
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
- super.afterBuild();
175
- if (this.isTemplate()) {
176
- const isTemplate = this.type === 'template';
177
- if (isTemplate) {
178
- this.#title = this.#getTitle();
179
- this.setAttribute('name', this.#title.title);
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
- /** @private */
184
- toString(skip) {
185
- return `{{${this.modifier}${this.type === 'magic-word'
186
- ? this.firstChild.toString(skip)
187
- + (this.length === 1 ? '' : this.#colon)
188
- + this.childNodes.slice(1).map(child => child.toString(skip)).join('|')
189
- : super.toString(skip, '|')}}}`;
190
- }
191
- /** @private */
192
- text() {
193
- const { childNodes, length, firstChild, modifier, type, name } = this;
194
- return type === 'magic-word' && name === 'vardefine'
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
- /** @private */
216
- getGaps() {
217
- return 1;
218
- }
219
- /** @private */
220
- lint(start = this.getAbsoluteIndex(), re) {
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
- const { type, childNodes, length } = this, rect = new rect_1.BoundingRect(this, start), invoke = type === 'magic-word';
226
- if (invoke && !this.#getTitle().valid) {
227
- errors.push((0, lint_1.generateForChild)(childNodes[1], rect, 'invalid-invoke', 'illegal module name'));
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
- else {
230
- const child = childNodes[invoke ? 1 : 0], i = child.childNodes
231
- .findIndex(c => c.type === 'text' && (0, string_1.decodeHtml)(c.data).includes('#')), textNode = child.childNodes[i];
232
- if (textNode) {
233
- const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', 'useless fragment');
234
- e.fix = {
235
- range: [
236
- e.startIndex + child.getRelativeIndex(i) + textNode.data.indexOf('#'),
237
- e.endIndex,
238
- ],
239
- text: '',
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
- if (invoke && length === 2) {
246
- errors.push((0, lint_1.generateForSelf)(this, rect, 'invalid-invoke', 'missing module function'));
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
- const duplicatedArgs = this.getDuplicatedArgs()
250
- .filter(([, parameter]) => !parameter[0].querySelector('ext'));
251
- if (duplicatedArgs.length > 0) {
252
- for (const [, args] of duplicatedArgs) {
253
- errors.push(...args.map(arg => {
254
- const e = (0, lint_1.generateForChild)(arg, rect, 'no-duplicate', 'duplicated parameter');
255
- e.suggestions = [{ desc: 'remove', range: [e.startIndex - 1, e.endIndex], text: '' }];
256
- return e;
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
- return errors;
261
- }
262
- /**
263
- * 处理匿名参数更改
264
- * @param addedToken 新增的参数
265
- */
266
- #handleAnonArgChange(addedToken) {
267
- const args = this.getAnonArgs(), added = typeof addedToken !== 'number';
268
- for (let i = added ? args.indexOf(addedToken) : addedToken - 1; i < args.length; i++) {
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
- * @override
278
- * @param token node to be inserted / 待插入的子节点
279
- * @param i position to be inserted at / 插入位置
280
- */
281
- insertAt(token, i = this.length) {
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
- return token;
290
- }
291
- /**
292
- * Get all parameters
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
- else {
323
- args = new Set(this.getAllArgs().filter(({ name }) => keyStr === name));
324
- this.#args.set(keyStr, args);
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
- return args;
327
- }
328
- /**
329
- * Get duplicated parameters
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
- let start, queue;
348
- switch (name) {
349
- case 'if':
350
- case 'ifexist':
351
- case 'ifexpr':
352
- case 'iferror':
353
- start = 2;
354
- break;
355
- case 'ifeq':
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
- else if (length > 1 || first.type !== 'magic-word') {
376
- i++;
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
- else {
379
- try {
380
- const possibleValues = first.getPossibleValues();
381
- queue.splice(i, 1, ...possibleValues);
382
- i += possibleValues.length;
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
- catch {
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
- return queue;
390
- }
391
- }
435
+ };
436
+ return TranscludeToken = _classThis;
437
+ })();
392
438
  exports.TranscludeToken = TranscludeToken;