wikilint 2.5.7 → 2.6.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/dist/mixin/attributesParent.d.ts +14 -0
- package/dist/mixin/attributesParent.js +25 -0
- package/dist/mixin/hidden.d.ts +5 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +70 -0
- package/dist/src/link/base.d.ts +1 -0
- package/dist/src/link/base.js +1 -0
- package/dist/src/table/base.d.ts +4 -4
- package/dist/src/table/base.js +2 -1
- package/dist/src/table/index.d.ts +38 -0
- package/dist/src/table/index.js +110 -1
- package/dist/src/table/td.d.ts +11 -1
- package/dist/src/table/td.js +16 -0
- package/dist/src/table/trBase.d.ts +10 -0
- package/dist/src/table/trBase.js +20 -0
- package/dist/util/debug.js +8 -1
- package/package.json +2 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface AttributesParentBase {
|
|
2
|
+
/**
|
|
3
|
+
* 获取AttributesToken子节点的属性
|
|
4
|
+
* @param key 属性键
|
|
5
|
+
*/
|
|
6
|
+
getAttr(key: string): string | true | undefined;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 子节点含有AttributesToken的类
|
|
10
|
+
* @param i AttributesToken子节点的位置
|
|
11
|
+
* @param constructor 基类
|
|
12
|
+
* @param _ context
|
|
13
|
+
*/
|
|
14
|
+
export declare const attributesParent: (i?: number) => <T extends AstConstructor>(constructor: T, _?: unknown) => T;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.attributesParent = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 子节点含有AttributesToken的类
|
|
6
|
+
* @param i AttributesToken子节点的位置
|
|
7
|
+
* @param constructor 基类
|
|
8
|
+
* @param _ context
|
|
9
|
+
*/
|
|
10
|
+
const attributesParent = (i = 0) => (constructor, _) => {
|
|
11
|
+
/** 子节点含有AttributesToken的类 */
|
|
12
|
+
class AttributesParent extends constructor {
|
|
13
|
+
/** AttributesToken子节点 */
|
|
14
|
+
get #attributesChild() {
|
|
15
|
+
return this.childNodes[i];
|
|
16
|
+
}
|
|
17
|
+
/** @implements */
|
|
18
|
+
getAttr(key) {
|
|
19
|
+
return this.#attributesChild.getAttr(key);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(AttributesParent, 'name', { value: constructor.name });
|
|
23
|
+
return AttributesParent;
|
|
24
|
+
};
|
|
25
|
+
exports.attributesParent = attributesParent;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { BuildMethod } from '../util/constants';
|
|
|
2
2
|
import Parser from '../index';
|
|
3
3
|
import { AstElement } from '../lib/element';
|
|
4
4
|
import { AstText } from '../lib/text';
|
|
5
|
+
import type { LintError } from '../base';
|
|
5
6
|
import type { Title } from '../lib/title';
|
|
6
7
|
import type { AstNodes } from '../internal';
|
|
7
8
|
import type { TokenTypes } from '../util/constants';
|
|
@@ -30,4 +31,6 @@ export declare class Token extends AstElement {
|
|
|
30
31
|
* @param selfLink 是否允许selfLink
|
|
31
32
|
*/
|
|
32
33
|
normalizeTitle(title: string, defaultNs?: number, halfParsed?: boolean, decode?: boolean, selfLink?: boolean): Title;
|
|
34
|
+
/** @override */
|
|
35
|
+
lint(start?: number, re?: RegExp): LintError[];
|
|
33
36
|
}
|
package/dist/src/index.js
CHANGED
|
@@ -41,6 +41,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
41
41
|
exports.Token = void 0;
|
|
42
42
|
const string_1 = require("../util/string");
|
|
43
43
|
const constants_1 = require("../util/constants");
|
|
44
|
+
const lint_1 = require("../util/lint");
|
|
44
45
|
const index_1 = require("../index");
|
|
45
46
|
const element_1 = require("../lib/element");
|
|
46
47
|
const text_1 = require("../lib/text");
|
|
@@ -317,5 +318,74 @@ class Token extends element_1.AstElement {
|
|
|
317
318
|
normalizeTitle(title, defaultNs = 0, halfParsed = false, decode = false, selfLink = false) {
|
|
318
319
|
return index_1.default.normalizeTitle(title, defaultNs, this.#include, this.#config, halfParsed, decode, selfLink);
|
|
319
320
|
}
|
|
321
|
+
/** @override */
|
|
322
|
+
lint(start = this.getAbsoluteIndex(), re) {
|
|
323
|
+
const errors = super.lint(start, re);
|
|
324
|
+
const record = {};
|
|
325
|
+
for (const cat of this.childNodes.filter((node) => node.type === 'category')) {
|
|
326
|
+
const thisCat = record[cat.name];
|
|
327
|
+
if (thisCat) {
|
|
328
|
+
thisCat.add(cat);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
record[cat.name] = new Set([cat]);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
for (const value of Object.values(record)) {
|
|
335
|
+
if (value.size > 1) {
|
|
336
|
+
errors.push(...[...value].map(cat => {
|
|
337
|
+
const e = (0, lint_1.generateForSelf)(cat, { start: cat.getAbsoluteIndex() }, 'no-duplicate', 'duplicated category');
|
|
338
|
+
e.suggestions = [
|
|
339
|
+
{
|
|
340
|
+
desc: 'remove',
|
|
341
|
+
range: [e.startIndex, e.endIndex],
|
|
342
|
+
text: '',
|
|
343
|
+
},
|
|
344
|
+
];
|
|
345
|
+
return e;
|
|
346
|
+
}));
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (this.type === 'root') {
|
|
350
|
+
const regex = /<!--\s*lint-(disable(?:(?:-next)?-line)?|enable)(\s[\sa-z,-]*)?-->/gu, wikitext = String(this), ignores = [];
|
|
351
|
+
let mt = regex.exec(wikitext), last = 0, curLine = 0;
|
|
352
|
+
while (mt) {
|
|
353
|
+
const { 1: type, index } = mt, detail = mt[2]?.trim();
|
|
354
|
+
curLine += wikitext.slice(last, index).split('\n').length - 1;
|
|
355
|
+
last = index;
|
|
356
|
+
ignores.push({
|
|
357
|
+
line: curLine + (type === 'disable-line' ? 0 : 1),
|
|
358
|
+
from: type === 'disable' ? regex.lastIndex : undefined,
|
|
359
|
+
to: type === 'enable' ? regex.lastIndex : undefined,
|
|
360
|
+
rules: detail ? new Set(detail.split(',').map(r => r.trim())) : undefined,
|
|
361
|
+
});
|
|
362
|
+
mt = regex.exec(wikitext);
|
|
363
|
+
}
|
|
364
|
+
return errors.filter(({ rule, startLine, startIndex }) => {
|
|
365
|
+
const nearest = { pos: 0 };
|
|
366
|
+
for (const { line, from, to, rules } of ignores) {
|
|
367
|
+
if (line > startLine + 1) {
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
else if (rules && !rules.has(rule)) {
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
else if (line === startLine && from === undefined && to === undefined) {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
else if (from <= startIndex && from > nearest.pos) {
|
|
377
|
+
nearest.pos = from;
|
|
378
|
+
nearest.type = 'from';
|
|
379
|
+
}
|
|
380
|
+
else if (to <= startIndex && to > nearest.pos) {
|
|
381
|
+
nearest.pos = to;
|
|
382
|
+
nearest.type = 'to';
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return nearest.type !== 'from';
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
return errors;
|
|
389
|
+
}
|
|
320
390
|
}
|
|
321
391
|
exports.Token = Token;
|
package/dist/src/link/base.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { Title } from '../../lib/title';
|
|
|
10
10
|
export declare abstract class LinkBaseToken extends Token {
|
|
11
11
|
#private;
|
|
12
12
|
type: 'link' | 'category' | 'file' | 'gallery-image' | 'imagemap-image';
|
|
13
|
+
readonly name: string;
|
|
13
14
|
readonly childNodes: readonly [AtomToken, ...Token[]];
|
|
14
15
|
abstract get firstChild(): AtomToken;
|
|
15
16
|
abstract get lastChild(): Token;
|
package/dist/src/link/base.js
CHANGED
|
@@ -36,6 +36,7 @@ class LinkBaseToken extends index_2.Token {
|
|
|
36
36
|
if (this.#delimiter.includes('\0')) {
|
|
37
37
|
this.#delimiter = this.buildFromStr(this.#delimiter, constants_1.BuildMethod.String);
|
|
38
38
|
}
|
|
39
|
+
this.setAttribute('name', this.#title.main);
|
|
39
40
|
}
|
|
40
41
|
/** @private */
|
|
41
42
|
setAttribute(key, value) {
|
package/dist/src/table/base.d.ts
CHANGED
|
@@ -2,10 +2,9 @@ import Parser from '../../index';
|
|
|
2
2
|
import { Token } from '../index';
|
|
3
3
|
import { SyntaxToken } from '../syntax';
|
|
4
4
|
import { AttributesToken } from '../attributes';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
5
|
+
import type { AttributesParentBase } from '../../mixin/attributesParent';
|
|
6
|
+
export interface TableBaseToken extends AttributesParentBase {
|
|
7
|
+
}
|
|
9
8
|
export declare abstract class TableBaseToken extends Token {
|
|
10
9
|
type: 'table' | 'tr' | 'td';
|
|
11
10
|
readonly childNodes: readonly [SyntaxToken, AttributesToken, ...Token[]];
|
|
@@ -18,3 +17,4 @@ export declare abstract class TableBaseToken extends Token {
|
|
|
18
17
|
*/
|
|
19
18
|
constructor(pattern: RegExp, syntax?: string, attr?: string, config?: Parser.Config, accum?: Token[], acceptable?: Acceptable);
|
|
20
19
|
}
|
|
20
|
+
export {};
|
package/dist/src/table/base.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TableBaseToken = void 0;
|
|
4
|
+
const attributesParent_1 = require("../../mixin/attributesParent");
|
|
4
5
|
const index_1 = require("../../index");
|
|
5
6
|
const index_2 = require("../index");
|
|
6
7
|
const syntax_1 = require("../syntax");
|
|
@@ -9,7 +10,7 @@ const attributes_1 = require("../attributes");
|
|
|
9
10
|
* 表格行,含开头的换行,不含结尾的换行
|
|
10
11
|
* @classdesc `{childNodes: [SyntaxToken, AttributesToken, ...Token]}`
|
|
11
12
|
*/
|
|
12
|
-
class TableBaseToken extends index_2.Token {
|
|
13
|
+
class TableBaseToken extends (0, attributesParent_1.attributesParent)(1)(index_2.Token) {
|
|
13
14
|
/**
|
|
14
15
|
* @param pattern 表格语法正则
|
|
15
16
|
* @param syntax 表格语法
|
|
@@ -3,6 +3,15 @@ import { TrBaseToken } from './trBase';
|
|
|
3
3
|
import { SyntaxToken } from '../syntax';
|
|
4
4
|
import type { LintError } from '../../base';
|
|
5
5
|
import type { AttributesToken, TdToken, TrToken, Token } from '../../internal';
|
|
6
|
+
import type { TableCoords } from './trBase';
|
|
7
|
+
/**
|
|
8
|
+
* 是否是行尾
|
|
9
|
+
* @param {Token} cell 表格单元格
|
|
10
|
+
*/
|
|
11
|
+
export declare const isRowEnd: ({ type }: Token) => boolean;
|
|
12
|
+
/** @extends {Array<TableCoords[]>} */
|
|
13
|
+
export declare class Layout extends Array<TableCoords[]> {
|
|
14
|
+
}
|
|
6
15
|
/**
|
|
7
16
|
* 表格
|
|
8
17
|
* @classdesc `{childNodes: [SyntaxToken, AttributesToken, ?Token, ...TdToken, ...TrToken, ?SyntaxToken]}`
|
|
@@ -20,4 +29,33 @@ export declare abstract class TableToken extends TrBaseToken {
|
|
|
20
29
|
constructor(syntax: string, attr?: string, config?: Parser.Config, accum?: Token[]);
|
|
21
30
|
/** @override */
|
|
22
31
|
lint(start?: number, re?: RegExp): LintError[];
|
|
32
|
+
/**
|
|
33
|
+
* 获取表格布局
|
|
34
|
+
* @param stop 中止条件
|
|
35
|
+
* @param stop.row 中止行
|
|
36
|
+
* @param stop.column 中止列
|
|
37
|
+
* @param stop.x 中止行
|
|
38
|
+
* @param stop.y 中止列
|
|
39
|
+
*/
|
|
40
|
+
getLayout(stop?: {
|
|
41
|
+
row?: number;
|
|
42
|
+
column?: number;
|
|
43
|
+
x?: number;
|
|
44
|
+
y?: number;
|
|
45
|
+
}): Layout;
|
|
46
|
+
/** 获取所有行 */
|
|
47
|
+
getAllRows(): (TrToken | this)[];
|
|
48
|
+
/**
|
|
49
|
+
* 获取指定坐标的单元格
|
|
50
|
+
* @param coords 表格坐标
|
|
51
|
+
*/
|
|
52
|
+
getNthCell(coords: TableCoords): TdToken | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* 获取第n行
|
|
55
|
+
* @param n 行号
|
|
56
|
+
* @param force 是否将表格自身视为第一行
|
|
57
|
+
* @param insert 是否用于判断插入新行的位置
|
|
58
|
+
* @throws `RangeError` 不存在该行
|
|
59
|
+
*/
|
|
60
|
+
getNthRow(n: number, force?: boolean, insert?: false): TrToken | this | undefined;
|
|
23
61
|
}
|
package/dist/src/table/index.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TableToken = void 0;
|
|
3
|
+
exports.TableToken = exports.Layout = exports.isRowEnd = void 0;
|
|
4
4
|
const lint_1 = require("../../util/lint");
|
|
5
5
|
const debug_1 = require("../../util/debug");
|
|
6
6
|
const index_1 = require("../../index");
|
|
7
7
|
const trBase_1 = require("./trBase");
|
|
8
8
|
const syntax_1 = require("../syntax");
|
|
9
9
|
const closingPattern = /^\n[^\S\n]*(?:\|\}|\{\{\s*!\s*\}\}\}|\{\{\s*!\)\s*\}\})$/u;
|
|
10
|
+
/**
|
|
11
|
+
* 是否是行尾
|
|
12
|
+
* @param {Token} cell 表格单元格
|
|
13
|
+
*/
|
|
14
|
+
const isRowEnd = ({ type }) => type === 'tr' || type === 'table-syntax';
|
|
15
|
+
exports.isRowEnd = isRowEnd;
|
|
16
|
+
/** @extends {Array<TableCoords[]>} */
|
|
17
|
+
class Layout extends Array {
|
|
18
|
+
}
|
|
19
|
+
exports.Layout = Layout;
|
|
10
20
|
/**
|
|
11
21
|
* 表格
|
|
12
22
|
* @classdesc `{childNodes: [SyntaxToken, AttributesToken, ?Token, ...TdToken, ...TrToken, ?SyntaxToken]}`
|
|
@@ -30,6 +40,29 @@ class TableToken extends trBase_1.TrBaseToken {
|
|
|
30
40
|
if (!this.closed) {
|
|
31
41
|
errors.push((0, lint_1.generateForChild)(this.firstChild, { start }, 'unclosed-table', index_1.default.msg('unclosed $1', 'table')));
|
|
32
42
|
}
|
|
43
|
+
const layout = this.getLayout(), { length } = layout;
|
|
44
|
+
if (length > 1) {
|
|
45
|
+
let low = 1, high = Infinity, j = 0;
|
|
46
|
+
for (; j < length; j++) {
|
|
47
|
+
const row = layout[j], max = row.length;
|
|
48
|
+
if (max < low) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
else if (max < high) {
|
|
52
|
+
high = max;
|
|
53
|
+
}
|
|
54
|
+
const { colspan } = this.getNthCell(row[row.length - 1]), min = max - colspan + 1;
|
|
55
|
+
if (min > high) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
else if (min > low) {
|
|
59
|
+
low = min;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (j < length) {
|
|
63
|
+
errors.push((0, lint_1.generateForChild)(this.getNthRow(j), { start }, 'table-layout', 'inconsistent table layout', 'warning'));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
33
66
|
return errors;
|
|
34
67
|
}
|
|
35
68
|
/** @private */
|
|
@@ -41,5 +74,81 @@ class TableToken extends trBase_1.TrBaseToken {
|
|
|
41
74
|
}
|
|
42
75
|
this.lastChild.replaceChildren(...inner);
|
|
43
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* 获取表格布局
|
|
79
|
+
* @param stop 中止条件
|
|
80
|
+
* @param stop.row 中止行
|
|
81
|
+
* @param stop.column 中止列
|
|
82
|
+
* @param stop.x 中止行
|
|
83
|
+
* @param stop.y 中止列
|
|
84
|
+
*/
|
|
85
|
+
getLayout(stop) {
|
|
86
|
+
const rows = this.getAllRows(), { length } = rows, layout = new Layout(...(0, debug_1.emptyArray)(length, () => []));
|
|
87
|
+
for (let i = 0; i < length; i++) {
|
|
88
|
+
const rowLayout = layout[i];
|
|
89
|
+
let j = 0, k = 0, last;
|
|
90
|
+
for (const cell of rows[i].childNodes.slice(2)) {
|
|
91
|
+
if (cell.type === 'td') {
|
|
92
|
+
if (cell.isIndependent()) {
|
|
93
|
+
last = cell.subtype !== 'caption';
|
|
94
|
+
}
|
|
95
|
+
if (last) {
|
|
96
|
+
const coords = { row: i, column: j }, { rowspan, colspan } = cell;
|
|
97
|
+
j++;
|
|
98
|
+
while (rowLayout[k]) {
|
|
99
|
+
k++;
|
|
100
|
+
}
|
|
101
|
+
for (let y = i; y < Math.min(i + rowspan, length); y++) {
|
|
102
|
+
for (let x = k; x < k + colspan; x++) {
|
|
103
|
+
layout[y][x] = coords;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
k += colspan;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if ((0, exports.isRowEnd)(cell)) {
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return layout;
|
|
115
|
+
}
|
|
116
|
+
/** 获取所有行 */
|
|
117
|
+
getAllRows() {
|
|
118
|
+
return [
|
|
119
|
+
...super.getRowCount() ? [this] : [],
|
|
120
|
+
...this.childNodes.slice(1)
|
|
121
|
+
.filter((child) => child.type === 'tr' && child.getRowCount() > 0),
|
|
122
|
+
];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 获取指定坐标的单元格
|
|
126
|
+
* @param coords 表格坐标
|
|
127
|
+
*/
|
|
128
|
+
getNthCell(coords) {
|
|
129
|
+
const rawCoords = coords;
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
131
|
+
return rawCoords && this.getNthRow(rawCoords.row, false, false)?.getNthCol(rawCoords.column);
|
|
132
|
+
}
|
|
133
|
+
getNthRow(n, force = false, insert = false) {
|
|
134
|
+
const isRow = super.getRowCount();
|
|
135
|
+
if (n === 0
|
|
136
|
+
// eslint-disable-next-line @stylistic/no-extra-parens
|
|
137
|
+
&& (isRow)) {
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
else if (isRow) {
|
|
141
|
+
n--;
|
|
142
|
+
}
|
|
143
|
+
for (const child of this.childNodes.slice(2)) {
|
|
144
|
+
if (child.type === 'tr' && child.getRowCount()) {
|
|
145
|
+
n--;
|
|
146
|
+
if (n < 0) {
|
|
147
|
+
return child;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
44
153
|
}
|
|
45
154
|
exports.TableToken = TableToken;
|
package/dist/src/table/td.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface TdSpanAttrs {
|
|
|
8
8
|
rowspan?: number;
|
|
9
9
|
colspan?: number;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
declare type TdAttrGetter<T extends string> = T extends keyof TdSpanAttrs ? number : string | true | undefined;
|
|
12
12
|
/**
|
|
13
13
|
* `<td>`、`<th>`和`<caption>`
|
|
14
14
|
* @classdesc `{childNodes: [SyntaxToken, AttributesToken, Token]}`
|
|
@@ -20,6 +20,10 @@ export declare abstract class TdToken extends TableBaseToken {
|
|
|
20
20
|
abstract get parentNode(): TrToken | TableToken | undefined;
|
|
21
21
|
abstract get nextSibling(): this | TrToken | SyntaxToken | undefined;
|
|
22
22
|
abstract get previousSibling(): Token | undefined;
|
|
23
|
+
/** rowspan */
|
|
24
|
+
get rowspan(): number;
|
|
25
|
+
/** colspan */
|
|
26
|
+
get colspan(): number;
|
|
23
27
|
/** 单元格类型 */
|
|
24
28
|
get subtype(): TdSubtypes;
|
|
25
29
|
/**
|
|
@@ -33,4 +37,10 @@ export declare abstract class TdToken extends TableBaseToken {
|
|
|
33
37
|
lint(start?: number, re?: RegExp): LintError[];
|
|
34
38
|
/** 是否位于行首 */
|
|
35
39
|
isIndependent(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* @override
|
|
42
|
+
* @param key 属性键
|
|
43
|
+
*/
|
|
44
|
+
getAttr<T extends string>(key: T): TdAttrGetter<T>;
|
|
36
45
|
}
|
|
46
|
+
export {};
|
package/dist/src/table/td.js
CHANGED
|
@@ -13,6 +13,14 @@ const base_1 = require("./base");
|
|
|
13
13
|
class TdToken extends base_1.TableBaseToken {
|
|
14
14
|
type = 'td';
|
|
15
15
|
#innerSyntax = '';
|
|
16
|
+
/** rowspan */
|
|
17
|
+
get rowspan() {
|
|
18
|
+
return this.getAttr('rowspan');
|
|
19
|
+
}
|
|
20
|
+
/** colspan */
|
|
21
|
+
get colspan() {
|
|
22
|
+
return this.getAttr('colspan');
|
|
23
|
+
}
|
|
16
24
|
/** 单元格类型 */
|
|
17
25
|
get subtype() {
|
|
18
26
|
return this.#getSyntax().subtype;
|
|
@@ -113,5 +121,13 @@ class TdToken extends base_1.TableBaseToken {
|
|
|
113
121
|
isIndependent() {
|
|
114
122
|
return this.firstChild.text().startsWith('\n');
|
|
115
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* @override
|
|
126
|
+
* @param key 属性键
|
|
127
|
+
*/
|
|
128
|
+
getAttr(key) {
|
|
129
|
+
const value = super.getAttr(key);
|
|
130
|
+
return (key === 'rowspan' || key === 'colspan' ? Number(value) || 1 : value);
|
|
131
|
+
}
|
|
116
132
|
}
|
|
117
133
|
exports.TdToken = TdToken;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TableBaseToken } from './base';
|
|
2
|
+
import { TdToken } from './td';
|
|
2
3
|
import type { LintError } from '../../base';
|
|
3
4
|
export interface TableCoords {
|
|
4
5
|
readonly row: number;
|
|
@@ -12,4 +13,13 @@ export declare abstract class TrBaseToken extends TableBaseToken {
|
|
|
12
13
|
type: 'table' | 'tr';
|
|
13
14
|
/** @override */
|
|
14
15
|
lint(start?: number, re?: RegExp): LintError[];
|
|
16
|
+
/** 获取行数 */
|
|
17
|
+
getRowCount(): number;
|
|
18
|
+
/**
|
|
19
|
+
* 获取第n列
|
|
20
|
+
* @param n 列号
|
|
21
|
+
* @param insert 是否用于判断插入新列的位置
|
|
22
|
+
* @throws `RangeError` 不存在对应单元格
|
|
23
|
+
*/
|
|
24
|
+
getNthCol(n: number, insert?: false): TdToken | undefined;
|
|
15
25
|
}
|
package/dist/src/table/trBase.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.TrBaseToken = void 0;
|
|
|
4
4
|
const lint_1 = require("../../util/lint");
|
|
5
5
|
const debug_1 = require("../../util/debug");
|
|
6
6
|
const base_1 = require("./base");
|
|
7
|
+
const td_1 = require("./td");
|
|
7
8
|
/** 表格行或表格 */
|
|
8
9
|
class TrBaseToken extends base_1.TableBaseToken {
|
|
9
10
|
/** @override */
|
|
@@ -34,5 +35,24 @@ class TrBaseToken extends base_1.TableBaseToken {
|
|
|
34
35
|
errors.push(error);
|
|
35
36
|
return errors;
|
|
36
37
|
}
|
|
38
|
+
/** 获取行数 */
|
|
39
|
+
getRowCount() {
|
|
40
|
+
return Number(this.childNodes.some(child => child instanceof td_1.TdToken && child.isIndependent() && !child.firstChild.text().endsWith('+')));
|
|
41
|
+
}
|
|
42
|
+
getNthCol(n, insert = false) {
|
|
43
|
+
let last = 0;
|
|
44
|
+
for (const child of this.childNodes.slice(2)) {
|
|
45
|
+
if (child instanceof td_1.TdToken) {
|
|
46
|
+
if (child.isIndependent()) {
|
|
47
|
+
last = Number(child.subtype !== 'caption');
|
|
48
|
+
}
|
|
49
|
+
n -= last;
|
|
50
|
+
if (n < 0) {
|
|
51
|
+
return child;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
37
57
|
}
|
|
38
58
|
exports.TrBaseToken = TrBaseToken;
|
package/dist/util/debug.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setChildNodes = exports.isToken = exports.Shadow = void 0;
|
|
3
|
+
exports.emptyArray = exports.setChildNodes = exports.isToken = exports.Shadow = void 0;
|
|
4
4
|
exports.Shadow = {
|
|
5
5
|
running: false,
|
|
6
6
|
/** @private */
|
|
@@ -31,3 +31,10 @@ const setChildNodes = (parent, position, deleteCount, inserted = []) => {
|
|
|
31
31
|
return removed;
|
|
32
32
|
};
|
|
33
33
|
exports.setChildNodes = setChildNodes;
|
|
34
|
+
/**
|
|
35
|
+
* 生成一个指定长度的空数组
|
|
36
|
+
* @param n 数组长度
|
|
37
|
+
* @param callback 回调函数
|
|
38
|
+
*/
|
|
39
|
+
const emptyArray = (n, callback) => new Array(n).fill(undefined).map((_, i) => callback(i));
|
|
40
|
+
exports.emptyArray = emptyArray;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikilint",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "A Node.js linter for MediaWiki markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"declaration": "grep -rl --include='*.d.ts' '@private' dist/ | xargs bash sed.sh -i -E '/^\\s+\\/\\*\\* @private/,+1d'; node ./dist/bin/declaration.js",
|
|
36
|
-
"prepublishOnly": "npm run build && rm dist/internal.js dist/[
|
|
36
|
+
"prepublishOnly": "npm run build && rm dist/internal.js dist/[bpu]*/*.d.ts",
|
|
37
37
|
"build": "bash build.sh",
|
|
38
38
|
"diff": "bash diff.sh",
|
|
39
39
|
"diff:stat": "f() { git diff --stat --ignore-all-space --color=always $1 $2 -- . ':!extensions/' ':!bin/' | grep '\\.ts'; }; f",
|