@openpresentation/opf 0.16.0 → 0.17.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 +16 -2
- package/dist/{catalog-refs-_anZs-Qz.d.ts → catalog-refs-C4K4y-vh.d.ts} +1 -1
- package/dist/{catalog-schemas-BZCjgAxu.d.ts → catalog-schemas-g7RFQBdc.d.ts} +1 -1
- package/dist/catalog.d.ts +2 -2
- package/dist/catalog.js +3 -23712
- package/dist/{chart-data-BnNqgnC-.d.ts → chart-data-DTxdRRT1.d.ts} +1 -1
- package/dist/{chunk-FQSIIADJ.js → chunk-BIC3SWPK.js} +4 -4
- package/dist/{chunk-5PDN7BN6.js → chunk-CW7GEAV3.js} +151 -49
- package/dist/{chunk-NAWQR7MN.js → chunk-ESRYBYLY.js} +1 -1
- package/dist/chunk-IPW5BS3X.js +973 -0
- package/dist/{chunk-5UEUAW57.js → chunk-IS5H5JKH.js} +1 -1
- package/dist/{chunk-UM24JFUE.js → chunk-M4UR3NPN.js} +2 -2
- package/dist/{chunk-KINQFU6X.js → chunk-N4EVOFEA.js} +19 -12
- package/dist/{chunk-PX5AWL7Y.js → chunk-NLNYNBTS.js} +79 -10
- package/dist/{chunk-SMLMI6IZ.js → chunk-O263APNI.js} +1 -1
- package/dist/{chunk-BSYQDWT4.js → chunk-O2CX5NEH.js} +26 -14
- package/dist/{chunk-3XDRQYWZ.js → chunk-O3CVNJTL.js} +1 -1
- package/dist/{chunk-5TO6I3GB.js → chunk-PPROJP2E.js} +1 -1
- package/dist/{chunk-WEDGVC5W.js → chunk-RA64UQKI.js} +18 -42
- package/dist/{chunk-K4DQQIT4.js → chunk-TCD2FB2K.js} +5 -5
- package/dist/chunk-WCG3THTD.js +23712 -0
- package/dist/chunk-WWYWFVOI.js +793 -0
- package/dist/{chunk-6OR326EA.js → chunk-YT7FMQER.js} +1 -1
- package/dist/{composition-D4ADF5c-.d.ts → composition-BbZ_9C-c.d.ts} +152 -132
- package/dist/composition.d.ts +3 -3
- package/dist/composition.js +1 -1
- package/dist/conversion-SBpTOwdg.d.ts +444 -0
- package/dist/convert.d.ts +4 -4
- package/dist/convert.js +7 -7
- package/dist/data.d.ts +2 -2
- package/dist/data.js +2 -2
- package/dist/deck-report-Bx3naFlF.d.ts +40 -0
- package/dist/deck.d.ts +23 -53
- package/dist/deck.js +10 -10
- package/dist/diff.d.ts +1 -1
- package/dist/diff.js +5 -5
- package/dist/docs.js +29 -23
- package/dist/examples.d.ts +1 -1
- package/dist/examples.js +237 -237
- package/dist/{finding-CT_f_vbD.d.ts → finding-CDQ_wH8j.d.ts} +1 -1
- package/dist/format.js +2 -2
- package/dist/index.d.ts +42 -12
- package/dist/index.js +15 -807
- package/dist/markdown.d.ts +6 -6
- package/dist/markdown.js +7 -7
- package/dist/node-engine.d.ts +94 -0
- package/dist/node-engine.js +21 -0
- package/dist/node.d.ts +60 -0
- package/dist/node.js +54 -0
- package/dist/{pagination-DzZPFheM.d.ts → pagination-BhX4M48Y.d.ts} +21 -7
- package/dist/pagination.d.ts +4 -4
- package/dist/pagination.js +4 -4
- package/dist/patch.d.ts +1 -1
- package/dist/patch.js +4 -4
- package/dist/{presentation-COrFuj2g.d.ts → presentation-fb8CZmRq.d.ts} +12 -75
- package/dist/repo-readme.js +1 -1
- package/dist/schemas.js +1 -1
- package/dist/spec/catalogs/manifest.json +1 -1
- package/dist/spec/schemas/opf.schema.json +16 -37
- package/dist/types.d.ts +3 -3
- package/dist/{validation-types-HxIgJfKx.d.ts → validation-types-iZbXfES6.d.ts} +19 -8
- package/dist/validator.d.ts +8 -8
- package/dist/validator.js +3 -3
- package/dist/yaml.d.ts +6 -6
- package/dist/yaml.js +7 -7
- package/package.json +34 -1
|
@@ -185,4 +185,4 @@ declare function resolveTableData(table: unknown, document?: unknown, options?:
|
|
|
185
185
|
/** Display value of a table cell: a number with a format (cell, else column) becomes formatted text; anything else is returned unchanged. */
|
|
186
186
|
declare function tableCellDisplayValue(cell: DataTableCell, columnFormat?: string): DataTableCell;
|
|
187
187
|
|
|
188
|
-
export {
|
|
188
|
+
export { numberFormatError as A, resolveChartData as B, type ChartComboSeries as C, type DataCellValue as D, resolveTableData as E, suggestChartNumberFix as F, tableCellDisplayValue as G, toExcelNumberFormat as H, unusedDatasets as I, type ResolvedChartData as R, type ChartMapping as a, type ChartNumberFix as b, type ChartNumberFixOperation as c, type ChartNumberFixOptions as d, type DataColumn as e, type DataDiagnostic as f, type DataDiagnosticCode as g, type DataResolveOptions as h, type DataSourceRef as i, type DataStyledCell as j, type DataTableCell as k, type DataTableHeader as l, type DataTableValue as m, type DataTextRun as n, type Dataset as o, type DatasetRef as p, type ResolvedTableData as q, chartNumber as r, datasetDiagnostics as s, formatDataNumber as t, fromExcelNumberFormat as u, inlineChartData as v, inlineDatasets as w, inlineTableData as x, isDatasetRef as y, isXYChartType as z };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Ctx, splitLines, lineRange, readYamlMapping, NOT_CHECKED, OPFMarkdownError, writeYaml, readCsv, DECIMAL, csvField, scalarText } from './chunk-
|
|
2
|
-
import { parseQuoteLines, levelsFromIndents, parseCodeFence, splitWhen, fenceCode } from './chunk-
|
|
3
|
-
import { same, isRecord, runText, isPlainRun, FORMATTING } from './chunk-
|
|
4
|
-
import { validate } from './chunk-
|
|
1
|
+
import { Ctx, splitLines, lineRange, readYamlMapping, NOT_CHECKED, OPFMarkdownError, writeYaml, readCsv, DECIMAL, csvField, scalarText } from './chunk-IS5H5JKH.js';
|
|
2
|
+
import { parseQuoteLines, levelsFromIndents, parseCodeFence, splitWhen, fenceCode } from './chunk-ESRYBYLY.js';
|
|
3
|
+
import { same, isRecord, runText, isPlainRun, FORMATTING } from './chunk-PPROJP2E.js';
|
|
4
|
+
import { validate } from './chunk-NLNYNBTS.js';
|
|
5
5
|
import { checkCatalogsOption } from './chunk-SPFV27O5.js';
|
|
6
6
|
|
|
7
7
|
// src/markdown/canon.ts
|
|
@@ -319,7 +319,6 @@ function visitContentPayloads(slide, slidePath, visit) {
|
|
|
319
319
|
|
|
320
320
|
// src/furniture-fields.ts
|
|
321
321
|
var DEFAULT_FURNITURE_DATE_FORMAT = "M/d/yyyy";
|
|
322
|
-
var DEFAULT_SLIDE_NUMBER_FORMAT = "{current}";
|
|
323
322
|
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
324
323
|
var weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
325
324
|
var tokenWidths = { y: [1, 2, 4], M: [1, 2, 3, 4], d: [1, 2], E: [1, 2, 3, 4] };
|
|
@@ -407,21 +406,6 @@ function formatFurnitureDate(iso, pattern) {
|
|
|
407
406
|
}
|
|
408
407
|
return { text: text2 };
|
|
409
408
|
}
|
|
410
|
-
function formatSlideNumber(format, current, total) {
|
|
411
|
-
if (!format.includes("{current}")) return { error: "slideNumberFormat must contain {current}." };
|
|
412
|
-
if (format.includes("{total}") && total === void 0) return { error: "slideNumberFormat uses {total}, which needs the rendered slide count." };
|
|
413
|
-
let text2 = "";
|
|
414
|
-
const fields2 = [];
|
|
415
|
-
for (const piece of format.split(/(\{current\}|\{total\})/)) {
|
|
416
|
-
if (piece === "{current}") {
|
|
417
|
-
const value = String(current);
|
|
418
|
-
fields2.push({ type: "slideNumber", start: text2.length, end: text2.length + value.length });
|
|
419
|
-
text2 += value;
|
|
420
|
-
} else if (piece === "{total}") text2 += String(total);
|
|
421
|
-
else text2 += piece;
|
|
422
|
-
}
|
|
423
|
-
return { text: text2, fields: fields2 };
|
|
424
|
-
}
|
|
425
409
|
|
|
426
410
|
// src/deck-metadata.ts
|
|
427
411
|
function recordsOf(value) {
|
|
@@ -441,6 +425,111 @@ function primaryOrganization(presentation) {
|
|
|
441
425
|
return organizations.find((item) => item.role === "primary") ?? organizations[0];
|
|
442
426
|
}
|
|
443
427
|
|
|
428
|
+
// src/slide-variables.ts
|
|
429
|
+
var SLIDE_SCOPED_BUILTINS = ["slide.number", "slide.section", "deck.slideCount"];
|
|
430
|
+
function isSlideScopedBuiltin(name) {
|
|
431
|
+
return SLIDE_SCOPED_BUILTINS.includes(name);
|
|
432
|
+
}
|
|
433
|
+
function isSlideScopedName(name) {
|
|
434
|
+
return name === "deck.slideCount" || name.startsWith("slide.");
|
|
435
|
+
}
|
|
436
|
+
var SLIDE_TOKEN_BODY = String.raw`\s*(?:slide(?:\.[A-Za-z0-9_-]+){1,2}|deck\.slideCount)\s*(?:\|[^{}]*)?\}\}`;
|
|
437
|
+
var slideTokenAhead = new RegExp(`^${SLIDE_TOKEN_BODY}`);
|
|
438
|
+
var slideTokenPattern = new RegExp(String.raw`\\\{\{(?=${SLIDE_TOKEN_BODY})|\{\{\s*(slide\.number|slide\.section|deck\.slideCount)\s*(?:\|[^{}]*)?\}\}`, "g");
|
|
439
|
+
var slideTokenSpanPattern = new RegExp(String.raw`\\?\{\{${SLIDE_TOKEN_BODY}`, "g");
|
|
440
|
+
var quickCheck = /\{\{\s*(?:slide\.|deck\.slideCount)/;
|
|
441
|
+
function slideTokenFollows(text2) {
|
|
442
|
+
return slideTokenAhead.test(text2);
|
|
443
|
+
}
|
|
444
|
+
function checkValues(values) {
|
|
445
|
+
if (!isRecord(values)) throw new TypeError("Slide variable values must be an object with slideNumber and slideCount.");
|
|
446
|
+
if (!Number.isSafeInteger(values.slideNumber) || values.slideNumber < 1) throw new RangeError("slideNumber must be a positive safe integer.");
|
|
447
|
+
if (values.slideCount !== void 0 && (!Number.isSafeInteger(values.slideCount) || values.slideCount < 1)) throw new RangeError("slideCount must be a positive safe integer.");
|
|
448
|
+
}
|
|
449
|
+
function substituteSlideTokens(text2, values) {
|
|
450
|
+
if (!text2.includes("{{")) return { text: text2, fields: [], changed: false };
|
|
451
|
+
const fields2 = [];
|
|
452
|
+
let out = "";
|
|
453
|
+
let last = 0;
|
|
454
|
+
let changed = false;
|
|
455
|
+
slideTokenPattern.lastIndex = 0;
|
|
456
|
+
for (let match = slideTokenPattern.exec(text2); match; match = slideTokenPattern.exec(text2)) {
|
|
457
|
+
const name = match[1];
|
|
458
|
+
let value;
|
|
459
|
+
if (name === void 0) value = "{{";
|
|
460
|
+
else if (name === "slide.number") value = String(values.slideNumber);
|
|
461
|
+
else if (name === "deck.slideCount") {
|
|
462
|
+
if (values.slideCount === void 0) continue;
|
|
463
|
+
value = String(values.slideCount);
|
|
464
|
+
} else value = typeof values.section === "string" ? values.section : "";
|
|
465
|
+
out += text2.slice(last, match.index);
|
|
466
|
+
if (name === "slide.number") fields2.push({ type: "slideNumber", start: out.length, end: out.length + value.length });
|
|
467
|
+
out += value;
|
|
468
|
+
last = match.index + match[0].length;
|
|
469
|
+
changed = true;
|
|
470
|
+
}
|
|
471
|
+
if (!changed) return { text: text2, fields: fields2, changed };
|
|
472
|
+
return { text: out + text2.slice(last), fields: fields2, changed };
|
|
473
|
+
}
|
|
474
|
+
function slideTokenSpans(text2) {
|
|
475
|
+
if (!text2.includes("{{")) return [];
|
|
476
|
+
return Array.from(text2.matchAll(slideTokenSpanPattern), (match) => [match.index, match.index + match[0].length]);
|
|
477
|
+
}
|
|
478
|
+
var skippedKeys = /* @__PURE__ */ new Set(["extensions"]);
|
|
479
|
+
function substitute(value, values, root) {
|
|
480
|
+
if (typeof value === "string") {
|
|
481
|
+
const result = substituteSlideTokens(value, values);
|
|
482
|
+
return result.changed ? result.text : value;
|
|
483
|
+
}
|
|
484
|
+
if (Array.isArray(value)) {
|
|
485
|
+
let changed2 = false;
|
|
486
|
+
const out2 = value.map((entry) => {
|
|
487
|
+
const next = substitute(entry, values, false);
|
|
488
|
+
if (next !== entry) changed2 = true;
|
|
489
|
+
return next;
|
|
490
|
+
});
|
|
491
|
+
return changed2 ? out2 : value;
|
|
492
|
+
}
|
|
493
|
+
if (!isRecord(value)) return value;
|
|
494
|
+
let changed = false;
|
|
495
|
+
const out = {};
|
|
496
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
497
|
+
let next = entry;
|
|
498
|
+
if (skippedKeys.has(key)) next = entry;
|
|
499
|
+
else if (root && key === "design" && isRecord(entry)) {
|
|
500
|
+
const design = {};
|
|
501
|
+
let designChanged = false;
|
|
502
|
+
for (const [designKey, designEntry] of Object.entries(entry)) {
|
|
503
|
+
const designNext = designKey === "header" || designKey === "footer" ? designEntry : substitute(designEntry, values, false);
|
|
504
|
+
if (designNext !== designEntry) designChanged = true;
|
|
505
|
+
design[designKey] = designNext;
|
|
506
|
+
}
|
|
507
|
+
next = designChanged ? design : entry;
|
|
508
|
+
} else next = substitute(entry, values, false);
|
|
509
|
+
if (next !== entry) changed = true;
|
|
510
|
+
out[key] = next;
|
|
511
|
+
}
|
|
512
|
+
return changed ? out : value;
|
|
513
|
+
}
|
|
514
|
+
function resolveSlideVariables(slide, values) {
|
|
515
|
+
if (!isRecord(slide)) return slide;
|
|
516
|
+
const full = { slideNumber: values?.slideNumber, ...values?.slideCount !== void 0 ? { slideCount: values.slideCount } : {}, section: slide.section };
|
|
517
|
+
checkValues(full);
|
|
518
|
+
if (!quickCheck.test(JSON.stringify(slide))) return slide;
|
|
519
|
+
return substitute(slide, full, true);
|
|
520
|
+
}
|
|
521
|
+
function usesSlideBuiltin(value, name) {
|
|
522
|
+
const pattern = new RegExp(String.raw`(?:^|[^\\])\{\{\s*${name.replace(".", String.raw`\.`)}\s*(?:\|[^{}]*)?\}\}`);
|
|
523
|
+
const visit = (entry) => {
|
|
524
|
+
if (typeof entry === "string") return entry.includes("{{") && pattern.test(entry);
|
|
525
|
+
if (Array.isArray(entry)) return entry.some(visit);
|
|
526
|
+
if (!isRecord(entry)) return false;
|
|
527
|
+
for (const [key, child] of Object.entries(entry)) if (!skippedKeys.has(key) && visit(child)) return true;
|
|
528
|
+
return false;
|
|
529
|
+
};
|
|
530
|
+
return visit(value);
|
|
531
|
+
}
|
|
532
|
+
|
|
444
533
|
// src/variables.ts
|
|
445
534
|
var VARIABLE_KINDS = ["color", "text", "number", "date", "image", "url", "list"];
|
|
446
535
|
var DEFAULT_VARIABLE_DATE_FORMAT = "MMMM d, yyyy";
|
|
@@ -454,10 +543,10 @@ var OPFVariableError = class extends Error {
|
|
|
454
543
|
}
|
|
455
544
|
};
|
|
456
545
|
var idPattern = /^[a-z][a-z0-9-]*$/;
|
|
457
|
-
var nameSource = String.raw`[a-z][a-z0-9-]*|(?:deck|speaker|organization)(?:\.[A-Za-z0-9_-]+){1,2}`;
|
|
546
|
+
var nameSource = String.raw`[a-z][a-z0-9-]*|(?:deck|speaker|organization|slide)(?:\.[A-Za-z0-9_-]+){1,2}`;
|
|
458
547
|
var referencePattern = new RegExp(String.raw`^var:(${nameSource})$`);
|
|
459
|
-
var builtinNamePattern = /^(?:speakers|(?:deck|speaker|organization)(?:\.[A-Za-z0-9_-]+){1,2})$/;
|
|
460
|
-
var builtinUsePattern = /\{\{\s*(?:speakers\b|(?:deck|speaker|organization)\.)|^var:(?:speakers$|(?:deck|speaker|organization)\.)/;
|
|
548
|
+
var builtinNamePattern = /^(?:speakers|(?:deck|speaker|organization|slide)(?:\.[A-Za-z0-9_-]+){1,2})$/;
|
|
549
|
+
var builtinUsePattern = /\{\{\s*(?:speakers\b|(?:deck|speaker|organization|slide)\.)|^var:(?:speakers$|(?:deck|speaker|organization|slide)\.)/;
|
|
461
550
|
var hexPattern = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
|
|
462
551
|
var urlPattern = /^(?:https?:\/\/|mailto:|tel:)\S+$/;
|
|
463
552
|
var datePrefixPattern = /^(\d{4}-\d{2}-\d{2})(?:[T ].*)?$/;
|
|
@@ -560,7 +649,7 @@ function usesBuiltins(value, root = true) {
|
|
|
560
649
|
if (Array.isArray(value)) return value.some((entry) => usesBuiltins(entry, false));
|
|
561
650
|
if (!isRecord(value)) return false;
|
|
562
651
|
for (const [key, entry] of Object.entries(value)) {
|
|
563
|
-
if (
|
|
652
|
+
if (skippedKeys2.has(key) || root && skippedRootKeys.has(key)) continue;
|
|
564
653
|
if (usesBuiltins(entry, false)) return true;
|
|
565
654
|
}
|
|
566
655
|
return false;
|
|
@@ -672,13 +761,17 @@ function builtinSource(name, doc) {
|
|
|
672
761
|
const names = speakersOf(doc).map((speaker) => present(speaker.name)).filter((entry) => typeof entry === "string");
|
|
673
762
|
return { ok: true, kind: "list", raw: names.length ? names : void 0 };
|
|
674
763
|
}
|
|
764
|
+
const list = (names) => names.map((entry) => `'${entry}'`).join(", ");
|
|
765
|
+
if (isSlideScopedName(name)) {
|
|
766
|
+
if (isSlideScopedBuiltin(name)) return { ok: false, message: `'var:${name}' is not supported: '${name}' is a slide-scoped built-in, written only as the inline token '{{${name}}}'.` };
|
|
767
|
+
return { ok: false, message: `'${name}' is not a built-in variable; the slide-scoped built-ins are ${list(SLIDE_SCOPED_BUILTINS)}.` };
|
|
768
|
+
}
|
|
675
769
|
const parts = name.split(".");
|
|
676
770
|
const root = parts[0];
|
|
677
771
|
const fields2 = builtinFields(root);
|
|
678
|
-
const list = (names) => names.map((entry) => `'${entry}'`).join(", ");
|
|
679
772
|
if (root === "deck") {
|
|
680
773
|
const field2 = parts[1];
|
|
681
|
-
if (parts.length !== 2 || !Object.hasOwn(fields2, field2)) return { ok: false, message: `'${name}' is not a built-in variable; the deck built-ins are ${list(Object.keys(fields2).map((key) => `deck.${key}`))}.` };
|
|
774
|
+
if (parts.length !== 2 || !Object.hasOwn(fields2, field2)) return { ok: false, message: `'${name}' is not a built-in variable; the deck built-ins are ${list(Object.keys(fields2).map((key) => `deck.${key}`))} and the slide-scoped 'deck.slideCount'.` };
|
|
682
775
|
const value = doc[field2];
|
|
683
776
|
return { ok: true, kind: "text", raw: field2 === "author" && Array.isArray(value) ? present(value.filter((entry) => typeof entry === "string").join(", ")) : present(value) };
|
|
684
777
|
}
|
|
@@ -742,15 +835,16 @@ function lookupVariable(id, path, context) {
|
|
|
742
835
|
}
|
|
743
836
|
function interpolate(text2, path, context) {
|
|
744
837
|
let changed = false;
|
|
745
|
-
const value = text2.replace(tokenPattern, (match, id, format) => {
|
|
838
|
+
const value = text2.replace(tokenPattern, (match, id, format, offset) => {
|
|
746
839
|
if (id === void 0) {
|
|
747
|
-
if (context.unescape) {
|
|
840
|
+
if (context.unescape && !slideTokenFollows(text2.slice(offset + match.length))) {
|
|
748
841
|
changed = true;
|
|
749
842
|
return "{{";
|
|
750
843
|
}
|
|
751
844
|
return match;
|
|
752
845
|
}
|
|
753
846
|
context.uses.push({ id, path, form: "token" });
|
|
847
|
+
if (isSlideScopedBuiltin(id)) return match;
|
|
754
848
|
const effective = lookupVariable(id, path, context);
|
|
755
849
|
if (!effective) {
|
|
756
850
|
if (!isBuiltinName(id)) diag(context, { code: "variable-unknown", severity: "warning", path, id, message: `'{{${id}}}' names no declared variable; declare '${id}' in the top-level variables map, or write '\\{{' for literal braces.` }, `unk:${id}:${path}`);
|
|
@@ -803,7 +897,7 @@ function reduceString(text2, path, parentIsArray, context) {
|
|
|
803
897
|
const result = interpolate(text2, path, context);
|
|
804
898
|
return result.changed ? { kind: "replace", value: result.value } : { kind: "keep" };
|
|
805
899
|
}
|
|
806
|
-
var
|
|
900
|
+
var skippedKeys2 = /* @__PURE__ */ new Set(["extensions"]);
|
|
807
901
|
var skippedRootKeys = /* @__PURE__ */ new Set(["variables", "catalogs", "$schema", "template"]);
|
|
808
902
|
function walk(value, path, parentIsArray, context) {
|
|
809
903
|
if (typeof value === "string") {
|
|
@@ -836,7 +930,7 @@ function walk(value, path, parentIsArray, context) {
|
|
|
836
930
|
let changed = false;
|
|
837
931
|
const entries = [];
|
|
838
932
|
for (const [key, entry] of Object.entries(value)) {
|
|
839
|
-
if (
|
|
933
|
+
if (skippedKeys2.has(key) || path === "" && skippedRootKeys.has(key)) {
|
|
840
934
|
entries.push([key, entry]);
|
|
841
935
|
continue;
|
|
842
936
|
}
|
|
@@ -940,6 +1034,21 @@ function rebuildVariables(presentation, built, keepAll) {
|
|
|
940
1034
|
}
|
|
941
1035
|
return out.length ? Object.fromEntries(out) : void 0;
|
|
942
1036
|
}
|
|
1037
|
+
function slideSectionDiagnostics(presentation, uses) {
|
|
1038
|
+
const paths = uses.filter((use) => use.id === "slide.section").map((use) => use.path);
|
|
1039
|
+
if (!paths.length || !Array.isArray(presentation.slides)) return [];
|
|
1040
|
+
const out = [];
|
|
1041
|
+
presentation.slides.forEach((slide, index) => {
|
|
1042
|
+
if (!isRecord(slide) || typeof slide.section === "string" && slide.section !== "") return;
|
|
1043
|
+
const own2 = `/slides/${index}/`;
|
|
1044
|
+
const design = isRecord(slide.design) ? slide.design : {};
|
|
1045
|
+
const inherited = ["header", "footer"].filter((kind2) => design[kind2] === void 0).map((kind2) => `/design/${kind2}/`);
|
|
1046
|
+
const where = paths.find((path) => path.startsWith(own2) || inherited.some((prefix) => path.startsWith(prefix)));
|
|
1047
|
+
if (where === void 0) return;
|
|
1048
|
+
out.push({ code: "variable-builtin-missing", severity: "warning", path: `/slides/${index}`, id: "slide.section", message: `Slide ${index + 1} has no section, so '{{slide.section}}' (used at ${where}) resolves to nothing on it; give the slide a section or remove the token.` });
|
|
1049
|
+
});
|
|
1050
|
+
return out;
|
|
1051
|
+
}
|
|
943
1052
|
function finish(presentation, built, options) {
|
|
944
1053
|
const { context } = built;
|
|
945
1054
|
const complete = built.unfilled.length === 0;
|
|
@@ -958,6 +1067,7 @@ function finish(presentation, built, options) {
|
|
|
958
1067
|
}
|
|
959
1068
|
}
|
|
960
1069
|
}
|
|
1070
|
+
if (context.shape) context.diagnostics.push(...slideSectionDiagnostics(presentation, context.uses));
|
|
961
1071
|
const diagnostics = context.diagnostics;
|
|
962
1072
|
if (options.strict && diagnostics.some((entry) => entry.severity === "error")) throw new OPFVariableError(diagnostics);
|
|
963
1073
|
return { presentation: result, diagnostics, unfilled: built.unfilled, examplesUsed: built.examplesUsed, complete };
|
|
@@ -991,6 +1101,7 @@ function listVariables(presentation, values = {}) {
|
|
|
991
1101
|
};
|
|
992
1102
|
});
|
|
993
1103
|
}
|
|
1104
|
+
var SLIDE_SCOPED_LABELS = { "slide.number": "Slide number", "slide.section": "Section", "deck.slideCount": "Slide count" };
|
|
994
1105
|
var FIELD_LABELS = { name: "name", legalName: "legal name", tagline: "tagline", domain: "domain", email: "email", phone: "phone", logo: "logo", title: "title", bio: "bio", photo: "photo", description: "description", author: "author" };
|
|
995
1106
|
function listBuiltinVariables(presentation) {
|
|
996
1107
|
if (!isRecord(presentation)) return [];
|
|
@@ -1013,7 +1124,12 @@ function listBuiltinVariables(presentation) {
|
|
|
1013
1124
|
const source = builtinSource(name, presentation);
|
|
1014
1125
|
if (!source.ok) continue;
|
|
1015
1126
|
const coerced = source.raw === void 0 ? void 0 : coerceVariableValue(source.kind, source.raw);
|
|
1016
|
-
out.push({ name, kind: source.kind, label, ...coerced?.ok ? { value: coerced.value } : {}, available: coerced?.ok === true, uses: built.context.uses.filter((use) => use.id === name) });
|
|
1127
|
+
out.push({ name, kind: source.kind, label, scope: "deck", ...coerced?.ok ? { value: coerced.value } : {}, available: coerced?.ok === true, uses: built.context.uses.filter((use) => use.id === name) });
|
|
1128
|
+
}
|
|
1129
|
+
const slides = Array.isArray(presentation.slides) ? presentation.slides : [];
|
|
1130
|
+
for (const name of SLIDE_SCOPED_BUILTINS) {
|
|
1131
|
+
const available = name !== "slide.section" || slides.some((slide) => isRecord(slide) && typeof slide.section === "string" && slide.section !== "");
|
|
1132
|
+
out.push({ name, kind: "text", label: SLIDE_SCOPED_LABELS[name], scope: "slide", available, uses: built.context.uses.filter((use) => use.id === name) });
|
|
1017
1133
|
}
|
|
1018
1134
|
return out;
|
|
1019
1135
|
}
|
|
@@ -4181,8 +4297,7 @@ function layoutFurniture(input, options = {}) {
|
|
|
4181
4297
|
const outlines = options.textMeasurement?.outlineBounds !== void 0, parts = [], diagnostics = [];
|
|
4182
4298
|
const sourceRoot = `slides.${options.slideIndex ?? 0}`, organizations = Array.isArray(options.presentation?.organization) ? options.presentation.organization : [options.presentation?.organization];
|
|
4183
4299
|
const primaryIndex = organizations.findIndex((item) => record6(item).role === "primary"), organizationIndex = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
|
|
4184
|
-
const organization = record6(organizations[organizationIndex]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex}` : "organization"
|
|
4185
|
-
const speakers = Array.isArray(options.presentation?.speaker) ? options.presentation.speaker : [options.presentation?.speaker], speaker = record6(speakers[0]), speakerRoot = Array.isArray(options.presentation?.speaker) ? "speaker.0" : "speaker";
|
|
4300
|
+
const organization = record6(organizations[organizationIndex]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex}` : "organization";
|
|
4186
4301
|
const fontFamily = options.fontFamilies?.body ?? "sans-serif";
|
|
4187
4302
|
let headerBottom = 0, footerTop = height, configured = false;
|
|
4188
4303
|
const error = (path, message, code = "text-overflow") => diagnostics.push({ code, path, message });
|
|
@@ -4248,30 +4363,17 @@ function layoutFurniture(input, options = {}) {
|
|
|
4248
4363
|
zoneParts.push({ type: "image", kind: kind2, zone, field: "image", path: `${path}.image`, sourcePath: `${path}.image`, generated: false, image: content.image, box, alignment: side });
|
|
4249
4364
|
y += box.height;
|
|
4250
4365
|
}
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
if (
|
|
4254
|
-
|
|
4255
|
-
}
|
|
4256
|
-
if (content.speaker === true) {
|
|
4257
|
-
if (typeof speaker.name === "string" && speaker.name.trim()) add("speaker", typeof speaker.title === "string" && speaker.title.trim() ? `${speaker.name}, ${speaker.title}` : speaker.name, true, `${speakerRoot}.name`);
|
|
4258
|
-
else error(`${path}.speaker`, "Generated speaker needs a named speaker in the presentation.", "unresolved-content");
|
|
4259
|
-
}
|
|
4366
|
+
if (typeof content.text === "string") {
|
|
4367
|
+
const resolved = substituteSlideTokens(content.text, { slideNumber: number, ...slideCount !== void 0 ? { slideCount } : {}, section: slide.section });
|
|
4368
|
+
if (slideCount === void 0 && usesSlideBuiltin(content.text, "deck.slideCount")) error(`${path}.text`, "{{deck.slideCount}} needs the rendered slide count (the slideCount option or the presentation slides).", "unresolved-content");
|
|
4369
|
+
add("text", resolved.text, false, void 0, { fields: resolved.fields });
|
|
4370
|
+
} else add("text", content.text);
|
|
4260
4371
|
if (content.socials === true) {
|
|
4261
4372
|
const links = Object.entries(record6(organization.socials)).filter(([, value2]) => typeof value2 === "string" && value2.trim()).map(([platform, value2]) => ({ platform, sourcePath: `${organizationRoot}.socials.${platform}`, ...resolveSocialProfile(platform, value2, "organization") }));
|
|
4262
4373
|
if (links.length) add("socials", links.map((link) => link.text).join("\n"), true, `${organizationRoot}.socials`, { links });
|
|
4263
4374
|
else error(`${path}.socials`, "Generated social profiles need a primary organization with socials.", "unresolved-content");
|
|
4264
4375
|
}
|
|
4265
|
-
if (content.
|
|
4266
|
-
if (typeof slide.section === "string") add("section", slide.section, true, `${sourceRoot}.section`);
|
|
4267
|
-
else error(`${path}.section`, "Generated section needs a literal slide section.", "unresolved-content");
|
|
4268
|
-
}
|
|
4269
|
-
for (const setting of ["slideNumberFormat", "dateFormat"]) if (content[setting] !== void 0 && typeof content[setting] !== "string") throw new TypeError(`Furniture setting ${path}.${setting} requires a string.`);
|
|
4270
|
-
if (content.slideNumber === true) {
|
|
4271
|
-
const resolved = formatSlideNumber(content.slideNumberFormat ?? DEFAULT_SLIDE_NUMBER_FORMAT, number, slideCount);
|
|
4272
|
-
if ("error" in resolved) error(`${path}.slideNumberFormat`, resolved.error, "unresolved-content");
|
|
4273
|
-
else add("slideNumber", resolved.text, true, void 0, { fields: resolved.fields });
|
|
4274
|
-
}
|
|
4376
|
+
if (content.dateFormat !== void 0 && typeof content.dateFormat !== "string") throw new TypeError(`Furniture setting ${path}.dateFormat requires a string.`);
|
|
4275
4377
|
if (content.date === true) {
|
|
4276
4378
|
const format = content.dateFormat ?? DEFAULT_FURNITURE_DATE_FORMAT;
|
|
4277
4379
|
if (options.date === void 0) error(`${path}.date`, "A current date needs a host-supplied ISO date option. For fixed content use a literal date, or an ISO date with dateFormat.", "unresolved-content");
|
|
@@ -5851,4 +5953,4 @@ function resolveCanvasDimensions(input) {
|
|
|
5851
5953
|
return { width, height };
|
|
5852
5954
|
}
|
|
5853
5955
|
|
|
5854
|
-
export { CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT,
|
|
5956
|
+
export { CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, LANGUAGES, LAYOUT_BODY_KINDS, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_PLACEHOLDER_GROUP_DEPTH, MAX_ROMAN_VALUE, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCompositionError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, annotationText, captionSettings, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, chartPrimaryLayout, citationMarkerText, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, composeSlide, datasetDiagnostics, defaultSlideBackground, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatVariableNumber, fromExcelNumberFormat, hasContentVariables, hasPlaceholderGroups, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isDarkColor, isDatasetRef, isPlaceholderGroup, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutLeaves, layoutMetric, layoutQuote, layoutSlots, layoutStructure, layoutTable, layoutTimeline, layoutWatermark, listBuiltinVariables, listNumbers, listVariables, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, promotedRegionKeys, readingRows, referencesSlide, resolveCanvasDimensions, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveScriptFonts, resolveSlideDirection, resolveSlideVariables, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, scriptFontRole, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unusedDatasets, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
|