@openpresentation/cli 0.3.0 → 0.4.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/index.js +267 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8163,11 +8163,46 @@ function createDataContent(input, options) {
|
|
|
8163
8163
|
return { chart: { type: options.chartType ?? "column", data: { columns: names, rows: rows2 } } };
|
|
8164
8164
|
}
|
|
8165
8165
|
|
|
8166
|
-
// ../javascript/dist/chunk-
|
|
8166
|
+
// ../javascript/dist/chunk-OVPWNQIJ.js
|
|
8167
|
+
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
8168
|
+
function tableGrid(value, path2 = "table") {
|
|
8169
|
+
const table = record(value), hasHeaders = Array.isArray(table.columns) && table.columns.length > 0;
|
|
8170
|
+
const values = [...hasHeaders ? [table.columns] : [], ...Array.isArray(table.rows) ? table.rows : []];
|
|
8171
|
+
const columnCount = values.reduce((count, row) => Math.max(count, Array.isArray(row) ? row.length : 0), 1), rowCount = values.length;
|
|
8172
|
+
const owners = Array.from({ length: rowCount }, () => Array(columnCount));
|
|
8173
|
+
const rows2 = Array.from({ length: rowCount }, () => []), issues = [];
|
|
8174
|
+
const location = (r, c) => `${path2}.${hasHeaders && r === 0 ? "columns" : `rows.${r - Number(hasHeaders)}`}.${c}`;
|
|
8175
|
+
for (let r = 0; r < rowCount; r++) for (let c = 0; c < columnCount; c++) {
|
|
8176
|
+
const input = values[r]?.[c], cellPath = location(r, c), existing = owners[r][c];
|
|
8177
|
+
if (existing) {
|
|
8178
|
+
if (input !== null) issues.push({ path: cellPath, message: "A position covered by a spanning cell must explicitly contain null; content cannot be hidden." });
|
|
8179
|
+
continue;
|
|
8180
|
+
}
|
|
8181
|
+
const object = record(input), styled = Object.hasOwn(object, "value");
|
|
8182
|
+
const rowSpan = styled ? object.rowSpan ?? 1 : 1, colSpan = styled ? object.colSpan ?? 1 : 1;
|
|
8183
|
+
if (!Number.isSafeInteger(rowSpan) || !Number.isSafeInteger(colSpan) || rowSpan < 1 || colSpan < 1 || r + rowSpan > rowCount || c + colSpan > columnCount || hasHeaders && r === 0 && rowSpan > 1) {
|
|
8184
|
+
issues.push({ path: cellPath, message: "Cell spans must be positive integers within the table grid and cannot cross from headers into body rows." });
|
|
8185
|
+
continue;
|
|
8186
|
+
}
|
|
8187
|
+
const cell2 = { input, value: styled ? object.value : input, style: styled ? record(object.style) : {}, row: r, column: c, rowSpan, colSpan, header: hasHeaders && r === 0, path: cellPath, valuePath: styled ? cellPath + ".value" : cellPath };
|
|
8188
|
+
rows2[r].push(cell2);
|
|
8189
|
+
for (let y = r; y < r + rowSpan; y++) for (let x = c; x < c + colSpan; x++) {
|
|
8190
|
+
if (owners[y][x]) issues.push({ path: cellPath, message: "Cell spans cannot overlap another spanning cell." });
|
|
8191
|
+
else owners[y][x] = cell2;
|
|
8192
|
+
}
|
|
8193
|
+
}
|
|
8194
|
+
return { rows: rows2, columnCount, rowCount, hasHeaders, owners, issues };
|
|
8195
|
+
}
|
|
8196
|
+
function tableRowBoundaries(value) {
|
|
8197
|
+
const grid = tableGrid(value), offset = Number(grid.hasHeaders), count = grid.rowCount - offset;
|
|
8198
|
+
const allowed = new Set(Array.from({ length: count + 1 }, (_, i) => i));
|
|
8199
|
+
for (const row of grid.rows) for (const cell2 of row) if (!cell2.header) for (let r = 1; r < cell2.rowSpan; r++) allowed.delete(cell2.row - offset + r);
|
|
8200
|
+
return [...allowed];
|
|
8201
|
+
}
|
|
8167
8202
|
var MAX_COMPOSITION_DEPTH = 32;
|
|
8168
8203
|
function resolveFontFamilies(input) {
|
|
8169
|
-
const scheme =
|
|
8170
|
-
const family = (value) => typeof value === "string" ? value :
|
|
8204
|
+
const scheme = record2(input);
|
|
8205
|
+
const family = (value) => typeof value === "string" ? value : record2(value).family;
|
|
8171
8206
|
return {
|
|
8172
8207
|
heading: family(scheme.heading) ?? scheme.major ?? scheme.minor ?? "Roboto",
|
|
8173
8208
|
body: family(scheme.body) ?? scheme.minor ?? scheme.major ?? "Roboto",
|
|
@@ -8198,7 +8233,7 @@ var fields = ["text", "items", "bullets", "image", "video", "chart", "table", "c
|
|
|
8198
8233
|
var headings = /* @__PURE__ */ new Set(["title", "subtitle", "tag"]);
|
|
8199
8234
|
var rows = ["top", "middle", "bottom"];
|
|
8200
8235
|
var columns = ["left", "center", "right"];
|
|
8201
|
-
var
|
|
8236
|
+
var record2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
8202
8237
|
var kind = (field) => field === "items" || field === "bullets" ? "list" : field;
|
|
8203
8238
|
var round = (value) => Math.round(value * 1e6) / 1e6 || value;
|
|
8204
8239
|
var textSegments = new Intl.Segmenter("und", { granularity: "grapheme" });
|
|
@@ -8401,53 +8436,61 @@ function fitList(input, box, requestedSize = 25, minFontSize = 16, options = { s
|
|
|
8401
8436
|
function contentText(field, value) {
|
|
8402
8437
|
if (field === "text" || headings.has(field)) return flatten(value);
|
|
8403
8438
|
if (field === "items" || field === "bullets") return (Array.isArray(value) ? value : [value]).map((item) => {
|
|
8404
|
-
const entry =
|
|
8439
|
+
const entry = record2(item);
|
|
8405
8440
|
return `\u2022 ${flatten(item)}${entry.description ? `
|
|
8406
8441
|
${flatten(entry.description)}` : ""}`;
|
|
8407
8442
|
}).join("\n");
|
|
8408
|
-
if (field === "code") return flatten(
|
|
8409
|
-
if (field === "quote") return flatten(
|
|
8443
|
+
if (field === "code") return flatten(record2(value).source ?? value);
|
|
8444
|
+
if (field === "quote") return flatten(record2(value).text ?? value);
|
|
8410
8445
|
return void 0;
|
|
8411
8446
|
}
|
|
8412
8447
|
function layoutTable(value, box, options = {}) {
|
|
8413
8448
|
const scale = options.scale ?? 1, requested = 15 * scale, minimum = (options.minFontSize ?? 16) * scale;
|
|
8414
8449
|
if (![box.x, box.y, box.width, box.height, scale, minimum].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0) throw new RangeError("Table dimensions, scale and font sizes must be finite and positive.");
|
|
8415
|
-
const
|
|
8416
|
-
|
|
8417
|
-
const columnCount =
|
|
8418
|
-
const
|
|
8450
|
+
const grid = tableGrid(value, options.path ?? "table");
|
|
8451
|
+
if (grid.issues.length) throw new RangeError(`${grid.issues[0].path}: ${grid.issues[0].message}`);
|
|
8452
|
+
const columnCount = grid.columnCount, cellWidth = box.width / columnCount;
|
|
8453
|
+
const cells = grid.rows.flat().map((cell2) => {
|
|
8454
|
+
const padding = { top: 8, right: 10, bottom: 4, left: 10, ...cell2.style.padding };
|
|
8455
|
+
const width = cellWidth * cell2.colSpan - (padding.left + padding.right) * scale;
|
|
8456
|
+
const style = { fontFamily: options.fontFamily ?? "sans-serif", fontWeight: cell2.header ? 700 : 400, italic: false, path: cell2.valuePath };
|
|
8457
|
+
return { ...cell2, padding, width, textStyle: style };
|
|
8458
|
+
});
|
|
8419
8459
|
const fitCell = (cell2, height, min) => {
|
|
8420
|
-
const textBox = { width, height: Math.max(scale, height) };
|
|
8421
|
-
return Array.isArray(cell2.value) ? fitRichText(cell2.value, textBox, requested, min, { style: cell2.
|
|
8460
|
+
const textBox = { width: Math.max(scale, cell2.width), height: Math.max(scale, height) };
|
|
8461
|
+
return Array.isArray(cell2.value) ? fitRichText(cell2.value, textBox, requested, min, { style: cell2.textStyle, textMeasurement: options.textMeasurement, uniformLineHeight: true }) : fitText(flatten(cell2.value), textBox, requested, min, textWidthMeasurer(resolveTextStyle(cell2.textStyle, options.textMeasurement), options.textMeasurement));
|
|
8422
8462
|
};
|
|
8423
8463
|
const textHeight = (fit) => "height" in fit ? fit.height : fit.lines.length * fit.lineHeight;
|
|
8424
|
-
const
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
const
|
|
8432
|
-
const
|
|
8433
|
-
|
|
8434
|
-
}
|
|
8435
|
-
const preferred =
|
|
8436
|
-
let
|
|
8437
|
-
const
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8464
|
+
const required = (cell2, size) => textHeight(fitCell(cell2, scale, size)) + (cell2.padding.top + cell2.padding.bottom) * scale;
|
|
8465
|
+
const natural = Array(grid.rowCount).fill(0), needed = Array(grid.rowCount).fill(0);
|
|
8466
|
+
for (const cell2 of cells) if (cell2.rowSpan === 1) {
|
|
8467
|
+
natural[cell2.row] = Math.max(natural[cell2.row], required(cell2, requested));
|
|
8468
|
+
needed[cell2.row] = Math.max(needed[cell2.row], required(cell2, minimum));
|
|
8469
|
+
}
|
|
8470
|
+
for (const cell2 of cells) if (cell2.rowSpan > 1) for (const [heights2, size] of [[natural, requested], [needed, minimum]]) {
|
|
8471
|
+
const current = heights2.slice(cell2.row, cell2.row + cell2.rowSpan).reduce((a, b) => a + b, 0);
|
|
8472
|
+
const extra = Math.max(0, required(cell2, size) - current) / cell2.rowSpan;
|
|
8473
|
+
for (let r = cell2.row; r < cell2.row + cell2.rowSpan; r++) heights2[r] += extra;
|
|
8474
|
+
}
|
|
8475
|
+
const preferred = natural.map((height) => Math.max(54 * scale, height));
|
|
8476
|
+
for (let r = 0; r < needed.length; r++) needed[r] = Math.min(preferred[r], needed[r]);
|
|
8477
|
+
const sum = (values) => values.reduce((a, b) => a + b, 0);
|
|
8478
|
+
const preferredTotal = sum(preferred), naturalTotal = sum(natural), neededTotal = sum(needed);
|
|
8479
|
+
const heights = preferred.map((height, r) => preferredTotal <= box.height ? height : naturalTotal <= box.height ? natural[r] + (height - natural[r]) * (box.height - naturalTotal) / Math.max(Number.EPSILON, preferredTotal - naturalTotal) : neededTotal <= box.height ? needed[r] + (natural[r] - needed[r]) * (box.height - neededTotal) / Math.max(Number.EPSILON, naturalTotal - neededTotal) : needed[r] * box.height / neededTotal);
|
|
8480
|
+
const ys = [box.y];
|
|
8481
|
+
for (const height of heights) ys.push(ys.at(-1) + height);
|
|
8482
|
+
let overflow = false;
|
|
8483
|
+
const rows2 = heights.map((height, r) => ({ box: { x: box.x, y: ys[r], width: box.width, height }, cells: [] }));
|
|
8484
|
+
for (const cell2 of cells) {
|
|
8485
|
+
const cellBox = { x: box.x + cell2.column * cellWidth, y: ys[cell2.row], width: cell2.colSpan * cellWidth, height: ys[cell2.row + cell2.rowSpan] - ys[cell2.row] };
|
|
8486
|
+
const available = cellBox.height - (cell2.padding.top + cell2.padding.bottom) * scale;
|
|
8487
|
+
const fit = fitCell(cell2, available, minimum), height = textHeight(fit);
|
|
8488
|
+
const offset = cell2.style.verticalAlign === "bottom" ? Math.max(0, available - height) : cell2.style.verticalAlign === "middle" ? Math.max(0, (available - height) / 2) : 0;
|
|
8489
|
+
const textBox = { x: cellBox.x + cell2.padding.left * scale, y: cellBox.y + cell2.padding.top * scale + offset, width: Math.max(scale, cell2.width), height: Math.max(scale, available - offset) };
|
|
8490
|
+
overflow ||= cell2.width <= 0 || available <= 0 || fit.overflow;
|
|
8491
|
+
rows2[cell2.row].cells.push({ value: cell2.value, input: cell2.input, path: cell2.valuePath, sourcePath: cell2.path, style: cell2.style, row: cell2.row, column: cell2.column, rowSpan: cell2.rowSpan, colSpan: cell2.colSpan, header: cell2.header, rich: Array.isArray(cell2.value), box: cellBox, textBox, textStyle: resolveTextStyle(cell2.textStyle, options.textMeasurement), fit });
|
|
8492
|
+
}
|
|
8493
|
+
return { rows: rows2, columnCount, height: sum(heights), overflow };
|
|
8451
8494
|
}
|
|
8452
8495
|
function tableOverflows(value, box, scale, settings, options, path2) {
|
|
8453
8496
|
return box.width <= 0 || box.height <= 0 || layoutTable(value, box, { scale, minFontSize: settings.minFontSize, fontFamily: options.fonts?.body, textMeasurement: options.textMeasurement, path: path2 }).overflow;
|
|
@@ -8456,7 +8499,7 @@ function flatten(value) {
|
|
|
8456
8499
|
if (value == null) return "";
|
|
8457
8500
|
if (typeof value !== "object") return String(value);
|
|
8458
8501
|
if (Array.isArray(value)) return value.map(flatten).join("");
|
|
8459
|
-
const item =
|
|
8502
|
+
const item = record2(value);
|
|
8460
8503
|
return flatten(item.text ?? item.value ?? item.source ?? JSON.stringify(value));
|
|
8461
8504
|
}
|
|
8462
8505
|
function regionParts(key) {
|
|
@@ -8512,11 +8555,11 @@ function assertComposition(value) {
|
|
|
8512
8555
|
if (value.overflow !== void 0 && !["warn", "error"].includes(value.overflow)) throw new RangeError("Invalid composition.overflow.");
|
|
8513
8556
|
}
|
|
8514
8557
|
function composeSlide(input, options = {}) {
|
|
8515
|
-
const slide =
|
|
8558
|
+
const slide = record2(input), layout2 = record2(options.layout);
|
|
8516
8559
|
const width = options.width ?? 1280, height = options.height ?? 720;
|
|
8517
8560
|
if (![width, height].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("Canvas dimensions must be finite and positive.");
|
|
8518
8561
|
const scale = Math.min(width, height) / 720;
|
|
8519
|
-
const composition = { ...
|
|
8562
|
+
const composition = { ...record2(layout2.composition), ...record2(slide.composition) };
|
|
8520
8563
|
assertComposition(composition);
|
|
8521
8564
|
const padding = (composition.padding ?? 0.08) * Math.min(width, height);
|
|
8522
8565
|
const gap = (composition.gap ?? 1 / 30) * Math.min(width, height);
|
|
@@ -8546,7 +8589,7 @@ function composeSlide(input, options = {}) {
|
|
|
8546
8589
|
const collect = (host, basePath, depth = 0, ancestors = []) => {
|
|
8547
8590
|
if (Array.isArray(host.blocks)) {
|
|
8548
8591
|
if (depth >= MAX_COMPOSITION_DEPTH || ancestors.includes(host)) throw new RangeError(`Content groups must be acyclic and nest at most ${MAX_COMPOSITION_DEPTH} levels.`);
|
|
8549
|
-
const settings =
|
|
8592
|
+
const settings = record2(host.composition);
|
|
8550
8593
|
assertComposition(settings);
|
|
8551
8594
|
return [{
|
|
8552
8595
|
field: "blocks",
|
|
@@ -8555,13 +8598,13 @@ function composeSlide(input, options = {}) {
|
|
|
8555
8598
|
path: basePath,
|
|
8556
8599
|
payload: host,
|
|
8557
8600
|
composition: settings,
|
|
8558
|
-
children: host.blocks.flatMap((block, index2) => collect(
|
|
8601
|
+
children: host.blocks.flatMap((block, index2) => collect(record2(block), `${basePath}.blocks.${index2}`, depth + 1, [...ancestors, host]))
|
|
8559
8602
|
}];
|
|
8560
8603
|
}
|
|
8561
8604
|
return fields.filter((field) => host[field] !== void 0).map((field) => ({ field, type: host.type ?? kind(field), value: host[field], path: `${basePath}.${field}`, payload: { type: host.type ?? kind(field), [field]: host[field] } }));
|
|
8562
8605
|
};
|
|
8563
8606
|
const regions = Object.keys(slide).filter((key) => regionParts(key)).sort();
|
|
8564
|
-
const pending = regions.length ? regions.flatMap((key) => collect(
|
|
8607
|
+
const pending = regions.length ? regions.flatMap((key) => collect(record2(slide[key]), `${path2}.${key}`).map((item) => ({ ...item, region: regionParts(key) }))) : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index2) => collect(record2(block), `${path2}.blocks.${index2}`)) : collect(slide, path2);
|
|
8565
8608
|
const groups = [], flows = [];
|
|
8566
8609
|
const inheritedSettings = (parent, own3 = {}) => ({
|
|
8567
8610
|
minFontSize: parent.minFontSize,
|
|
@@ -8653,7 +8696,7 @@ function resolveCanvasDimensions(input) {
|
|
|
8653
8696
|
letter: [11, 8.5],
|
|
8654
8697
|
a4: [11.69, 8.27]
|
|
8655
8698
|
};
|
|
8656
|
-
const value =
|
|
8699
|
+
const value = record2(input);
|
|
8657
8700
|
const preset = presets[typeof input === "string" ? input : value.preset] ?? presets.widescreen;
|
|
8658
8701
|
const width = (value.widthInches ?? preset[0]) * 96;
|
|
8659
8702
|
const height = (value.heightInches ?? preset[1]) * 96;
|
|
@@ -8661,7 +8704,7 @@ function resolveCanvasDimensions(input) {
|
|
|
8661
8704
|
return { width, height };
|
|
8662
8705
|
}
|
|
8663
8706
|
|
|
8664
|
-
// ../javascript/dist/chunk-
|
|
8707
|
+
// ../javascript/dist/chunk-GQSK3T7X.js
|
|
8665
8708
|
var presentation = {
|
|
8666
8709
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
8667
8710
|
"$id": "https://openpresentation.org/schema/opf/v1",
|
|
@@ -12351,10 +12394,16 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
|
|
|
12351
12394
|
"items": {
|
|
12352
12395
|
"$ref": "#/$defs/TextRun"
|
|
12353
12396
|
}
|
|
12397
|
+
},
|
|
12398
|
+
{
|
|
12399
|
+
"$ref": "#/$defs/StyledTableCell"
|
|
12400
|
+
},
|
|
12401
|
+
{
|
|
12402
|
+
"type": "null"
|
|
12354
12403
|
}
|
|
12355
12404
|
]
|
|
12356
12405
|
},
|
|
12357
|
-
"description": "Optional column labels
|
|
12406
|
+
"description": "Optional column labels. Labels may be strings, rich runs or styled cell objects. Null is an empty label or a placeholder covered by a preceding column span.",
|
|
12358
12407
|
"examples": [
|
|
12359
12408
|
[
|
|
12360
12409
|
"Region",
|
|
@@ -12525,6 +12574,17 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
|
|
|
12525
12574
|
"description": "A cell in inline chart data."
|
|
12526
12575
|
},
|
|
12527
12576
|
"TableCell": {
|
|
12577
|
+
"oneOf": [
|
|
12578
|
+
{
|
|
12579
|
+
"$ref": "#/$defs/TableCellValue"
|
|
12580
|
+
},
|
|
12581
|
+
{
|
|
12582
|
+
"$ref": "#/$defs/StyledTableCell"
|
|
12583
|
+
}
|
|
12584
|
+
],
|
|
12585
|
+
"description": "A scalar, rich-run array, or styled/spanning cell object. Existing scalar and rich forms remain valid."
|
|
12586
|
+
},
|
|
12587
|
+
"TableCellValue": {
|
|
12528
12588
|
"oneOf": [
|
|
12529
12589
|
{
|
|
12530
12590
|
"type": "string"
|
|
@@ -12545,7 +12605,149 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
|
|
|
12545
12605
|
}
|
|
12546
12606
|
}
|
|
12547
12607
|
],
|
|
12548
|
-
"description": "A
|
|
12608
|
+
"description": "A scalar table value or canonical rich text runs, without cell decoration or geometry."
|
|
12609
|
+
},
|
|
12610
|
+
"StyledTableCell": {
|
|
12611
|
+
"type": "object",
|
|
12612
|
+
"additionalProperties": false,
|
|
12613
|
+
"required": [
|
|
12614
|
+
"value"
|
|
12615
|
+
],
|
|
12616
|
+
"properties": {
|
|
12617
|
+
"value": {
|
|
12618
|
+
"$ref": "#/$defs/TableCellValue",
|
|
12619
|
+
"description": "Editable cell content; styling and spans do not change its scalar type or rich runs."
|
|
12620
|
+
},
|
|
12621
|
+
"style": {
|
|
12622
|
+
"$ref": "#/$defs/TableCellStyle"
|
|
12623
|
+
},
|
|
12624
|
+
"colSpan": {
|
|
12625
|
+
"type": "integer",
|
|
12626
|
+
"minimum": 1,
|
|
12627
|
+
"description": "Number of grid columns covered, starting at this cell. Covered positions must contain null. Default 1."
|
|
12628
|
+
},
|
|
12629
|
+
"rowSpan": {
|
|
12630
|
+
"type": "integer",
|
|
12631
|
+
"minimum": 1,
|
|
12632
|
+
"description": "Number of grid rows covered, starting at this cell. Covered positions must contain null. Header cells cannot span into body rows. Default 1."
|
|
12633
|
+
}
|
|
12634
|
+
},
|
|
12635
|
+
"description": "A cell with explicit visual style or merged geometry. Its position remains its array column index; use null placeholders for every covered grid position."
|
|
12636
|
+
},
|
|
12637
|
+
"TableCellStyle": {
|
|
12638
|
+
"type": "object",
|
|
12639
|
+
"additionalProperties": false,
|
|
12640
|
+
"properties": {
|
|
12641
|
+
"fill": {
|
|
12642
|
+
"type": "string",
|
|
12643
|
+
"pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
|
|
12644
|
+
"description": "Explicit RGB or RGBA color. Eight-digit colors include alpha; #00000000 is transparent."
|
|
12645
|
+
},
|
|
12646
|
+
"color": {
|
|
12647
|
+
"type": "string",
|
|
12648
|
+
"pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
|
|
12649
|
+
"description": "Default text color, overridden by individual rich run colors."
|
|
12650
|
+
},
|
|
12651
|
+
"align": {
|
|
12652
|
+
"type": "string",
|
|
12653
|
+
"enum": [
|
|
12654
|
+
"left",
|
|
12655
|
+
"center",
|
|
12656
|
+
"right"
|
|
12657
|
+
],
|
|
12658
|
+
"description": "Horizontal text alignment inside the cell."
|
|
12659
|
+
},
|
|
12660
|
+
"verticalAlign": {
|
|
12661
|
+
"type": "string",
|
|
12662
|
+
"enum": [
|
|
12663
|
+
"top",
|
|
12664
|
+
"middle",
|
|
12665
|
+
"bottom"
|
|
12666
|
+
],
|
|
12667
|
+
"description": "Vertical alignment inside the padded cell box."
|
|
12668
|
+
},
|
|
12669
|
+
"padding": {
|
|
12670
|
+
"$ref": "#/$defs/TableCellPadding"
|
|
12671
|
+
},
|
|
12672
|
+
"borders": {
|
|
12673
|
+
"type": "object",
|
|
12674
|
+
"additionalProperties": false,
|
|
12675
|
+
"properties": {
|
|
12676
|
+
"top": {
|
|
12677
|
+
"$ref": "#/$defs/TableCellBorder"
|
|
12678
|
+
},
|
|
12679
|
+
"right": {
|
|
12680
|
+
"$ref": "#/$defs/TableCellBorder"
|
|
12681
|
+
},
|
|
12682
|
+
"bottom": {
|
|
12683
|
+
"$ref": "#/$defs/TableCellBorder"
|
|
12684
|
+
},
|
|
12685
|
+
"left": {
|
|
12686
|
+
"$ref": "#/$defs/TableCellBorder"
|
|
12687
|
+
}
|
|
12688
|
+
},
|
|
12689
|
+
"description": "Independent cell edges. Omitted edges retain the table theme border; width 0 removes an edge."
|
|
12690
|
+
}
|
|
12691
|
+
},
|
|
12692
|
+
"description": "Cell appearance. Sizes use reference pixels at a 720-pixel canvas short edge and scale with the slide."
|
|
12693
|
+
},
|
|
12694
|
+
"TableCellPadding": {
|
|
12695
|
+
"type": "object",
|
|
12696
|
+
"additionalProperties": false,
|
|
12697
|
+
"properties": {
|
|
12698
|
+
"top": {
|
|
12699
|
+
"type": "number",
|
|
12700
|
+
"minimum": 0,
|
|
12701
|
+
"maximum": 200
|
|
12702
|
+
},
|
|
12703
|
+
"right": {
|
|
12704
|
+
"type": "number",
|
|
12705
|
+
"minimum": 0,
|
|
12706
|
+
"maximum": 200
|
|
12707
|
+
},
|
|
12708
|
+
"bottom": {
|
|
12709
|
+
"type": "number",
|
|
12710
|
+
"minimum": 0,
|
|
12711
|
+
"maximum": 200
|
|
12712
|
+
},
|
|
12713
|
+
"left": {
|
|
12714
|
+
"type": "number",
|
|
12715
|
+
"minimum": 0,
|
|
12716
|
+
"maximum": 200
|
|
12717
|
+
}
|
|
12718
|
+
},
|
|
12719
|
+
"description": "Text insets in reference pixels. Defaults: top 8, right 10, bottom 4, left 10."
|
|
12720
|
+
},
|
|
12721
|
+
"TableCellBorder": {
|
|
12722
|
+
"type": "object",
|
|
12723
|
+
"additionalProperties": false,
|
|
12724
|
+
"required": [
|
|
12725
|
+
"color",
|
|
12726
|
+
"width"
|
|
12727
|
+
],
|
|
12728
|
+
"properties": {
|
|
12729
|
+
"color": {
|
|
12730
|
+
"type": "string",
|
|
12731
|
+
"pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
|
|
12732
|
+
"description": "Explicit RGB or RGBA color. Eight-digit colors include alpha; #00000000 is transparent."
|
|
12733
|
+
},
|
|
12734
|
+
"width": {
|
|
12735
|
+
"type": "number",
|
|
12736
|
+
"minimum": 0,
|
|
12737
|
+
"maximum": 32,
|
|
12738
|
+
"description": "Border width in reference pixels; 0 removes this edge."
|
|
12739
|
+
},
|
|
12740
|
+
"dash": {
|
|
12741
|
+
"type": "string",
|
|
12742
|
+
"enum": [
|
|
12743
|
+
"solid",
|
|
12744
|
+
"dash",
|
|
12745
|
+
"dot"
|
|
12746
|
+
],
|
|
12747
|
+
"description": "Default solid."
|
|
12748
|
+
}
|
|
12749
|
+
},
|
|
12750
|
+
"description": "One explicit cell border."
|
|
12549
12751
|
},
|
|
12550
12752
|
"Catalogs": {
|
|
12551
12753
|
"type": "object",
|
|
@@ -33739,7 +33941,7 @@ var catalogEntries = [
|
|
|
33739
33941
|
], records: fontSchemes, index: catalogIndexes.fontSchemes }
|
|
33740
33942
|
];
|
|
33741
33943
|
|
|
33742
|
-
// ../javascript/dist/chunk-
|
|
33944
|
+
// ../javascript/dist/chunk-H7UXKXEJ.js
|
|
33743
33945
|
var import__ = __toESM(require__(), 1);
|
|
33744
33946
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
33745
33947
|
var catalogIds = {
|
|
@@ -34537,6 +34739,14 @@ function validatePresentationSemantics(value) {
|
|
|
34537
34739
|
slideIds.add(slide.id);
|
|
34538
34740
|
}
|
|
34539
34741
|
issues.push(...validateSlideRegions(slide, `/slides/${index2}`));
|
|
34742
|
+
const visitTables = (node, path2) => {
|
|
34743
|
+
if (isRecord(node.table)) for (const issue of tableGrid(node.table).issues) issues.push(semanticIssue(pathFor(path2, "table") + issue.path.slice(5).replaceAll(".", "/"), issue.message));
|
|
34744
|
+
if (Array.isArray(node.blocks)) node.blocks.forEach((block, i) => {
|
|
34745
|
+
if (isRecord(block)) visitTables(block, `${path2}/blocks/${i}`);
|
|
34746
|
+
});
|
|
34747
|
+
for (const key of promotedRegionKeys) if (isRecord(node[key])) visitTables(node[key], pathFor(path2, key));
|
|
34748
|
+
};
|
|
34749
|
+
visitTables(slide, `/slides/${index2}`);
|
|
34540
34750
|
}
|
|
34541
34751
|
});
|
|
34542
34752
|
return issues;
|
|
@@ -34557,7 +34767,7 @@ function unknownIdWarning(kind2, value, path2, context) {
|
|
|
34557
34767
|
if (context) {
|
|
34558
34768
|
const entry = inlineCatalogEntry(context, kind2);
|
|
34559
34769
|
if (entry) {
|
|
34560
|
-
if (Array.isArray(entry.records) && entry.records.some((
|
|
34770
|
+
if (Array.isArray(entry.records) && entry.records.some((record3) => isRecord(record3) && record3.id === value)) {
|
|
34561
34771
|
return void 0;
|
|
34562
34772
|
}
|
|
34563
34773
|
if (typeof entry.source === "string") {
|
|
@@ -34733,7 +34943,7 @@ function assertValidPresentation(value) {
|
|
|
34733
34943
|
assertValid(value, "presentation");
|
|
34734
34944
|
}
|
|
34735
34945
|
|
|
34736
|
-
// ../javascript/dist/chunk-
|
|
34946
|
+
// ../javascript/dist/chunk-IQ727X3E.js
|
|
34737
34947
|
var OPFPaginationError = class extends Error {
|
|
34738
34948
|
constructor(message, diagnostics = []) {
|
|
34739
34949
|
super(message);
|
|
@@ -34783,7 +34993,7 @@ function leafFor(path2, field, value) {
|
|
|
34783
34993
|
const values = Array.isArray(value) ? value : value[key];
|
|
34784
34994
|
if (Array.isArray(values)) {
|
|
34785
34995
|
leaf.unit = "items";
|
|
34786
|
-
leaf.boundaries = Array.from({ length: values.length + 1 }, (_, i) => i);
|
|
34996
|
+
leaf.boundaries = field === "table" ? tableRowBoundaries(value) : Array.from({ length: values.length + 1 }, (_, i) => i);
|
|
34787
34997
|
leaf.slice = (a, b) => Array.isArray(value) ? value.slice(a, b) : { ...value, [key]: values.slice(a, b) };
|
|
34788
34998
|
}
|
|
34789
34999
|
}
|
|
@@ -34931,7 +35141,7 @@ function paginatePresentation(input, options = {}) {
|
|
|
34931
35141
|
if (!Number.isInteger(maxSlides) || maxSlides < 1 || maxSlides > 1e4) throw new RangeError("maxSlides must be an integer between 1 and 10000.");
|
|
34932
35142
|
const output = [], pages = [];
|
|
34933
35143
|
const reservedIds = presentation2.slides.map((slide) => slide.id).filter(Boolean);
|
|
34934
|
-
const resolve = (kind2, id) => presentation2.catalogs?.[kind2]?.records?.find((
|
|
35144
|
+
const resolve = (kind2, id) => presentation2.catalogs?.[kind2]?.records?.find((record3) => record3.id === id) ?? catalogs[kind2].find((record3) => record3.id === id);
|
|
34935
35145
|
presentation2.slides.forEach((slide, index2) => {
|
|
34936
35146
|
const overrides = options.slideOptions?.(slide, index2) ?? {};
|
|
34937
35147
|
const layout2 = overrides.layout ?? (slide.layout ? resolve("layouts", slide.layout) : void 0);
|
|
@@ -35173,7 +35383,7 @@ async function main(argv) {
|
|
|
35173
35383
|
return;
|
|
35174
35384
|
}
|
|
35175
35385
|
if (argv.length === 1 && argv[0] === "--version") {
|
|
35176
|
-
print({ cli: "0.
|
|
35386
|
+
print({ cli: "0.4.0", opf: "0.7.0" });
|
|
35177
35387
|
return;
|
|
35178
35388
|
}
|
|
35179
35389
|
const [command, ...args] = argv;
|
|
@@ -35285,7 +35495,7 @@ async function main(argv) {
|
|
|
35285
35495
|
arity(args, 1, 2);
|
|
35286
35496
|
const entry = catalogEntries.find((entry2) => entry2.kind === args[0]);
|
|
35287
35497
|
if (!entry) throw new CliError("Unknown catalog. Run opf catalogs.");
|
|
35288
|
-
const result = args[1] === void 0 ? entry.records : entry.records.find((
|
|
35498
|
+
const result = args[1] === void 0 ? entry.records : entry.records.find((record3) => record3.id === args[1]);
|
|
35289
35499
|
if (!result) throw new CliError(`Unknown ${args[0]} id: ${args[1]}`);
|
|
35290
35500
|
print(result);
|
|
35291
35501
|
return;
|