@openpresentation/opf-editor 0.10.6 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +333 -8
- package/dist/annotations.d.ts +71 -0
- package/dist/annotations.js +281 -0
- package/dist/assets.d.ts +67 -0
- package/dist/assets.js +176 -0
- package/dist/background-options.d.ts +48 -0
- package/dist/background-options.js +134 -0
- package/dist/block-convert.d.ts +64 -0
- package/dist/block-convert.js +142 -0
- package/dist/canvas.d.ts +16 -0
- package/dist/canvas.js +82 -21
- package/dist/chart-data.d.ts +32 -0
- package/dist/chart-data.js +101 -0
- package/dist/chart-options-panel.d.ts +16 -0
- package/dist/chart-options-panel.js +127 -0
- package/dist/chart-options.d.ts +49 -0
- package/dist/chart-options.js +157 -0
- package/dist/content-actions.d.ts +91 -0
- package/dist/content-actions.js +207 -0
- package/dist/content-controls.js +326 -0
- package/dist/data-grid.d.ts +37 -0
- package/dist/data-grid.js +1035 -0
- package/dist/design-controls.d.ts +43 -0
- package/dist/design-controls.js +1077 -0
- package/dist/design-options.d.ts +108 -0
- package/dist/design-options.js +412 -0
- package/dist/edit-helpers.js +52 -0
- package/dist/export.d.ts +77 -0
- package/dist/export.js +216 -0
- package/dist/find-panel.d.ts +44 -0
- package/dist/find-panel.js +431 -0
- package/dist/find-replace.d.ts +100 -0
- package/dist/find-replace.js +374 -0
- package/dist/grid-model.d.ts +135 -0
- package/dist/grid-model.js +836 -0
- package/dist/grid-text.d.ts +33 -0
- package/dist/grid-text.js +251 -0
- package/dist/image-crop.d.ts +59 -0
- package/dist/image-crop.js +336 -0
- package/dist/image-cropper.d.ts +29 -0
- package/dist/image-cropper.js +519 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.js +104 -171
- package/dist/numbering-panel.d.ts +21 -0
- package/dist/numbering-panel.js +200 -0
- package/dist/numbering.d.ts +62 -0
- package/dist/numbering.js +223 -0
- package/dist/outline-view.d.ts +17 -0
- package/dist/outline-view.js +278 -0
- package/dist/outline.d.ts +56 -0
- package/dist/outline.js +271 -0
- package/dist/persistence-ui.d.ts +24 -0
- package/dist/persistence-ui.js +81 -0
- package/dist/persistence.d.ts +105 -0
- package/dist/persistence.js +429 -0
- package/dist/review-panel.d.ts +44 -0
- package/dist/review-panel.js +359 -0
- package/dist/review.d.ts +75 -0
- package/dist/review.js +170 -0
- package/dist/slide-manager.d.ts +44 -0
- package/dist/slide-manager.js +695 -0
- package/dist/slides.d.ts +96 -0
- package/dist/slides.js +433 -0
- package/dist/switches.d.ts +26 -0
- package/dist/switches.js +127 -43
- package/dist/table-options.d.ts +80 -0
- package/dist/table-options.js +419 -0
- package/dist/table-structure.d.ts +30 -0
- package/dist/table-structure.js +92 -0
- package/dist/template-panel.d.ts +31 -0
- package/dist/template-panel.js +377 -0
- package/dist/templates.d.ts +126 -0
- package/dist/templates.js +331 -0
- package/dist/zip.d.ts +4 -0
- package/dist/zip.js +71 -0
- package/package.json +150 -10
package/dist/switches.js
CHANGED
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
validateOpfDocument,
|
|
14
14
|
} from "./index.js";
|
|
15
15
|
import { createContentBlock, prepareBlockReplace } from "./blocks.js";
|
|
16
|
+
import { checkedDocument, designPatches, fail, same } from "./edit-helpers.js";
|
|
16
17
|
import { populateLayoutPlaceholders } from "./layout-placeholders.js";
|
|
18
|
+
import { blockConversionTargets, prepareBlockConversion } from "./block-convert.js";
|
|
17
19
|
|
|
18
20
|
/** The 14 pptx.gallery dimensions (gallery-support.md), in the gallery's order. */
|
|
19
21
|
export const SWITCH_DIMENSIONS = Object.freeze([
|
|
@@ -59,20 +61,6 @@ const DESIGN_KEYS = Object.freeze({
|
|
|
59
61
|
const REGION = /^(?:(?:top|middle|bottom)(?:\+(?:top|middle|bottom))*(?::(?:left|center|right)(?:\+(?:left|center|right))*)?|(?:left|center|right)(?:\+(?:left|center|right))*)$/;
|
|
60
62
|
const BLOCK_KINDS = ["text", "list", "chart", "table", "metric", "quote", "code", "timeline", "group", "image", "video"];
|
|
61
63
|
|
|
62
|
-
function fail(code, message, details) {
|
|
63
|
-
return new OPFEditorError(code, message, details);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function same(a, b) {
|
|
67
|
-
return JSON.stringify(canonical(a)) === JSON.stringify(canonical(b));
|
|
68
|
-
}
|
|
69
|
-
function canonical(value) {
|
|
70
|
-
if (Array.isArray(value)) return value.map(canonical);
|
|
71
|
-
if (value && typeof value === "object")
|
|
72
|
-
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonical(value[key])]));
|
|
73
|
-
return value;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
64
|
function recordList(source) {
|
|
77
65
|
const records = Array.isArray(source) ? source : source?.records;
|
|
78
66
|
return Array.isArray(records) ? records.filter((record) => record && typeof record.id === "string") : [];
|
|
@@ -123,25 +111,6 @@ function rootPatch(document, field, value) {
|
|
|
123
111
|
return same(document[field], value) ? [] : createValuePatch(document, [field], value);
|
|
124
112
|
}
|
|
125
113
|
|
|
126
|
-
// Set (value) or remove (null) design keys at deck or slide scope.
|
|
127
|
-
function designPatches(document, base, entries) {
|
|
128
|
-
const design = getValueAtPath(document, base.length ? [...base, "design"] : ["design"]);
|
|
129
|
-
const at = (key) => opfPathToJsonPointer([...base, "design", key]);
|
|
130
|
-
const set = Object.entries(entries).filter(([, value]) => value !== undefined && value !== null);
|
|
131
|
-
if (!design || typeof design !== "object" || Array.isArray(design))
|
|
132
|
-
return set.length ? [{ op: "add", path: opfPathToJsonPointer([...base, "design"]), value: structuredClone(Object.fromEntries(set)) }] : [];
|
|
133
|
-
const patches = [];
|
|
134
|
-
for (const [key, value] of Object.entries(entries)) {
|
|
135
|
-
if (value === undefined) continue;
|
|
136
|
-
const present = Object.hasOwn(design, key);
|
|
137
|
-
if (value === null) {
|
|
138
|
-
if (present) patches.push({ op: "remove", path: at(key) });
|
|
139
|
-
} else if (!present) patches.push({ op: "add", path: at(key), value: structuredClone(value) });
|
|
140
|
-
else if (!same(design[key], value)) patches.push({ op: "replace", path: at(key), value: structuredClone(value) });
|
|
141
|
-
}
|
|
142
|
-
return patches;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
114
|
// A deck-level switch does nothing for a slide that carries its own value for that key.
|
|
146
115
|
function shadowedSlides(document, keys) {
|
|
147
116
|
return (document.slides ?? []).flatMap((slide, index) => (keys.some((key) => slide?.design?.[key] !== undefined) ? [index] : []));
|
|
@@ -213,6 +182,7 @@ export function prepareDimensionSwitch(document, dimension, value, options = {})
|
|
|
213
182
|
let scope = "deck";
|
|
214
183
|
let shadowed = [];
|
|
215
184
|
let slideIndex;
|
|
185
|
+
let conversionLoss;
|
|
216
186
|
|
|
217
187
|
if (dimension === "layouts") {
|
|
218
188
|
slideIndex = scopeIndex;
|
|
@@ -244,9 +214,17 @@ export function prepareDimensionSwitch(document, dimension, value, options = {})
|
|
|
244
214
|
patches = [...catalogRecordPatches(document, dimension, options), ...(chart.type === value ? [] : createValuePatch(document, [...owner, "chart", "type"], value))];
|
|
245
215
|
} else if (dimension === "blocks") {
|
|
246
216
|
if (options.path === undefined) throw fail("missing-path", "Choose the block to replace with options.path.");
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
217
|
+
// convert: true moves the block's own text into the new kind (block-convert.js) instead of replacing it.
|
|
218
|
+
if (options.convert) {
|
|
219
|
+
if (typeof value !== "string") throw fail("invalid-switch-value", "Convert a block to a content kind name.", { value });
|
|
220
|
+
const conversion = prepareBlockConversion(document, options.path, value, options.conversion);
|
|
221
|
+
patches = conversion.changed ? conversion.patches : [];
|
|
222
|
+
conversionLoss = conversion.loss;
|
|
223
|
+
} else {
|
|
224
|
+
const block = blockValue(value, options);
|
|
225
|
+
const change = prepareBlockReplace(document, options.path, block);
|
|
226
|
+
patches = change.changed ? change.patches : [];
|
|
227
|
+
}
|
|
250
228
|
const parts = splitOpfPath(options.path);
|
|
251
229
|
if (parts[0] === "slides") slideIndex = Number(parts[1]);
|
|
252
230
|
scope = "block";
|
|
@@ -276,11 +254,18 @@ export function prepareDimensionSwitch(document, dimension, value, options = {})
|
|
|
276
254
|
} else if (dimension === "color-schemes" || dimension === "font-schemes") {
|
|
277
255
|
requireCatalogId(document, dimension, value, options);
|
|
278
256
|
entries = { [DESIGN_KEYS[dimension][0]]: value };
|
|
257
|
+
if (dimension === "font-schemes") {
|
|
258
|
+
// An accent font is its own choice, not part of the scheme being left: it stays (in the object form).
|
|
259
|
+
const scopeBase = scopeIndex !== undefined && document.slides?.[scopeIndex] ? ["slides", String(scopeIndex)] : [];
|
|
260
|
+
const own = getValueAtPath(document, [...scopeBase, "design", "fontScheme"]);
|
|
261
|
+
if (own && typeof own === "object" && own.accent !== undefined) entries.fontScheme = { id: value, accent: structuredClone(own.accent) };
|
|
262
|
+
}
|
|
279
263
|
patches = catalogRecordPatches(document, dimension, options);
|
|
280
264
|
} else {
|
|
281
265
|
// A background is an object or a shorthand string (theme slot or hex color); the schema
|
|
282
266
|
// validates the candidate document, so a string that is neither is rejected below.
|
|
283
|
-
|
|
267
|
+
// null removes the background so the theme's (or, on a slide, the deck's) shows again.
|
|
268
|
+
const valid = dimension === "backgrounds" ? value === null || typeof value === "string" || (Boolean(value) && typeof value === "object" && !Array.isArray(value)) : Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
284
269
|
if (!valid)
|
|
285
270
|
throw fail("invalid-switch-value", `Switch ${dimension} to ${dimension === "backgrounds" ? "a background object or shorthand string" : "an object with " + DESIGN_KEYS[dimension].join(" and ")}.`, { value });
|
|
286
271
|
if (dimension === "backgrounds") entries = { background: value };
|
|
@@ -309,12 +294,7 @@ export function prepareDimensionSwitch(document, dimension, value, options = {})
|
|
|
309
294
|
}
|
|
310
295
|
}
|
|
311
296
|
|
|
312
|
-
const next =
|
|
313
|
-
if (patches.length) {
|
|
314
|
-
const validation = validateOpfDocument(next);
|
|
315
|
-
if (!validation.valid && before.valid)
|
|
316
|
-
throw fail("invalid-opf-edit", validation.errors[0]?.message ?? "This switch produces an invalid document.", { issues: validation.errors, patches });
|
|
317
|
-
}
|
|
297
|
+
const next = checkedDocument(document, patches, before);
|
|
318
298
|
return {
|
|
319
299
|
dimension,
|
|
320
300
|
scope,
|
|
@@ -323,6 +303,7 @@ export function prepareDimensionSwitch(document, dimension, value, options = {})
|
|
|
323
303
|
patches,
|
|
324
304
|
changed: patches.length > 0,
|
|
325
305
|
shadowed,
|
|
306
|
+
...(conversionLoss ? { loss: conversionLoss } : {}),
|
|
326
307
|
};
|
|
327
308
|
}
|
|
328
309
|
|
|
@@ -342,3 +323,106 @@ export function switchDimension(editor, dimension, value, options = {}) {
|
|
|
342
323
|
const change = editor.applyPatch(patches, { ...meta, source: meta?.source ?? "dimension-switch", dimension, scope: prepared.scope });
|
|
343
324
|
return { ...change, ...summary };
|
|
344
325
|
}
|
|
326
|
+
|
|
327
|
+
// --- options for pickers and current values ---------------------------------------------------
|
|
328
|
+
|
|
329
|
+
const labelOf = (record) => record.label ?? record.name ?? record.id;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* The values a picker can offer for a catalog-backed dimension, in document order: the document's
|
|
333
|
+
* inline records first (they override), then caller-loaded records, then the bundled catalog,
|
|
334
|
+
* without duplicates. `blocks` lists the content kinds. `charts` lists every chart type; use
|
|
335
|
+
* `compatibleChartTypes` to narrow it to the types the chart's data can use.
|
|
336
|
+
*/
|
|
337
|
+
export function listSwitchOptions(document, dimension, options = {}) {
|
|
338
|
+
if (dimension === "blocks") return BLOCK_KINDS.map((kind) => ({ id: kind, label: kind[0].toUpperCase() + kind.slice(1) }));
|
|
339
|
+
const kind = CATALOG_KIND[dimension];
|
|
340
|
+
if (!kind) return [];
|
|
341
|
+
const seen = new Set();
|
|
342
|
+
const out = [];
|
|
343
|
+
for (const source of [document?.catalogs?.[kind], options.catalogs?.[kind] ?? options.catalogSources?.[kind], bundledCatalogs[kind]])
|
|
344
|
+
for (const record of recordList(source)) {
|
|
345
|
+
if (seen.has(record.id)) continue;
|
|
346
|
+
seen.add(record.id);
|
|
347
|
+
out.push({ id: record.id, label: labelOf(record), record });
|
|
348
|
+
}
|
|
349
|
+
return out;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const SINGLE_SERIES_ONLY = new Set(["pieChart", "doughnutChart", "funnelChart", "treemapChart", "waterfallChart"]);
|
|
353
|
+
const MULTI_SERIES_CAPABLE = new Set(["barChart", "lineChart", "areaChart", "radarChart"]);
|
|
354
|
+
const DISTRIBUTION_ELEMENTS = new Set(["histogramChart", "boxWhiskerChart", "mapChart"]);
|
|
355
|
+
|
|
356
|
+
function chartDataShape(chart) {
|
|
357
|
+
const data = chart?.data;
|
|
358
|
+
if (!data || !Array.isArray(data.columns) || !Array.isArray(data.rows)) return undefined;
|
|
359
|
+
// The renderers read the first column as the category label and every further column as a series.
|
|
360
|
+
return { series: Math.max(0, data.columns.length - 1), categories: data.rows.length };
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Chart types the chart's inline data can use as it is, from the chartTypes catalog: simple,
|
|
365
|
+
* non-geographic, non-distribution types whose series count fits the data (the first column labels
|
|
366
|
+
* the categories and each further column is a series; a type with N series needs exactly N value
|
|
367
|
+
* columns; column, bar, line, area and radar take any number). Data that is read from
|
|
368
|
+
* an external source returns every simple type. This is data-shape compatibility, not a claim that
|
|
369
|
+
* an engine draws the type. `path` or `slideIndex` picks the chart (default: the slide's first).
|
|
370
|
+
* Each entry has `current: true` for the chart's present type, which is always listed.
|
|
371
|
+
*/
|
|
372
|
+
export function compatibleChartTypes(document, options = {}) {
|
|
373
|
+
const slideIndex = options.slideIndex ?? 0;
|
|
374
|
+
const owner = options.path ? splitOpfPath(options.path) : document.slides?.[slideIndex] ? findChartOwner(document, slideIndex) : undefined;
|
|
375
|
+
const chart = owner && getValueAtPath(document, [...owner, "chart"]);
|
|
376
|
+
if (!chart || typeof chart !== "object") return [];
|
|
377
|
+
const shape = chartDataShape(chart);
|
|
378
|
+
const result = [];
|
|
379
|
+
for (const option of listSwitchOptions(document, "charts", options)) {
|
|
380
|
+
const record = option.record;
|
|
381
|
+
const element = record.mappings?.openxml?.element;
|
|
382
|
+
const current = option.id === chart.type;
|
|
383
|
+
const simple = record.complexity === "simple" && record.mappings?.openxml?.composition !== "mixed" && !DISTRIBUTION_ELEMENTS.has(element);
|
|
384
|
+
const seriesOk =
|
|
385
|
+
!shape || !record.series || (record.series > 1 ? record.series === shape.series : shape.series === 1 || (MULTI_SERIES_CAPABLE.has(element) && !SINGLE_SERIES_ONLY.has(element)));
|
|
386
|
+
if (current || (simple && seriesOk)) result.push({ id: option.id, label: option.label, current, record });
|
|
387
|
+
}
|
|
388
|
+
return result;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* The value a dimension currently has, for pickers: `{ value, scope }` where scope is "slide" when
|
|
393
|
+
* `slideIndex` names a slide whose own design sets it, else "deck". `value` is undefined when the
|
|
394
|
+
* dimension is unset. Catalog dimensions return the catalog id even when the document holds an
|
|
395
|
+
* inline object.
|
|
396
|
+
*/
|
|
397
|
+
export function currentSwitchValue(document, dimension, options = {}) {
|
|
398
|
+
const idOf = (reference) => (reference && typeof reference === "object" && !Array.isArray(reference) ? reference.id : reference);
|
|
399
|
+
const design = (key) => {
|
|
400
|
+
const slide = options.slideIndex !== undefined ? document.slides?.[options.slideIndex]?.design?.[key] : undefined;
|
|
401
|
+
if (slide !== undefined) return { value: slide, scope: "slide" };
|
|
402
|
+
return document.design?.[key] === undefined ? { scope: "deck" } : { value: document.design[key], scope: "deck" };
|
|
403
|
+
};
|
|
404
|
+
if (dimension === "layouts") return { value: document.slides?.[options.slideIndex]?.layout, scope: "slide" };
|
|
405
|
+
if (dimension === "charts") {
|
|
406
|
+
const owner = options.path ? splitOpfPath(options.path) : findChartOwner(document, options.slideIndex ?? 0);
|
|
407
|
+
return { value: owner ? getValueAtPath(document, [...owner, "chart", "type"]) : undefined, scope: "slide" };
|
|
408
|
+
}
|
|
409
|
+
if (dimension === "blocks") return { value: undefined, scope: "block" };
|
|
410
|
+
if (dimension === "socials") {
|
|
411
|
+
const host = document[options.owner ?? "speaker"];
|
|
412
|
+
const target = Array.isArray(host) ? host[options.index ?? 0] : host;
|
|
413
|
+
return { value: target?.socials, scope: "deck" };
|
|
414
|
+
}
|
|
415
|
+
if (ROOT_FIELD[dimension]) return { value: document[ROOT_FIELD[dimension]], scope: "deck" };
|
|
416
|
+
if (dimension === "color-schemes") return { ...design("colorScheme"), value: idOf(design("colorScheme").value) };
|
|
417
|
+
if (dimension === "font-schemes") return { ...design("fontScheme"), value: idOf(design("fontScheme").value) };
|
|
418
|
+
if (dimension === "themes") return { ...design("theme"), value: idOf(design("theme").value) };
|
|
419
|
+
if (dimension === "backgrounds") return design("background");
|
|
420
|
+
const keys = DESIGN_KEYS[dimension];
|
|
421
|
+
if (keys) {
|
|
422
|
+
const found = keys.map((key) => design(key));
|
|
423
|
+
return { value: Object.fromEntries(keys.map((key, index) => [key, found[index].value])), scope: found.some((entry) => entry.scope === "slide") ? "slide" : "deck" };
|
|
424
|
+
}
|
|
425
|
+
return { scope: "deck" };
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
export { blockConversionTargets };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { EditorChange, EditorSession, JsonPatchOperation } from "./index.js";
|
|
2
|
+
|
|
3
|
+
export interface TableCellAddress {
|
|
4
|
+
section: "header" | "body";
|
|
5
|
+
/** Body row; ignored for the header section. */
|
|
6
|
+
row?: number;
|
|
7
|
+
column: number;
|
|
8
|
+
}
|
|
9
|
+
export interface TableStyle {
|
|
10
|
+
/** "theme": the renderer default (primary fill). "plain": the header looks like the body. "accent": accent fill. */
|
|
11
|
+
header: "theme" | "plain" | "accent";
|
|
12
|
+
/** Alternating body-row fill. */
|
|
13
|
+
banding: boolean;
|
|
14
|
+
/** "theme" keeps the default thin borders; "none" removes them; "horizontal" keeps row rules; "grid" draws every edge. */
|
|
15
|
+
borders: "theme" | "none" | "horizontal" | "grid";
|
|
16
|
+
}
|
|
17
|
+
export declare const TABLE_STYLE_PRESETS: Readonly<Record<"theme" | "banded" | "grid" | "minimal" | "open", Readonly<TableStyle>>>;
|
|
18
|
+
export declare const TABLE_HEADER_STYLES: readonly ["theme", "plain", "accent"];
|
|
19
|
+
export declare const TABLE_BORDER_STYLES: readonly ["theme", "none", "horizontal", "grid"];
|
|
20
|
+
export interface TableMerge {
|
|
21
|
+
section: "header" | "body";
|
|
22
|
+
row: number;
|
|
23
|
+
column: number;
|
|
24
|
+
rowSpan: number;
|
|
25
|
+
colSpan: number;
|
|
26
|
+
}
|
|
27
|
+
export interface TableCellState extends TableCellAddress {
|
|
28
|
+
value: unknown;
|
|
29
|
+
style: Record<string, unknown>;
|
|
30
|
+
colSpan: number;
|
|
31
|
+
rowSpan: number;
|
|
32
|
+
merged: boolean;
|
|
33
|
+
anchor: boolean;
|
|
34
|
+
covered: boolean;
|
|
35
|
+
anchorCell?: TableCellAddress;
|
|
36
|
+
columns: number;
|
|
37
|
+
rows: number;
|
|
38
|
+
}
|
|
39
|
+
export interface PreparedTableChange {
|
|
40
|
+
action: "merge" | "split" | "style" | "table-style";
|
|
41
|
+
tablePath: string;
|
|
42
|
+
document: unknown;
|
|
43
|
+
patches: JsonPatchOperation[];
|
|
44
|
+
changed: boolean;
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
}
|
|
47
|
+
export interface TableChange extends Omit<EditorChange, "document" | "patches"> {
|
|
48
|
+
action: PreparedTableChange["action"];
|
|
49
|
+
tablePath: string;
|
|
50
|
+
document: unknown;
|
|
51
|
+
patches: JsonPatchOperation[];
|
|
52
|
+
changed: boolean;
|
|
53
|
+
[key: string]: unknown;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The table path and cell a selection path points at, or undefined. */
|
|
57
|
+
export declare function parseTableCellPath(path: string): { tablePath: string; cell: Required<TableCellAddress> } | undefined;
|
|
58
|
+
/** Merge rectangles of the table. */
|
|
59
|
+
export declare function tableMerges(table: unknown): TableMerge[];
|
|
60
|
+
/** The state of one cell, including merge anchor/covered status. */
|
|
61
|
+
export declare function describeTableCell(table: unknown, cell: TableCellAddress): TableCellState;
|
|
62
|
+
/** Merge `span.colSpan` x `span.rowSpan` cells from `cell`. `join` keeps the text of covered cells by joining it into the anchor; without it, covered text refuses with `merge-would-lose-content`. */
|
|
63
|
+
export declare function prepareTableMerge(document: unknown, tablePath: string, cell: TableCellAddress, span: { colSpan?: number; rowSpan?: number }, options?: { join?: boolean }): PreparedTableChange;
|
|
64
|
+
export declare function prepareTableSplit(document: unknown, tablePath: string, cell: TableCellAddress): PreparedTableChange;
|
|
65
|
+
/** Merge style fields into the cells' styles (null removes a field, `style: null` clears). */
|
|
66
|
+
export declare function prepareTableCellStyle(document: unknown, tablePath: string, cells: TableCellAddress | TableCellAddress[], style: Record<string, unknown> | null): PreparedTableChange;
|
|
67
|
+
/** Apply `{ header, banding, borders }` (missing fields mean theme/false) or a named preset: sets the header fill, banded-row fill and borders of every cell and clears them elsewhere; `theme` removes a previous style. */
|
|
68
|
+
export declare function prepareTableStyle(document: unknown, tablePath: string, preset: keyof typeof TABLE_STYLE_PRESETS | Partial<TableStyle>): PreparedTableChange;
|
|
69
|
+
/** The current style per axis, or "custom" in every field when the fills and borders are not one this module writes. */
|
|
70
|
+
export declare function readTableStyle(document: unknown, tablePath: string): (TableStyle | { header: "custom"; banding: "custom"; borders: "custom" }) & { preset: keyof typeof TABLE_STYLE_PRESETS | "custom" };
|
|
71
|
+
export declare function mergeTableCells(editor: EditorSession, tablePath: string, cell: TableCellAddress, span: { colSpan?: number; rowSpan?: number }, options?: { join?: boolean; meta?: Record<string, unknown> }): TableChange;
|
|
72
|
+
export declare function splitTableCell(editor: EditorSession, tablePath: string, cell: TableCellAddress, meta?: Record<string, unknown>): TableChange;
|
|
73
|
+
export declare function setTableCellStyle(editor: EditorSession, tablePath: string, cells: TableCellAddress | TableCellAddress[], style: Record<string, unknown> | null, meta?: Record<string, unknown>): TableChange;
|
|
74
|
+
export declare function setTableStyle(editor: EditorSession, tablePath: string, preset: keyof typeof TABLE_STYLE_PRESETS | Partial<TableStyle>, meta?: Record<string, unknown>): TableChange;
|
|
75
|
+
/** {@link readTableStyle} for a table object. */
|
|
76
|
+
export declare function readTableStyleOfTable(table: unknown): (TableStyle | { header: "custom"; banding: "custom"; borders: "custom" }) & { preset: keyof typeof TABLE_STYLE_PRESETS | "custom" };
|
|
77
|
+
/** Apply a table style to a table object in place (the structure operations use it to keep banding, header fill and borders correct). */
|
|
78
|
+
export declare function applyTableStyleToTable(table: unknown, preset: keyof typeof TABLE_STYLE_PRESETS | Partial<TableStyle>): TableStyle;
|
|
79
|
+
// Rows, columns, header row and cell values (RR-24).
|
|
80
|
+
export * from "./table-structure.js";
|