wikiparser-node 0.0.0 → 0.0.3
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 +70 -25
- package/config/default.json +1 -0
- package/config/llwiki.json +1 -0
- package/config/moegirl.json +1 -0
- package/errors/README +1 -0
- package/index.js +42 -9
- package/lib/element.js +70 -12
- package/lib/node.js +17 -9
- package/package.json +1 -1
- package/parser/externalLinks.js +1 -1
- package/parser/links.js +7 -2
- package/parser/table.js +9 -8
- package/printed/README +1 -0
- package/src/arg.js +3 -3
- package/src/attribute.js +6 -6
- package/src/extLink.js +8 -10
- package/src/heading.js +2 -3
- package/src/html.js +4 -3
- package/src/imageParameter.js +67 -14
- package/src/index.js +5 -5
- package/src/link/file.js +39 -7
- package/src/link/index.js +2 -4
- package/src/magicLink.js +10 -4
- package/src/nowiki/comment.js +1 -1
- package/src/parameter.js +3 -3
- package/src/table/index.js +28 -23
- package/src/table/td.js +2 -2
- package/src/table/tr.js +4 -8
- package/src/tagPair/index.js +1 -1
- package/src/transclude.js +14 -11
- package/tool/index.js +50 -40
- package/typings/index.d.ts +1 -0
- package/util/debug.js +3 -3
- package/util/string.js +4 -1
package/src/attribute.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {externalUse} = require('../util/debug'),
|
|
4
4
|
{toCase, removeComment} = require('../util/string'),
|
|
5
5
|
/** @type {Parser} */ Parser = require('..'),
|
|
6
6
|
Token = require('.');
|
|
@@ -147,7 +147,7 @@ class AttributeToken extends Token {
|
|
|
147
147
|
/** @param {string} key */
|
|
148
148
|
hasAttr(key) {
|
|
149
149
|
if (typeof key !== 'string') {
|
|
150
|
-
typeError(
|
|
150
|
+
this.typeError('hasAttr', 'String');
|
|
151
151
|
}
|
|
152
152
|
return this.#attr.has(key.toLowerCase().trim());
|
|
153
153
|
}
|
|
@@ -161,7 +161,7 @@ class AttributeToken extends Token {
|
|
|
161
161
|
if (key === undefined) {
|
|
162
162
|
return Object.fromEntries(this.#attr);
|
|
163
163
|
} else if (typeof key !== 'string') {
|
|
164
|
-
typeError(
|
|
164
|
+
this.typeError('getAttr', 'String');
|
|
165
165
|
}
|
|
166
166
|
return this.#attr.get(key.toLowerCase().trim());
|
|
167
167
|
}
|
|
@@ -182,7 +182,7 @@ class AttributeToken extends Token {
|
|
|
182
182
|
setAttr(key, value, init = false) {
|
|
183
183
|
init &&= !externalUse('setAttr');
|
|
184
184
|
if (typeof key !== 'string' || !['string', 'boolean'].includes(typeof value)) {
|
|
185
|
-
typeError(
|
|
185
|
+
this.typeError('setValue', 'String', 'Boolean');
|
|
186
186
|
} else if (!init && this.type === 'ext-attr' && typeof value === 'string' && value.includes('>')) {
|
|
187
187
|
throw new RangeError('扩展标签属性不能包含 ">"!');
|
|
188
188
|
}
|
|
@@ -214,7 +214,7 @@ class AttributeToken extends Token {
|
|
|
214
214
|
*/
|
|
215
215
|
removeAttr(key) {
|
|
216
216
|
if (typeof key !== 'string') {
|
|
217
|
-
typeError(
|
|
217
|
+
this.typeError('removeAttr', 'String');
|
|
218
218
|
}
|
|
219
219
|
key = key.toLowerCase().trim();
|
|
220
220
|
if (this.#attr.delete(key)) {
|
|
@@ -229,7 +229,7 @@ class AttributeToken extends Token {
|
|
|
229
229
|
*/
|
|
230
230
|
toggleAttr(key, force) {
|
|
231
231
|
if (typeof key !== 'string') {
|
|
232
|
-
typeError(
|
|
232
|
+
this.typeError('toggleAttr', 'String');
|
|
233
233
|
} else if (force !== undefined) {
|
|
234
234
|
force = Boolean(force);
|
|
235
235
|
}
|
package/src/extLink.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const {noWrap} = require('../util/string'),
|
|
4
|
+
/** @type {Parser} */ Parser = require('..'),
|
|
4
5
|
Token = require('.'),
|
|
5
6
|
MagicLinkToken = require('./magicLink');
|
|
6
7
|
|
|
@@ -12,16 +13,13 @@ class ExtLinkToken extends Token {
|
|
|
12
13
|
type = 'ext-link';
|
|
13
14
|
#space;
|
|
14
15
|
|
|
15
|
-
/** @this {
|
|
16
|
+
/** @this {{firstChild: MagicLinkToken}} */
|
|
16
17
|
get protocol() {
|
|
17
|
-
return this.
|
|
18
|
+
return this.firstChild.protocol;
|
|
18
19
|
}
|
|
19
|
-
/**
|
|
20
|
-
* @this {ExtLinkToken & {firstElementChild: MagicLinkToken}}
|
|
21
|
-
* @param {string} value
|
|
22
|
-
*/
|
|
20
|
+
/** @this {{firstChild: MagicLinkToken}} */
|
|
23
21
|
set protocol(value) {
|
|
24
|
-
this.
|
|
22
|
+
this.firstChild.protocol = value;
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
/**
|
|
@@ -52,7 +50,7 @@ class ExtLinkToken extends Token {
|
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
toString() {
|
|
55
|
-
return `[${
|
|
53
|
+
return `[${this.firstElementChild.toString()}${this.#space}${this.children[1]?.toString() ?? ''}]`;
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
getPadding() {
|
|
@@ -100,7 +98,7 @@ class ExtLinkToken extends Token {
|
|
|
100
98
|
const root = Parser.parse(`[//url ${text}]`, this.getAttribute('include'), 8, this.getAttribute('config')),
|
|
101
99
|
{childNodes: {length}, firstElementChild} = root;
|
|
102
100
|
if (length !== 1 || firstElementChild?.type !== 'ext-link' || firstElementChild.childElementCount !== 2) {
|
|
103
|
-
throw new SyntaxError(`非法的外链文字:${text
|
|
101
|
+
throw new SyntaxError(`非法的外链文字:${noWrap(text)}`);
|
|
104
102
|
}
|
|
105
103
|
const {lastChild} = firstElementChild;
|
|
106
104
|
if (this.childElementCount === 1) {
|
package/src/heading.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
fixedToken = require('../mixin/fixedToken'),
|
|
3
|
+
const fixedToken = require('../mixin/fixedToken'),
|
|
5
4
|
/** @type {Parser} */ Parser = require('..'),
|
|
6
5
|
Token = require('.');
|
|
7
6
|
|
|
@@ -76,7 +75,7 @@ class HeadingToken extends fixedToken(Token) {
|
|
|
76
75
|
/** @param {number} n */
|
|
77
76
|
setLevel(n) {
|
|
78
77
|
if (typeof n !== 'number') {
|
|
79
|
-
typeError(
|
|
78
|
+
this.typeError('setLevel', 'Number');
|
|
80
79
|
}
|
|
81
80
|
n = Math.min(Math.max(n, 1), 6);
|
|
82
81
|
this.setAttribute('name', String(n)).firstElementChild.setAttribute('name', this.name);
|
package/src/html.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const {noWrap} = require('../util/string'),
|
|
4
|
+
fixedToken = require('../mixin/fixedToken'),
|
|
4
5
|
attributeParent = require('../mixin/attributeParent'),
|
|
5
6
|
/** @type {Parser} */ Parser = require('..'),
|
|
6
7
|
Token = require('.');
|
|
@@ -79,7 +80,7 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
|
|
|
79
80
|
findMatchingTag() {
|
|
80
81
|
const {html} = this.getAttribute('config'),
|
|
81
82
|
{name, parentElement, closing, selfClosing} = this,
|
|
82
|
-
string = this.toString()
|
|
83
|
+
string = noWrap(this.toString());
|
|
83
84
|
if (closing && selfClosing) {
|
|
84
85
|
throw new SyntaxError(`同时闭合和自封闭的标签:${string}`);
|
|
85
86
|
} else if (html[2].includes(name) || selfClosing && html[1].includes(name)) { // 自封闭标签
|
|
@@ -134,7 +135,7 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
|
|
|
134
135
|
this.selfClosing = false;
|
|
135
136
|
this.closing = true;
|
|
136
137
|
} else {
|
|
137
|
-
Parser.warn('无法修复无效自封闭标签', this.toString()
|
|
138
|
+
Parser.warn('无法修复无效自封闭标签', noWrap(this.toString()));
|
|
138
139
|
throw new Error(`无法修复无效自封闭标签:前文共有 ${imbalance} 个未匹配的闭合标签`);
|
|
139
140
|
}
|
|
140
141
|
}
|
package/src/imageParameter.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
{extUrlChar} = require('../util/string'),
|
|
3
|
+
const {text, noWrap, extUrlChar} = require('../util/string'),
|
|
5
4
|
Title = require('../lib/title'),
|
|
6
5
|
/** @type {Parser} */ Parser = require('..'),
|
|
7
6
|
Token = require('.');
|
|
@@ -14,24 +13,27 @@ class ImageParameterToken extends Token {
|
|
|
14
13
|
type = 'image-parameter';
|
|
15
14
|
#syntax = '';
|
|
16
15
|
|
|
16
|
+
static #noLink = Symbol('no-link');
|
|
17
|
+
|
|
17
18
|
/**
|
|
18
|
-
* @
|
|
19
|
+
* @template {string} T
|
|
20
|
+
* @param {T} key
|
|
19
21
|
* @param {string} value
|
|
22
|
+
* @returns {T extends 'link' ? string|Symbol : boolean}
|
|
20
23
|
*/
|
|
21
24
|
static #validate(key, value, config = Parser.getConfig()) {
|
|
22
|
-
value = value.trim();
|
|
25
|
+
value = value.replace(/\x00\d+t\x7f/g, '').trim();
|
|
23
26
|
if (key === 'width') {
|
|
24
|
-
|
|
25
|
-
return Number(mt?.[1]) > 0 || Number(mt?.[2]) > 0;
|
|
27
|
+
return /^\d*(?:x\d*)?$/.test(value);
|
|
26
28
|
} else if (['alt', 'class', 'manualthumb', 'frameless', 'framed', 'thumbnail'].includes(key)) {
|
|
27
29
|
return true;
|
|
28
30
|
} else if (key === 'link') {
|
|
29
31
|
if (!value) {
|
|
30
|
-
return
|
|
32
|
+
return this.#noLink;
|
|
31
33
|
}
|
|
32
|
-
const regex = new RegExp(`(?:${config.protocol}|//)${extUrlChar}`, 'ui');
|
|
34
|
+
const regex = new RegExp(`(?:${config.protocol}|//)${extUrlChar}(?=\x00\\d+t\x7f|$)`, 'ui');
|
|
33
35
|
if (regex.test(value)) {
|
|
34
|
-
return
|
|
36
|
+
return value;
|
|
35
37
|
}
|
|
36
38
|
if (/^\[\[.+]]$/.test(value)) {
|
|
37
39
|
value = value.slice(2, -2);
|
|
@@ -41,11 +43,62 @@ class ImageParameterToken extends Token {
|
|
|
41
43
|
value = decodeURIComponent(value);
|
|
42
44
|
} catch {}
|
|
43
45
|
}
|
|
44
|
-
|
|
46
|
+
const {title, fragment, valid} = new Title(value, 0, config);
|
|
47
|
+
return valid && `${title}${fragment && '#'}${fragment}`;
|
|
45
48
|
}
|
|
46
49
|
return !isNaN(value);
|
|
47
50
|
}
|
|
48
51
|
|
|
52
|
+
get link() {
|
|
53
|
+
if (this.name === 'link') {
|
|
54
|
+
return ImageParameterToken.#validate('link', this.getValue(), this.getAttribute('config'));
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
set link(value) {
|
|
59
|
+
if (this.name === 'link') {
|
|
60
|
+
value = value === ImageParameterToken.#noLink ? '' : value;
|
|
61
|
+
this.setValue(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
get size() {
|
|
65
|
+
if (this.name === 'width') {
|
|
66
|
+
const /** @type {string} */ size = this.getValue().trim();
|
|
67
|
+
if (!size.includes('{{')) {
|
|
68
|
+
const [width, height = ''] = size.split('x');
|
|
69
|
+
return {width, height};
|
|
70
|
+
}
|
|
71
|
+
const token = Parser.parse(size, false, 2, this.getAttribute('config')),
|
|
72
|
+
{childNodes} = token,
|
|
73
|
+
i = childNodes.findIndex(child => typeof child === 'string' && child.includes('x'));
|
|
74
|
+
if (i === -1) {
|
|
75
|
+
return {width: size, height: ''};
|
|
76
|
+
}
|
|
77
|
+
token.splitText(i, childNodes[i].indexOf('x'));
|
|
78
|
+
token.splitText(i + 1, 1);
|
|
79
|
+
return {width: text(token.childNodes.slice(0, i + 1)), height: text(token.childNodes.slice(i + 2))};
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
get width() {
|
|
84
|
+
return this.size?.width;
|
|
85
|
+
}
|
|
86
|
+
set width(width) {
|
|
87
|
+
if (this.name === 'width') {
|
|
88
|
+
const {height} = this;
|
|
89
|
+
this.setValue(`${String(width || '')}${height && 'x'}${height}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
get height() {
|
|
93
|
+
return this.size?.height;
|
|
94
|
+
}
|
|
95
|
+
set height(height) {
|
|
96
|
+
height = String(height || '');
|
|
97
|
+
if (this.name === 'width') {
|
|
98
|
+
this.setValue(`${this.width}${height && 'x'}${height}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
49
102
|
/**
|
|
50
103
|
* @param {string} str
|
|
51
104
|
* @param {accum} accum
|
|
@@ -68,7 +121,7 @@ class ImageParameterToken extends Token {
|
|
|
68
121
|
super(mt[2], config, true, accum, {'Stage-2': ':', '!HeadingToken': ':'});
|
|
69
122
|
this.#syntax = `${mt[1]}${param[0]}${mt[3]}`;
|
|
70
123
|
}
|
|
71
|
-
this.setAttribute('name', param[1]).setAttribute('stage',
|
|
124
|
+
this.setAttribute('name', param[1]).setAttribute('stage', Parser.MAX_STAGE);
|
|
72
125
|
return;
|
|
73
126
|
}
|
|
74
127
|
}
|
|
@@ -146,13 +199,13 @@ class ImageParameterToken extends Token {
|
|
|
146
199
|
setValue(value) {
|
|
147
200
|
if (this.#isVoid()) {
|
|
148
201
|
if (typeof value !== 'boolean') {
|
|
149
|
-
typeError(
|
|
202
|
+
this.typeError('setValue', 'Boolean');
|
|
150
203
|
} else if (value === false) {
|
|
151
204
|
this.remove();
|
|
152
205
|
}
|
|
153
206
|
return;
|
|
154
207
|
} else if (typeof value !== 'string') {
|
|
155
|
-
typeError(
|
|
208
|
+
this.typeError('setValue', 'String');
|
|
156
209
|
}
|
|
157
210
|
const root = Parser.parse(`[[File:F|${
|
|
158
211
|
this.#syntax ? this.#syntax.replace('$1', value) : value
|
|
@@ -162,7 +215,7 @@ class ImageParameterToken extends Token {
|
|
|
162
215
|
if (length !== 1 || !firstElementChild?.matches('file#File:F')
|
|
163
216
|
|| firstElementChild.childElementCount !== 2 || param.name !== this.name
|
|
164
217
|
) {
|
|
165
|
-
throw new SyntaxError(`非法的 ${this.name} 参数:${value
|
|
218
|
+
throw new SyntaxError(`非法的 ${this.name} 参数:${noWrap(value)}`);
|
|
166
219
|
}
|
|
167
220
|
this.replaceChildren(...param.childNodes);
|
|
168
221
|
}
|
package/src/index.js
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
* w: ExtLinkToken
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
|
-
const {
|
|
42
|
+
const {externalUse} = require('../util/debug'),
|
|
43
43
|
Ranges = require('../lib/ranges'),
|
|
44
44
|
AstElement = require('../lib/element'),
|
|
45
45
|
assert = require('assert/strict'),
|
|
@@ -255,7 +255,7 @@ class Token extends AstElement {
|
|
|
255
255
|
if (!parentNode) {
|
|
256
256
|
throw new Error('不存在父节点!');
|
|
257
257
|
} else if (token.constructor !== this.constructor) {
|
|
258
|
-
typeError(
|
|
258
|
+
this.typeError('safeReplaceWith', this.constructor.name);
|
|
259
259
|
}
|
|
260
260
|
try {
|
|
261
261
|
assert.deepEqual(token.getAttribute('acceptable'), this.#acceptable);
|
|
@@ -320,7 +320,7 @@ class Token extends AstElement {
|
|
|
320
320
|
*/
|
|
321
321
|
section(n) {
|
|
322
322
|
if (typeof n !== 'number') {
|
|
323
|
-
typeError(
|
|
323
|
+
this.typeError('section', 'Number');
|
|
324
324
|
}
|
|
325
325
|
return this.sections()[n];
|
|
326
326
|
}
|
|
@@ -332,7 +332,7 @@ class Token extends AstElement {
|
|
|
332
332
|
*/
|
|
333
333
|
findEnclosingHtml(tag) {
|
|
334
334
|
if (tag !== undefined && typeof tag !== 'string') {
|
|
335
|
-
typeError(
|
|
335
|
+
this.typeError('findEnclosingHtml', 'String');
|
|
336
336
|
}
|
|
337
337
|
tag = tag?.toLowerCase();
|
|
338
338
|
if (tag !== undefined && !this.#config.html.slice(0, 2).flat().includes(tag)) {
|
|
@@ -519,7 +519,7 @@ class Token extends AstElement {
|
|
|
519
519
|
/** 解析、重构、生成部分Token的`name`属性 */
|
|
520
520
|
parse(n = MAX_STAGE, include = false) {
|
|
521
521
|
if (typeof n !== 'number') {
|
|
522
|
-
typeError(
|
|
522
|
+
this.typeError('parse', 'Number');
|
|
523
523
|
} else if (n < MAX_STAGE && !Parser.debugging && externalUse('parse')) {
|
|
524
524
|
Parser.warn('指定解析层级的方法仅供熟练用户使用!');
|
|
525
525
|
}
|
package/src/link/file.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {explode} = require('../../util/string'),
|
|
4
|
-
{
|
|
3
|
+
const {explode, noWrap} = require('../../util/string'),
|
|
4
|
+
{externalUse} = require('../../util/debug'),
|
|
5
5
|
/** @type {Parser} */ Parser = require('../..'),
|
|
6
6
|
LinkToken = require('.'),
|
|
7
7
|
ImageParameterToken = require('../imageParameter');
|
|
@@ -20,6 +20,38 @@ class FileToken extends LinkToken {
|
|
|
20
20
|
setLinkText = undefined;
|
|
21
21
|
pipeTrick = undefined;
|
|
22
22
|
|
|
23
|
+
get link() {
|
|
24
|
+
return this.getArg('link')?.link;
|
|
25
|
+
}
|
|
26
|
+
set link(value) {
|
|
27
|
+
this.setValue('link', value);
|
|
28
|
+
}
|
|
29
|
+
get size() {
|
|
30
|
+
return this.getArg('width')?.size;
|
|
31
|
+
}
|
|
32
|
+
get width() {
|
|
33
|
+
return this.size?.width;
|
|
34
|
+
}
|
|
35
|
+
set width(width) {
|
|
36
|
+
const arg = this.getArg('width');
|
|
37
|
+
if (arg) {
|
|
38
|
+
arg.width = width;
|
|
39
|
+
} else {
|
|
40
|
+
this.setValue('width', width);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
get height() {
|
|
44
|
+
return this.size?.height;
|
|
45
|
+
}
|
|
46
|
+
set height(height) {
|
|
47
|
+
const arg = this.getArg('width');
|
|
48
|
+
if (arg) {
|
|
49
|
+
arg.height = height;
|
|
50
|
+
} else {
|
|
51
|
+
this.setValue('width', `x${height}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
23
55
|
/**
|
|
24
56
|
* @param {string} link
|
|
25
57
|
* @param {string|undefined} text
|
|
@@ -70,7 +102,7 @@ class FileToken extends LinkToken {
|
|
|
70
102
|
const args = this.getAllArgs()
|
|
71
103
|
.filter(({name}) => ['manualthumb', 'frameless', 'framed', 'thumbnail'].includes(name));
|
|
72
104
|
if (args.length > 1) {
|
|
73
|
-
Parser.error(
|
|
105
|
+
Parser.error(`图片 ${this.name} 带有 ${args.length} 个框架参数,只有第 1 个 ${args[0].name} 会生效!`);
|
|
74
106
|
}
|
|
75
107
|
return args;
|
|
76
108
|
}
|
|
@@ -81,7 +113,7 @@ class FileToken extends LinkToken {
|
|
|
81
113
|
*/
|
|
82
114
|
getArgs(key, copy = true) {
|
|
83
115
|
if (typeof key !== 'string') {
|
|
84
|
-
typeError(
|
|
116
|
+
this.typeError('getArgs', 'String');
|
|
85
117
|
} else if (!copy && !Parser.debugging && externalUse('getArgs')) {
|
|
86
118
|
this.debugOnly('getArgs');
|
|
87
119
|
}
|
|
@@ -158,7 +190,7 @@ class FileToken extends LinkToken {
|
|
|
158
190
|
*/
|
|
159
191
|
setValue(key, value) {
|
|
160
192
|
if (typeof key !== 'string') {
|
|
161
|
-
typeError(
|
|
193
|
+
this.typeError('setValue', 'String');
|
|
162
194
|
} else if (value === false) {
|
|
163
195
|
this.removeArg(key);
|
|
164
196
|
return;
|
|
@@ -179,7 +211,7 @@ class FileToken extends LinkToken {
|
|
|
179
211
|
}
|
|
180
212
|
if (value === true) {
|
|
181
213
|
if (syntax.includes('$1')) {
|
|
182
|
-
typeError(
|
|
214
|
+
this.typeError('setValue', 'Boolean');
|
|
183
215
|
}
|
|
184
216
|
const newArg = Parser.run(() => new ImageParameterToken(syntax, config));
|
|
185
217
|
this.appendChild(newArg);
|
|
@@ -191,7 +223,7 @@ class FileToken extends LinkToken {
|
|
|
191
223
|
if (length !== 1 || !firstElementChild?.matches('file#File:F')
|
|
192
224
|
|| firstElementChild.childElementCount !== 2 || firstElementChild.lastElementChild.name !== key
|
|
193
225
|
) {
|
|
194
|
-
throw new SyntaxError(`非法的 ${key} 参数:${value
|
|
226
|
+
throw new SyntaxError(`非法的 ${key} 参数:${noWrap(value)}`);
|
|
195
227
|
}
|
|
196
228
|
this.appendChild(firstElementChild.lastChild);
|
|
197
229
|
}
|
package/src/link/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const Title = require('../../lib/title'), // eslint-disable-line no-unused-vars
|
|
4
|
-
{text} = require('../../util/string'),
|
|
4
|
+
{text, noWrap} = require('../../util/string'),
|
|
5
5
|
{undo} = require('../../util/debug'),
|
|
6
6
|
/** @type {Parser} */ Parser = require('../..'),
|
|
7
7
|
Token = require('..');
|
|
@@ -170,9 +170,7 @@ class LinkToken extends Token {
|
|
|
170
170
|
}L|${linkText}]]`, this.getAttribute('include'), 6, config),
|
|
171
171
|
{childNodes: {length}, firstElementChild} = root;
|
|
172
172
|
if (length !== 1 || firstElementChild?.type !== this.type || firstElementChild.childElementCount !== 2) {
|
|
173
|
-
throw new SyntaxError(`非法的${this.type === 'link' ? '内链文字' : '分类关键字'}:${
|
|
174
|
-
linkText.replaceAll('\n', '\\n')
|
|
175
|
-
}`);
|
|
173
|
+
throw new SyntaxError(`非法的${this.type === 'link' ? '内链文字' : '分类关键字'}:${noWrap(linkText)}`);
|
|
176
174
|
}
|
|
177
175
|
({lastElementChild} = firstElementChild);
|
|
178
176
|
} else {
|
package/src/magicLink.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
/** @type {Parser} */ Parser = require('..'),
|
|
3
|
+
const /** @type {Parser} */ Parser = require('..'),
|
|
5
4
|
Token = require('.');
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -15,10 +14,9 @@ class MagicLinkToken extends Token {
|
|
|
15
14
|
get protocol() {
|
|
16
15
|
return this.text().match(this.#protocolRegex)?.[0];
|
|
17
16
|
}
|
|
18
|
-
/** @param {string} value */
|
|
19
17
|
set protocol(value) {
|
|
20
18
|
if (typeof value !== 'string') {
|
|
21
|
-
typeError(
|
|
19
|
+
this.typeError('protocol', 'String');
|
|
22
20
|
}
|
|
23
21
|
if (!new RegExp(`${this.#protocolRegex.source}$`, 'i').test(value)) {
|
|
24
22
|
throw new RangeError(`非法的外链协议:${value}`);
|
|
@@ -38,6 +36,14 @@ class MagicLinkToken extends Token {
|
|
|
38
36
|
this.#protocolRegex = new RegExp(`^(?:${config.protocol}${doubleSlash ? '|//' : ''})`, 'i');
|
|
39
37
|
}
|
|
40
38
|
|
|
39
|
+
afterBuild() {
|
|
40
|
+
const ParameterToken = require('./parameter'), // eslint-disable-line no-unused-vars
|
|
41
|
+
/** @type {ParameterToken} */ parameter = this.closest('parameter');
|
|
42
|
+
if (parameter?.getValue() === this.text()) {
|
|
43
|
+
this.replaceWith(this.toString());
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
getUrl() {
|
|
42
48
|
const url = this.text();
|
|
43
49
|
try {
|
package/src/nowiki/comment.js
CHANGED
|
@@ -30,7 +30,7 @@ class CommentToken extends hidden(NowikiToken) {
|
|
|
30
30
|
toString() {
|
|
31
31
|
const {firstChild, closed, nextSibling} = this;
|
|
32
32
|
if (!closed && nextSibling) {
|
|
33
|
-
Parser.error('自动闭合HTML注释',
|
|
33
|
+
Parser.error('自动闭合HTML注释', this);
|
|
34
34
|
this.closed = true;
|
|
35
35
|
}
|
|
36
36
|
return `<!--${firstChild}${this.closed ? '-->' : ''}`;
|
package/src/parameter.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {noWrap} = require('../util/string'),
|
|
4
4
|
fixedToken = require('../mixin/fixedToken'),
|
|
5
5
|
/** @type {Parser} */ Parser = require('..'),
|
|
6
6
|
Token = require('.');
|
|
@@ -116,7 +116,7 @@ class ParameterToken extends fixedToken(Token) {
|
|
|
116
116
|
|| firstElementChild.childElementCount !== 2
|
|
117
117
|
|| lastElementChild.anon !== this.anon || lastElementChild.name !== '1'
|
|
118
118
|
) {
|
|
119
|
-
throw new SyntaxError(`非法的模板参数:${value
|
|
119
|
+
throw new SyntaxError(`非法的模板参数:${noWrap(value)}`);
|
|
120
120
|
}
|
|
121
121
|
const newValue = lastElementChild.lastChild;
|
|
122
122
|
root.destroy();
|
|
@@ -128,7 +128,7 @@ class ParameterToken extends fixedToken(Token) {
|
|
|
128
128
|
/** @param {string} key */
|
|
129
129
|
rename(key, force = false) {
|
|
130
130
|
if (typeof key !== 'string') {
|
|
131
|
-
typeError(
|
|
131
|
+
this.typeError('rename', 'String');
|
|
132
132
|
}
|
|
133
133
|
const {parentNode} = this;
|
|
134
134
|
// 必须检测是否是TranscludeToken
|