wikiparser-node 0.5.0 → 0.6.2-b

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 (70) hide show
  1. package/bundle/bundle.min.js +34 -0
  2. package/package.json +10 -13
  3. package/README.md +0 -39
  4. package/config/default.json +0 -769
  5. package/config/llwiki.json +0 -630
  6. package/config/moegirl.json +0 -727
  7. package/config/zhwiki.json +0 -1269
  8. package/index.js +0 -268
  9. package/lib/element.js +0 -639
  10. package/lib/node.js +0 -743
  11. package/lib/ranges.js +0 -130
  12. package/lib/text.js +0 -175
  13. package/lib/title.js +0 -69
  14. package/mixin/attributeParent.js +0 -113
  15. package/mixin/fixedToken.js +0 -40
  16. package/mixin/hidden.js +0 -19
  17. package/mixin/sol.js +0 -69
  18. package/parser/brackets.js +0 -112
  19. package/parser/commentAndExt.js +0 -63
  20. package/parser/converter.js +0 -45
  21. package/parser/externalLinks.js +0 -31
  22. package/parser/hrAndDoubleUnderscore.js +0 -36
  23. package/parser/html.js +0 -42
  24. package/parser/links.js +0 -97
  25. package/parser/list.js +0 -59
  26. package/parser/magicLinks.js +0 -41
  27. package/parser/quotes.js +0 -64
  28. package/parser/selector.js +0 -175
  29. package/parser/table.js +0 -112
  30. package/src/arg.js +0 -193
  31. package/src/atom/hidden.js +0 -13
  32. package/src/atom/index.js +0 -41
  33. package/src/attribute.js +0 -449
  34. package/src/converter.js +0 -165
  35. package/src/converterFlags.js +0 -269
  36. package/src/converterRule.js +0 -259
  37. package/src/extLink.js +0 -173
  38. package/src/gallery.js +0 -122
  39. package/src/heading.js +0 -119
  40. package/src/html.js +0 -230
  41. package/src/imageParameter.js +0 -260
  42. package/src/index.js +0 -744
  43. package/src/link/category.js +0 -53
  44. package/src/link/file.js +0 -285
  45. package/src/link/galleryImage.js +0 -61
  46. package/src/link/index.js +0 -325
  47. package/src/magicLink.js +0 -136
  48. package/src/nowiki/comment.js +0 -71
  49. package/src/nowiki/dd.js +0 -59
  50. package/src/nowiki/doubleUnderscore.js +0 -56
  51. package/src/nowiki/hr.js +0 -41
  52. package/src/nowiki/index.js +0 -44
  53. package/src/nowiki/list.js +0 -16
  54. package/src/nowiki/noinclude.js +0 -28
  55. package/src/nowiki/quote.js +0 -63
  56. package/src/onlyinclude.js +0 -59
  57. package/src/parameter.js +0 -200
  58. package/src/syntax.js +0 -83
  59. package/src/table/index.js +0 -980
  60. package/src/table/td.js +0 -314
  61. package/src/table/tr.js +0 -299
  62. package/src/tagPair/ext.js +0 -104
  63. package/src/tagPair/include.js +0 -60
  64. package/src/tagPair/index.js +0 -125
  65. package/src/transclude.js +0 -736
  66. package/tool/index.js +0 -918
  67. package/util/debug.js +0 -73
  68. package/util/diff.js +0 -76
  69. package/util/lint.js +0 -40
  70. package/util/string.js +0 -105
@@ -1,269 +0,0 @@
1
- 'use strict';
2
-
3
- const {generateForChild} = require('../util/lint'),
4
- Parser = require('..'),
5
- Token = require('.'),
6
- AtomToken = require('./atom');
7
-
8
- /**
9
- * 转换flags
10
- * @classdesc `{childNodes: ...AtomToken}`
11
- */
12
- class ConverterFlagsToken extends Token {
13
- type = 'converter-flags';
14
- /** @type {string[]} */ #flags;
15
-
16
- /**
17
- * @param {string[]} flags 转换类型标记
18
- * @param {accum} accum
19
- */
20
- constructor(flags, config = Parser.getConfig(), accum = []) {
21
- super(undefined, config, true, accum, {AtomToken: ':'});
22
- this.append(...flags.map(flag => new AtomToken(flag, 'converter-flag', config, accum)));
23
- }
24
-
25
- /** @override */
26
- cloneNode() {
27
- const cloned = this.cloneChildNodes(),
28
- token = Parser.run(() => new ConverterFlagsToken([], this.getAttribute('config')));
29
- token.append(...cloned);
30
- token.afterBuild();
31
- return token;
32
- }
33
-
34
- /**
35
- * @override
36
- * @complexity `n`
37
- */
38
- afterBuild() {
39
- this.#flags = this.childNodes.map(child => child.text().trim());
40
- const /** @type {AstListener} */ converterFlagsListener = ({prevTarget}) => {
41
- if (prevTarget) {
42
- this.#flags[this.childNodes.indexOf(prevTarget)] = prevTarget.text().trim();
43
- }
44
- };
45
- this.addEventListener(['remove', 'insert', 'text', 'replace'], converterFlagsListener);
46
- return this;
47
- }
48
-
49
- /**
50
- * @override
51
- * @template {string} T
52
- * @param {T} key 属性键
53
- * @returns {TokenAttribute<T>}
54
- */
55
- getAttribute(key) {
56
- if (key === 'flags') {
57
- return Parser.debugging ? this.#flags : [...this.#flags];
58
- }
59
- return super.getAttribute(key);
60
- }
61
-
62
- /**
63
- * @override
64
- * @param {number} i 移除位置
65
- * @complexity `n`
66
- */
67
- removeAt(i) {
68
- const /** @type {AtomToken} */ token = super.removeAt(i);
69
- this.#flags?.splice(i, 1);
70
- return token;
71
- }
72
-
73
- /**
74
- * @override
75
- * @param {AtomToken} token 待插入的子节点
76
- * @param {number} i 插入位置
77
- * @complexity `n`
78
- */
79
- insertAt(token, i = this.childNodes.length) {
80
- super.insertAt(token, i);
81
- this.#flags?.splice(i, 0, token.text());
82
- return token;
83
- }
84
-
85
- /**
86
- * @override
87
- * @param {string} selector
88
- */
89
- toString(selector) {
90
- return super.toString(selector, ';');
91
- }
92
-
93
- /** @override */
94
- getGaps() {
95
- return 1;
96
- }
97
-
98
- /** @override */
99
- print() {
100
- return super.print({sep: ';'});
101
- }
102
-
103
- /**
104
- * @override
105
- * @param {number} start 起始位置
106
- */
107
- lint(start = 0) {
108
- const variantFlags = this.getVariantFlags(),
109
- unknownFlags = this.getUnknownFlags(),
110
- emptyFlags = this.#flags.filter(flag => !flag),
111
- validFlags = this.#flags.filter(flag => ['A', 'T', 'R', 'D', '-', 'H', 'N'].includes(flag)),
112
- knownFlagCount = this.#flags.length - unknownFlags.length - emptyFlags,
113
- errors = super.lint(start);
114
- if (variantFlags.length === knownFlagCount || validFlags.length === knownFlagCount) {
115
- return errors;
116
- }
117
- const rect = this.getRootNode().posFromIndex(start);
118
- for (const child of this.childNodes) {
119
- const flag = child.text().trim();
120
- if (flag && !variantFlags.includes(flag) && !unknownFlags.includes(flag)
121
- && (variantFlags.length > 0 || !validFlags.includes(flag))
122
- ) {
123
- errors.push(generateForChild(child, rect, '无效的转换标记'));
124
- }
125
- }
126
- return errors;
127
- }
128
-
129
- /** @override */
130
- text() {
131
- return super.text(';');
132
- }
133
-
134
- /**
135
- * 获取转换类型标记节点
136
- * @param {string} flag 转换类型标记
137
- * @returns {AtomToken[]}
138
- * @complexity `n`
139
- */
140
- getFlagToken(flag) {
141
- return this.#flags.includes(flag) ? this.childNodes.filter(child => child.text().trim() === flag) : [];
142
- }
143
-
144
- /** 获取所有转换类型标记 */
145
- getAllFlags() {
146
- return new Set(this.#flags);
147
- }
148
-
149
- /**
150
- * 获取未知转换类型标记
151
- * @complexity `n`
152
- */
153
- getUnknownFlags() {
154
- return this.#flags.filter(flag => /\{\{[^{}]+\}\}/u.test(flag));
155
- }
156
-
157
- /** 获取指定语言变体的转换标记 */
158
- getVariantFlags() {
159
- const {variants} = this.getAttribute('config');
160
- return this.#flags.filter(flag => variants.includes(flag));
161
- }
162
-
163
- /**
164
- * 获取有效转换类型标记
165
- * @complexity `n`
166
- */
167
- getEffectiveFlags() {
168
- const variantFlags = this.getVariantFlags(),
169
- unknownFlags = this.getUnknownFlags();
170
- if (variantFlags.length > 0) {
171
- return new Set([...variantFlags, ...unknownFlags]);
172
- }
173
- const validFlags = ['A', 'T', 'R', 'D', '-', 'H', 'N'],
174
- flags = new Set([...this.#flags.filter(flag => validFlags.includes(flag)), ...unknownFlags]);
175
- if (flags.size === 0) {
176
- return new Set('S');
177
- } else if (flags.has('R')) {
178
- return new Set('R');
179
- } else if (flags.has('N')) {
180
- return new Set('N');
181
- } else if (flags.has('-')) {
182
- return new Set('-');
183
- } else if (flags.has('H')) {
184
- const hasT = flags.has('T'),
185
- hasD = flags.has('D');
186
- return hasT && hasD
187
- ? new Set(['+', 'H', 'T', 'D'])
188
- : new Set(['+', 'H', ...hasT ? ['T'] : [], ...hasD ? ['D'] : [], ...unknownFlags]);
189
- }
190
- if (flags.size === 1 && flags.has('T')) {
191
- flags.add('H');
192
- }
193
- if (flags.has('A')) {
194
- flags.add('+');
195
- flags.add('S');
196
- }
197
- if (flags.has('D')) {
198
- flags.delete('S');
199
- }
200
- return flags;
201
- }
202
-
203
- /**
204
- * 是否具有某转换类型标记
205
- * @param {string} flag 转换类型标记
206
- */
207
- hasFlag(flag) {
208
- return typeof flag === 'string' ? this.#flags.includes(flag) : this.typeError('hasFlag', 'String');
209
- }
210
-
211
- /**
212
- * 是否具有某有效转换类型标记
213
- * @param {string} flag 转换类型标记
214
- * @complexity `n`
215
- */
216
- hasEffectiveFlag(flag) {
217
- return typeof flag === 'string' ? this.getEffectiveFlags().has(flag) : this.typeError('hasFlag', 'String');
218
- }
219
-
220
- /**
221
- * 移除某转换类型标记
222
- * @param {string} flag 转换类型标记
223
- * @complexity `n²`
224
- */
225
- removeFlag(flag) {
226
- for (const token of this.getFlagToken(flag)) {
227
- token.remove();
228
- }
229
- }
230
-
231
- /**
232
- * 添加转换类型标记
233
- * @param {string} flag 转换类型标记
234
- * @complexity `n`
235
- */
236
- #newFlag(flag) {
237
- const token = Parser.run(() => new AtomToken(flag, 'converter-flag', this.getAttribute('config')));
238
- this.appendChild(token);
239
- }
240
-
241
- /**
242
- * 设置转换类型标记
243
- * @param {string} flag 转换类型标记
244
- * @complexity `n`
245
- */
246
- setFlag(flag) {
247
- if (!this.#flags.includes(flag)) {
248
- this.#newFlag(flag);
249
- } else if (!this.getEffectiveFlags().has(flag)) {
250
- Parser.error('此 flag 不会生效', flag);
251
- }
252
- }
253
-
254
- /**
255
- * 开关转换类型标记
256
- * @param {string} flag 转换类型标记
257
- * @complexity `n²`
258
- */
259
- toggleFlag(flag) {
260
- if (this.#flags.includes(flag)) {
261
- this.removeFlag(flag);
262
- } else {
263
- this.#newFlag(flag);
264
- }
265
- }
266
- }
267
-
268
- Parser.classes.ConverterFlagsToken = __filename;
269
- module.exports = ConverterFlagsToken;
@@ -1,259 +0,0 @@
1
- 'use strict';
2
-
3
- const {undo} = require('../util/debug'),
4
- {noWrap} = require('../util/string'),
5
- Parser = require('..'),
6
- Token = require('.'),
7
- AtomToken = require('./atom');
8
-
9
- /**
10
- * 转换规则
11
- * @classdesc `{childNodes: ...AtomToken)}`
12
- */
13
- class ConverterRuleToken extends Token {
14
- type = 'converter-rule';
15
-
16
- /** 语言变体 */
17
- get variant() {
18
- return this.childNodes.at(-2)?.text()?.trim() ?? '';
19
- }
20
-
21
- set variant(variant) {
22
- this.setVariant(variant);
23
- }
24
-
25
- /** 是否是单向转换 */
26
- get unidirectional() {
27
- return this.childNodes.length === 3;
28
- }
29
-
30
- set unidirectional(unidirectional) {
31
- if (unidirectional === false) {
32
- this.makeBidirectional();
33
- }
34
- }
35
-
36
- /** 是否是双向转换 */
37
- get bidirectional() {
38
- return this.childNodes.length === 2;
39
- }
40
-
41
- /**
42
- * @param {string} rule 转换规则
43
- * @param {boolean} hasColon 是否带有":"
44
- * @param {accum} accum
45
- */
46
- constructor(rule, hasColon = true, config = Parser.getConfig(), accum = []) {
47
- super(undefined, config, true, accum, {AtomToken: ':'});
48
- if (hasColon) {
49
- const i = rule.indexOf(':'),
50
- j = rule.slice(0, i).indexOf('=>'),
51
- v = j === -1 ? rule.slice(0, i) : rule.slice(j + 2, i),
52
- {variants} = config;
53
- if (variants.includes(v.trim())) {
54
- super.insertAt(new AtomToken(v, 'converter-rule-variant', config, accum));
55
- super.insertAt(new AtomToken(rule.slice(i + 1), 'converter-rule-to', config, accum));
56
- if (j !== -1) {
57
- super.insertAt(new AtomToken(rule.slice(0, j), 'converter-rule-from', config, accum), 0);
58
- }
59
- } else {
60
- super.insertAt(new AtomToken(rule, 'converter-rule-noconvert', config, accum));
61
- }
62
- } else {
63
- super.insertAt(new AtomToken(rule, 'converter-rule-noconvert', config, accum));
64
- }
65
- this.getAttribute('protectChildren')('1:');
66
- }
67
-
68
- /** @override */
69
- cloneNode() {
70
- const cloned = this.cloneChildNodes(),
71
- placeholders = ['', 'zh:', '=>zh:'],
72
- placeholder = placeholders[cloned.length - 1],
73
- token = Parser.run(() => new ConverterRuleToken(placeholder, placeholder, this.getAttribute('config')));
74
- for (let i = 0; i < cloned.length; i++) {
75
- token.childNodes[i].safeReplaceWith(cloned[i]);
76
- }
77
- token.afterBuild();
78
- return token;
79
- }
80
-
81
- /** @override */
82
- afterBuild() {
83
- const /** @type {AstListener} */ converterRuleListener = (e, data) => {
84
- const {childNodes} = this,
85
- {prevTarget} = e;
86
- if (childNodes.length > 1 && childNodes.at(-2) === prevTarget) {
87
- const v = prevTarget.text().trim(),
88
- {variants} = this.getAttribute('config');
89
- if (!variants.includes(v)) {
90
- undo(e, data);
91
- throw new Error(`无效的语言变体:${v}`);
92
- }
93
- }
94
- };
95
- this.addEventListener(['remove', 'insert', 'text', 'replace'], converterRuleListener);
96
- return this;
97
- }
98
-
99
- /**
100
- * @override
101
- * @param {number} i 移除位置
102
- * @returns {AtomToken}
103
- * @throws `Error` 至少保留1个子节点
104
- */
105
- removeAt(i) {
106
- if (this.childNodes.length === 1) {
107
- throw new Error(`${this.constructor.name} 需至少保留 1 个子节点!`);
108
- }
109
- const removed = super.removeAt(i);
110
- if (this.childNodes.length === 1) {
111
- this.firstChild.type = 'converter-rule-noconvert';
112
- }
113
- return removed;
114
- }
115
-
116
- /**
117
- * @override
118
- * @throws `Error` 请勿手动插入子节点
119
- */
120
- insertAt() {
121
- throw new Error(`转换规则语法复杂,请勿尝试对 ${this.constructor.name} 手动插入子节点!`);
122
- }
123
-
124
- /**
125
- * @override
126
- * @param {string} selector
127
- * @returns {string}
128
- */
129
- toString(selector) {
130
- if (this.childNodes.length === 3 && !(selector && this.matches(selector))) {
131
- const {childNodes: [from, variant, to]} = this;
132
- return `${from.toString(selector)}=>${variant.toString(selector)}:${to.toString(selector)}`;
133
- }
134
- return super.toString(selector, ':');
135
- }
136
-
137
- /**
138
- * @override
139
- * @param {number} i 子节点序号
140
- */
141
- getGaps(i = 0) {
142
- const {childNodes: {length}} = this;
143
- i = i < 0 ? i + length : i;
144
- return i === 0 && length === 3 ? 2 : 1;
145
- }
146
-
147
- /** @override */
148
- print() {
149
- if (this.childNodes.length === 3) {
150
- const {childNodes: [from, variant, to]} = this;
151
- return `<span class="wpb-converter-rule">${from.print()}=>${variant.print()}:${to.print()}</span>`;
152
- }
153
- return super.print({sep: ':'});
154
- }
155
-
156
- /**
157
- * @override
158
- * @returns {string}
159
- */
160
- text() {
161
- if (this.childNodes.length === 3) {
162
- const {childNodes: [from, variant, to]} = this;
163
- return `${from.text()}=>${variant.text()}:${to.text()}`;
164
- }
165
- return super.text(':');
166
- }
167
-
168
- /** 修改为不转换 */
169
- noConvert() {
170
- const {childNodes: {length}, lastChild} = this;
171
- for (let i = 0; i < length - 1; i++) { // ConverterRuleToken只能从前往后删除子节点
172
- this.removeAt(0);
173
- }
174
- lastChild.type = 'converter-rule-noconvert';
175
- }
176
-
177
- /**
178
- * 设置转换目标
179
- * @param {string} to 转换目标
180
- * @throws `SyntaxError` 非法的转换目标
181
- */
182
- setTo(to) {
183
- to = String(to);
184
- const config = this.getAttribute('config'),
185
- root = Parser.parse(`-{|${config.variants[0]}:${to}}-`, this.getAttribute('include'), undefined, config),
186
- {childNodes: {length}, firstChild: converter} = root,
187
- {lastChild: converterRule, type, childNodes: {length: converterLength}} = converter;
188
- if (length !== 1 || type !== 'converter' || converterLength !== 2 || converterRule.childNodes.length !== 2) {
189
- throw new SyntaxError(`非法的转换目标:${noWrap(to)}`);
190
- }
191
- const {lastChild} = converterRule;
192
- converterRule.destroy(true);
193
- this.lastChild.safeReplaceWith(lastChild);
194
- }
195
-
196
- /**
197
- * 设置语言变体
198
- * @param {string} variant 语言变体
199
- * @throws `RangeError` 无效的语言变体
200
- */
201
- setVariant(variant) {
202
- if (typeof variant !== 'string') {
203
- this.typeError('setVariant', 'String');
204
- }
205
- const config = this.getAttribute('config'),
206
- v = variant.trim();
207
- if (!config.variants.includes(v)) {
208
- throw new RangeError(`无效的语言变体:${v}`);
209
- } else if (this.childNodes.length === 1) {
210
- super.insertAt(Parser.run(() => new AtomToken(variant, 'converter-rule-variant', config)), 0);
211
- } else {
212
- this.childNodes.at(-2).setText(variant);
213
- }
214
- }
215
-
216
- /**
217
- * 设置转换原文
218
- * @param {string} from 转换原文
219
- * @throws `Error` 尚未指定语言变体
220
- * @throws `SyntaxError` 非法的转换原文
221
- */
222
- setFrom(from) {
223
- const {variant, unidirectional} = this;
224
- if (!variant) {
225
- throw new Error('请先指定语言变体!');
226
- }
227
- from = String(from);
228
- const config = this.getAttribute('config'),
229
- root = Parser.parse(`-{|${from}=>${variant}:}-`, this.getAttribute('include'), undefined, config),
230
- {childNodes: {length}, firstChild: converter} = root,
231
- {type, childNodes: {length: converterLength}, lastChild: converterRule} = converter;
232
- if (length !== 1 || type !== 'converter' || converterLength !== 2 || converterRule.childNodes.length !== 3) {
233
- throw new SyntaxError(`非法的转换原文:${noWrap(from)}`);
234
- }
235
- if (unidirectional) {
236
- this.firstChild.safeReplaceWith(converterRule.firstChild);
237
- } else {
238
- super.insertAt(converterRule.firstChild, 0);
239
- }
240
- }
241
-
242
- /**
243
- * 修改为单向转换
244
- * @param {string} from 转换来源
245
- */
246
- makeUnidirectional(from) {
247
- this.setFrom(from);
248
- }
249
-
250
- /** 修改为双向转换 */
251
- makeBidirectional() {
252
- if (this.unidirectional) {
253
- super.removeAt(0);
254
- }
255
- }
256
- }
257
-
258
- Parser.classes.ConverterRuleToken = __filename;
259
- module.exports = ConverterRuleToken;
package/src/extLink.js DELETED
@@ -1,173 +0,0 @@
1
- 'use strict';
2
-
3
- const {noWrap, normalizeSpace} = require('../util/string'),
4
- Parser = require('..'),
5
- Token = require('.'),
6
- MagicLinkToken = require('./magicLink');
7
-
8
- /**
9
- * 外链
10
- * @classdesc `{childNodes: [MagicLinkToken, ?Token]}`
11
- */
12
- class ExtLinkToken extends Token {
13
- type = 'ext-link';
14
- #space;
15
-
16
- /**
17
- * 协议
18
- * @this {{firstChild: MagicLinkToken}}
19
- */
20
- get protocol() {
21
- return this.firstChild.protocol;
22
- }
23
-
24
- /** @this {{firstChild: MagicLinkToken}} */
25
- set protocol(value) {
26
- this.firstChild.protocol = value;
27
- }
28
-
29
- /**
30
- * 和内链保持一致
31
- * @this {{firstChild: MagicLinkToken}}
32
- */
33
- get link() {
34
- return this.firstChild.link;
35
- }
36
-
37
- set link(url) {
38
- this.setTarget(url);
39
- }
40
-
41
- /** 链接显示文字 */
42
- get innerText() {
43
- return this.childNodes.length > 1
44
- ? this.lastChild.text()
45
- : `[${this.getRootNode().querySelectorAll('ext-link[childElementCount=1]').indexOf(this) + 1}]`;
46
- }
47
-
48
- /**
49
- * @param {string} url 网址
50
- * @param {string} space 空白字符
51
- * @param {string} text 链接文字
52
- * @param {accum} accum
53
- */
54
- constructor(url, space, text, config = Parser.getConfig(), accum = []) {
55
- super(undefined, config, true, accum, {AtomToken: 0, Token: 1});
56
- this.appendChild(new MagicLinkToken(url, true, config, accum));
57
- this.#space = space;
58
- if (text) {
59
- const inner = new Token(text, config, true, accum, {'Stage-7': ':', ConverterToken: ':'});
60
- inner.type = 'ext-link-text';
61
- this.appendChild(inner.setAttribute('stage', Parser.MAX_STAGE - 1));
62
- }
63
- this.getAttribute('protectChildren')(0);
64
- }
65
-
66
- /** @override */
67
- cloneNode() {
68
- const [url, text] = this.cloneChildNodes(),
69
- token = Parser.run(() => new ExtLinkToken(undefined, '', '', this.getAttribute('config')));
70
- token.firstChild.safeReplaceWith(url);
71
- if (text) {
72
- token.appendChild(text);
73
- }
74
- return token;
75
- }
76
-
77
- /** 修正空白字符 */
78
- #correct() {
79
- if (!this.#space && this.childNodes.length > 1
80
- // 都替换成`<`肯定不对,但无妨
81
- && /^[^[\]<>"{\0-\x1F\x7F\p{Zs}\uFFFD]/u.test(this.lastChild.text().replace(/&[lg]t;/u, '<'))
82
- ) {
83
- this.#space = ' ';
84
- }
85
- }
86
-
87
- /**
88
- * @override
89
- * @param {string} selector
90
- */
91
- toString(selector) {
92
- if (selector && this.matches(selector)) {
93
- return '';
94
- } else if (this.childNodes.length === 1) {
95
- return `[${super.toString(selector)}${this.#space}]`;
96
- }
97
- this.#correct();
98
- normalizeSpace(this.lastChild);
99
- return `[${super.toString(selector, this.#space)}]`;
100
- }
101
-
102
- /** @override */
103
- getPadding() {
104
- return 1;
105
- }
106
-
107
- /** @override */
108
- getGaps() {
109
- this.#correct();
110
- return this.#space.length;
111
- }
112
-
113
- /** @override */
114
- print() {
115
- const {childNodes: {length}} = this;
116
- return super.print(length > 1 ? {pre: '[', sep: this.#space, post: ']'} : {pre: '[', post: `${this.#space}]`});
117
- }
118
-
119
- /** @override */
120
- text() {
121
- normalizeSpace(this.childNodes[1]);
122
- return `[${super.text(' ')}]`;
123
- }
124
-
125
- /**
126
- * 获取网址
127
- * @this {{firstChild: MagicLinkToken}}
128
- */
129
- getUrl() {
130
- return this.firstChild.getUrl();
131
- }
132
-
133
- /**
134
- * 设置链接目标
135
- * @param {string|URL} url 网址
136
- * @throws `SyntaxError` 非法的外链目标
137
- */
138
- setTarget(url) {
139
- url = String(url);
140
- const root = Parser.parse(`[${url}]`, this.getAttribute('include'), 8, this.getAttribute('config')),
141
- {childNodes: {length}, firstChild: extLink} = root;
142
- if (length !== 1 || extLink.type !== 'ext-link' || extLink.childNodes.length !== 1) {
143
- throw new SyntaxError(`非法的外链目标:${url}`);
144
- }
145
- const {firstChild} = extLink;
146
- extLink.destroy(true);
147
- this.firstChild.safeReplaceWith(firstChild);
148
- }
149
-
150
- /**
151
- * 设置链接显示文字
152
- * @param {string} text 链接显示文字
153
- * @throws `SyntaxError` 非法的链接显示文字
154
- */
155
- setLinkText(text) {
156
- text = String(text);
157
- const root = Parser.parse(`[//url ${text}]`, this.getAttribute('include'), 8, this.getAttribute('config')),
158
- {childNodes: {length}, firstChild: extLink} = root;
159
- if (length !== 1 || extLink.type !== 'ext-link' || extLink.childNodes.length !== 2) {
160
- throw new SyntaxError(`非法的外链文字:${noWrap(text)}`);
161
- }
162
- const {lastChild} = extLink;
163
- if (this.childNodes.length === 1) {
164
- this.appendChild(lastChild);
165
- } else {
166
- this.lastChild.safeReplaceWith(lastChild);
167
- }
168
- this.#space ||= ' ';
169
- }
170
- }
171
-
172
- Parser.classes.ExtLinkToken = __filename;
173
- module.exports = ExtLinkToken;