wikiparser-node 1.31.0 → 1.33.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/README.md +5 -0
- package/bundle/bundle-es8.min.js +28 -29
- package/bundle/bundle-lsp.min.js +31 -31
- package/bundle/bundle.min.js +24 -24
- package/coverage/badge.svg +1 -1
- package/dist/addon/attribute.js +186 -0
- package/dist/addon/link.js +91 -0
- package/dist/addon/table.js +150 -105
- package/dist/addon/token.js +8 -304
- package/dist/addon/transclude.js +9 -6
- package/dist/base.d.mts +9 -1
- package/dist/base.d.ts +9 -1
- package/dist/bin/config.js +1 -1
- package/dist/index.d.ts +24 -5
- package/dist/index.js +71 -92
- package/dist/internal.d.ts +4 -0
- package/dist/lib/document.d.ts +9 -7
- package/dist/lib/document.js +91 -66
- package/dist/lib/element.d.ts +7 -7
- package/dist/lib/element.js +48 -50
- package/dist/lib/lintConfig.js +3 -1
- package/dist/lib/lsp.js +127 -56
- package/dist/lib/node.js +20 -14
- package/dist/lib/text.js +6 -6
- package/dist/lib/title.d.ts +11 -0
- package/dist/lib/title.js +37 -13
- package/dist/mixin/elementLike.js +2 -3
- package/dist/mixin/syntax.js +13 -7
- package/dist/parser/commentAndExt.js +3 -3
- package/dist/parser/selector.js +16 -41
- package/dist/render/expand.js +216 -0
- package/dist/render/extension.js +141 -0
- package/dist/render/html.js +91 -0
- package/dist/{addon → render}/magicWords.js +48 -7
- package/dist/render/syntaxhighlight.js +415 -0
- package/dist/src/arg.js +1 -1
- package/dist/src/attribute.d.ts +9 -5
- package/dist/src/attribute.js +68 -108
- package/dist/src/attributes.d.ts +7 -1
- package/dist/src/attributes.js +22 -51
- package/dist/src/converter.js +4 -2
- package/dist/src/converterFlags.js +8 -6
- package/dist/src/converterRule.js +19 -15
- package/dist/src/extLink.js +1 -1
- package/dist/src/heading.d.ts +1 -1
- package/dist/src/heading.js +5 -3
- package/dist/src/imageParameter.d.ts +7 -4
- package/dist/src/imageParameter.js +47 -28
- package/dist/src/index.d.ts +13 -5
- package/dist/src/index.js +67 -42
- package/dist/src/link/base.d.ts +1 -1
- package/dist/src/link/base.js +26 -38
- package/dist/src/link/category.d.ts +7 -0
- package/dist/src/link/category.js +101 -37
- package/dist/src/link/categorytree.d.ts +27 -0
- package/dist/src/link/categorytree.js +115 -0
- package/dist/src/link/file.d.ts +3 -2
- package/dist/src/link/file.js +23 -9
- package/dist/src/link/galleryImage.js +7 -9
- package/dist/src/link/index.d.ts +1 -1
- package/dist/src/link/index.js +10 -31
- package/dist/src/multiLine/gallery.d.ts +1 -4
- package/dist/src/multiLine/gallery.js +1 -11
- package/dist/src/multiLine/imagemap.d.ts +0 -1
- package/dist/src/multiLine/imagemap.js +98 -152
- package/dist/src/multiLine/index.d.ts +1 -0
- package/dist/src/multiLine/index.js +77 -22
- package/dist/src/multiLine/inputbox.d.ts +3 -3
- package/dist/src/multiLine/inputbox.js +3 -7
- package/dist/src/multiLine/paramTag.d.ts +3 -4
- package/dist/src/multiLine/paramTag.js +6 -48
- package/dist/src/nowiki/comment.js +1 -1
- package/dist/src/nowiki/doubleUnderscore.js +4 -2
- package/dist/src/nowiki/index.js +34 -31
- package/dist/src/nowiki/listBase.d.ts +2 -1
- package/dist/src/nowiki/listBase.js +22 -8
- package/dist/src/nowiki/quote.d.ts +1 -1
- package/dist/src/nowiki/quote.js +1 -1
- package/dist/src/onlyinclude.js +1 -1
- package/dist/src/paramLine.d.ts +3 -0
- package/dist/src/paramLine.js +45 -7
- package/dist/src/parameter.js +1 -1
- package/dist/src/redirect.js +1 -1
- package/dist/src/table/base.d.ts +1 -1
- package/dist/src/table/base.js +4 -2
- package/dist/src/table/index.d.ts +2 -7
- package/dist/src/table/index.js +7 -54
- package/dist/src/table/td.js +9 -5
- package/dist/src/table/tr.d.ts +1 -1
- package/dist/src/tag/index.js +1 -1
- package/dist/src/tagPair/ext.js +33 -48
- package/dist/src/tagPair/index.js +6 -4
- package/dist/src/tagPair/translate.js +2 -2
- package/dist/src/transclude.d.ts +0 -6
- package/dist/src/transclude.js +16 -33
- package/dist/util/constants.js +5 -1
- package/dist/util/debug.js +81 -7
- package/dist/util/diff.js +17 -15
- package/dist/util/html.js +5 -3
- package/dist/util/selector.js +37 -0
- package/dist/util/sharable.d.mts +5 -1
- package/dist/util/sharable.js +69 -8
- package/dist/util/sharable.mjs +69 -7
- package/dist/util/string.js +31 -12
- package/extensions/dist/base.js +1 -1
- package/extensions/typings.d.ts +40 -0
- package/extensions/ui.css +1 -1
- package/i18n/en.json +2 -0
- package/i18n/zh-hans.json +31 -29
- package/i18n/zh-hant.json +32 -30
- package/package.json +19 -15
package/coverage/badge.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="98" height="20" role="img" aria-label="Coverage:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="98" height="20" role="img" aria-label="Coverage: 88%"><title>Coverage: 88%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="98" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="63" height="20" fill="#555"/><rect x="63" width="35" height="20" fill="#4c1"/><rect width="98" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">Coverage</text><text x="325" y="140" transform="scale(.1)" fill="#fff" textLength="530">Coverage</text><text aria-hidden="true" x="795" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250">88%</text><text x="795" y="140" transform="scale(.1)" fill="#fff" textLength="250">88%</text></g></svg>
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint @stylistic/operator-linebreak: [2, "before", {overrides: {"=": "after"}}] */
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const constants_1 = require("../util/constants");
|
|
8
|
+
const debug_1 = require("../util/debug");
|
|
9
|
+
const string_1 = require("../util/string");
|
|
10
|
+
const index_1 = __importDefault(require("../index"));
|
|
11
|
+
const document_1 = require("../lib/document");
|
|
12
|
+
const attribute_1 = require("../src/attribute");
|
|
13
|
+
const attributes_1 = require("../src/attributes");
|
|
14
|
+
const atom_1 = require("../src/atom");
|
|
15
|
+
attribute_1.AttributeToken.prototype.setValue =
|
|
16
|
+
/** @implements */
|
|
17
|
+
function (value) {
|
|
18
|
+
if (value === false) {
|
|
19
|
+
this.remove();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
else if (value === true) {
|
|
23
|
+
this.setAttribute('equal', '');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const { type, lastChild } = this;
|
|
27
|
+
/* istanbul ignore next */
|
|
28
|
+
if (type === 'ext-attr' && value.includes('>')) {
|
|
29
|
+
throw new RangeError('Attributes of an extension tag cannot contain ">"!');
|
|
30
|
+
}
|
|
31
|
+
else if (value.includes('"') && value.includes(`'`)) {
|
|
32
|
+
throw new RangeError('Attribute values cannot contain single and double quotes simultaneously!');
|
|
33
|
+
}
|
|
34
|
+
const { childNodes } = index_1.default.parseWithRef(value, this, attribute_1.stages[type] + 1);
|
|
35
|
+
lastChild.safeReplaceChildren(childNodes);
|
|
36
|
+
this.setAttribute('equal', this.isInside('parameter') ? '{{=}}' : '=');
|
|
37
|
+
if (value.includes('"')) {
|
|
38
|
+
this.setAttribute('quotes', [`'`, `'`]);
|
|
39
|
+
}
|
|
40
|
+
else if (value.includes(`'`) || !this.getAttribute('quotes')[0]) {
|
|
41
|
+
this.setAttribute('quotes', ['"', '"']);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.close();
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
attribute_1.AttributeToken.prototype.rename =
|
|
48
|
+
/** @implements */
|
|
49
|
+
function (key) {
|
|
50
|
+
const { type, name, tag, firstChild } = this;
|
|
51
|
+
/* istanbul ignore if */
|
|
52
|
+
if (name === 'title' || name === 'alt' && tag === 'img') {
|
|
53
|
+
throw new Error(`${name} attribute cannot be renamed!`);
|
|
54
|
+
}
|
|
55
|
+
const { childNodes } = index_1.default.parseWithRef(key, this, attribute_1.stages[type] + 1);
|
|
56
|
+
firstChild.safeReplaceChildren(childNodes);
|
|
57
|
+
};
|
|
58
|
+
attribute_1.AttributeToken.prototype.css =
|
|
59
|
+
/** @implements */
|
|
60
|
+
function (key, value) {
|
|
61
|
+
const { name, lastChild } = this;
|
|
62
|
+
/* istanbul ignore next */
|
|
63
|
+
if (name !== 'style') {
|
|
64
|
+
throw new Error('Not a style attribute!');
|
|
65
|
+
}
|
|
66
|
+
else if (lastChild.length > 1 || lastChild.length === 1 && lastChild.firstChild.type !== 'text') {
|
|
67
|
+
throw new Error('Complex style attribute!');
|
|
68
|
+
}
|
|
69
|
+
const cssLSP = (0, document_1.loadCssLSP)();
|
|
70
|
+
/* istanbul ignore if */
|
|
71
|
+
if (!cssLSP) {
|
|
72
|
+
throw new Error('CSS language service is not available!');
|
|
73
|
+
}
|
|
74
|
+
const doc = new document_1.EmbeddedCSSDocument(this.getRootNode(), lastChild), styleSheet = doc.styleSheet, { children: [{ declarations: { children } }] } = styleSheet, declaration = children?.filter(({ property }) => property.getText() === key) ?? [];
|
|
75
|
+
if (value === undefined) {
|
|
76
|
+
return declaration.at(-1)?.value.getText();
|
|
77
|
+
}
|
|
78
|
+
else if (typeof value === 'number') {
|
|
79
|
+
value = String(value);
|
|
80
|
+
}
|
|
81
|
+
const style = styleSheet.getText().slice(0, -1);
|
|
82
|
+
if (!value) {
|
|
83
|
+
if (declaration.length === children?.length) {
|
|
84
|
+
this.setValue('');
|
|
85
|
+
}
|
|
86
|
+
else if (declaration.length > 0) {
|
|
87
|
+
let output = '', start = doc.pre.length;
|
|
88
|
+
for (const { offset, length } of declaration) {
|
|
89
|
+
output += style.slice(start, offset);
|
|
90
|
+
start = offset + length;
|
|
91
|
+
}
|
|
92
|
+
output += style.slice(start);
|
|
93
|
+
this.setValue(output.replace(/^\s*;\s*|;\s*(?=;)/gu, ''));
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const hasQuote = value.includes('"'), [quot] = this.getAttribute('quotes');
|
|
98
|
+
/* istanbul ignore next */
|
|
99
|
+
if (quot && value.includes(quot) || hasQuote && value.includes(`'`)) {
|
|
100
|
+
const quote = quot || '"';
|
|
101
|
+
throw new RangeError(`Please consider replacing \`${quote}\` with \`${quote === '"' ? `'` : '"'}\`!`);
|
|
102
|
+
}
|
|
103
|
+
else if (declaration.length > 0) {
|
|
104
|
+
const { offset, length } = declaration.at(-1).value;
|
|
105
|
+
this.setValue(style.slice(doc.pre.length, offset) + value + style.slice(offset + length));
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.setValue(`${style.slice(doc.pre.length)}${!children?.length || /;\s*$/u.test(style) ? '' : '; '}${key}: ${value}`);
|
|
109
|
+
}
|
|
110
|
+
return undefined;
|
|
111
|
+
};
|
|
112
|
+
attributes_1.AttributesToken.prototype.sanitize =
|
|
113
|
+
/** @implements */
|
|
114
|
+
function () {
|
|
115
|
+
const type = (0, attributes_1.toAttributeType)(this.type);
|
|
116
|
+
let dirty = false;
|
|
117
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
118
|
+
const child = this.childNodes[i];
|
|
119
|
+
if (child instanceof atom_1.AtomToken && child.text().trim()) {
|
|
120
|
+
dirty = true;
|
|
121
|
+
if (child.previousSibling?.is(type) && child.nextSibling?.is(type)) {
|
|
122
|
+
child.replaceChildren(' ');
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this.removeAt(i);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (!debug_1.Shadow.running && dirty) {
|
|
130
|
+
index_1.default.warn('AttributesToken.sanitize will remove invalid attributes!');
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
attributes_1.AttributesToken.prototype.setAttr =
|
|
134
|
+
/** @implements */
|
|
135
|
+
function (keyOrProp, value) {
|
|
136
|
+
if (typeof keyOrProp === 'object') {
|
|
137
|
+
for (const [key, val] of Object.entries(keyOrProp)) {
|
|
138
|
+
this.setAttr(key, val);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const { type, name } = this;
|
|
143
|
+
/* istanbul ignore if */
|
|
144
|
+
if (type === 'ext-attrs' && typeof value === 'string' && value.includes('>')) {
|
|
145
|
+
throw new RangeError('Attributes of an extension tag cannot contain ">"!');
|
|
146
|
+
}
|
|
147
|
+
const key = (0, string_1.trimLc)(keyOrProp), attr = this.getAttrToken(key);
|
|
148
|
+
if (attr) {
|
|
149
|
+
attr.setValue(value);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
else if (value === false) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// @ts-expect-error abstract class
|
|
156
|
+
const token = debug_1.Shadow.run(() => new attribute_1.AttributeToken((0, attributes_1.toAttributeType)(type), name, key, ['"', '"'], this.getAttribute('config'), value === true ? '' : '=', value === true ? '' : value));
|
|
157
|
+
this.insertAt(token);
|
|
158
|
+
};
|
|
159
|
+
attributes_1.AttributesToken.prototype.toggleAttr =
|
|
160
|
+
/** @implements */
|
|
161
|
+
function (key, force) {
|
|
162
|
+
key = (0, string_1.trimLc)(key);
|
|
163
|
+
const attr = this.getAttrToken(key);
|
|
164
|
+
/* istanbul ignore if */
|
|
165
|
+
if (attr && attr.getValue() !== true) {
|
|
166
|
+
throw new RangeError(`${key} attribute is not Boolean!`);
|
|
167
|
+
}
|
|
168
|
+
else if (attr) {
|
|
169
|
+
attr.setValue(force === true);
|
|
170
|
+
}
|
|
171
|
+
else if (force !== false) {
|
|
172
|
+
this.setAttr(key, true);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
attributes_1.AttributesToken.prototype.css =
|
|
176
|
+
/** @implements */
|
|
177
|
+
function (key, value) {
|
|
178
|
+
let attr = this.getAttrToken('style');
|
|
179
|
+
if (!attr) {
|
|
180
|
+
// @ts-expect-error abstract class
|
|
181
|
+
const token = debug_1.Shadow.run(() => new attribute_1.AttributeToken((0, attributes_1.toAttributeType)(this.type), this.name, 'style', [], this.getAttribute('config')));
|
|
182
|
+
attr = this.insertAt(token);
|
|
183
|
+
}
|
|
184
|
+
return attr.css(key, value);
|
|
185
|
+
};
|
|
186
|
+
constants_1.classes['ExtendedAttributeToken'] = __filename;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint @stylistic/operator-linebreak: [2, "before", {overrides: {"=": "after"}}] */
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const constants_1 = require("../util/constants");
|
|
8
|
+
const debug_1 = require("../util/debug");
|
|
9
|
+
const string_1 = require("../util/string");
|
|
10
|
+
const index_1 = __importDefault(require("../index"));
|
|
11
|
+
const index_2 = require("../src/index");
|
|
12
|
+
const base_1 = require("../src/link/base");
|
|
13
|
+
const index_3 = require("../src/link/index");
|
|
14
|
+
const atom_1 = require("../src/atom");
|
|
15
|
+
base_1.LinkBaseToken.prototype.setTarget =
|
|
16
|
+
/** @implements */
|
|
17
|
+
function (link) {
|
|
18
|
+
const { childNodes } = index_1.default.parseWithRef(link, this, 2), token = debug_1.Shadow.run(() => new atom_1.AtomToken(undefined, 'link-target', this.getAttribute('config'), [], { 'Stage-2': ':', '!ExtToken': '', '!HeadingToken': '' }));
|
|
19
|
+
token.concat(childNodes); // eslint-disable-line unicorn/prefer-spread
|
|
20
|
+
this.firstChild.safeReplaceWith(token);
|
|
21
|
+
};
|
|
22
|
+
base_1.LinkBaseToken.prototype.setFragment =
|
|
23
|
+
/** @implements */
|
|
24
|
+
function (fragment) {
|
|
25
|
+
const { type, name } = this;
|
|
26
|
+
if (fragment === undefined || (0, debug_1.isLink)(type)) {
|
|
27
|
+
fragment &&= (0, string_1.encode)(fragment);
|
|
28
|
+
this.setTarget(name + (fragment === undefined ? '' : `#${fragment}`));
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
base_1.LinkBaseToken.prototype.setLinkText =
|
|
32
|
+
/** @implements */
|
|
33
|
+
function (linkStr) {
|
|
34
|
+
if (linkStr === undefined) {
|
|
35
|
+
this.childNodes[1]?.remove();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
else if (this.length === 1) {
|
|
39
|
+
this.insertAt(debug_1.Shadow.run(() => {
|
|
40
|
+
const inner = new index_2.Token(undefined, this.getAttribute('config'), [], {
|
|
41
|
+
'Stage-5': ':', QuoteToken: ':', ConverterToken: ':',
|
|
42
|
+
});
|
|
43
|
+
inner.type = 'link-text';
|
|
44
|
+
return inner;
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
this.lastChild.safeReplaceChildren(index_1.default.parseWithRef(linkStr, this).childNodes);
|
|
48
|
+
};
|
|
49
|
+
index_3.LinkToken.prototype.setLangLink =
|
|
50
|
+
/** @implements */
|
|
51
|
+
function (lang, link) {
|
|
52
|
+
link = link.trim();
|
|
53
|
+
/* istanbul ignore if */
|
|
54
|
+
if (link.startsWith('#')) {
|
|
55
|
+
throw new SyntaxError('An interlanguage link cannot be fragment only!');
|
|
56
|
+
}
|
|
57
|
+
this.setTarget(lang + (link.startsWith(':') ? '' : ':') + link);
|
|
58
|
+
};
|
|
59
|
+
index_3.LinkToken.prototype.asSelfLink =
|
|
60
|
+
/** @implements */
|
|
61
|
+
function (fragment) {
|
|
62
|
+
fragment ??= this.fragment;
|
|
63
|
+
/* istanbul ignore if */
|
|
64
|
+
if (!fragment?.trim()) {
|
|
65
|
+
throw new RangeError('LinkToken.asSelfLink method must specify a non-empty fragment!');
|
|
66
|
+
}
|
|
67
|
+
this.setTarget(`#${(0, string_1.encode)(fragment)}`);
|
|
68
|
+
};
|
|
69
|
+
index_3.LinkToken.prototype.pipeTrick =
|
|
70
|
+
/** @implements */
|
|
71
|
+
function () {
|
|
72
|
+
const linkText = this.firstChild.text();
|
|
73
|
+
/* istanbul ignore if */
|
|
74
|
+
if (linkText.includes('#') || linkText.includes('%')) {
|
|
75
|
+
throw new Error('Pipe trick cannot be used with "#" or "%"!');
|
|
76
|
+
}
|
|
77
|
+
const m1 = /^:?(?:[ \w\x80-\xFF-]+:)?([^(]+?) ?\(.+\)$/u.exec(linkText);
|
|
78
|
+
if (m1) {
|
|
79
|
+
this.setLinkText(m1[1]);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const m2 = /^:?(?:[ \w\x80-\xFF-]+:)?([^(]+?) ?(.+)$/u.exec(linkText);
|
|
83
|
+
if (m2) {
|
|
84
|
+
this.setLinkText(m2[1]);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const m3 = /^:?(?:[ \w\x80-\xFF-]+:)?(.*?)(?: ?(?<!\()\(.+\))?(?:(?:, |,|، ).|$)/u
|
|
88
|
+
.exec(linkText);
|
|
89
|
+
this.setLinkText(m3[1]);
|
|
90
|
+
};
|
|
91
|
+
constants_1.classes['ExtendedLinkToken'] = __filename;
|
package/dist/addon/table.js
CHANGED
|
@@ -106,6 +106,145 @@ const getMaxCol = (layout) => {
|
|
|
106
106
|
}
|
|
107
107
|
return maxCol;
|
|
108
108
|
};
|
|
109
|
+
/**
|
|
110
|
+
* 在表格开头插入一行
|
|
111
|
+
* @param table 表格
|
|
112
|
+
*/
|
|
113
|
+
const prependTableRow = (table) => {
|
|
114
|
+
// @ts-expect-error abstract class
|
|
115
|
+
const row = debug_1.Shadow.run(() => new tr_1.TrToken('\n|-', undefined, table.getAttribute('config'))), { childNodes } = table, [, , plain] = childNodes, start = plain?.constructor === index_1.Token ? 3 : 2, tdChildren = childNodes.slice(start), index = tdChildren.findIndex(({ type }) => type !== 'td');
|
|
116
|
+
table.insertAt(row, index === -1 ? -1 : index + start);
|
|
117
|
+
debug_1.Shadow.run(() => {
|
|
118
|
+
for (const cell of tdChildren.slice(0, index === -1 ? undefined : index)) {
|
|
119
|
+
if (cell.subtype !== 'caption') {
|
|
120
|
+
row.insertAt(cell);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return row;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* 分裂单元格
|
|
128
|
+
* @param table 表格
|
|
129
|
+
* @param coords 单元格坐标
|
|
130
|
+
* @param dirs 分裂方向
|
|
131
|
+
* @throws `RangeError` 指定坐标不是某个单元格的起始点
|
|
132
|
+
*/
|
|
133
|
+
const split = (table, coords, dirs) => {
|
|
134
|
+
const cell = table.getNthCell(coords), attr = cell.getAttrs(), { subtype } = cell;
|
|
135
|
+
attr.rowspan ||= 1;
|
|
136
|
+
attr.colspan ||= 1;
|
|
137
|
+
for (const dir of dirs) {
|
|
138
|
+
if (attr[dir] === 1) {
|
|
139
|
+
dirs.delete(dir);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (dirs.size === 0) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
let { x, y } = coords;
|
|
146
|
+
const rawCoords = isTableCoords(coords) ? coords : table.toRawCoords(coords);
|
|
147
|
+
if (rawCoords.start === false || x === undefined) {
|
|
148
|
+
({ x, y } = table.toRenderedCoords(rawCoords));
|
|
149
|
+
}
|
|
150
|
+
const splitting = { rowspan: 1, colspan: 1 };
|
|
151
|
+
for (const dir of dirs) {
|
|
152
|
+
cell.setAttr(dir, 1);
|
|
153
|
+
splitting[dir] = attr[dir];
|
|
154
|
+
delete attr[dir];
|
|
155
|
+
}
|
|
156
|
+
for (let j = y; j < y + splitting.rowspan; j++) {
|
|
157
|
+
for (let i = x; i < x + splitting.colspan; i++) {
|
|
158
|
+
if (i > x || j > y) {
|
|
159
|
+
try {
|
|
160
|
+
table.insertTableCell('', { x: i, y: j }, subtype, attr);
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
if (e instanceof RangeError
|
|
164
|
+
&& e.message.startsWith('The specified coordinates are not the starting point of a cell: ')) {
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
throw e;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* 移动表格列
|
|
175
|
+
* @param table 表格
|
|
176
|
+
* @param x 列号
|
|
177
|
+
* @param reference 参考列号
|
|
178
|
+
* @param after 是否插入到参考列之后
|
|
179
|
+
* @throws `RangeError` 两列结构不一致,无法移动
|
|
180
|
+
*/
|
|
181
|
+
const moveCol = (table, x, reference, after) => {
|
|
182
|
+
const layout = table.getLayout();
|
|
183
|
+
if (layout.some(rowLayout => isStartCol(rowLayout, x) !== isStartCol(rowLayout, reference, after))) {
|
|
184
|
+
throw new RangeError(`The structure of column ${x} is different from that of column ${reference}, so it cannot be moved!`);
|
|
185
|
+
}
|
|
186
|
+
const setX = new WeakSet(), setRef = new WeakSet(), rows = table.getAllRows();
|
|
187
|
+
for (let i = 0; i < layout.length; i++) {
|
|
188
|
+
const rowLayout = layout[i], coords = rowLayout[x], refCoords = rowLayout[reference], start = isStartCol(rowLayout, x);
|
|
189
|
+
if (refCoords && !start && !setRef.has(refCoords)) {
|
|
190
|
+
setRef.add(refCoords);
|
|
191
|
+
rows[refCoords.row].getNthCol(refCoords.column).colspan++;
|
|
192
|
+
}
|
|
193
|
+
if (coords && !setX.has(coords)) {
|
|
194
|
+
setX.add(coords);
|
|
195
|
+
const rowToken = rows[i];
|
|
196
|
+
let token = rowToken.getNthCol(coords.column);
|
|
197
|
+
const { colspan } = token;
|
|
198
|
+
if (colspan > 1) {
|
|
199
|
+
token.colspan = colspan - 1;
|
|
200
|
+
if (start) {
|
|
201
|
+
const original = token;
|
|
202
|
+
token = token.cloneNode();
|
|
203
|
+
original.lastChild.replaceChildren();
|
|
204
|
+
token.colspan = 1;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (start) {
|
|
208
|
+
const col = rowLayout.slice(reference + Number(after)).find(({ row }) => row === i)?.column;
|
|
209
|
+
rowToken.insertBefore(token, col === undefined
|
|
210
|
+
? rowToken.childNodes.slice(2).find(debug_1.isRowEnd)
|
|
211
|
+
: rowToken.getNthCol(col));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
index_2.Layout.prototype.print =
|
|
217
|
+
/** @implements */
|
|
218
|
+
function () {
|
|
219
|
+
const hBorders = (0, debug_1.emptyArray)(this.length + 1, i => {
|
|
220
|
+
const prev = this[i - 1] ?? [], next = this[i] ?? [];
|
|
221
|
+
return (0, debug_1.emptyArray)(Math.max(prev.length, next.length), j => prev[j] !== next[j]);
|
|
222
|
+
}), vBorders = this.map(cur => (0, debug_1.emptyArray)(cur.length + 1, j => cur[j - 1] !== cur[j]));
|
|
223
|
+
let out = '';
|
|
224
|
+
for (let i = 0; i <= this.length; i++) {
|
|
225
|
+
const hBorder = hBorders[i].map(Number), vBorderTop = (vBorders[i - 1] ?? []).map(Number), vBorderBottom = (vBorders[i] ?? []).map(Number),
|
|
226
|
+
// eslint-disable-next-line no-sparse-arrays
|
|
227
|
+
border = [' ', , , '┌', , '┐', '─', '┬', , '│', '└', '├', '┘', '┤', '┴', '┼'];
|
|
228
|
+
for (let j = 0; j <= hBorder.length; j++) {
|
|
229
|
+
/* eslint-disable no-bitwise */
|
|
230
|
+
const bit = (vBorderTop[j] << 3) + (vBorderBottom[j] << 0)
|
|
231
|
+
+ (hBorder[j - 1] << 2) + (hBorder[j] << 1);
|
|
232
|
+
/* eslint-enable no-bitwise */
|
|
233
|
+
out += border[bit] + (hBorder[j] ? '─' : ' ');
|
|
234
|
+
}
|
|
235
|
+
out += '\n';
|
|
236
|
+
}
|
|
237
|
+
console.log(out.slice(0, -1));
|
|
238
|
+
};
|
|
239
|
+
index_2.TableToken.prototype.getNthCell =
|
|
240
|
+
/** @implements */
|
|
241
|
+
function (coords) {
|
|
242
|
+
let rawCoords = coords;
|
|
243
|
+
if (coords.row === undefined) {
|
|
244
|
+
rawCoords = this.toRawCoords(coords);
|
|
245
|
+
}
|
|
246
|
+
return rawCoords && this.getNthRow(rawCoords.row, false, false)?.getNthCol(rawCoords.column);
|
|
247
|
+
};
|
|
109
248
|
index_2.TableToken.prototype.printLayout =
|
|
110
249
|
/** @implements */
|
|
111
250
|
function () {
|
|
@@ -144,7 +283,7 @@ index_2.TableToken.prototype.getFullCol =
|
|
|
144
283
|
/** @implements */
|
|
145
284
|
function (x) {
|
|
146
285
|
const layout = this.getLayout(), rows = this.getAllRows();
|
|
147
|
-
return new Map(layout.map(row => row[x]).filter(
|
|
286
|
+
return new Map(layout.map(row => row[x]).filter(coords => coords !== undefined).map(coords => [rows[coords.row].getNthCol(coords.column), layout[coords.row][x - 1] !== coords]));
|
|
148
287
|
};
|
|
149
288
|
index_2.TableToken.prototype.formatTableRow =
|
|
150
289
|
/** @implements */
|
|
@@ -189,21 +328,6 @@ index_2.TableToken.prototype.insertTableCell =
|
|
|
189
328
|
? trBase_1.TrBaseToken.prototype.insertTableCell.call(this, inner, rawCoords, subtype, attr)
|
|
190
329
|
: rowToken.insertTableCell(inner, rawCoords, subtype, attr);
|
|
191
330
|
};
|
|
192
|
-
index_2.TableToken.prototype.prependTableRow =
|
|
193
|
-
/** @implements */
|
|
194
|
-
function () {
|
|
195
|
-
// @ts-expect-error abstract class
|
|
196
|
-
const row = debug_1.Shadow.run(() => new tr_1.TrToken('\n|-', undefined, this.getAttribute('config'))), { childNodes } = this, [, , plain] = childNodes, start = plain?.constructor === index_1.Token ? 3 : 2, tdChildren = childNodes.slice(start), index = tdChildren.findIndex(({ type }) => type !== 'td');
|
|
197
|
-
this.insertAt(row, index === -1 ? -1 : index + start);
|
|
198
|
-
debug_1.Shadow.run(() => {
|
|
199
|
-
for (const cell of tdChildren.slice(0, index === -1 ? undefined : index)) {
|
|
200
|
-
if (cell.subtype !== 'caption') {
|
|
201
|
-
row.insertAt(cell);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
return row;
|
|
206
|
-
};
|
|
207
331
|
index_2.TableToken.prototype.insertTableRow =
|
|
208
332
|
/** @implements */
|
|
209
333
|
function (y, attr = {}, inner, subtype = 'td', innerAttr = {}) {
|
|
@@ -212,7 +336,7 @@ index_2.TableToken.prototype.insertTableRow =
|
|
|
212
336
|
const token = debug_1.Shadow.run(() => new tr_1.TrToken('\n|-', undefined, this.getAttribute('config')));
|
|
213
337
|
token.setAttr(attr);
|
|
214
338
|
if (reference?.is('table')) { // `row === 0`且表格自身是有效行
|
|
215
|
-
reference =
|
|
339
|
+
reference = prependTableRow(this);
|
|
216
340
|
}
|
|
217
341
|
this.insertBefore(token, reference);
|
|
218
342
|
if (inner !== undefined) {
|
|
@@ -289,7 +413,7 @@ index_2.TableToken.prototype.removeTableRow =
|
|
|
289
413
|
}
|
|
290
414
|
}
|
|
291
415
|
}
|
|
292
|
-
const row = rows[y], rowToken = row.is('tr') ? row :
|
|
416
|
+
const row = rows[y], rowToken = row.is('tr') ? row : prependTableRow(this);
|
|
293
417
|
rowToken.remove();
|
|
294
418
|
return rowToken;
|
|
295
419
|
};
|
|
@@ -326,69 +450,27 @@ index_2.TableToken.prototype.mergeCells =
|
|
|
326
450
|
}
|
|
327
451
|
return cornerCell;
|
|
328
452
|
};
|
|
329
|
-
index_2.TableToken.prototype.split =
|
|
330
|
-
/** @implements */
|
|
331
|
-
function (coords, dirs) {
|
|
332
|
-
const cell = this.getNthCell(coords), attr = cell.getAttrs(), { subtype } = cell;
|
|
333
|
-
attr.rowspan ||= 1;
|
|
334
|
-
attr.colspan ||= 1;
|
|
335
|
-
for (const dir of dirs) {
|
|
336
|
-
if (attr[dir] === 1) {
|
|
337
|
-
dirs.delete(dir);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
if (dirs.size === 0) {
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
let { x, y } = coords;
|
|
344
|
-
const rawCoords = isTableCoords(coords) ? coords : this.toRawCoords(coords);
|
|
345
|
-
if (rawCoords.start === false || x === undefined) {
|
|
346
|
-
({ x, y } = this.toRenderedCoords(rawCoords));
|
|
347
|
-
}
|
|
348
|
-
const splitting = { rowspan: 1, colspan: 1 };
|
|
349
|
-
for (const dir of dirs) {
|
|
350
|
-
cell.setAttr(dir, 1);
|
|
351
|
-
splitting[dir] = attr[dir];
|
|
352
|
-
delete attr[dir];
|
|
353
|
-
}
|
|
354
|
-
for (let j = y; j < y + splitting.rowspan; j++) {
|
|
355
|
-
for (let i = x; i < x + splitting.colspan; i++) {
|
|
356
|
-
if (i > x || j > y) {
|
|
357
|
-
try {
|
|
358
|
-
this.insertTableCell('', { x: i, y: j }, subtype, attr);
|
|
359
|
-
}
|
|
360
|
-
catch (e) {
|
|
361
|
-
if (e instanceof RangeError
|
|
362
|
-
&& e.message.startsWith('The specified coordinates are not the starting point of a cell: ')) {
|
|
363
|
-
break;
|
|
364
|
-
}
|
|
365
|
-
throw e;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
};
|
|
371
453
|
index_2.TableToken.prototype.splitIntoRows =
|
|
372
454
|
/** @implements */
|
|
373
455
|
function (coords) {
|
|
374
|
-
|
|
456
|
+
split(this, coords, new Set(['rowspan']));
|
|
375
457
|
};
|
|
376
458
|
index_2.TableToken.prototype.splitIntoCols =
|
|
377
459
|
/** @implements */
|
|
378
460
|
function (coords) {
|
|
379
|
-
|
|
461
|
+
split(this, coords, new Set(['colspan']));
|
|
380
462
|
};
|
|
381
463
|
index_2.TableToken.prototype.splitIntoCells =
|
|
382
464
|
/** @implements */
|
|
383
465
|
function (coords) {
|
|
384
|
-
|
|
466
|
+
split(this, coords, new Set(['rowspan', 'colspan']));
|
|
385
467
|
};
|
|
386
468
|
index_2.TableToken.prototype.replicateTableRow =
|
|
387
469
|
/** @implements */
|
|
388
470
|
function (row) {
|
|
389
471
|
let rowToken = this.getNthRow(row);
|
|
390
472
|
if (rowToken.is('table')) {
|
|
391
|
-
rowToken =
|
|
473
|
+
rowToken = prependTableRow(this);
|
|
392
474
|
}
|
|
393
475
|
const replicated = this.insertBefore(rowToken.cloneNode(), rowToken);
|
|
394
476
|
for (const [token, start] of this.getFullRow(row)) {
|
|
@@ -439,7 +521,7 @@ index_2.TableToken.prototype.moveTableRowBefore =
|
|
|
439
521
|
}
|
|
440
522
|
let beforeToken = this.getNthRow(before);
|
|
441
523
|
if (beforeToken.is('table')) {
|
|
442
|
-
beforeToken =
|
|
524
|
+
beforeToken = prependTableRow(this);
|
|
443
525
|
}
|
|
444
526
|
this.insertBefore(rowToken, beforeToken);
|
|
445
527
|
return rowToken;
|
|
@@ -470,7 +552,7 @@ index_2.TableToken.prototype.moveTableRowAfter =
|
|
|
470
552
|
}
|
|
471
553
|
}
|
|
472
554
|
if (afterToken === this) {
|
|
473
|
-
const index = this.childNodes.slice(2).findIndex(
|
|
555
|
+
const index = this.childNodes.slice(2).findIndex(debug_1.isRowEnd);
|
|
474
556
|
this.insertAt(rowToken, index + 2);
|
|
475
557
|
}
|
|
476
558
|
else {
|
|
@@ -478,51 +560,14 @@ index_2.TableToken.prototype.moveTableRowAfter =
|
|
|
478
560
|
}
|
|
479
561
|
return rowToken;
|
|
480
562
|
};
|
|
481
|
-
index_2.TableToken.prototype.moveCol =
|
|
482
|
-
/** @implements */
|
|
483
|
-
function (x, reference, after) {
|
|
484
|
-
const layout = this.getLayout();
|
|
485
|
-
if (layout.some(rowLayout => isStartCol(rowLayout, x) !== isStartCol(rowLayout, reference, after))) {
|
|
486
|
-
throw new RangeError(`The structure of column ${x} is different from that of column ${reference}, so it cannot be moved!`);
|
|
487
|
-
}
|
|
488
|
-
const setX = new WeakSet(), setRef = new WeakSet(), rows = this.getAllRows();
|
|
489
|
-
for (let i = 0; i < layout.length; i++) {
|
|
490
|
-
const rowLayout = layout[i], coords = rowLayout[x], refCoords = rowLayout[reference], start = isStartCol(rowLayout, x);
|
|
491
|
-
if (refCoords && !start && !setRef.has(refCoords)) {
|
|
492
|
-
setRef.add(refCoords);
|
|
493
|
-
rows[refCoords.row].getNthCol(refCoords.column).colspan++;
|
|
494
|
-
}
|
|
495
|
-
if (coords && !setX.has(coords)) {
|
|
496
|
-
setX.add(coords);
|
|
497
|
-
const rowToken = rows[i];
|
|
498
|
-
let token = rowToken.getNthCol(coords.column);
|
|
499
|
-
const { colspan } = token;
|
|
500
|
-
if (colspan > 1) {
|
|
501
|
-
token.colspan = colspan - 1;
|
|
502
|
-
if (start) {
|
|
503
|
-
const original = token;
|
|
504
|
-
token = token.cloneNode();
|
|
505
|
-
original.lastChild.replaceChildren();
|
|
506
|
-
token.colspan = 1;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
if (start) {
|
|
510
|
-
const col = rowLayout.slice(reference + Number(after)).find(({ row }) => row === i)?.column;
|
|
511
|
-
rowToken.insertBefore(token, col === undefined
|
|
512
|
-
? rowToken.childNodes.slice(2).find(index_2.isRowEnd)
|
|
513
|
-
: rowToken.getNthCol(col));
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
};
|
|
518
563
|
index_2.TableToken.prototype.moveTableColBefore =
|
|
519
564
|
/** @implements */
|
|
520
565
|
function (x, before) {
|
|
521
|
-
|
|
566
|
+
moveCol(this, x, before);
|
|
522
567
|
};
|
|
523
568
|
index_2.TableToken.prototype.moveTableColAfter =
|
|
524
569
|
/** @implements */
|
|
525
570
|
function (x, after) {
|
|
526
|
-
|
|
571
|
+
moveCol(this, x, after, true);
|
|
527
572
|
};
|
|
528
573
|
constants_1.classes['ExtendedTableToken'] = __filename;
|