wikiparser-node 0.2.3 → 0.3.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/.eslintrc.json +53 -6
- package/lib/element.js +2 -2
- package/lib/node.js +2 -2
- package/lib/title.js +7 -3
- package/mixin/attributeParent.js +2 -2
- package/mixin/fixedToken.js +1 -1
- package/mixin/hidden.js +1 -1
- package/mixin/sol.js +2 -2
- package/package.json +3 -3
- package/parser/links.js +2 -2
- package/parser/quotes.js +2 -2
- package/src/converterRule.js +1 -1
- package/src/extLink.js +1 -0
- package/src/gallery.js +44 -11
- package/src/link/category.js +1 -1
- package/src/link/file.js +1 -1
- package/src/link/galleryImage.js +47 -0
- package/src/link/index.js +6 -5
- package/src/magicLink.js +11 -1
- package/src/table/index.js +5 -5
- package/src/table/td.js +13 -11
- package/src/table/tr.js +3 -3
- package/src/tagPair/ext.js +11 -3
- package/util/string.js +2 -2
- package/errors/2022-12-07T10:07:09.577Z +0 -1
- package/errors/2022-12-07T10:07:09.577Z.err +0 -11
- package/errors/2022-12-07T10:07:09.577Z.json +0 -5
- package/errors/2022-12-07T10:22:31.325Z +0 -1
- package/errors/2022-12-07T10:22:31.325Z.err +0 -11
- package/errors/2022-12-07T10:22:31.325Z.json +0 -5
package/.eslintrc.json
CHANGED
|
@@ -5,10 +5,7 @@
|
|
|
5
5
|
},
|
|
6
6
|
"extends": "eslint:recommended",
|
|
7
7
|
"parserOptions": {
|
|
8
|
-
"ecmaVersion": 13
|
|
9
|
-
"ecmaFeatures": {
|
|
10
|
-
"impliedStrict": true
|
|
11
|
-
}
|
|
8
|
+
"ecmaVersion": 13
|
|
12
9
|
},
|
|
13
10
|
"rules": {
|
|
14
11
|
"array-callback-return": [
|
|
@@ -18,13 +15,39 @@
|
|
|
18
15
|
}
|
|
19
16
|
],
|
|
20
17
|
"no-await-in-loop": 2,
|
|
18
|
+
"no-constant-binary-expression": 2,
|
|
21
19
|
"no-constructor-return": 2,
|
|
22
20
|
"no-fallthrough": 1,
|
|
23
21
|
"no-promise-executor-return": 2,
|
|
24
22
|
"no-self-compare": 2,
|
|
25
23
|
"no-template-curly-in-string": 2,
|
|
24
|
+
"no-undef": [
|
|
25
|
+
2,
|
|
26
|
+
{
|
|
27
|
+
"typeof": true
|
|
28
|
+
}
|
|
29
|
+
],
|
|
26
30
|
"no-unmodified-loop-condition": 2,
|
|
27
31
|
"no-unreachable-loop": 2,
|
|
32
|
+
"no-unsafe-negation": [
|
|
33
|
+
2,
|
|
34
|
+
{
|
|
35
|
+
"enforceForOrderingRelations": true
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"no-unsafe-optional-chaining": [
|
|
39
|
+
2,
|
|
40
|
+
{
|
|
41
|
+
"disallowArithmeticOperators": true
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"no-unused-vars": [
|
|
45
|
+
2,
|
|
46
|
+
{
|
|
47
|
+
"varsIgnorePattern": "AstNode|AstElement|[a-zA-Z]*Token",
|
|
48
|
+
"ignoreRestSiblings": true
|
|
49
|
+
}
|
|
50
|
+
],
|
|
28
51
|
"no-use-before-define": [
|
|
29
52
|
2,
|
|
30
53
|
{
|
|
@@ -33,7 +56,12 @@
|
|
|
33
56
|
"variables": false
|
|
34
57
|
}
|
|
35
58
|
],
|
|
36
|
-
"require-atomic-updates":
|
|
59
|
+
"require-atomic-updates": [
|
|
60
|
+
2,
|
|
61
|
+
{
|
|
62
|
+
"allowProperties": true
|
|
63
|
+
}
|
|
64
|
+
],
|
|
37
65
|
"block-scoped-var": 2,
|
|
38
66
|
"class-methods-use-this": 0,
|
|
39
67
|
"consistent-this": 2,
|
|
@@ -47,6 +75,13 @@
|
|
|
47
75
|
2,
|
|
48
76
|
"never"
|
|
49
77
|
],
|
|
78
|
+
"logical-assignment-operators": [
|
|
79
|
+
2,
|
|
80
|
+
"always",
|
|
81
|
+
{
|
|
82
|
+
"enforceForIfStatements": true
|
|
83
|
+
}
|
|
84
|
+
],
|
|
50
85
|
"multiline-comment-style": 2,
|
|
51
86
|
"new-cap": [
|
|
52
87
|
1,
|
|
@@ -67,6 +102,12 @@
|
|
|
67
102
|
],
|
|
68
103
|
"no-eval": 2,
|
|
69
104
|
"no-extend-native": 2,
|
|
105
|
+
"no-extra-boolean-cast": [
|
|
106
|
+
2,
|
|
107
|
+
{
|
|
108
|
+
"enforceForLogicalOperands": true
|
|
109
|
+
}
|
|
110
|
+
],
|
|
70
111
|
"no-floating-decimal": 2,
|
|
71
112
|
"no-implied-eval": 2,
|
|
72
113
|
"no-invalid-this": [
|
|
@@ -91,7 +132,12 @@
|
|
|
91
132
|
"no-return-await": 2,
|
|
92
133
|
"no-script-url": 2,
|
|
93
134
|
"no-sequences": 2,
|
|
94
|
-
"no-shadow":
|
|
135
|
+
"no-shadow": [
|
|
136
|
+
2,
|
|
137
|
+
{
|
|
138
|
+
"builtinGlobals": true
|
|
139
|
+
}
|
|
140
|
+
],
|
|
95
141
|
"no-undef-init": 2,
|
|
96
142
|
"no-unneeded-ternary": [
|
|
97
143
|
2,
|
|
@@ -139,6 +185,7 @@
|
|
|
139
185
|
],
|
|
140
186
|
"require-await": 2,
|
|
141
187
|
"spaced-comment": 2,
|
|
188
|
+
"strict": 2,
|
|
142
189
|
"symbol-description": 2,
|
|
143
190
|
"yoda": 2,
|
|
144
191
|
"array-bracket-spacing": 2,
|
package/lib/element.js
CHANGED
|
@@ -39,12 +39,12 @@ class AstElement extends AstNode {
|
|
|
39
39
|
/** @complexity `n` */
|
|
40
40
|
get nextElementSibling() {
|
|
41
41
|
const children = this.parentElement?.children;
|
|
42
|
-
return children
|
|
42
|
+
return children && children[children.indexOf(this) + 1];
|
|
43
43
|
}
|
|
44
44
|
/** @complexity `n` */
|
|
45
45
|
get previousElementSibling() {
|
|
46
46
|
const children = this.parentElement?.children;
|
|
47
|
-
return children
|
|
47
|
+
return children && children[children.indexOf(this) - 1];
|
|
48
48
|
}
|
|
49
49
|
/** @complexity `n` */
|
|
50
50
|
get hidden() {
|
package/lib/node.js
CHANGED
|
@@ -22,12 +22,12 @@ class AstNode {
|
|
|
22
22
|
/** @complexity `n` */
|
|
23
23
|
get nextSibling() {
|
|
24
24
|
const childNodes = this.#parentNode?.childNodes;
|
|
25
|
-
return childNodes
|
|
25
|
+
return childNodes && childNodes[childNodes.indexOf(this) + 1];
|
|
26
26
|
}
|
|
27
27
|
/** @complexity `n` */
|
|
28
28
|
get previousSibling() {
|
|
29
29
|
const childNodes = this.#parentNode?.childNodes;
|
|
30
|
-
return childNodes
|
|
30
|
+
return childNodes && childNodes[childNodes.indexOf(this) - 1];
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
debugOnly(method = 'debugOnly') {
|
package/lib/title.js
CHANGED
|
@@ -5,6 +5,8 @@ const {ucfirst} = require('../util/string'),
|
|
|
5
5
|
|
|
6
6
|
class Title {
|
|
7
7
|
title = '';
|
|
8
|
+
main = '';
|
|
9
|
+
prefix = '';
|
|
8
10
|
ns = 0;
|
|
9
11
|
interwiki = '';
|
|
10
12
|
fragment = '';
|
|
@@ -19,7 +21,7 @@ class Title {
|
|
|
19
21
|
namespace = '';
|
|
20
22
|
title = title.slice(1).trim();
|
|
21
23
|
}
|
|
22
|
-
const iw = Parser.isInterwiki(title, config);
|
|
24
|
+
const iw = defaultNs ? null : Parser.isInterwiki(title, config);
|
|
23
25
|
if (iw) {
|
|
24
26
|
this.interwiki = iw[1].toLowerCase();
|
|
25
27
|
title = title.slice(iw[0].length);
|
|
@@ -48,8 +50,10 @@ class Title {
|
|
|
48
50
|
this.fragment ||= fragment;
|
|
49
51
|
title = title.slice(0, i).trim();
|
|
50
52
|
}
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
53
|
+
this.main = ucfirst(title);
|
|
54
|
+
this.prefix = `${namespace}${namespace && ':'}`;
|
|
55
|
+
this.title = `${iw ? `${this.interwiki}:` : ''}${this.prefix}${this.main}`;
|
|
56
|
+
this.valid = Boolean(this.main) && !/\x00\d+[eh!+-]\x7f|[<>[\]{}|]/.test(this.title);
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
59
|
|
package/mixin/attributeParent.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const /** @type {Parser} */ Parser = require('..'),
|
|
4
|
-
AttributeToken = require('../src/attribute');
|
|
4
|
+
AttributeToken = require('../src/attribute');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @template T
|
|
8
8
|
* @param {T} constructor
|
|
9
9
|
* @returns {T}
|
|
10
10
|
*/
|
|
11
|
-
const attributeParent = (
|
|
11
|
+
const attributeParent = (ct, i = 0) => class extends ct {
|
|
12
12
|
/**
|
|
13
13
|
* @this {{children: AttributeToken[]}}
|
|
14
14
|
* @param {string} key
|
package/mixin/fixedToken.js
CHANGED
package/mixin/hidden.js
CHANGED
package/mixin/sol.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const /** @type {Parser} */ Parser = require('..'),
|
|
4
|
-
Token = require('../src');
|
|
4
|
+
Token = require('../src');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @template T
|
|
8
8
|
* @param {T} constructor
|
|
9
9
|
* @returns {T}
|
|
10
10
|
*/
|
|
11
|
-
const sol =
|
|
11
|
+
const sol = ct => class extends ct {
|
|
12
12
|
/** @this {Token} */
|
|
13
13
|
prependNewLine() {
|
|
14
14
|
const {previousVisibleSibling = '', parentNode} = this;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikiparser-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A Node.js parser for MediaWiki markup with AST",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"test": "echo 'Error: no test specified' && exit 1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"@types/node": "^17.0.23",
|
|
25
|
+
"eslint": "^8.30.0"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
28
28
|
"node": "^18.4.0"
|
package/parser/links.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const /** @type {Parser} */ Parser = require('..'),
|
|
4
|
-
Token = require('../src');
|
|
4
|
+
Token = require('../src');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {string} firstChild
|
|
@@ -78,7 +78,7 @@ const parseLinks = (firstChild, config = Parser.getConfig(), accum = []) => {
|
|
|
78
78
|
continue;
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
text
|
|
81
|
+
text &&= parseQuotes(text, config, accum);
|
|
82
82
|
s += `\x00${accum.length}l\x7f${after}`;
|
|
83
83
|
let LinkToken = require('../src/link');
|
|
84
84
|
if (!force) {
|
package/parser/quotes.js
CHANGED
package/src/converterRule.js
CHANGED
|
@@ -47,7 +47,7 @@ class ConverterRuleToken extends Token {
|
|
|
47
47
|
|
|
48
48
|
cloneNode() {
|
|
49
49
|
const cloned = this.cloneChildren(),
|
|
50
|
-
placeholders = ['', ':', '
|
|
50
|
+
placeholders = ['', 'zh:', '=>zh:'],
|
|
51
51
|
placeholder = placeholders[cloned.length - 1],
|
|
52
52
|
token = Parser.run(() => new ConverterRuleToken(placeholder, placeholder, this.getAttribute('config')));
|
|
53
53
|
for (let i = 0; i < cloned.length; i++) {
|
package/src/extLink.js
CHANGED
package/src/gallery.js
CHANGED
|
@@ -1,30 +1,63 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const {text} = require('../util/string'),
|
|
4
|
+
/** @type {Parser} */ Parser = require('..'),
|
|
4
5
|
Token = require('.'),
|
|
5
|
-
|
|
6
|
+
GalleryImageToken = require('./link/galleryImage');
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @classdesc `{childNodes: [
|
|
9
|
+
* gallery标签
|
|
10
|
+
* @classdesc `{childNodes: (string|FileToken)[]]}`
|
|
10
11
|
*/
|
|
11
12
|
class GalleryToken extends Token {
|
|
12
13
|
type = 'ext-inner';
|
|
13
14
|
name = 'gallery';
|
|
14
15
|
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
/**
|
|
17
|
+
* @param {string} inner
|
|
18
|
+
* @param {accum} accum
|
|
19
|
+
*/
|
|
20
|
+
constructor(inner, config = Parser.getConfig(), accum = []) {
|
|
21
|
+
super(undefined, config, true, accum, {String: ':', GalleryImageToken: ':'});
|
|
22
|
+
for (const line of inner?.split('\n') ?? []) {
|
|
23
|
+
const matches = line.match(/^([^|]+)(?:\|(.*))?/);
|
|
24
|
+
if (!matches) {
|
|
25
|
+
this.appendChild(line);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const [, file, alt] = matches;
|
|
29
|
+
let title;
|
|
30
|
+
try {
|
|
31
|
+
title = this.normalizeTitle(decodeURIComponent(file), 6, true);
|
|
32
|
+
} catch {
|
|
33
|
+
title = this.normalizeTitle(file, 6, true);
|
|
34
|
+
}
|
|
35
|
+
if (!title.valid) {
|
|
36
|
+
this.appendChild(line);
|
|
37
|
+
} else {
|
|
38
|
+
this.appendChild(new GalleryImageToken(file, alt, title, config, accum));
|
|
39
|
+
}
|
|
22
40
|
}
|
|
23
41
|
}
|
|
24
42
|
|
|
43
|
+
cloneNode() {
|
|
44
|
+
const cloned = this.cloneChildren(),
|
|
45
|
+
token = Parser.run(() => new GalleryToken(undefined, this.getAttribute('config')));
|
|
46
|
+
token.append(...cloned);
|
|
47
|
+
return token;
|
|
48
|
+
}
|
|
49
|
+
|
|
25
50
|
toString() {
|
|
26
51
|
return super.toString('\n');
|
|
27
52
|
}
|
|
53
|
+
|
|
54
|
+
getGaps() {
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
text() {
|
|
59
|
+
return text(this.children, '\n');
|
|
60
|
+
}
|
|
28
61
|
}
|
|
29
62
|
|
|
30
63
|
Parser.classes.GalleryToken = __filename;
|
package/src/link/category.js
CHANGED
package/src/link/file.js
CHANGED
|
@@ -64,7 +64,7 @@ class FileToken extends LinkToken {
|
|
|
64
64
|
super(link, undefined, title, config, accum);
|
|
65
65
|
this.setAttribute('acceptable', {AtomToken: 0, ImageParameterToken: '1:'});
|
|
66
66
|
this.append(...explode('-{', '}-', '|', text).map(part => new ImageParameterToken(part, config, accum)));
|
|
67
|
-
this.seal(['setFragment', 'asSelfLink', 'setLinkText', 'pipeTrick']);
|
|
67
|
+
this.seal(['setLangLink', 'setFragment', 'asSelfLink', 'setLinkText', 'pipeTrick']);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const /** @type {Parser} */ Parser = require('../..'),
|
|
4
|
+
Token = require('..'),
|
|
5
|
+
FileToken = require('./file');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 图片
|
|
9
|
+
* @classdesc `{childNodes: [AtomToken, ...ImageParameterToken]}`
|
|
10
|
+
*/
|
|
11
|
+
class GalleryImageToken extends FileToken {
|
|
12
|
+
type = 'gallery-image';
|
|
13
|
+
|
|
14
|
+
size = undefined;
|
|
15
|
+
width = undefined;
|
|
16
|
+
height = undefined;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {string} link
|
|
20
|
+
* @param {string|undefined} text
|
|
21
|
+
* @param {Title} title
|
|
22
|
+
* @param {accum} accum
|
|
23
|
+
*/
|
|
24
|
+
constructor(link, text, title, config = Parser.getConfig(), accum = []) {
|
|
25
|
+
let token;
|
|
26
|
+
if (text !== undefined) {
|
|
27
|
+
token = new Token(text, config, true, accum);
|
|
28
|
+
token.type = 'temp';
|
|
29
|
+
token.setAttribute('stage', 1);
|
|
30
|
+
for (let n = 1; n < Parser.MAX_STAGE; n++) {
|
|
31
|
+
token.parseOnce();
|
|
32
|
+
}
|
|
33
|
+
accum.splice(accum.indexOf(token), 1);
|
|
34
|
+
}
|
|
35
|
+
const newConfig = structuredClone(config);
|
|
36
|
+
newConfig.img = Object.fromEntries(Object.entries(config.img).filter(([, param]) => param !== 'width'));
|
|
37
|
+
super(link, token?.toString(), title, newConfig, accum);
|
|
38
|
+
this.seal(['size', 'width', 'height']);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getPadding() {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Parser.classes.GalleryImageToken = __filename;
|
|
47
|
+
module.exports = GalleryImageToken;
|
package/src/link/index.js
CHANGED
|
@@ -47,7 +47,7 @@ class LinkToken extends Token {
|
|
|
47
47
|
title: this.name, interwiki: this.interwiki, fragment: this.fragment,
|
|
48
48
|
}, this.getAttribute('config'));
|
|
49
49
|
token.firstElementChild.safeReplaceWith(link);
|
|
50
|
-
token.
|
|
50
|
+
token.append(...linkText);
|
|
51
51
|
return token.afterBuild();
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -91,7 +91,7 @@ class LinkToken extends Token {
|
|
|
91
91
|
|
|
92
92
|
toString() {
|
|
93
93
|
const str = super.toString('|');
|
|
94
|
-
return this.
|
|
94
|
+
return this.type === 'gallery-image' ? str : `[[${str}]]`;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
getPadding() {
|
|
@@ -103,19 +103,20 @@ class LinkToken extends Token {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
text() {
|
|
106
|
-
|
|
106
|
+
const str = super.text('|');
|
|
107
|
+
return this.type === 'gallery-image' ? str : `[[${str}]]`;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
/** @param {string} link */
|
|
110
111
|
setTarget(link) {
|
|
111
112
|
link = String(link);
|
|
112
|
-
if (!/^\s*[:#]/.test(link)) {
|
|
113
|
+
if (link.type === 'link' && !/^\s*[:#]/.test(link)) {
|
|
113
114
|
link = `:${link}`;
|
|
114
115
|
}
|
|
115
116
|
const root = Parser.parse(`[[${link}]]`, this.getAttribute('include'), 6, this.getAttribute('config')),
|
|
116
117
|
{childNodes: {length}, firstElementChild} = root;
|
|
117
118
|
if (length !== 1 || firstElementChild?.type !== this.type || firstElementChild.childNodes.length !== 1) {
|
|
118
|
-
const msgs = {link: '内链', file: '文件链接', category: '分类'};
|
|
119
|
+
const msgs = {link: '内链', file: '文件链接', category: '分类', 'gallery-image': '文件链接'};
|
|
119
120
|
throw new SyntaxError(`非法的${msgs[this.type]}目标:${link}`);
|
|
120
121
|
}
|
|
121
122
|
const {firstChild} = firstElementChild;
|
package/src/magicLink.js
CHANGED
|
@@ -37,7 +37,7 @@ class MagicLinkToken extends Token {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
afterBuild() {
|
|
40
|
-
const ParameterToken = require('./parameter'),
|
|
40
|
+
const ParameterToken = require('./parameter'),
|
|
41
41
|
/** @type {ParameterToken} */ parameter = this.closest('parameter');
|
|
42
42
|
if (parameter?.getValue() === this.text()) {
|
|
43
43
|
this.replaceWith(this.toString());
|
|
@@ -45,6 +45,16 @@ class MagicLinkToken extends Token {
|
|
|
45
45
|
return this;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
cloneNode() {
|
|
49
|
+
const cloned = this.cloneChildren(),
|
|
50
|
+
token = Parser.run(() => new MagicLinkToken(
|
|
51
|
+
undefined, this.type === 'ext-link-url', this.getAttribute('config'),
|
|
52
|
+
));
|
|
53
|
+
token.append(...cloned);
|
|
54
|
+
token.afterBuild();
|
|
55
|
+
return token;
|
|
56
|
+
}
|
|
57
|
+
|
|
48
58
|
getUrl() {
|
|
49
59
|
let url = this.text();
|
|
50
60
|
if (url.startsWith('//')) {
|
package/src/table/index.js
CHANGED
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
const assert = require('assert/strict'),
|
|
4
4
|
{noWrap} = require('../../util/string'),
|
|
5
5
|
/** @type {Parser} */ Parser = require('../..'),
|
|
6
|
-
Token = require('..'),
|
|
6
|
+
Token = require('..'),
|
|
7
7
|
TrToken = require('./tr'),
|
|
8
8
|
TdToken = require('./td'),
|
|
9
9
|
SyntaxToken = require('../syntax'),
|
|
10
|
-
AttributeToken = require('../attribute');
|
|
10
|
+
AttributeToken = require('../attribute');
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @param {TableCoords} coords1
|
|
14
14
|
* @param {TableCoords} coords2
|
|
15
15
|
*/
|
|
16
16
|
const cmpCoords = (coords1, coords2) => {
|
|
17
|
-
const diff = coords1
|
|
18
|
-
return diff === 0 ? coords1
|
|
17
|
+
const diff = coords1.row - coords2.row;
|
|
18
|
+
return diff === 0 ? coords1.column - coords2.column : diff;
|
|
19
19
|
};
|
|
20
20
|
const isRowEnd = /** @param {Token} */ ({type}) => ['tr', 'table-syntax'].includes(type);
|
|
21
21
|
|
|
@@ -192,7 +192,7 @@ class TableToken extends TrToken {
|
|
|
192
192
|
{length} = rows,
|
|
193
193
|
/** @type {Layout} */ layout = new Layout(length).fill().map(() => []);
|
|
194
194
|
for (const [i, rowToken] of rows.entries()) {
|
|
195
|
-
if (i > stop.row ?? stop.y) {
|
|
195
|
+
if (i > (stop.row ?? stop.y)) {
|
|
196
196
|
break;
|
|
197
197
|
}
|
|
198
198
|
const rowLayout = layout[i];
|
package/src/table/td.js
CHANGED
|
@@ -45,7 +45,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
45
45
|
*/
|
|
46
46
|
getSyntax() {
|
|
47
47
|
const syntax = this.firstElementChild.text(),
|
|
48
|
-
|
|
48
|
+
esc = syntax.includes('{{');
|
|
49
49
|
let subtype = 'td';
|
|
50
50
|
if (syntax.endsWith('!')) {
|
|
51
51
|
subtype = 'th';
|
|
@@ -53,14 +53,14 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
53
53
|
subtype = 'caption';
|
|
54
54
|
}
|
|
55
55
|
if (this.isIndependent()) {
|
|
56
|
-
return {subtype, escape, correction: false};
|
|
56
|
+
return {subtype, escape: esc, correction: false};
|
|
57
57
|
}
|
|
58
58
|
const {previousElementSibling} = this;
|
|
59
59
|
if (previousElementSibling?.type !== 'td') {
|
|
60
|
-
return {subtype, escape, correction: true};
|
|
60
|
+
return {subtype, escape: esc, correction: true};
|
|
61
61
|
}
|
|
62
62
|
const result = previousElementSibling.getSyntax();
|
|
63
|
-
result.escape ||=
|
|
63
|
+
result.escape ||= esc;
|
|
64
64
|
result.correction = previousElementSibling.lastElementChild.offsetHeight > 1;
|
|
65
65
|
if (subtype === 'th' && result.subtype !== 'th') {
|
|
66
66
|
result.subtype = 'th';
|
|
@@ -91,6 +91,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
91
91
|
if (innerSyntax) {
|
|
92
92
|
[this.#innerSyntax] = innerSyntax;
|
|
93
93
|
}
|
|
94
|
+
// eslint-disable-next-line no-unsafe-optional-chaining
|
|
94
95
|
const innerToken = new Token(inner?.slice(innerSyntax?.index + this.#innerSyntax.length), config, true, accum);
|
|
95
96
|
innerToken.type = 'td-inner';
|
|
96
97
|
this.setAttribute('acceptable', {SyntaxToken: 0, AttributeToken: 1, Token: 2})
|
|
@@ -98,7 +99,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
cloneNode() {
|
|
101
|
-
const token = super.cloneNode();
|
|
102
|
+
const /** @type {TdToken} */ token = super.cloneNode();
|
|
102
103
|
token.setAttribute('innerSyntax', this.#innerSyntax);
|
|
103
104
|
return token;
|
|
104
105
|
}
|
|
@@ -141,6 +142,7 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
141
142
|
* @template {string} T
|
|
142
143
|
* @param {T} key
|
|
143
144
|
* @param {TokenAttribute<T>} value
|
|
145
|
+
* @return {this}
|
|
144
146
|
*/
|
|
145
147
|
setAttribute(key, value) {
|
|
146
148
|
if (key !== 'innerSyntax') {
|
|
@@ -162,8 +164,8 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
162
164
|
static #aliases = {td: '\n|', th: '\n!', caption: '\n|+'};
|
|
163
165
|
|
|
164
166
|
/** @param {string} syntax */
|
|
165
|
-
setSyntax(syntax,
|
|
166
|
-
super.setSyntax(TdToken.#aliases[syntax] ?? syntax,
|
|
167
|
+
setSyntax(syntax, esc = false) {
|
|
168
|
+
super.setSyntax(TdToken.#aliases[syntax] ?? syntax, esc);
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
/** @complexity `n` */
|
|
@@ -171,17 +173,17 @@ class TdToken extends fixedToken(TrToken) {
|
|
|
171
173
|
if (this.children[1].toString()) {
|
|
172
174
|
this.#innerSyntax ||= '|';
|
|
173
175
|
}
|
|
174
|
-
const {subtype, escape, correction} = this.getSyntax();
|
|
176
|
+
const {subtype, escape: esc, correction} = this.getSyntax();
|
|
175
177
|
if (correction) {
|
|
176
|
-
this.setSyntax(subtype,
|
|
178
|
+
this.setSyntax(subtype, esc);
|
|
177
179
|
}
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
/** @complexity `n` */
|
|
181
183
|
independence() {
|
|
182
184
|
if (!this.isIndependent()) {
|
|
183
|
-
const {subtype, escape} = this.getSyntax();
|
|
184
|
-
this.setSyntax(subtype,
|
|
185
|
+
const {subtype, escape: esc} = this.getSyntax();
|
|
186
|
+
this.setSyntax(subtype, esc);
|
|
185
187
|
}
|
|
186
188
|
}
|
|
187
189
|
|
package/src/table/tr.js
CHANGED
|
@@ -93,10 +93,10 @@ class TrToken extends attributeParent(Token, 1) {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/** @param {string} syntax */
|
|
96
|
-
setSyntax(syntax,
|
|
96
|
+
setSyntax(syntax, esc = false) {
|
|
97
97
|
const {firstElementChild} = this;
|
|
98
98
|
firstElementChild.replaceChildren(syntax);
|
|
99
|
-
if (
|
|
99
|
+
if (esc) {
|
|
100
100
|
TrToken.escape(firstElementChild);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -202,7 +202,7 @@ class TrToken extends attributeParent(Token, 1) {
|
|
|
202
202
|
if (n < 0 || n > nCols || n === nCols && !insert) {
|
|
203
203
|
throw new RangeError(`不存在第 ${n} 个单元格!`);
|
|
204
204
|
}
|
|
205
|
-
const TdToken = require('./td');
|
|
205
|
+
const TdToken = require('./td');
|
|
206
206
|
let last = 0;
|
|
207
207
|
for (const child of this.children.slice(2)) {
|
|
208
208
|
if (child instanceof TdToken) {
|
package/src/tagPair/ext.js
CHANGED
|
@@ -23,7 +23,7 @@ class ExtToken extends attributeParent(TagPairToken) {
|
|
|
23
23
|
attrToken = new AttributeToken(attr, 'ext-attr', lcName, config, accum),
|
|
24
24
|
newConfig = structuredClone(config),
|
|
25
25
|
ext = new Set(newConfig.ext);
|
|
26
|
-
let /** @type {acceptable} */ acceptable, innerToken;
|
|
26
|
+
let /** @type {acceptable} */ acceptable, /** @type {Token} */ innerToken;
|
|
27
27
|
switch (lcName) {
|
|
28
28
|
case 'choose':
|
|
29
29
|
ext.add('option');
|
|
@@ -42,15 +42,23 @@ class ExtToken extends attributeParent(TagPairToken) {
|
|
|
42
42
|
innerToken = new Token(inner, newConfig, false, accum);
|
|
43
43
|
break;
|
|
44
44
|
}
|
|
45
|
+
case 'gallery': {
|
|
46
|
+
ext.delete(lcName);
|
|
47
|
+
newConfig.ext = [...ext];
|
|
48
|
+
const GalleryToken = require('../gallery');
|
|
49
|
+
acceptable = {AttributeToken: 0, GalleryToken: 1};
|
|
50
|
+
innerToken = new GalleryToken(inner, newConfig, accum);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
45
53
|
/*
|
|
46
54
|
* 更多定制扩展的代码示例:
|
|
47
55
|
* ```
|
|
48
56
|
* case 'extensionName': {
|
|
49
|
-
* ext.delete(
|
|
57
|
+
* ext.delete(lcName);
|
|
50
58
|
* newConfig.ext = [...ext];
|
|
51
59
|
* const ExtensionToken = require('../extension');
|
|
52
60
|
* acceptable = {AttributeToken: 0, ExtensionToken: 1};
|
|
53
|
-
* innerToken = new ExtensionToken(
|
|
61
|
+
* innerToken = new ExtensionToken(inner, newConfig, accum);
|
|
54
62
|
* break;
|
|
55
63
|
* }
|
|
56
64
|
* ```
|
package/util/string.js
CHANGED
|
@@ -21,7 +21,7 @@ const escapeRegExp = str => str.replace(/[\\{}()|.?*+\-^$[\]]/g, '\\$&');
|
|
|
21
21
|
|
|
22
22
|
/** @param {(string|AstNode)[]} childNodes */
|
|
23
23
|
const text = (childNodes, separator = '') => {
|
|
24
|
-
const AstNode = require('../lib/node');
|
|
24
|
+
const AstNode = require('../lib/node');
|
|
25
25
|
return childNodes.map(child => typeof child === 'string' ? child : child.text()).join(separator);
|
|
26
26
|
};
|
|
27
27
|
|
|
@@ -62,7 +62,7 @@ const noWrap = str => str.replaceAll('\n', '\\n');
|
|
|
62
62
|
* @returns {string}
|
|
63
63
|
*/
|
|
64
64
|
const normalizeSpace = (token = '', separator = '') => {
|
|
65
|
-
const Token = require('../src');
|
|
65
|
+
const Token = require('../src');
|
|
66
66
|
return typeof token === 'string'
|
|
67
67
|
? token.replaceAll('\n', ' ')
|
|
68
68
|
: token.childNodes.map(child => typeof child === 'string' ? normalizeSpace(child) : child.toString())
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<!---->:
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
Error: ListToken 不可删除元素!
|
|
2
|
-
at ListToken.removeAt (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/mixin/fixedToken.js:14:9)
|
|
3
|
-
at ListToken.replaceChildren (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/lib/element.js:232:9)
|
|
4
|
-
at ListToken.build (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/src/index.js:500:8)
|
|
5
|
-
at Token.build (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/src/index.js:504:11)
|
|
6
|
-
at Token.parse (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/src/index.js:533:19)
|
|
7
|
-
at /Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/index.js:135:11
|
|
8
|
-
at Object.run (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/index.js:33:19)
|
|
9
|
-
at Object.parse (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/index.js:125:8)
|
|
10
|
-
at REPL8:1:10
|
|
11
|
-
at Script.runInThisContext (node:vm:130:12)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<!---->:
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
Error: ListToken 不可删除元素!
|
|
2
|
-
at ListToken.removeAt (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/mixin/fixedToken.js:14:9)
|
|
3
|
-
at ListToken.replaceChildren (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/lib/element.js:232:9)
|
|
4
|
-
at ListToken.build (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/src/index.js:500:8)
|
|
5
|
-
at Token.build (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/src/index.js:504:11)
|
|
6
|
-
at Token.parse (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/src/index.js:533:19)
|
|
7
|
-
at /Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/index.js:135:11
|
|
8
|
-
at Object.run (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/index.js:33:19)
|
|
9
|
-
at Object.parse (/Users/mengxiwu/Documents/CCM-RP/node/wikiparser-node/index.js:125:8)
|
|
10
|
-
at REPL68:1:10
|
|
11
|
-
at Script.runInThisContext (node:vm:130:12)
|