@k2b/ui 0.34.0 → 0.35.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/browser/actions/Dropdown.js +1 -0
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/content/MatchText.js +61 -0
- package/dist/browser/content/MatchText.js.map +1 -0
- package/dist/browser/content/index.js +1 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +1358 -0
- package/dist/browser/text-editor/TextEditor.js.map +1 -0
- package/dist/browser/text-editor/clipboard-html.js +152 -0
- package/dist/browser/text-editor/clipboard-html.js.map +1 -0
- package/dist/browser/text-editor/clipboard-loading.js +68 -0
- package/dist/browser/text-editor/clipboard-loading.js.map +1 -0
- package/dist/browser/text-editor/clipboard.js +51 -0
- package/dist/browser/text-editor/clipboard.js.map +1 -0
- package/dist/browser/text-editor/engine.js +125 -0
- package/dist/browser/text-editor/engine.js.map +1 -0
- package/dist/browser/text-editor/format.js +218 -0
- package/dist/browser/text-editor/format.js.map +1 -0
- package/dist/browser/text-editor/formatted.js +164 -0
- package/dist/browser/text-editor/formatted.js.map +1 -0
- package/dist/browser/text-editor/language.js +19 -0
- package/dist/browser/text-editor/language.js.map +1 -0
- package/dist/browser/text-editor/markdown-table.js +563 -0
- package/dist/browser/text-editor/markdown-table.js.map +1 -0
- package/dist/browser/text-editor/messages.js +233 -0
- package/dist/browser/text-editor/messages.js.map +1 -0
- package/dist/browser/text-editor/paste.js +115 -0
- package/dist/browser/text-editor/paste.js.map +1 -0
- package/dist/browser/text-editor/table.js +1760 -0
- package/dist/browser/text-editor/table.js.map +1 -0
- package/dist/browser/text-editor.js +5 -0
- package/dist/browser/text-editor.js.map +1 -0
- package/dist/ssr/actions/Dropdown.js +1 -0
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/content/MatchText.js +56 -0
- package/dist/ssr/content/MatchText.js.map +1 -0
- package/dist/ssr/content/index.js +1 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +1155 -0
- package/dist/ssr/text-editor/TextEditor.js.map +1 -0
- package/dist/ssr/text-editor/clipboard-html.js +152 -0
- package/dist/ssr/text-editor/clipboard-html.js.map +1 -0
- package/dist/ssr/text-editor/clipboard-loading.js +68 -0
- package/dist/ssr/text-editor/clipboard-loading.js.map +1 -0
- package/dist/ssr/text-editor/clipboard.js +51 -0
- package/dist/ssr/text-editor/clipboard.js.map +1 -0
- package/dist/ssr/text-editor/engine.js +125 -0
- package/dist/ssr/text-editor/engine.js.map +1 -0
- package/dist/ssr/text-editor/format.js +218 -0
- package/dist/ssr/text-editor/format.js.map +1 -0
- package/dist/ssr/text-editor/formatted.js +164 -0
- package/dist/ssr/text-editor/formatted.js.map +1 -0
- package/dist/ssr/text-editor/language.js +19 -0
- package/dist/ssr/text-editor/language.js.map +1 -0
- package/dist/ssr/text-editor/markdown-table.js +563 -0
- package/dist/ssr/text-editor/markdown-table.js.map +1 -0
- package/dist/ssr/text-editor/messages.js +233 -0
- package/dist/ssr/text-editor/messages.js.map +1 -0
- package/dist/ssr/text-editor/paste.js +115 -0
- package/dist/ssr/text-editor/paste.js.map +1 -0
- package/dist/ssr/text-editor/table.js +1760 -0
- package/dist/ssr/text-editor/table.js.map +1 -0
- package/dist/ssr/text-editor.js +5 -0
- package/dist/ssr/text-editor.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/types/actions/Dropdown.d.ts +2 -0
- package/dist/types/content/MatchText.d.ts +21 -0
- package/dist/types/content/index.d.ts +1 -0
- package/dist/types/text-editor/TextEditor.d.ts +69 -0
- package/dist/types/text-editor/clipboard-html.d.ts +9 -0
- package/dist/types/text-editor/clipboard-loading.d.ts +8 -0
- package/dist/types/text-editor/clipboard.d.ts +20 -0
- package/dist/types/text-editor/engine.d.ts +34 -0
- package/dist/types/text-editor/format.d.ts +34 -0
- package/dist/types/text-editor/formatted.d.ts +1 -0
- package/dist/types/text-editor/language.d.ts +8 -0
- package/dist/types/text-editor/markdown-table.d.ts +105 -0
- package/dist/types/text-editor/messages.d.ts +113 -0
- package/dist/types/text-editor/paste.d.ts +6 -0
- package/dist/types/text-editor/table.d.ts +81 -0
- package/dist/types/text-editor.d.ts +4 -0
- package/package.json +23 -3
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure GFM table edits in original Markdown coordinates. Markdown is the only
|
|
3
|
+
* model; callers reparse after applying a transaction. No repair of damaged
|
|
4
|
+
* tables or prose is attempted. Extra and missing body cells remain inspectable.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { GFM, parser } from "@lezer/markdown";
|
|
8
|
+
|
|
9
|
+
/** Trimmed raw content, with absolute UTF-16 source offsets. */
|
|
10
|
+
|
|
11
|
+
const gfm = parser.configure(GFM);
|
|
12
|
+
const index = value => Number.isSafeInteger(value) && value >= 0;
|
|
13
|
+
const normalizeBreaks = value => value.replace(/\r\n|[\r\n\u2028\u2029]/g, " ");
|
|
14
|
+
const splitsCharacter = (value, at) => {
|
|
15
|
+
const before = value.charCodeAt(at - 1),
|
|
16
|
+
after = value.charCodeAt(at);
|
|
17
|
+
return before >= 0xd800 && before <= 0xdbff && after >= 0xdc00 && after <= 0xdfff;
|
|
18
|
+
};
|
|
19
|
+
const parseLine = (text, from, lineBreak) => {
|
|
20
|
+
const pipes = [];
|
|
21
|
+
for (let i = 0; i < text.length; i++) {
|
|
22
|
+
if (text[i] === "\\") i++;else if (text[i] === "|") pipes.push(from + i);
|
|
23
|
+
}
|
|
24
|
+
const leadingPipe = pipes[0] === from + text.search(/[^ \t]/);
|
|
25
|
+
const trailingPipe = pipes.length > (leadingPipe ? 1 : 0) && pipes.at(-1) === from + text.trimEnd().length - 1;
|
|
26
|
+
const cells = [];
|
|
27
|
+
let start = leadingPipe ? pipes[0] + 1 : from;
|
|
28
|
+
const addCell = end => {
|
|
29
|
+
const segment = text.slice(start - from, end - from);
|
|
30
|
+
const trimmed = segment.trim();
|
|
31
|
+
const at = start + (trimmed ? segment.length - segment.trimStart().length : Math.min(1, segment.length));
|
|
32
|
+
cells.push({
|
|
33
|
+
from: at,
|
|
34
|
+
to: at + trimmed.length,
|
|
35
|
+
text: trimmed
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
for (const pipe of leadingPipe ? pipes.slice(1) : pipes) {
|
|
39
|
+
addCell(pipe);
|
|
40
|
+
start = pipe + 1;
|
|
41
|
+
}
|
|
42
|
+
if (!trailingPipe) addCell(from + text.length);
|
|
43
|
+
return {
|
|
44
|
+
from,
|
|
45
|
+
to: from + text.length,
|
|
46
|
+
pipes,
|
|
47
|
+
leadingPipe,
|
|
48
|
+
trailingPipe,
|
|
49
|
+
cells,
|
|
50
|
+
lineBreak
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const alignOf = text => text.startsWith(":") ? text.endsWith(":") ? "center" : "left" : text.endsWith(":") ? "right" : null;
|
|
54
|
+
|
|
55
|
+
/** Only top-level Lezer GFM tables: never code, block quotes, or list items. */
|
|
56
|
+
export const findTables = doc => {
|
|
57
|
+
const lines = [];
|
|
58
|
+
let from = 0,
|
|
59
|
+
normalizedFrom = 0;
|
|
60
|
+
for (const match of doc.matchAll(/([^\r\n]*)(\r\n|\r|\n|$)/g)) {
|
|
61
|
+
if (match[0] === "" && from === doc.length) break;
|
|
62
|
+
const text = match[1],
|
|
63
|
+
lineBreak = match[2];
|
|
64
|
+
lines.push({
|
|
65
|
+
text,
|
|
66
|
+
from,
|
|
67
|
+
normalizedFrom,
|
|
68
|
+
lineBreak
|
|
69
|
+
});
|
|
70
|
+
from += match[0].length;
|
|
71
|
+
normalizedFrom += text.length + (lineBreak ? 1 : 0);
|
|
72
|
+
}
|
|
73
|
+
if (!lines.length) return [];
|
|
74
|
+
const lineAt = pos => {
|
|
75
|
+
let low = 0,
|
|
76
|
+
high = lines.length;
|
|
77
|
+
while (low + 1 < high) {
|
|
78
|
+
const mid = low + high >>> 1;
|
|
79
|
+
if (lines[mid].normalizedFrom <= pos) low = mid;else high = mid;
|
|
80
|
+
}
|
|
81
|
+
return low;
|
|
82
|
+
};
|
|
83
|
+
const tree = gfm.parse(lines.map(line => line.text + (line.lineBreak ? "\n" : "")).join(""));
|
|
84
|
+
const tables = [];
|
|
85
|
+
for (let node = tree.topNode.firstChild; node; node = node.nextSibling) {
|
|
86
|
+
if (node.name !== "Table") continue;
|
|
87
|
+
const rows = lines.slice(lineAt(node.from), lineAt(node.to) + 1).map(line => parseLine(line.text, line.from, line.lineBreak));
|
|
88
|
+
const header = rows[0],
|
|
89
|
+
separator = rows[1];
|
|
90
|
+
if (!separator) continue;
|
|
91
|
+
tables.push({
|
|
92
|
+
from: header.from,
|
|
93
|
+
to: rows.at(-1).to,
|
|
94
|
+
lines: rows,
|
|
95
|
+
align: separator.cells.map(cell => alignOf(cell.text)),
|
|
96
|
+
columns: header.cells.length
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return tables;
|
|
100
|
+
};
|
|
101
|
+
export const tableAt = (doc, pos) => findTables(doc).find(table => pos >= table.from && pos <= table.to) ?? null;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Problems that must stay visible before formatted output is sent. A damaged
|
|
105
|
+
* separator makes GFM fall back to a paragraph: two adjacent pipe-framed rows
|
|
106
|
+
* there still need review. This only inspects top-level paragraph nodes, never
|
|
107
|
+
* code, quotations or lists, and does not repair or rewrite any text.
|
|
108
|
+
*/
|
|
109
|
+
export const inspectTableStructure = doc => {
|
|
110
|
+
// Both GFM tables and the damaged pipe-framed rows below require a pipe.
|
|
111
|
+
// Avoid parsing large prose twice on every editor update and mail preview.
|
|
112
|
+
if (!doc.includes("|")) return {
|
|
113
|
+
extraCells: false,
|
|
114
|
+
missingSeparator: false
|
|
115
|
+
};
|
|
116
|
+
const extraCells = findTables(doc).some(table => table.lines.some(line => line.cells.length > table.columns));
|
|
117
|
+
const normalized = doc.replace(/\r\n?/g, "\n");
|
|
118
|
+
const tree = gfm.parse(normalized);
|
|
119
|
+
let missingSeparator = false;
|
|
120
|
+
for (let node = tree.topNode.firstChild; node && !missingSeparator; node = node.nextSibling) {
|
|
121
|
+
if (node.name !== "Paragraph") continue;
|
|
122
|
+
let consecutive = 0;
|
|
123
|
+
for (const text of normalized.slice(node.from, node.to).split("\n")) {
|
|
124
|
+
const line = parseLine(text, 0, "");
|
|
125
|
+
consecutive = line.leadingPipe && line.trailingPipe ? consecutive + 1 : 0;
|
|
126
|
+
if (consecutive >= 2) {
|
|
127
|
+
missingSeparator = true;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
extraCells,
|
|
134
|
+
missingSeparator
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
export const gridLine = (table, row) => index(row) ? table.lines[row === 0 ? 0 : row + 1] : undefined;
|
|
138
|
+
export const rowCount = table => table.lines.length - 1;
|
|
139
|
+
|
|
140
|
+
/** Literal displayed text → safe raw content. Call once, never on existing raw Markdown. */
|
|
141
|
+
export const escapeCell = value => normalizeBreaks(value).replace(/[\\|]/g, "\\$&");
|
|
142
|
+
|
|
143
|
+
/** Display text and a raw offset for every displayed UTF-16 boundary. */
|
|
144
|
+
export const cellDisplayMap = raw => {
|
|
145
|
+
let text = "";
|
|
146
|
+
const offsets = [0];
|
|
147
|
+
for (let i = 0; i < raw.length;) {
|
|
148
|
+
const escaped = raw[i] === "\\" && (raw[i + 1] === "\\" || raw[i + 1] === "|");
|
|
149
|
+
text += raw[i + (escaped ? 1 : 0)];
|
|
150
|
+
i += escaped ? 2 : 1;
|
|
151
|
+
offsets.push(i);
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
text,
|
|
155
|
+
offsets
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
/** Decode only table pipes and backslashes; leave inline Markdown source editable. */
|
|
159
|
+
export const displayCell = raw => cellDisplayMap(raw).text;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* One minimal contiguous source edit from literal displayed input. Unchanged
|
|
163
|
+
* escapes keep their exact bytes, including noncanonical lone backslashes.
|
|
164
|
+
* `from` is the old cell's absolute start; input must NOT be pre-escaped.
|
|
165
|
+
*/
|
|
166
|
+
export const cellChanges = (raw, nextDisplayed, from) => {
|
|
167
|
+
const {
|
|
168
|
+
text,
|
|
169
|
+
offsets
|
|
170
|
+
} = cellDisplayMap(raw);
|
|
171
|
+
const next = normalizeBreaks(nextDisplayed);
|
|
172
|
+
if (text === next) return [];
|
|
173
|
+
let prefix = 0,
|
|
174
|
+
suffix = 0;
|
|
175
|
+
while (prefix < text.length && prefix < next.length && text[prefix] === next[prefix]) prefix++;
|
|
176
|
+
if (splitsCharacter(text, prefix) || splitsCharacter(next, prefix)) prefix--;
|
|
177
|
+
while (suffix < text.length - prefix && suffix < next.length - prefix && text[text.length - suffix - 1] === next[next.length - suffix - 1]) suffix++;
|
|
178
|
+
if (splitsCharacter(text, text.length - suffix) || splitsCharacter(next, next.length - suffix)) suffix--;
|
|
179
|
+
const end = offsets[text.length - suffix];
|
|
180
|
+
let start = offsets[prefix];
|
|
181
|
+
let insert = escapeCell(next.slice(prefix, next.length - suffix));
|
|
182
|
+
// A lone slash can consume the inserted pipe escape without changing the
|
|
183
|
+
// displayed text, yet expose a structural pipe. Check source parity too.
|
|
184
|
+
const candidate = raw.slice(0, start) + insert + raw.slice(end);
|
|
185
|
+
let exposedPipe = false,
|
|
186
|
+
escaped = false;
|
|
187
|
+
for (const ch of candidate) {
|
|
188
|
+
if (ch === "|" && !escaped) exposedPipe = true;
|
|
189
|
+
escaped = ch === "\\" && !escaped;
|
|
190
|
+
}
|
|
191
|
+
// Newly exposing a final lone slash could escape an adjacent closing pipe.
|
|
192
|
+
// Existing trailing escapes in an untouched suffix retain their bytes.
|
|
193
|
+
if ((displayCell(candidate) !== next || exposedPipe || escaped && suffix === 0) && prefix > 0) {
|
|
194
|
+
prefix--;
|
|
195
|
+
start = offsets[prefix];
|
|
196
|
+
insert = escapeCell(next.slice(prefix, next.length - suffix));
|
|
197
|
+
}
|
|
198
|
+
let to = end;
|
|
199
|
+
while (start < to && insert && raw[start] === insert[0] && !splitsCharacter(raw, start + 1) && !splitsCharacter(insert, 1)) {
|
|
200
|
+
start++;
|
|
201
|
+
insert = insert.slice(1);
|
|
202
|
+
}
|
|
203
|
+
while (start < to && insert && raw[to - 1] === insert.at(-1) && !splitsCharacter(raw, to - 1) && !splitsCharacter(insert, insert.length - 1)) {
|
|
204
|
+
to--;
|
|
205
|
+
insert = insert.slice(0, -1);
|
|
206
|
+
}
|
|
207
|
+
return [{
|
|
208
|
+
from: from + start,
|
|
209
|
+
to: from + to,
|
|
210
|
+
insert
|
|
211
|
+
}];
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Map an edit based on an old cell through intervening document changes.
|
|
216
|
+
* Deletes only surviving old-source spans (iterGaps), preserving remote inserts
|
|
217
|
+
* and excluding replaced/deleted identities. Returns current-document offsets.
|
|
218
|
+
* The caller must first verify that the mapped range is still the same cell;
|
|
219
|
+
* concurrent structural/escape edits require resyncing its displayed snapshot.
|
|
220
|
+
*/
|
|
221
|
+
export const mappedCellChanges = (raw, nextDisplayed, from, changes) => {
|
|
222
|
+
const edit = cellChanges(raw, nextDisplayed, from)[0];
|
|
223
|
+
if (!edit) return [];
|
|
224
|
+
const result = [];
|
|
225
|
+
changes.iterGaps((oldFrom, newFrom, length) => {
|
|
226
|
+
const a = Math.max(edit.from, oldFrom),
|
|
227
|
+
b = Math.min(edit.to, oldFrom + length);
|
|
228
|
+
if (a < b) result.push({
|
|
229
|
+
from: newFrom + a - oldFrom,
|
|
230
|
+
to: newFrom + b - oldFrom,
|
|
231
|
+
insert: ""
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
if (edit.insert) {
|
|
235
|
+
const at = changes.mapPos(edit.from, 1);
|
|
236
|
+
const deletion = result.find(change => change.from === at);
|
|
237
|
+
if (deletion) deletion.insert = edit.insert;else result.push({
|
|
238
|
+
from: at,
|
|
239
|
+
to: at,
|
|
240
|
+
insert: edit.insert
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
return result.sort((a, b) => a.from - b.from || a.to - b.to);
|
|
244
|
+
};
|
|
245
|
+
const appendCells = (line, count, separator = false) => count > 0 ? [{
|
|
246
|
+
from: line.to,
|
|
247
|
+
to: line.to,
|
|
248
|
+
insert: (line.trailingPipe ? "" : " |") + (separator ? " --- |" : " |").repeat(count)
|
|
249
|
+
}] : [];
|
|
250
|
+
|
|
251
|
+
/** Spike-compatible escaped RAW input; fills ragged cells within the existing grid width. */
|
|
252
|
+
export const setCellText = (table, row, col, next) => {
|
|
253
|
+
const line = gridLine(table, row);
|
|
254
|
+
if (!line || !index(col) || col >= width(table)) return [];
|
|
255
|
+
const cell = line.cells[col];
|
|
256
|
+
if (cell) return cellChanges(cell.text, displayCell(next), cell.from);
|
|
257
|
+
return [{
|
|
258
|
+
from: line.to,
|
|
259
|
+
to: line.to,
|
|
260
|
+
insert: (line.trailingPipe ? "" : " |") + " |".repeat(col - line.cells.length) + ` ${escapeCell(displayCell(next))} |`
|
|
261
|
+
}];
|
|
262
|
+
};
|
|
263
|
+
export const insertRow = (table, after) => {
|
|
264
|
+
const line = after === 0 ? table.lines[1] : gridLine(table, after);
|
|
265
|
+
if (!line) return [];
|
|
266
|
+
const newline = table.lines[0]?.lineBreak || "\n";
|
|
267
|
+
return [{
|
|
268
|
+
from: line.to,
|
|
269
|
+
to: line.to,
|
|
270
|
+
insert: `${newline}|${" |".repeat(table.columns)}`
|
|
271
|
+
}];
|
|
272
|
+
};
|
|
273
|
+
export const deleteRow = (table, row) => {
|
|
274
|
+
const line = gridLine(table, row),
|
|
275
|
+
previous = table.lines[row];
|
|
276
|
+
return row > 0 && line && previous ? [{
|
|
277
|
+
from: previous.to,
|
|
278
|
+
to: line.to,
|
|
279
|
+
insert: ""
|
|
280
|
+
}] : [];
|
|
281
|
+
};
|
|
282
|
+
/** Move a body row, retaining every untouched row's original source and identities. */
|
|
283
|
+
export const moveRow = (source, table, row, to) => {
|
|
284
|
+
if (!index(row) || !index(to) || row === 0 || to === 0 || row === to) return [];
|
|
285
|
+
const line = gridLine(table, row),
|
|
286
|
+
target = gridLine(table, to),
|
|
287
|
+
previous = table.lines[row];
|
|
288
|
+
if (!line || !target || !previous) return [];
|
|
289
|
+
const insertAt = row < to ? target.to : table.lines[to].to;
|
|
290
|
+
return [{
|
|
291
|
+
from: previous.to,
|
|
292
|
+
to: line.to,
|
|
293
|
+
insert: ""
|
|
294
|
+
}, {
|
|
295
|
+
from: insertAt,
|
|
296
|
+
to: insertAt,
|
|
297
|
+
insert: source.slice(previous.to, line.to)
|
|
298
|
+
}].sort((a, b) => a.from - b.from);
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
/** Swap adjacent columns, including their alignment, without rewriting other cells. */
|
|
302
|
+
export const moveColumn = (table, column, to) => {
|
|
303
|
+
if (!index(column) || !index(to) || Math.abs(column - to) !== 1 || column >= table.columns || to >= table.columns) return [];
|
|
304
|
+
// Complete ragged rows first, so a move cannot discard or invent a target.
|
|
305
|
+
if (table.lines.some(line => line.cells.length !== table.columns)) return [];
|
|
306
|
+
return table.lines.flatMap(line => {
|
|
307
|
+
const a = line.cells[column],
|
|
308
|
+
b = line.cells[to];
|
|
309
|
+
return a.text === b.text ? [] : [{
|
|
310
|
+
from: a.from,
|
|
311
|
+
to: a.to,
|
|
312
|
+
insert: b.text
|
|
313
|
+
}, {
|
|
314
|
+
from: b.from,
|
|
315
|
+
to: b.to,
|
|
316
|
+
insert: a.text
|
|
317
|
+
}];
|
|
318
|
+
}).sort((a, b) => a.from - b.from);
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
/** A hidden header is an empty GFM header; its former values become the first body row. */
|
|
322
|
+
export const toggleHeader = (source, table) => {
|
|
323
|
+
const header = table.lines[0],
|
|
324
|
+
separator = table.lines[1];
|
|
325
|
+
const newline = header.lineBreak || "\n";
|
|
326
|
+
const marker = source.slice(separator.from, separator.to);
|
|
327
|
+
if (header.cells.some(cell => cell.text)) return [{
|
|
328
|
+
from: table.from,
|
|
329
|
+
to: table.from,
|
|
330
|
+
insert: `|${" |".repeat(table.columns)}${newline}${marker}${newline}`
|
|
331
|
+
}, {
|
|
332
|
+
from: header.to,
|
|
333
|
+
to: separator.to,
|
|
334
|
+
insert: ""
|
|
335
|
+
}];
|
|
336
|
+
const first = table.lines[2];
|
|
337
|
+
if (!first || !first.cells.some(cell => cell.text) || first.cells.length > table.columns) return [];
|
|
338
|
+
const padding = appendCells(first, table.columns - first.cells.length)[0]?.insert ?? "";
|
|
339
|
+
return [{
|
|
340
|
+
from: table.from,
|
|
341
|
+
to: first.from,
|
|
342
|
+
insert: ""
|
|
343
|
+
}, {
|
|
344
|
+
from: first.to,
|
|
345
|
+
to: first.to,
|
|
346
|
+
insert: `${padding}${newline}${marker}`
|
|
347
|
+
}];
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
/** Delete only the selected table; surrounding prose remains byte-for-byte intact. */
|
|
351
|
+
export const deleteTable = table => [{
|
|
352
|
+
from: table.from,
|
|
353
|
+
to: table.to,
|
|
354
|
+
insert: ""
|
|
355
|
+
}];
|
|
356
|
+
const width = table => table.lines.reduce((max, line) => Math.max(max, line.cells.length), table.columns);
|
|
357
|
+
|
|
358
|
+
/** Insert before `at`, including at the widest row's end; pad ragged rows without dropping cells. */
|
|
359
|
+
export const insertColumn = (table, at) => {
|
|
360
|
+
if (!index(at) || at > width(table)) return [];
|
|
361
|
+
return table.lines.flatMap((line, i) => {
|
|
362
|
+
if (at >= line.cells.length) return appendCells(line, at - line.cells.length + 1, i === 1);
|
|
363
|
+
const pos = line.leadingPipe ? line.pipes[at] + 1 : at === 0 ? line.from : line.pipes[at - 1] + 1;
|
|
364
|
+
return [{
|
|
365
|
+
from: pos,
|
|
366
|
+
to: pos,
|
|
367
|
+
insert: (at === 0 && !line.leadingPipe ? "|" : "") + (i === 1 ? " --- |" : " |")
|
|
368
|
+
}];
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
/** Complete a ragged grid without changing or removing any existing cell. */
|
|
372
|
+
export const completeColumns = table => {
|
|
373
|
+
const columns = width(table);
|
|
374
|
+
return table.lines.flatMap((line, i) => appendCells(line, columns - line.cells.length, i === 1));
|
|
375
|
+
};
|
|
376
|
+
export const deleteColumn = (table, col) => {
|
|
377
|
+
if (!index(col) || col >= width(table) || table.columns <= 1 && col < table.columns) return [];
|
|
378
|
+
return table.lines.flatMap((line, row) => {
|
|
379
|
+
if (col >= line.cells.length) return [];
|
|
380
|
+
const before = line.leadingPipe ? line.pipes[col] : col === 0 ? line.from - 1 : line.pipes[col - 1];
|
|
381
|
+
const after = line.leadingPipe ? line.pipes[col + 1] : line.pipes[col];
|
|
382
|
+
// A blank physical line would end the table and orphan later body rows.
|
|
383
|
+
// Preserve a delimiter as the explicit empty row, or insert one if absent.
|
|
384
|
+
if (line.cells.length === 1 && !line.leadingPipe) {
|
|
385
|
+
return [{
|
|
386
|
+
from: line.from,
|
|
387
|
+
to: after ?? line.to,
|
|
388
|
+
insert: after === undefined ? "|" : ""
|
|
389
|
+
}];
|
|
390
|
+
}
|
|
391
|
+
// Keep the last delimiter when reducing to one cell. Lezer additionally
|
|
392
|
+
// needs a trailing delimiter on a one-cell separator (a leading one alone
|
|
393
|
+
// is not recognized), so add it only on that marker line when necessary.
|
|
394
|
+
if (line.cells.length === 2 && !line.trailingPipe) {
|
|
395
|
+
if (col === 1) return [{
|
|
396
|
+
from: before + 1,
|
|
397
|
+
to: line.to,
|
|
398
|
+
insert: ""
|
|
399
|
+
}];
|
|
400
|
+
if (!line.leadingPipe) return [{
|
|
401
|
+
from: line.from,
|
|
402
|
+
to: after,
|
|
403
|
+
insert: ""
|
|
404
|
+
}, ...(row === 1 ? [{
|
|
405
|
+
from: line.to,
|
|
406
|
+
to: line.to,
|
|
407
|
+
insert: "|"
|
|
408
|
+
}] : [])];
|
|
409
|
+
return [{
|
|
410
|
+
from: before + 1,
|
|
411
|
+
to: after + 1,
|
|
412
|
+
insert: ""
|
|
413
|
+
}, ...(row === 1 ? [{
|
|
414
|
+
from: line.to,
|
|
415
|
+
to: line.to,
|
|
416
|
+
insert: "|"
|
|
417
|
+
}] : [])];
|
|
418
|
+
}
|
|
419
|
+
// With omitted outer pipes, remove the preceding delimiter for the last cell.
|
|
420
|
+
if (after === undefined && col > 0) return [{
|
|
421
|
+
from: before,
|
|
422
|
+
to: line.to,
|
|
423
|
+
insert: ""
|
|
424
|
+
}];
|
|
425
|
+
if (after === undefined) return [{
|
|
426
|
+
from: before + 1,
|
|
427
|
+
to: line.to,
|
|
428
|
+
insert: ""
|
|
429
|
+
}];
|
|
430
|
+
return [{
|
|
431
|
+
from: before + 1,
|
|
432
|
+
to: after + 1,
|
|
433
|
+
insert: ""
|
|
434
|
+
}];
|
|
435
|
+
});
|
|
436
|
+
};
|
|
437
|
+
export const setAlign = (table, col, align) => {
|
|
438
|
+
if (!index(col)) return [];
|
|
439
|
+
const cell = table.lines[1]?.cells[col];
|
|
440
|
+
if (!cell) return [];
|
|
441
|
+
const result = [];
|
|
442
|
+
const left = align === "left" || align === "center",
|
|
443
|
+
right = align === "right" || align === "center";
|
|
444
|
+
const hasLeft = cell.text.startsWith(":"),
|
|
445
|
+
hasRight = cell.text.endsWith(":");
|
|
446
|
+
if (left !== hasLeft) result.push({
|
|
447
|
+
from: cell.from,
|
|
448
|
+
to: cell.from + Number(hasLeft),
|
|
449
|
+
insert: left ? ":" : ""
|
|
450
|
+
});
|
|
451
|
+
if (right !== hasRight) result.push({
|
|
452
|
+
from: cell.to - Number(hasRight),
|
|
453
|
+
to: cell.to,
|
|
454
|
+
insert: right ? ":" : ""
|
|
455
|
+
});
|
|
456
|
+
return result;
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
/** First grid row is the header; pad short rows, preserve every extra cell. */
|
|
460
|
+
export const tableFromGrid = grid => {
|
|
461
|
+
const columns = grid.reduce((max, row) => Math.max(max, row.length), 1);
|
|
462
|
+
const rows = (grid.length ? grid : [[]]).map(row => `| ${Array.from({
|
|
463
|
+
length: columns
|
|
464
|
+
}, (_, col) => escapeCell(row[col] ?? "")).join(" | ")} |`);
|
|
465
|
+
rows.splice(1, 0, `|${" --- |".repeat(columns)}`);
|
|
466
|
+
return rows.join("\n");
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
/** Quoted TSV (including doubled quotes and embedded newlines). Invalid quotes stay raw. */
|
|
470
|
+
export const parseTsv = text => {
|
|
471
|
+
if (!text.includes("\t")) return null;
|
|
472
|
+
const rows = [];
|
|
473
|
+
let row = [],
|
|
474
|
+
cell = "",
|
|
475
|
+
quoted = false,
|
|
476
|
+
closed = false;
|
|
477
|
+
for (let i = 0; i < text.length; i++) {
|
|
478
|
+
const ch = text[i];
|
|
479
|
+
if (quoted) {
|
|
480
|
+
if (ch === '"' && text[i + 1] === '"') {
|
|
481
|
+
cell += '"';
|
|
482
|
+
i++;
|
|
483
|
+
} else if (ch === '"') {
|
|
484
|
+
quoted = false;
|
|
485
|
+
closed = true;
|
|
486
|
+
} else cell += ch;
|
|
487
|
+
} else if (ch === '"' && cell === "" && !closed) quoted = true;else if (ch === "\t") {
|
|
488
|
+
row.push(cell);
|
|
489
|
+
cell = "";
|
|
490
|
+
closed = false;
|
|
491
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
492
|
+
if (ch === "\r" && text[i + 1] === "\n") i++;
|
|
493
|
+
row.push(cell);
|
|
494
|
+
rows.push(row);
|
|
495
|
+
row = [];
|
|
496
|
+
cell = "";
|
|
497
|
+
closed = false;
|
|
498
|
+
} else if (closed) return null;else cell += ch;
|
|
499
|
+
}
|
|
500
|
+
if (quoted) return null;
|
|
501
|
+
if (cell !== "" || row.length || closed) {
|
|
502
|
+
row.push(cell);
|
|
503
|
+
rows.push(row);
|
|
504
|
+
}
|
|
505
|
+
return rows.length ? rows : null;
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
/** Apply sorted or unsorted, non-overlapping edits in old-document coordinates. */
|
|
509
|
+
export const applyChanges = (doc, changes) => {
|
|
510
|
+
const sorted = [...changes].sort((a, b) => a.from - b.from || a.to - b.to);
|
|
511
|
+
let result = "",
|
|
512
|
+
pos = 0;
|
|
513
|
+
for (const change of sorted) {
|
|
514
|
+
if (!index(change.from) || !index(change.to) || change.from < pos || change.to < change.from || change.to > doc.length) throw new RangeError("Invalid or overlapping table changes");
|
|
515
|
+
result += doc.slice(pos, change.from) + change.insert;
|
|
516
|
+
pos = change.to;
|
|
517
|
+
}
|
|
518
|
+
return result + doc.slice(pos);
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Settle recognized ragged GFM tables without deleting or rewriting source.
|
|
523
|
+
* Extra cells become named-grid positions with empty headers, never discarded.
|
|
524
|
+
* Unrecognizable tables remain raw text for the application's check state;
|
|
525
|
+
* code, quotes and lists are not repair candidates.
|
|
526
|
+
*/
|
|
527
|
+
export const repairTables = (doc, maxLength) => {
|
|
528
|
+
if (!Number.isSafeInteger(maxLength) || maxLength < 0) throw new RangeError("Invalid repair text budget");
|
|
529
|
+
const candidates = findTables(doc).map(table => ({
|
|
530
|
+
table,
|
|
531
|
+
columns: width(table)
|
|
532
|
+
})).filter(({
|
|
533
|
+
table,
|
|
534
|
+
columns
|
|
535
|
+
}) => table.lines.some(line => line.cells.length !== columns));
|
|
536
|
+
let length = doc.length;
|
|
537
|
+
// A wide row followed by many short rows can require quadratic padding.
|
|
538
|
+
// Count first; leave the damage visible if the document budget cannot fit it.
|
|
539
|
+
for (const {
|
|
540
|
+
table,
|
|
541
|
+
columns
|
|
542
|
+
} of candidates) {
|
|
543
|
+
for (const [row, line] of table.lines.entries()) {
|
|
544
|
+
const count = columns - line.cells.length;
|
|
545
|
+
length += count * (row === 1 ? 6 : 4) + (line.trailingPipe ? 0 : 2);
|
|
546
|
+
if (length > maxLength) return [];
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return candidates.flatMap(({
|
|
550
|
+
table,
|
|
551
|
+
columns
|
|
552
|
+
}) => table.lines.flatMap((line, row) => {
|
|
553
|
+
const padding = appendCells(line, columns - line.cells.length, row === 1);
|
|
554
|
+
if (padding.length) return padding;
|
|
555
|
+
// Surviving peer text after append undo becomes an explicit extra cell.
|
|
556
|
+
return line.trailingPipe ? [] : [{
|
|
557
|
+
from: line.to,
|
|
558
|
+
to: line.to,
|
|
559
|
+
insert: " |"
|
|
560
|
+
}];
|
|
561
|
+
}));
|
|
562
|
+
};
|
|
563
|
+
//# sourceMappingURL=markdown-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["text-editor/markdown-table.ts"],"sourcesContent":["/**\n * Pure GFM table edits in original Markdown coordinates. Markdown is the only\n * model; callers reparse after applying a transaction. No repair of damaged\n * tables or prose is attempted. Extra and missing body cells remain inspectable.\n */\nimport type { ChangeDesc } from \"@codemirror/state\";\nimport { GFM, parser } from \"@lezer/markdown\";\n\nexport type Align = \"left\" | \"center\" | \"right\" | null;\nexport type Change = { from: number; to: number; insert: string };\n/** Trimmed raw content, with absolute UTF-16 source offsets. */\nexport type Cell = { from: number; to: number; text: string };\nexport type Line = {\n from: number;\n to: number;\n pipes: number[];\n leadingPipe: boolean;\n trailingPipe: boolean;\n cells: Cell[];\n /** Original terminator, used when inserting rows. */\n lineBreak?: string;\n};\nexport type Table = {\n from: number;\n to: number;\n /** Header, delimiter, then body rows. */\n lines: Line[];\n align: Align[];\n columns: number;\n};\n\nconst gfm = parser.configure(GFM);\nconst index = (value: number) => Number.isSafeInteger(value) && value >= 0;\nconst normalizeBreaks = (value: string) => value.replace(/\\r\\n|[\\r\\n\\u2028\\u2029]/g, \" \");\nconst splitsCharacter = (value: string, at: number): boolean => {\n const before = value.charCodeAt(at - 1),\n after = value.charCodeAt(at);\n return before >= 0xd800 && before <= 0xdbff && after >= 0xdc00 && after <= 0xdfff;\n};\n\nconst parseLine = (text: string, from: number, lineBreak: string): Line => {\n const pipes: number[] = [];\n for (let i = 0; i < text.length; i++) {\n if (text[i] === \"\\\\\") i++;\n else if (text[i] === \"|\") pipes.push(from + i);\n }\n const leadingPipe = pipes[0] === from + text.search(/[^ \\t]/);\n const trailingPipe = pipes.length > (leadingPipe ? 1 : 0) && pipes.at(-1) === from + text.trimEnd().length - 1;\n const cells: Cell[] = [];\n let start = leadingPipe ? pipes[0]! + 1 : from;\n const addCell = (end: number) => {\n const segment = text.slice(start - from, end - from);\n const trimmed = segment.trim();\n const at = start + (trimmed ? segment.length - segment.trimStart().length : Math.min(1, segment.length));\n cells.push({ from: at, to: at + trimmed.length, text: trimmed });\n };\n for (const pipe of leadingPipe ? pipes.slice(1) : pipes) {\n addCell(pipe);\n start = pipe + 1;\n }\n if (!trailingPipe) addCell(from + text.length);\n return { from, to: from + text.length, pipes, leadingPipe, trailingPipe, cells, lineBreak };\n};\n\nconst alignOf = (text: string): Align =>\n text.startsWith(\":\") ? (text.endsWith(\":\") ? \"center\" : \"left\") : text.endsWith(\":\") ? \"right\" : null;\n\n/** Only top-level Lezer GFM tables: never code, block quotes, or list items. */\nexport const findTables = (doc: string): Table[] => {\n const lines: { text: string; from: number; normalizedFrom: number; lineBreak: string }[] = [];\n let from = 0,\n normalizedFrom = 0;\n for (const match of doc.matchAll(/([^\\r\\n]*)(\\r\\n|\\r|\\n|$)/g)) {\n if (match[0] === \"\" && from === doc.length) break;\n const text = match[1]!,\n lineBreak = match[2]!;\n lines.push({ text, from, normalizedFrom, lineBreak });\n from += match[0].length;\n normalizedFrom += text.length + (lineBreak ? 1 : 0);\n }\n if (!lines.length) return [];\n const lineAt = (pos: number) => {\n let low = 0,\n high = lines.length;\n while (low + 1 < high) {\n const mid = (low + high) >>> 1;\n if (lines[mid]!.normalizedFrom <= pos) low = mid;\n else high = mid;\n }\n return low;\n };\n const tree = gfm.parse(lines.map((line) => line.text + (line.lineBreak ? \"\\n\" : \"\")).join(\"\"));\n const tables: Table[] = [];\n for (let node = tree.topNode.firstChild; node; node = node.nextSibling) {\n if (node.name !== \"Table\") continue;\n const rows = lines.slice(lineAt(node.from), lineAt(node.to) + 1).map((line) => parseLine(line.text, line.from, line.lineBreak));\n const header = rows[0]!,\n separator = rows[1];\n if (!separator) continue;\n tables.push({\n from: header.from,\n to: rows.at(-1)!.to,\n lines: rows,\n align: separator.cells.map((cell) => alignOf(cell.text)),\n columns: header.cells.length,\n });\n }\n return tables;\n};\n\nexport const tableAt = (doc: string, pos: number): Table | null =>\n findTables(doc).find((table) => pos >= table.from && pos <= table.to) ?? null;\n\n/**\n * Problems that must stay visible before formatted output is sent. A damaged\n * separator makes GFM fall back to a paragraph: two adjacent pipe-framed rows\n * there still need review. This only inspects top-level paragraph nodes, never\n * code, quotations or lists, and does not repair or rewrite any text.\n */\nexport const inspectTableStructure = (doc: string): { extraCells: boolean; missingSeparator: boolean } => {\n // Both GFM tables and the damaged pipe-framed rows below require a pipe.\n // Avoid parsing large prose twice on every editor update and mail preview.\n if (!doc.includes(\"|\")) return { extraCells: false, missingSeparator: false };\n const extraCells = findTables(doc).some((table) => table.lines.some((line) => line.cells.length > table.columns));\n const normalized = doc.replace(/\\r\\n?/g, \"\\n\");\n const tree = gfm.parse(normalized);\n let missingSeparator = false;\n for (let node = tree.topNode.firstChild; node && !missingSeparator; node = node.nextSibling) {\n if (node.name !== \"Paragraph\") continue;\n let consecutive = 0;\n for (const text of normalized.slice(node.from, node.to).split(\"\\n\")) {\n const line = parseLine(text, 0, \"\");\n consecutive = line.leadingPipe && line.trailingPipe ? consecutive + 1 : 0;\n if (consecutive >= 2) {\n missingSeparator = true;\n break;\n }\n }\n }\n return { extraCells, missingSeparator };\n};\nexport const gridLine = (table: Table, row: number): Line | undefined => (index(row) ? table.lines[row === 0 ? 0 : row + 1] : undefined);\nexport const rowCount = (table: Table): number => table.lines.length - 1;\n\n/** Literal displayed text → safe raw content. Call once, never on existing raw Markdown. */\nexport const escapeCell = (value: string): string => normalizeBreaks(value).replace(/[\\\\|]/g, \"\\\\$&\");\n\n/** Display text and a raw offset for every displayed UTF-16 boundary. */\nexport const cellDisplayMap = (raw: string): { text: string; offsets: number[] } => {\n let text = \"\";\n const offsets = [0];\n for (let i = 0; i < raw.length; ) {\n const escaped = raw[i] === \"\\\\\" && (raw[i + 1] === \"\\\\\" || raw[i + 1] === \"|\");\n text += raw[i + (escaped ? 1 : 0)]!;\n i += escaped ? 2 : 1;\n offsets.push(i);\n }\n return { text, offsets };\n};\n/** Decode only table pipes and backslashes; leave inline Markdown source editable. */\nexport const displayCell = (raw: string): string => cellDisplayMap(raw).text;\n\n/**\n * One minimal contiguous source edit from literal displayed input. Unchanged\n * escapes keep their exact bytes, including noncanonical lone backslashes.\n * `from` is the old cell's absolute start; input must NOT be pre-escaped.\n */\nexport const cellChanges = (raw: string, nextDisplayed: string, from: number): Change[] => {\n const { text, offsets } = cellDisplayMap(raw);\n const next = normalizeBreaks(nextDisplayed);\n if (text === next) return [];\n let prefix = 0,\n suffix = 0;\n while (prefix < text.length && prefix < next.length && text[prefix] === next[prefix]) prefix++;\n if (splitsCharacter(text, prefix) || splitsCharacter(next, prefix)) prefix--;\n while (\n suffix < text.length - prefix &&\n suffix < next.length - prefix &&\n text[text.length - suffix - 1] === next[next.length - suffix - 1]\n )\n suffix++;\n if (splitsCharacter(text, text.length - suffix) || splitsCharacter(next, next.length - suffix)) suffix--;\n const end = offsets[text.length - suffix]!;\n let start = offsets[prefix]!;\n let insert = escapeCell(next.slice(prefix, next.length - suffix));\n // A lone slash can consume the inserted pipe escape without changing the\n // displayed text, yet expose a structural pipe. Check source parity too.\n const candidate = raw.slice(0, start) + insert + raw.slice(end);\n let exposedPipe = false,\n escaped = false;\n for (const ch of candidate) {\n if (ch === \"|\" && !escaped) exposedPipe = true;\n escaped = ch === \"\\\\\" && !escaped;\n }\n // Newly exposing a final lone slash could escape an adjacent closing pipe.\n // Existing trailing escapes in an untouched suffix retain their bytes.\n if ((displayCell(candidate) !== next || exposedPipe || (escaped && suffix === 0)) && prefix > 0) {\n prefix--;\n start = offsets[prefix]!;\n insert = escapeCell(next.slice(prefix, next.length - suffix));\n }\n let to = end;\n while (start < to && insert && raw[start] === insert[0] && !splitsCharacter(raw, start + 1) && !splitsCharacter(insert, 1)) {\n start++;\n insert = insert.slice(1);\n }\n while (\n start < to &&\n insert &&\n raw[to - 1] === insert.at(-1) &&\n !splitsCharacter(raw, to - 1) &&\n !splitsCharacter(insert, insert.length - 1)\n ) {\n to--;\n insert = insert.slice(0, -1);\n }\n return [{ from: from + start, to: from + to, insert }];\n};\n\n/**\n * Map an edit based on an old cell through intervening document changes.\n * Deletes only surviving old-source spans (iterGaps), preserving remote inserts\n * and excluding replaced/deleted identities. Returns current-document offsets.\n * The caller must first verify that the mapped range is still the same cell;\n * concurrent structural/escape edits require resyncing its displayed snapshot.\n */\nexport const mappedCellChanges = (raw: string, nextDisplayed: string, from: number, changes: ChangeDesc): Change[] => {\n const edit = cellChanges(raw, nextDisplayed, from)[0];\n if (!edit) return [];\n const result: Change[] = [];\n changes.iterGaps((oldFrom, newFrom, length) => {\n const a = Math.max(edit.from, oldFrom),\n b = Math.min(edit.to, oldFrom + length);\n if (a < b) result.push({ from: newFrom + a - oldFrom, to: newFrom + b - oldFrom, insert: \"\" });\n });\n if (edit.insert) {\n const at = changes.mapPos(edit.from, 1);\n const deletion = result.find((change) => change.from === at);\n if (deletion) deletion.insert = edit.insert;\n else result.push({ from: at, to: at, insert: edit.insert });\n }\n return result.sort((a, b) => a.from - b.from || a.to - b.to);\n};\n\nconst appendCells = (line: Line, count: number, separator = false): Change[] =>\n count > 0\n ? [\n {\n from: line.to,\n to: line.to,\n insert: (line.trailingPipe ? \"\" : \" |\") + (separator ? \" --- |\" : \" |\").repeat(count),\n },\n ]\n : [];\n\n/** Spike-compatible escaped RAW input; fills ragged cells within the existing grid width. */\nexport const setCellText = (table: Table, row: number, col: number, next: string): Change[] => {\n const line = gridLine(table, row);\n if (!line || !index(col) || col >= width(table)) return [];\n const cell = line.cells[col];\n if (cell) return cellChanges(cell.text, displayCell(next), cell.from);\n return [\n {\n from: line.to,\n to: line.to,\n insert: (line.trailingPipe ? \"\" : \" |\") + \" |\".repeat(col - line.cells.length) + ` ${escapeCell(displayCell(next))} |`,\n },\n ];\n};\n\nexport const insertRow = (table: Table, after: number): Change[] => {\n const line = after === 0 ? table.lines[1] : gridLine(table, after);\n if (!line) return [];\n const newline = table.lines[0]?.lineBreak || \"\\n\";\n return [{ from: line.to, to: line.to, insert: `${newline}|${\" |\".repeat(table.columns)}` }];\n};\nexport const deleteRow = (table: Table, row: number): Change[] => {\n const line = gridLine(table, row),\n previous = table.lines[row];\n return row > 0 && line && previous ? [{ from: previous.to, to: line.to, insert: \"\" }] : [];\n};\n/** Move a body row, retaining every untouched row's original source and identities. */\nexport const moveRow = (source: string, table: Table, row: number, to: number): Change[] => {\n if (!index(row) || !index(to) || row === 0 || to === 0 || row === to) return [];\n const line = gridLine(table, row),\n target = gridLine(table, to),\n previous = table.lines[row];\n if (!line || !target || !previous) return [];\n const insertAt = row < to ? target.to : table.lines[to]!.to;\n return [\n { from: previous.to, to: line.to, insert: \"\" },\n { from: insertAt, to: insertAt, insert: source.slice(previous.to, line.to) },\n ].sort((a, b) => a.from - b.from);\n};\n\n/** Swap adjacent columns, including their alignment, without rewriting other cells. */\nexport const moveColumn = (table: Table, column: number, to: number): Change[] => {\n if (!index(column) || !index(to) || Math.abs(column - to) !== 1 || column >= table.columns || to >= table.columns) return [];\n // Complete ragged rows first, so a move cannot discard or invent a target.\n if (table.lines.some((line) => line.cells.length !== table.columns)) return [];\n return table.lines\n .flatMap((line) => {\n const a = line.cells[column]!,\n b = line.cells[to]!;\n return a.text === b.text\n ? []\n : [\n { from: a.from, to: a.to, insert: b.text },\n { from: b.from, to: b.to, insert: a.text },\n ];\n })\n .sort((a, b) => a.from - b.from);\n};\n\n/** A hidden header is an empty GFM header; its former values become the first body row. */\nexport const toggleHeader = (source: string, table: Table): Change[] => {\n const header = table.lines[0]!,\n separator = table.lines[1]!;\n const newline = header.lineBreak || \"\\n\";\n const marker = source.slice(separator.from, separator.to);\n if (header.cells.some((cell) => cell.text))\n return [\n { from: table.from, to: table.from, insert: `|${\" |\".repeat(table.columns)}${newline}${marker}${newline}` },\n { from: header.to, to: separator.to, insert: \"\" },\n ];\n const first = table.lines[2];\n if (!first || !first.cells.some((cell) => cell.text) || first.cells.length > table.columns) return [];\n const padding = appendCells(first, table.columns - first.cells.length)[0]?.insert ?? \"\";\n return [\n { from: table.from, to: first.from, insert: \"\" },\n { from: first.to, to: first.to, insert: `${padding}${newline}${marker}` },\n ];\n};\n\n/** Delete only the selected table; surrounding prose remains byte-for-byte intact. */\nexport const deleteTable = (table: Table): Change[] => [{ from: table.from, to: table.to, insert: \"\" }];\n\nconst width = (table: Table) => table.lines.reduce((max, line) => Math.max(max, line.cells.length), table.columns);\n\n/** Insert before `at`, including at the widest row's end; pad ragged rows without dropping cells. */\nexport const insertColumn = (table: Table, at: number): Change[] => {\n if (!index(at) || at > width(table)) return [];\n return table.lines.flatMap((line, i) => {\n if (at >= line.cells.length) return appendCells(line, at - line.cells.length + 1, i === 1);\n const pos = line.leadingPipe ? line.pipes[at]! + 1 : at === 0 ? line.from : line.pipes[at - 1]! + 1;\n return [{ from: pos, to: pos, insert: (at === 0 && !line.leadingPipe ? \"|\" : \"\") + (i === 1 ? \" --- |\" : \" |\") }];\n });\n};\n/** Complete a ragged grid without changing or removing any existing cell. */\nexport const completeColumns = (table: Table): Change[] => {\n const columns = width(table);\n return table.lines.flatMap((line, i) => appendCells(line, columns - line.cells.length, i === 1));\n};\n\nexport const deleteColumn = (table: Table, col: number): Change[] => {\n if (!index(col) || col >= width(table) || (table.columns <= 1 && col < table.columns)) return [];\n return table.lines.flatMap((line, row) => {\n if (col >= line.cells.length) return [];\n const before = line.leadingPipe ? line.pipes[col]! : col === 0 ? line.from - 1 : line.pipes[col - 1]!;\n const after = line.leadingPipe ? line.pipes[col + 1] : line.pipes[col];\n // A blank physical line would end the table and orphan later body rows.\n // Preserve a delimiter as the explicit empty row, or insert one if absent.\n if (line.cells.length === 1 && !line.leadingPipe) {\n return [{ from: line.from, to: after ?? line.to, insert: after === undefined ? \"|\" : \"\" }];\n }\n // Keep the last delimiter when reducing to one cell. Lezer additionally\n // needs a trailing delimiter on a one-cell separator (a leading one alone\n // is not recognized), so add it only on that marker line when necessary.\n if (line.cells.length === 2 && !line.trailingPipe) {\n if (col === 1) return [{ from: before + 1, to: line.to, insert: \"\" }];\n if (!line.leadingPipe)\n return [{ from: line.from, to: after!, insert: \"\" }, ...(row === 1 ? [{ from: line.to, to: line.to, insert: \"|\" }] : [])];\n return [{ from: before + 1, to: after! + 1, insert: \"\" }, ...(row === 1 ? [{ from: line.to, to: line.to, insert: \"|\" }] : [])];\n }\n // With omitted outer pipes, remove the preceding delimiter for the last cell.\n if (after === undefined && col > 0) return [{ from: before, to: line.to, insert: \"\" }];\n if (after === undefined) return [{ from: before + 1, to: line.to, insert: \"\" }];\n return [{ from: before + 1, to: after + 1, insert: \"\" }];\n });\n};\nexport const setAlign = (table: Table, col: number, align: Align): Change[] => {\n if (!index(col)) return [];\n const cell = table.lines[1]?.cells[col];\n if (!cell) return [];\n const result: Change[] = [];\n const left = align === \"left\" || align === \"center\",\n right = align === \"right\" || align === \"center\";\n const hasLeft = cell.text.startsWith(\":\"),\n hasRight = cell.text.endsWith(\":\");\n if (left !== hasLeft) result.push({ from: cell.from, to: cell.from + Number(hasLeft), insert: left ? \":\" : \"\" });\n if (right !== hasRight) result.push({ from: cell.to - Number(hasRight), to: cell.to, insert: right ? \":\" : \"\" });\n return result;\n};\n\n/** First grid row is the header; pad short rows, preserve every extra cell. */\nexport const tableFromGrid = (grid: string[][]): string => {\n const columns = grid.reduce((max, row) => Math.max(max, row.length), 1);\n const rows = (grid.length ? grid : [[]]).map(\n (row) => `| ${Array.from({ length: columns }, (_, col) => escapeCell(row[col] ?? \"\")).join(\" | \")} |`,\n );\n rows.splice(1, 0, `|${\" --- |\".repeat(columns)}`);\n return rows.join(\"\\n\");\n};\n\n/** Quoted TSV (including doubled quotes and embedded newlines). Invalid quotes stay raw. */\nexport const parseTsv = (text: string): string[][] | null => {\n if (!text.includes(\"\\t\")) return null;\n const rows: string[][] = [];\n let row: string[] = [],\n cell = \"\",\n quoted = false,\n closed = false;\n for (let i = 0; i < text.length; i++) {\n const ch = text[i]!;\n if (quoted) {\n if (ch === '\"' && text[i + 1] === '\"') {\n cell += '\"';\n i++;\n } else if (ch === '\"') {\n quoted = false;\n closed = true;\n } else cell += ch;\n } else if (ch === '\"' && cell === \"\" && !closed) quoted = true;\n else if (ch === \"\\t\") {\n row.push(cell);\n cell = \"\";\n closed = false;\n } else if (ch === \"\\n\" || ch === \"\\r\") {\n if (ch === \"\\r\" && text[i + 1] === \"\\n\") i++;\n row.push(cell);\n rows.push(row);\n row = [];\n cell = \"\";\n closed = false;\n } else if (closed) return null;\n else cell += ch;\n }\n if (quoted) return null;\n if (cell !== \"\" || row.length || closed) {\n row.push(cell);\n rows.push(row);\n }\n return rows.length ? rows : null;\n};\n\n/** Apply sorted or unsorted, non-overlapping edits in old-document coordinates. */\nexport const applyChanges = (doc: string, changes: Change[]): string => {\n const sorted = [...changes].sort((a, b) => a.from - b.from || a.to - b.to);\n let result = \"\",\n pos = 0;\n for (const change of sorted) {\n if (!index(change.from) || !index(change.to) || change.from < pos || change.to < change.from || change.to > doc.length)\n throw new RangeError(\"Invalid or overlapping table changes\");\n result += doc.slice(pos, change.from) + change.insert;\n pos = change.to;\n }\n return result + doc.slice(pos);\n};\n\n/**\n * Settle recognized ragged GFM tables without deleting or rewriting source.\n * Extra cells become named-grid positions with empty headers, never discarded.\n * Unrecognizable tables remain raw text for the application's check state;\n * code, quotes and lists are not repair candidates.\n */\nexport const repairTables = (doc: string, maxLength: number): Change[] => {\n if (!Number.isSafeInteger(maxLength) || maxLength < 0) throw new RangeError(\"Invalid repair text budget\");\n const candidates = findTables(doc)\n .map((table) => ({ table, columns: width(table) }))\n .filter(({ table, columns }) => table.lines.some((line) => line.cells.length !== columns));\n let length = doc.length;\n // A wide row followed by many short rows can require quadratic padding.\n // Count first; leave the damage visible if the document budget cannot fit it.\n for (const { table, columns } of candidates) {\n for (const [row, line] of table.lines.entries()) {\n const count = columns - line.cells.length;\n length += count * (row === 1 ? 6 : 4) + (line.trailingPipe ? 0 : 2);\n if (length > maxLength) return [];\n }\n }\n return candidates.flatMap(({ table, columns }) =>\n table.lines.flatMap((line, row) => {\n const padding = appendCells(line, columns - line.cells.length, row === 1);\n if (padding.length) return padding;\n // Surviving peer text after append undo becomes an explicit extra cell.\n return line.trailingPipe ? [] : [{ from: line.to, to: line.to, insert: \" |\" }];\n }),\n );\n};\n"],"mappings":"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","ignoreList":[]}
|