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.
Files changed (111) hide show
  1. package/README.md +5 -0
  2. package/bundle/bundle-es8.min.js +28 -29
  3. package/bundle/bundle-lsp.min.js +31 -31
  4. package/bundle/bundle.min.js +24 -24
  5. package/coverage/badge.svg +1 -1
  6. package/dist/addon/attribute.js +186 -0
  7. package/dist/addon/link.js +91 -0
  8. package/dist/addon/table.js +150 -105
  9. package/dist/addon/token.js +8 -304
  10. package/dist/addon/transclude.js +9 -6
  11. package/dist/base.d.mts +9 -1
  12. package/dist/base.d.ts +9 -1
  13. package/dist/bin/config.js +1 -1
  14. package/dist/index.d.ts +24 -5
  15. package/dist/index.js +71 -92
  16. package/dist/internal.d.ts +4 -0
  17. package/dist/lib/document.d.ts +9 -7
  18. package/dist/lib/document.js +91 -66
  19. package/dist/lib/element.d.ts +7 -7
  20. package/dist/lib/element.js +48 -50
  21. package/dist/lib/lintConfig.js +3 -1
  22. package/dist/lib/lsp.js +127 -56
  23. package/dist/lib/node.js +20 -14
  24. package/dist/lib/text.js +6 -6
  25. package/dist/lib/title.d.ts +11 -0
  26. package/dist/lib/title.js +37 -13
  27. package/dist/mixin/elementLike.js +2 -3
  28. package/dist/mixin/syntax.js +13 -7
  29. package/dist/parser/commentAndExt.js +3 -3
  30. package/dist/parser/selector.js +16 -41
  31. package/dist/render/expand.js +216 -0
  32. package/dist/render/extension.js +141 -0
  33. package/dist/render/html.js +91 -0
  34. package/dist/{addon → render}/magicWords.js +48 -7
  35. package/dist/render/syntaxhighlight.js +415 -0
  36. package/dist/src/arg.js +1 -1
  37. package/dist/src/attribute.d.ts +9 -5
  38. package/dist/src/attribute.js +68 -108
  39. package/dist/src/attributes.d.ts +7 -1
  40. package/dist/src/attributes.js +22 -51
  41. package/dist/src/converter.js +4 -2
  42. package/dist/src/converterFlags.js +8 -6
  43. package/dist/src/converterRule.js +19 -15
  44. package/dist/src/extLink.js +1 -1
  45. package/dist/src/heading.d.ts +1 -1
  46. package/dist/src/heading.js +5 -3
  47. package/dist/src/imageParameter.d.ts +7 -4
  48. package/dist/src/imageParameter.js +47 -28
  49. package/dist/src/index.d.ts +13 -5
  50. package/dist/src/index.js +67 -42
  51. package/dist/src/link/base.d.ts +1 -1
  52. package/dist/src/link/base.js +26 -38
  53. package/dist/src/link/category.d.ts +7 -0
  54. package/dist/src/link/category.js +101 -37
  55. package/dist/src/link/categorytree.d.ts +27 -0
  56. package/dist/src/link/categorytree.js +115 -0
  57. package/dist/src/link/file.d.ts +3 -2
  58. package/dist/src/link/file.js +23 -9
  59. package/dist/src/link/galleryImage.js +7 -9
  60. package/dist/src/link/index.d.ts +1 -1
  61. package/dist/src/link/index.js +10 -31
  62. package/dist/src/multiLine/gallery.d.ts +1 -4
  63. package/dist/src/multiLine/gallery.js +1 -11
  64. package/dist/src/multiLine/imagemap.d.ts +0 -1
  65. package/dist/src/multiLine/imagemap.js +98 -152
  66. package/dist/src/multiLine/index.d.ts +1 -0
  67. package/dist/src/multiLine/index.js +77 -22
  68. package/dist/src/multiLine/inputbox.d.ts +3 -3
  69. package/dist/src/multiLine/inputbox.js +3 -7
  70. package/dist/src/multiLine/paramTag.d.ts +3 -4
  71. package/dist/src/multiLine/paramTag.js +6 -48
  72. package/dist/src/nowiki/comment.js +1 -1
  73. package/dist/src/nowiki/doubleUnderscore.js +4 -2
  74. package/dist/src/nowiki/index.js +34 -31
  75. package/dist/src/nowiki/listBase.d.ts +2 -1
  76. package/dist/src/nowiki/listBase.js +22 -8
  77. package/dist/src/nowiki/quote.d.ts +1 -1
  78. package/dist/src/nowiki/quote.js +1 -1
  79. package/dist/src/onlyinclude.js +1 -1
  80. package/dist/src/paramLine.d.ts +3 -0
  81. package/dist/src/paramLine.js +45 -7
  82. package/dist/src/parameter.js +1 -1
  83. package/dist/src/redirect.js +1 -1
  84. package/dist/src/table/base.d.ts +1 -1
  85. package/dist/src/table/base.js +4 -2
  86. package/dist/src/table/index.d.ts +2 -7
  87. package/dist/src/table/index.js +7 -54
  88. package/dist/src/table/td.js +9 -5
  89. package/dist/src/table/tr.d.ts +1 -1
  90. package/dist/src/tag/index.js +1 -1
  91. package/dist/src/tagPair/ext.js +33 -48
  92. package/dist/src/tagPair/index.js +6 -4
  93. package/dist/src/tagPair/translate.js +2 -2
  94. package/dist/src/transclude.d.ts +0 -6
  95. package/dist/src/transclude.js +16 -33
  96. package/dist/util/constants.js +5 -1
  97. package/dist/util/debug.js +81 -7
  98. package/dist/util/diff.js +17 -15
  99. package/dist/util/html.js +5 -3
  100. package/dist/util/selector.js +37 -0
  101. package/dist/util/sharable.d.mts +5 -1
  102. package/dist/util/sharable.js +69 -8
  103. package/dist/util/sharable.mjs +69 -7
  104. package/dist/util/string.js +31 -12
  105. package/extensions/dist/base.js +1 -1
  106. package/extensions/typings.d.ts +40 -0
  107. package/extensions/ui.css +1 -1
  108. package/i18n/en.json +2 -0
  109. package/i18n/zh-hans.json +31 -29
  110. package/i18n/zh-hant.json +32 -30
  111. package/package.json +19 -15
@@ -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: 87%"><title>Coverage: 87%</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">87%</text><text x="795" y="140" transform="scale(.1)" fill="#fff" textLength="250">87%</text></g></svg>
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;
@@ -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(Boolean).map(coords => [rows[coords.row].getNthCol(coords.column), layout[coords.row][x - 1] !== coords]));
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 = this.prependTableRow();
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 : this.prependTableRow();
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
- this.split(coords, new Set(['rowspan']));
456
+ split(this, coords, new Set(['rowspan']));
375
457
  };
376
458
  index_2.TableToken.prototype.splitIntoCols =
377
459
  /** @implements */
378
460
  function (coords) {
379
- this.split(coords, new Set(['colspan']));
461
+ split(this, coords, new Set(['colspan']));
380
462
  };
381
463
  index_2.TableToken.prototype.splitIntoCells =
382
464
  /** @implements */
383
465
  function (coords) {
384
- this.split(coords, new Set(['rowspan', 'colspan']));
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 = this.prependTableRow();
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 = this.prependTableRow();
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(index_2.isRowEnd);
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
- this.moveCol(x, before);
566
+ moveCol(this, x, before);
522
567
  };
523
568
  index_2.TableToken.prototype.moveTableColAfter =
524
569
  /** @implements */
525
570
  function (x, after) {
526
- this.moveCol(x, after, true);
571
+ moveCol(this, x, after, true);
527
572
  };
528
573
  constants_1.classes['ExtendedTableToken'] = __filename;