@milkdown/preset-gfm 6.5.2 → 6.5.4
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/lib/footnote/definition.d.ts +1 -1
- package/lib/footnote/definition.d.ts.map +1 -1
- package/lib/footnote/index.d.ts.map +1 -1
- package/lib/footnote/reference.d.ts +1 -1
- package/lib/footnote/reference.d.ts.map +1 -1
- package/lib/footnote/utils.d.ts.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +649 -607
- package/lib/index.es.js.map +1 -1
- package/lib/strike-through.d.ts +1 -1
- package/lib/strike-through.d.ts.map +1 -1
- package/lib/supported-keys.d.ts +1 -1
- package/lib/supported-keys.d.ts.map +1 -1
- package/lib/table/command.d.ts +2 -2
- package/lib/table/command.d.ts.map +1 -1
- package/lib/table/index.d.ts +1 -1
- package/lib/table/index.d.ts.map +1 -1
- package/lib/table/nodes/index.d.ts +1 -1
- package/lib/table/nodes/index.d.ts.map +1 -1
- package/lib/table/operator-plugin/actions.d.ts +5 -5
- package/lib/table/operator-plugin/actions.d.ts.map +1 -1
- package/lib/table/operator-plugin/calc-pos.d.ts +1 -1
- package/lib/table/operator-plugin/calc-pos.d.ts.map +1 -1
- package/lib/table/operator-plugin/constant.d.ts.map +1 -1
- package/lib/table/operator-plugin/helper.d.ts +3 -3
- package/lib/table/operator-plugin/helper.d.ts.map +1 -1
- package/lib/table/operator-plugin/index.d.ts +2 -2
- package/lib/table/operator-plugin/index.d.ts.map +1 -1
- package/lib/table/operator-plugin/style.d.ts +1 -1
- package/lib/table/operator-plugin/style.d.ts.map +1 -1
- package/lib/table/operator-plugin/widget.d.ts +2 -2
- package/lib/table/operator-plugin/widget.d.ts.map +1 -1
- package/lib/table/plugin/auto-insert-zero-space.d.ts.map +1 -1
- package/lib/table/plugin/cell-selection.d.ts +5 -3
- package/lib/table/plugin/cell-selection.d.ts.map +1 -1
- package/lib/table/plugin/column-resizing.d.ts +2 -1
- package/lib/table/plugin/column-resizing.d.ts.map +1 -1
- package/lib/table/plugin/commands.d.ts +2 -2
- package/lib/table/plugin/commands.d.ts.map +1 -1
- package/lib/table/plugin/copy-paste.d.ts +6 -5
- package/lib/table/plugin/copy-paste.d.ts.map +1 -1
- package/lib/table/plugin/fix-tables.d.ts +3 -2
- package/lib/table/plugin/fix-tables.d.ts.map +1 -1
- package/lib/table/plugin/index.d.ts.map +1 -1
- package/lib/table/plugin/schema.d.ts +1 -1
- package/lib/table/plugin/schema.d.ts.map +1 -1
- package/lib/table/plugin/table-editing.d.ts +1 -1
- package/lib/table/plugin/table-editing.d.ts.map +1 -1
- package/lib/table/plugin/table-map.d.ts +2 -2
- package/lib/table/plugin/table-map.d.ts.map +1 -1
- package/lib/table/plugin/table-view.d.ts +2 -2
- package/lib/table/plugin/table-view.d.ts.map +1 -1
- package/lib/table/plugin/types.d.ts +2 -2
- package/lib/table/plugin/types.d.ts.map +1 -1
- package/lib/table/plugin/util.d.ts +2 -2
- package/lib/table/plugin/util.d.ts.map +1 -1
- package/lib/table/utils.d.ts +5 -5
- package/lib/table/utils.d.ts.map +1 -1
- package/lib/task-list-item.d.ts +2 -2
- package/lib/task-list-item.d.ts.map +1 -1
- package/package.json +22 -17
- package/src/footnote/definition.ts +172 -166
- package/src/footnote/index.ts +2 -2
- package/src/footnote/reference.ts +166 -162
- package/src/footnote/utils.ts +2 -2
- package/src/index.ts +83 -83
- package/src/strike-through.ts +36 -36
- package/src/supported-keys.ts +9 -8
- package/src/table/command.ts +17 -16
- package/src/table/index.ts +9 -9
- package/src/table/nodes/index.ts +177 -174
- package/src/table/operator-plugin/actions.ts +103 -102
- package/src/table/operator-plugin/calc-pos.ts +31 -34
- package/src/table/operator-plugin/constant.ts +3 -3
- package/src/table/operator-plugin/helper.ts +31 -32
- package/src/table/operator-plugin/index.ts +104 -95
- package/src/table/operator-plugin/style.ts +10 -9
- package/src/table/operator-plugin/widget.ts +47 -45
- package/src/table/plugin/auto-insert-zero-space.ts +41 -41
- package/src/table/plugin/cell-selection.ts +325 -296
- package/src/table/plugin/column-resizing.ts +226 -198
- package/src/table/plugin/commands.ts +464 -421
- package/src/table/plugin/copy-paste.ts +256 -240
- package/src/table/plugin/fix-tables.ts +103 -88
- package/src/table/plugin/index.ts +3 -3
- package/src/table/plugin/schema.ts +100 -94
- package/src/table/plugin/table-editing.ts +324 -230
- package/src/table/plugin/table-map.ts +294 -229
- package/src/table/plugin/table-view.ts +66 -62
- package/src/table/plugin/types.ts +8 -8
- package/src/table/plugin/util.ts +78 -66
- package/src/table/utils.ts +141 -138
- package/src/task-list-item.ts +151 -146
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
2
|
|
|
3
|
-
import { Attrs, Node } from '@milkdown/prose/model'
|
|
3
|
+
import type { Attrs, Node } from '@milkdown/prose/model'
|
|
4
4
|
|
|
5
|
-
const cache = new WeakMap<Node, TableMap>()
|
|
6
|
-
const readFromCache = (key: Node) => cache.get(key)
|
|
5
|
+
const cache = new WeakMap<Node, TableMap>()
|
|
6
|
+
const readFromCache = (key: Node) => cache.get(key)
|
|
7
7
|
const addToCache = (key: Node, value: TableMap) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
8
|
+
cache.set(key, value)
|
|
9
|
+
return value
|
|
10
|
+
}
|
|
11
11
|
|
|
12
12
|
export class Rect {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
public tableStart?: number
|
|
14
|
+
public map?: TableMap
|
|
15
|
+
public table?: Node
|
|
16
|
+
constructor(
|
|
17
|
+
public left: number,
|
|
18
|
+
public top: number,
|
|
19
|
+
public right: number,
|
|
20
|
+
public bottom: number,
|
|
21
|
+
) {}
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
// ::- A table map describes the structore of a given table. To avoid
|
|
@@ -21,260 +26,320 @@ export class Rect {
|
|
|
21
26
|
// be able to do that, positions saved in the map are relative to the
|
|
22
27
|
// start of the table, rather than the start of the document.
|
|
23
28
|
export class TableMap {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
constructor(
|
|
30
|
+
public width: number,
|
|
31
|
+
public height: number,
|
|
32
|
+
public map: number[],
|
|
33
|
+
public problems?: Problem[],
|
|
34
|
+
) {
|
|
35
|
+
// :: number The width of the table
|
|
36
|
+
this.width = width
|
|
37
|
+
// :: number The table's height
|
|
38
|
+
this.height = height
|
|
39
|
+
// :: [number] A width * height array with the start position of
|
|
40
|
+
// the cell covering that part of the table in each slot
|
|
41
|
+
this.map = map
|
|
42
|
+
// An optional array of problems (cell overlap or non-rectangular
|
|
43
|
+
// shape) for the table, used by the table normalizer.
|
|
44
|
+
this.problems = problems
|
|
45
|
+
}
|
|
36
46
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
// Find the dimensions of the cell at the given position.
|
|
48
|
+
findCell(pos: number): Rect {
|
|
49
|
+
for (let i = 0; i < this.map.length; i++) {
|
|
50
|
+
const curPos = this.map[i]
|
|
51
|
+
if (curPos != pos)
|
|
52
|
+
continue
|
|
53
|
+
const left = i % this.width
|
|
54
|
+
const top = (i / this.width) | 0
|
|
55
|
+
let right = left + 1
|
|
56
|
+
let bottom = top + 1
|
|
57
|
+
for (let j = 1; right < this.width && this.map[i + j] == curPos; j++)
|
|
58
|
+
right++
|
|
59
|
+
for (
|
|
60
|
+
let j = 1;
|
|
61
|
+
bottom < this.height && this.map[i + this.width * j] == curPos;
|
|
62
|
+
j++
|
|
63
|
+
)
|
|
64
|
+
bottom++
|
|
65
|
+
return new Rect(left, top, right, bottom)
|
|
51
66
|
}
|
|
67
|
+
throw new RangeError(`No cell with offset ${pos} found`)
|
|
68
|
+
}
|
|
52
69
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
colCount(pos: number): number {
|
|
71
|
+
for (let i = 0; i < this.map.length; i++) {
|
|
72
|
+
if (this.map[i] == pos)
|
|
73
|
+
return i % this.width
|
|
56
74
|
}
|
|
57
75
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// at `pos`, if any.
|
|
61
|
-
nextCell(pos: number, axis: string, dir: number): number | undefined {
|
|
62
|
-
const { left, right, top, bottom } = this.findCell(pos);
|
|
63
|
-
if (axis == 'horiz') {
|
|
64
|
-
if (dir < 0 ? left == 0 : right == this.width) return undefined;
|
|
65
|
-
return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
|
|
66
|
-
} else {
|
|
67
|
-
if (dir < 0 ? top == 0 : bottom == this.height) return undefined;
|
|
68
|
-
return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
|
|
69
|
-
}
|
|
70
|
-
}
|
|
76
|
+
throw new RangeError(`No cell with offset ${pos} found`)
|
|
77
|
+
}
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
Math.max(bottomA, bottomB),
|
|
82
|
-
);
|
|
79
|
+
// :: (number, string, number) → ?number
|
|
80
|
+
// Find the next cell in the given direction, starting from the cell
|
|
81
|
+
// at `pos`, if any.
|
|
82
|
+
nextCell(pos: number, axis: string, dir: number): number | undefined {
|
|
83
|
+
const { left, right, top, bottom } = this.findCell(pos)
|
|
84
|
+
if (axis == 'horiz') {
|
|
85
|
+
if (dir < 0 ? left == 0 : right == this.width)
|
|
86
|
+
return undefined
|
|
87
|
+
return this.map[top * this.width + (dir < 0 ? left - 1 : right)]
|
|
83
88
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
cellsInRect(rect: Rect): number[] {
|
|
89
|
-
const result: number[] = [],
|
|
90
|
-
seen: Record<number, boolean> = {};
|
|
91
|
-
for (let row = rect.top; row < rect.bottom; row++) {
|
|
92
|
-
for (let col = rect.left; col < rect.right; col++) {
|
|
93
|
-
const index = row * this.width + col,
|
|
94
|
-
pos = this.map[index] as number;
|
|
95
|
-
if (seen[pos]) continue;
|
|
96
|
-
seen[pos] = true;
|
|
97
|
-
if (
|
|
98
|
-
(col != rect.left || !col || this.map[index - 1] != pos) &&
|
|
99
|
-
(row != rect.top || !row || this.map[index - this.width] != pos)
|
|
100
|
-
)
|
|
101
|
-
result.push(pos);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return result;
|
|
89
|
+
else {
|
|
90
|
+
if (dir < 0 ? top == 0 : bottom == this.height)
|
|
91
|
+
return undefined
|
|
92
|
+
return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)]
|
|
105
93
|
}
|
|
94
|
+
}
|
|
106
95
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
96
|
+
// :: (number, number) → Rect
|
|
97
|
+
// Get the rectangle spanning the two given cells.
|
|
98
|
+
rectBetween(a: number, b: number): Rect {
|
|
99
|
+
const {
|
|
100
|
+
left: leftA,
|
|
101
|
+
right: rightA,
|
|
102
|
+
top: topA,
|
|
103
|
+
bottom: bottomA,
|
|
104
|
+
} = this.findCell(a)
|
|
105
|
+
const {
|
|
106
|
+
left: leftB,
|
|
107
|
+
right: rightB,
|
|
108
|
+
top: topB,
|
|
109
|
+
bottom: bottomB,
|
|
110
|
+
} = this.findCell(b)
|
|
111
|
+
return new Rect(
|
|
112
|
+
Math.min(leftA, leftB),
|
|
113
|
+
Math.min(topA, topB),
|
|
114
|
+
Math.max(rightA, rightB),
|
|
115
|
+
Math.max(bottomA, bottomB),
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// :: (Rect) → [number]
|
|
120
|
+
// Return the position of all cells that have the top left corner in
|
|
121
|
+
// the given rectangle.
|
|
122
|
+
cellsInRect(rect: Rect): number[] {
|
|
123
|
+
const result: number[] = []
|
|
124
|
+
const seen: Record<number, boolean> = {}
|
|
125
|
+
for (let row = rect.top; row < rect.bottom; row++) {
|
|
126
|
+
for (let col = rect.left; col < rect.right; col++) {
|
|
127
|
+
const index = row * this.width + col
|
|
128
|
+
const pos = this.map[index] as number
|
|
129
|
+
if (seen[pos])
|
|
130
|
+
continue
|
|
131
|
+
seen[pos] = true
|
|
132
|
+
if (
|
|
133
|
+
(col != rect.left || !col || this.map[index - 1] != pos)
|
|
134
|
+
&& (row != rect.top || !row || this.map[index - this.width] != pos)
|
|
135
|
+
)
|
|
136
|
+
result.push(pos)
|
|
137
|
+
}
|
|
122
138
|
}
|
|
139
|
+
return result
|
|
140
|
+
}
|
|
123
141
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
142
|
+
// :: (number, number, Node) → number
|
|
143
|
+
// Return the position at which the cell at the given row and column
|
|
144
|
+
// starts, or would start, if a cell started there.
|
|
145
|
+
positionAt(row: number, col: number, table: Node): number {
|
|
146
|
+
for (let i = 0, rowStart = 0; ; i++) {
|
|
147
|
+
const rowEnd = rowStart + table.child(i).nodeSize
|
|
148
|
+
if (i == row) {
|
|
149
|
+
let index = col + row * this.width
|
|
150
|
+
const rowEndIndex = (row + 1) * this.width
|
|
151
|
+
// Skip past cells from previous rows (via rowspan)
|
|
152
|
+
while (index < rowEndIndex && (this.map[index] as number) < rowStart)
|
|
153
|
+
index++
|
|
154
|
+
return index == rowEndIndex ? rowEnd - 1 : (this.map[index] as number)
|
|
155
|
+
}
|
|
156
|
+
rowStart = rowEnd
|
|
127
157
|
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Find the table map for the given table node.
|
|
161
|
+
static get(table: Node): TableMap {
|
|
162
|
+
return readFromCache(table) || addToCache(table, computeMap(table))
|
|
163
|
+
}
|
|
128
164
|
}
|
|
129
165
|
|
|
130
166
|
export type Problem =
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
167
|
+
| {
|
|
168
|
+
type: 'missing'
|
|
169
|
+
row: number
|
|
170
|
+
n: number
|
|
171
|
+
}
|
|
172
|
+
| {
|
|
173
|
+
type: 'overlong_rowspan'
|
|
174
|
+
pos: number
|
|
175
|
+
n: number
|
|
176
|
+
}
|
|
177
|
+
| {
|
|
178
|
+
type: 'collision'
|
|
179
|
+
row: number
|
|
180
|
+
pos: number
|
|
181
|
+
n: number
|
|
182
|
+
}
|
|
183
|
+
| {
|
|
184
|
+
type: 'colwidth mismatch'
|
|
185
|
+
pos: number
|
|
186
|
+
colwidth: boolean
|
|
187
|
+
}
|
|
152
188
|
|
|
153
189
|
// Compute a table map.
|
|
154
190
|
function computeMap(table: Node) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
191
|
+
if (table.type.spec.tableRole != 'table')
|
|
192
|
+
throw new RangeError(`Not a table node: ${table.type.name}`)
|
|
193
|
+
const width = findWidth(table)
|
|
194
|
+
const height = table.childCount
|
|
195
|
+
const map: number[] = []
|
|
196
|
+
const colWidths: number[] = []
|
|
197
|
+
let mapPos = 0
|
|
198
|
+
let problems: Problem[] | undefined
|
|
199
|
+
for (let i = 0, e = width * height; i < e; i++) map[i] = 0
|
|
163
200
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
201
|
+
for (let row = 0, pos = 0; row < height; row++) {
|
|
202
|
+
const rowNode = table.child(row)
|
|
203
|
+
pos++
|
|
204
|
+
for (let i = 0; ; i++) {
|
|
205
|
+
while (mapPos < map.length && map[mapPos] != 0) mapPos++
|
|
206
|
+
if (i == rowNode.childCount)
|
|
207
|
+
break
|
|
208
|
+
const cellNode = rowNode.child(i)
|
|
209
|
+
const { colspan, rowspan, colwidth } = cellNode.attrs
|
|
210
|
+
for (let h = 0; h < rowspan; h++) {
|
|
211
|
+
if (h + row >= height) {
|
|
212
|
+
(problems || (problems = [])).push({
|
|
213
|
+
type: 'overlong_rowspan',
|
|
214
|
+
pos,
|
|
215
|
+
n: rowspan - h,
|
|
216
|
+
})
|
|
217
|
+
break
|
|
218
|
+
}
|
|
219
|
+
const start = mapPos + h * width
|
|
220
|
+
for (let w = 0; w < colspan; w++) {
|
|
221
|
+
if (map[start + w] == 0) {
|
|
222
|
+
map[start + w] = pos
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
(problems || (problems = [])).push({
|
|
226
|
+
type: 'collision',
|
|
227
|
+
row,
|
|
228
|
+
pos,
|
|
229
|
+
n: colspan - w,
|
|
230
|
+
})
|
|
231
|
+
}
|
|
232
|
+
const colW = colwidth && colwidth[w]
|
|
233
|
+
if (colW) {
|
|
234
|
+
const widthIndex = ((start + w) % width) * 2
|
|
235
|
+
const prev = colWidths[widthIndex]
|
|
236
|
+
if (
|
|
237
|
+
prev == null
|
|
238
|
+
|| (prev != colW && colWidths[widthIndex + 1] == 1)
|
|
239
|
+
) {
|
|
240
|
+
colWidths[widthIndex] = colW
|
|
241
|
+
colWidths[widthIndex + 1] = 1
|
|
203
242
|
}
|
|
204
|
-
|
|
205
|
-
|
|
243
|
+
else if (prev == colW) {
|
|
244
|
+
colWidths[widthIndex + 1]++
|
|
245
|
+
}
|
|
246
|
+
}
|
|
206
247
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
248
|
+
}
|
|
249
|
+
mapPos += colspan
|
|
250
|
+
pos += cellNode.nodeSize
|
|
251
|
+
}
|
|
252
|
+
const expectedPos = (row + 1) * width
|
|
253
|
+
let missing = 0
|
|
254
|
+
while (mapPos < expectedPos) {
|
|
255
|
+
if (map[mapPos++] == 0)
|
|
256
|
+
missing++
|
|
212
257
|
}
|
|
213
258
|
|
|
214
|
-
|
|
215
|
-
|
|
259
|
+
if (missing)
|
|
260
|
+
(problems || (problems = [])).push({ type: 'missing', row, n: missing })
|
|
261
|
+
pos++
|
|
262
|
+
}
|
|
216
263
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
// computed one.
|
|
220
|
-
for (let i = 0; !badWidths && i < colWidths.length; i += 2)
|
|
221
|
-
if (colWidths[i] != null && (colWidths[i + 1] as number) < height) badWidths = true;
|
|
222
|
-
if (badWidths) findBadColWidths(tableMap, colWidths, table);
|
|
264
|
+
const tableMap = new TableMap(width, height, map, problems)
|
|
265
|
+
let badWidths = false
|
|
223
266
|
|
|
224
|
-
|
|
267
|
+
// For columns that have defined widths, but whose widths disagree
|
|
268
|
+
// between rows, fix up the cells whose width doesn't match the
|
|
269
|
+
// computed one.
|
|
270
|
+
for (let i = 0; !badWidths && i < colWidths.length; i += 2) {
|
|
271
|
+
if (colWidths[i] != null && (colWidths[i + 1] as number) < height)
|
|
272
|
+
badWidths = true
|
|
273
|
+
}
|
|
274
|
+
if (badWidths)
|
|
275
|
+
findBadColWidths(tableMap, colWidths, table)
|
|
276
|
+
|
|
277
|
+
return tableMap
|
|
225
278
|
}
|
|
226
279
|
|
|
227
280
|
function findWidth(table: Node) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
for (let i = 0; i < rowNode.childCount; i++) {
|
|
242
|
-
const cell = rowNode.child(i);
|
|
243
|
-
rowWidth += cell.attrs['colspan'];
|
|
244
|
-
if (cell.attrs['rowspan'] > 1) hasRowSpan = true;
|
|
281
|
+
let width = -1
|
|
282
|
+
let hasRowSpan = false
|
|
283
|
+
for (let row = 0; row < table.childCount; row++) {
|
|
284
|
+
const rowNode = table.child(row)
|
|
285
|
+
let rowWidth = 0
|
|
286
|
+
if (hasRowSpan) {
|
|
287
|
+
for (let j = 0; j < row; j++) {
|
|
288
|
+
const prevRow = table.child(j)
|
|
289
|
+
for (let i = 0; i < prevRow.childCount; i++) {
|
|
290
|
+
const cell = prevRow.child(i)
|
|
291
|
+
if (j + cell.attrs.rowspan > row)
|
|
292
|
+
rowWidth += cell.attrs.colspan
|
|
245
293
|
}
|
|
246
|
-
|
|
247
|
-
else if (width != rowWidth) width = Math.max(width, rowWidth);
|
|
294
|
+
}
|
|
248
295
|
}
|
|
249
|
-
|
|
296
|
+
for (let i = 0; i < rowNode.childCount; i++) {
|
|
297
|
+
const cell = rowNode.child(i)
|
|
298
|
+
rowWidth += cell.attrs.colspan
|
|
299
|
+
if (cell.attrs.rowspan > 1)
|
|
300
|
+
hasRowSpan = true
|
|
301
|
+
}
|
|
302
|
+
if (width == -1)
|
|
303
|
+
width = rowWidth
|
|
304
|
+
else if (width != rowWidth)
|
|
305
|
+
width = Math.max(width, rowWidth)
|
|
306
|
+
}
|
|
307
|
+
return width
|
|
250
308
|
}
|
|
251
309
|
|
|
252
310
|
function findBadColWidths(map: TableMap, colWidths: number[], table: Node) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
311
|
+
if (!map.problems)
|
|
312
|
+
map.problems = []
|
|
313
|
+
for (let i = 0, seen: Record<number, boolean> = {}; i < map.map.length; i++) {
|
|
314
|
+
const pos = map.map[i] as number
|
|
315
|
+
if (seen[pos])
|
|
316
|
+
continue
|
|
317
|
+
seen[pos] = true
|
|
318
|
+
const node = table.nodeAt(pos) as Node
|
|
319
|
+
let updated = null
|
|
320
|
+
for (let j = 0; j < node.attrs.colspan; j++) {
|
|
321
|
+
const col = (i + j) % map.width
|
|
322
|
+
const colWidth = colWidths[col * 2]
|
|
323
|
+
if (
|
|
324
|
+
colWidth != null
|
|
325
|
+
&& (!node.attrs.colwidth || node.attrs.colwidth[j] != colWidth)
|
|
326
|
+
)
|
|
327
|
+
(updated || (updated = freshColWidth(node.attrs)))[j] = colWidth
|
|
328
|
+
}
|
|
329
|
+
if (updated) {
|
|
330
|
+
map.problems.unshift({
|
|
331
|
+
type: 'colwidth mismatch',
|
|
332
|
+
pos,
|
|
333
|
+
colwidth: updated,
|
|
334
|
+
})
|
|
272
335
|
}
|
|
336
|
+
}
|
|
273
337
|
}
|
|
274
338
|
|
|
275
339
|
function freshColWidth(attrs: Attrs) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
340
|
+
if (attrs.colwidth)
|
|
341
|
+
return attrs.colwidth.slice()
|
|
342
|
+
const result = []
|
|
343
|
+
for (let i = 0; i < attrs.colspan; i++) result.push(0)
|
|
344
|
+
return result
|
|
280
345
|
}
|