@openpresentation/opf 0.17.0 → 0.18.3
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 +4 -4
- package/dist/browser.js +38 -0
- package/dist/{catalog-refs-C4K4y-vh.d.ts → catalog-refs-BSfGELpt.d.ts} +1 -1
- package/dist/{catalog-schemas-g7RFQBdc.d.ts → catalog-schemas-CinPh5WA.d.ts} +1 -1
- package/dist/catalog.d.ts +2 -2
- package/dist/{chart-data-DTxdRRT1.d.ts → chart-data-BnNqgnC-.d.ts} +1 -1
- package/dist/{chunk-RA64UQKI.js → chunk-2PEWUUBR.js} +97 -73
- package/dist/{chunk-TCD2FB2K.js → chunk-ECP7QPGK.js} +5 -5
- package/dist/{chunk-O2CX5NEH.js → chunk-FO3WGS4R.js} +6 -5
- package/dist/{chunk-N4EVOFEA.js → chunk-GVOLSWAJ.js} +4 -4
- package/dist/{chunk-WWYWFVOI.js → chunk-IM337HP5.js} +151 -25
- package/dist/{chunk-YT7FMQER.js → chunk-JCOSZTOI.js} +1 -1
- package/dist/{chunk-IPW5BS3X.js → chunk-K5EG3UMS.js} +190 -172
- package/dist/{chunk-NLNYNBTS.js → chunk-KA3ZPFVT.js} +84 -26
- package/dist/{chunk-M4UR3NPN.js → chunk-L5YACLWK.js} +2 -2
- package/dist/{chunk-CW7GEAV3.js → chunk-MBU42S5Y.js} +291 -133
- package/dist/{chunk-BIC3SWPK.js → chunk-MSFE2HUK.js} +30 -5
- package/dist/{chunk-ESRYBYLY.js → chunk-PNINP5IF.js} +1 -1
- package/dist/{chunk-IS5H5JKH.js → chunk-R7KIASS4.js} +1 -1
- package/dist/{chunk-PPROJP2E.js → chunk-TRELE6I6.js} +1 -1
- package/dist/{chunk-O3CVNJTL.js → chunk-WHHLGDCQ.js} +1 -1
- package/dist/{chunk-O263APNI.js → chunk-ZCFSDSUX.js} +3 -3
- package/dist/{composition-BbZ_9C-c.d.ts → composition-C-OoqvAr.d.ts} +80 -40
- package/dist/composition.d.ts +3 -3
- package/dist/composition.js +1 -1
- package/dist/conversion-4CLOEG6O.js +21 -0
- package/dist/{conversion-SBpTOwdg.d.ts → conversion-BxZbBd_0.d.ts} +96 -38
- package/dist/convert.d.ts +4 -4
- package/dist/convert.js +7 -7
- package/dist/data.d.ts +7 -7
- package/dist/data.js +2 -2
- package/dist/{deck-report-Bx3naFlF.d.ts → deck-report-DiDf_Vew.d.ts} +5 -5
- package/dist/deck.d.ts +8 -8
- package/dist/deck.js +10 -10
- package/dist/diff.d.ts +1 -1
- package/dist/diff.js +5 -5
- package/dist/docs.js +35 -29
- package/dist/examples.d.ts +1 -1
- package/dist/examples.js +181 -214
- package/dist/{finding-CDQ_wH8j.d.ts → finding-CT_f_vbD.d.ts} +1 -1
- package/dist/format.js +2 -2
- package/dist/index.d.ts +153 -20
- package/dist/index.js +62 -15
- package/dist/markdown.d.ts +12 -8
- package/dist/markdown.js +7 -7
- package/dist/node-engine.d.ts +37 -17
- package/dist/node-engine.js +39 -16
- package/dist/{pagination-BhX4M48Y.d.ts → pagination-BaUjDrTz.d.ts} +7 -4
- 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-fb8CZmRq.d.ts → presentation-81rNihF0.d.ts} +271 -384
- package/dist/repo-readme.js +1 -1
- package/dist/schemas.d.ts +4 -2
- package/dist/schemas.js +1 -1
- package/dist/spec/README.md +1 -1
- package/dist/spec/schemas/opf.schema.json +67 -72
- package/dist/types.d.ts +3 -3
- package/dist/{validation-types-iZbXfES6.d.ts → validation-types-PbGDrNUr.d.ts} +12 -7
- 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 +14 -12
- package/dist/node.d.ts +0 -60
- package/dist/node.js +0 -54
|
@@ -1,6 +1,58 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OPFDataImportError, parseTabularData } from './chunk-ZCFSDSUX.js';
|
|
2
|
+
import { applyPatchWithInverse } from './chunk-WHHLGDCQ.js';
|
|
3
|
+
import { validate, OPFValidationError } from './chunk-KA3ZPFVT.js';
|
|
4
|
+
import { isRecord, visitContentPayloads, listVariables, resolveVariables, LOGO_SHAPES, resolveDesignRecords, resolveFontFamilies, resolveCanvasDimensions, imageBackground } from './chunk-MBU42S5Y.js';
|
|
2
5
|
import { embeddedCopy, checkCatalogsOption, catalogReferenceSites, parseReference, catalogGroupDeclared, resolveReference, dottedPath, unresolvedReference, recordReferenceSites, catalogGroupSource, registeredCatalog, catalogKinds, CATALOG_GROUP_PATTERN } from './chunk-SPFV27O5.js';
|
|
3
6
|
|
|
7
|
+
// src/api-errors.ts
|
|
8
|
+
var OPFApiError = class extends Error {
|
|
9
|
+
code;
|
|
10
|
+
details;
|
|
11
|
+
findings;
|
|
12
|
+
constructor(message, code, extra = {}) {
|
|
13
|
+
super(message, extra.cause === void 0 ? void 0 : { cause: extra.cause });
|
|
14
|
+
this.name = new.target.name;
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.details = extra.details ?? {};
|
|
17
|
+
this.findings = extra.findings ?? [];
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var OPFExportError = class extends OPFApiError {
|
|
21
|
+
};
|
|
22
|
+
var OPFImportError = class extends OPFApiError {
|
|
23
|
+
};
|
|
24
|
+
function asApiError(Class, error, fallbackCode) {
|
|
25
|
+
if (error instanceof Class) return error;
|
|
26
|
+
if (error instanceof OPFApiError) return new Class(error.message, error.code, { details: error.details, findings: error.findings, cause: error });
|
|
27
|
+
const failure = error;
|
|
28
|
+
return new Class(failure?.message ?? String(error), typeof failure?.code === "string" ? failure.code : fallbackCode, { cause: error });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/slide-selection.ts
|
|
32
|
+
var isSlideNumber = (value) => typeof value === "number" && Number.isInteger(value) && value >= 1;
|
|
33
|
+
function parseSlideSelection(selection, total, label = "slides") {
|
|
34
|
+
if (!(total >= 1)) throw new OPFApiError("The presentation has no slides.", "no-slides");
|
|
35
|
+
const listed = typeof selection === "number" ? [selection] : Array.isArray(selection) ? selection : void 0;
|
|
36
|
+
if (listed) {
|
|
37
|
+
const bad = listed.find((value) => !isSlideNumber(value));
|
|
38
|
+
if (bad !== void 0 || listed.length === 0) throw new OPFApiError(`${label} needs slide numbers counted from 1 (got ${JSON.stringify(bad ?? listed)}).`, "invalid-option");
|
|
39
|
+
} else if (typeof selection !== "string") throw new OPFApiError(`${label} needs a slide number, a list of numbers or text like "1,3-5".`, "invalid-option");
|
|
40
|
+
const spec = listed ? listed.join(",") : selection;
|
|
41
|
+
const chosen = /* @__PURE__ */ new Set();
|
|
42
|
+
for (const part of spec.split(",")) {
|
|
43
|
+
const text = part.trim();
|
|
44
|
+
const match = /^(\d*)(-?)(\d*)$/.exec(text);
|
|
45
|
+
if (!text || !match || !match[1] && !match[3]) throw new OPFApiError(`${label} needs numbers like 1,3-5 (got "${spec}").`, "invalid-option");
|
|
46
|
+
const [, from, dash, to] = match;
|
|
47
|
+
const first = from ? Number(from) : 1;
|
|
48
|
+
const last = dash ? to ? Number(to) : total : first;
|
|
49
|
+
if (first < 1 || last < first) throw new OPFApiError(`${label} range "${text}" is not valid (slides count from 1).`, "invalid-option");
|
|
50
|
+
if (last > total) throw new OPFApiError(`${label} ${text} is outside the presentation, which has ${total} slide${total === 1 ? "" : "s"}.`, "invalid-option");
|
|
51
|
+
for (let n = first; n <= last; n++) chosen.add(n);
|
|
52
|
+
}
|
|
53
|
+
return [...chosen].sort((a, b) => a - b);
|
|
54
|
+
}
|
|
55
|
+
|
|
4
56
|
// src/catalog-helpers.ts
|
|
5
57
|
var isRec = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
58
|
var rec = (value) => isRec(value) ? value : {};
|
|
@@ -294,9 +346,8 @@ function moveToCustom(document, ref, options = {}) {
|
|
|
294
346
|
// src/stats.ts
|
|
295
347
|
var DEFAULT_WORDS_PER_MINUTE = 130;
|
|
296
348
|
var KIND_ORDER = ["text", "items", "bullets", "quote", "metric", "code", "timeline", "chart", "table", "image", "video"];
|
|
297
|
-
var FURNITURE_FIELDS = ["
|
|
349
|
+
var FURNITURE_FIELDS = ["image", "text", "socials", "date"];
|
|
298
350
|
var ZONES = ["left", "center", "right"];
|
|
299
|
-
var LOGO_VARIANTS = ["default", "light", "dark", "stacked", "stackedLight", "stackedDark", "icon", "iconLight", "iconDark", "wordmark", "wordmarkLight", "wordmarkDark"];
|
|
300
351
|
var WORD = /[\p{L}\p{N}\p{M}]+(?:['’.,-][\p{L}\p{N}\p{M}]+)*/gu;
|
|
301
352
|
var UNSPACED = /[-က-႟ក--ヿ㐀-䶿一-鿿豈-]/gu;
|
|
302
353
|
var wordCount = (text) => {
|
|
@@ -417,7 +468,7 @@ function stats(presentation2, options = {}) {
|
|
|
417
468
|
const images = { content: { total: 0, withAlt: 0, decorative: 0, missingAlt: 0 }, logos: 0, watermarks: { deck: false, slides: 0 }, backgrounds: { deck: false, slides: 0 }, headerFooter: 0, speakerPhotos: 0, videos: 0 };
|
|
418
469
|
const contentImage = (asset) => {
|
|
419
470
|
if (srcOf(asset) === void 0) return 0;
|
|
420
|
-
useAsset(asset);
|
|
471
|
+
if (!String(srcOf(asset)).startsWith("var:organization.")) useAsset(asset);
|
|
421
472
|
images.content.total++;
|
|
422
473
|
const alt = altOf(asset);
|
|
423
474
|
if (alt === void 0 || alt !== "" && alt.trim() === "") images.content.missingAlt++;
|
|
@@ -425,18 +476,14 @@ function stats(presentation2, options = {}) {
|
|
|
425
476
|
else images.content.withAlt++;
|
|
426
477
|
return 1;
|
|
427
478
|
};
|
|
428
|
-
const
|
|
429
|
-
if (srcOf(value) !== void 0)
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
useAsset(value[variant]);
|
|
437
|
-
images.logos++;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
479
|
+
const logoAssets = (value) => {
|
|
480
|
+
if (srcOf(value) !== void 0) return [value];
|
|
481
|
+
if (!isRecord(value)) return [];
|
|
482
|
+
return LOGO_SHAPES.flatMap((shape) => {
|
|
483
|
+
const entry = value[shape];
|
|
484
|
+
if (srcOf(entry) !== void 0) return [entry];
|
|
485
|
+
return isRecord(entry) ? [entry.onLight, entry.onDark].filter((tone2) => srcOf(tone2) !== void 0) : [];
|
|
486
|
+
});
|
|
440
487
|
};
|
|
441
488
|
const watermarkOf = (value) => {
|
|
442
489
|
if (value === void 0 || value === false) return false;
|
|
@@ -453,15 +500,13 @@ function stats(presentation2, options = {}) {
|
|
|
453
500
|
if (!isRecord(value)) return;
|
|
454
501
|
for (const zone of ZONES) {
|
|
455
502
|
const item = value[zone];
|
|
456
|
-
if (isRecord(item)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}
|
|
503
|
+
if (!isRecord(item) || srcOf(item.image) === void 0) continue;
|
|
504
|
+
if (!String(srcOf(item.image)).startsWith("var:organization.")) useAsset(item.image);
|
|
505
|
+
images.headerFooter++;
|
|
460
506
|
}
|
|
461
507
|
};
|
|
462
508
|
const designAssets = (value, scope) => {
|
|
463
509
|
if (!isRecord(value)) return;
|
|
464
|
-
logoImages(value.logo);
|
|
465
510
|
if (watermarkOf(value.watermark)) {
|
|
466
511
|
if (scope === "deck") images.watermarks.deck = true;
|
|
467
512
|
else images.watermarks.slides++;
|
|
@@ -474,11 +519,12 @@ function stats(presentation2, options = {}) {
|
|
|
474
519
|
furnitureImages(value.footer);
|
|
475
520
|
};
|
|
476
521
|
const organizations = list(deck.organization).filter(isRecord).map((entry) => {
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
useAsset(
|
|
522
|
+
const logos = logoAssets(entry.logo);
|
|
523
|
+
for (const logo of logos) {
|
|
524
|
+
useAsset(logo);
|
|
480
525
|
images.logos++;
|
|
481
526
|
}
|
|
527
|
+
const hasLogo = logos.length > 0;
|
|
482
528
|
return { id: str(entry.id) ?? "", name: str(entry.name) ?? "", role: str(entry.role), hasLogo };
|
|
483
529
|
});
|
|
484
530
|
const speakers = list(deck.speaker).filter(isRecord).map((entry) => {
|
|
@@ -790,4 +836,84 @@ function stats(presentation2, options = {}) {
|
|
|
790
836
|
return result;
|
|
791
837
|
}
|
|
792
838
|
|
|
793
|
-
|
|
839
|
+
// src/edit.ts
|
|
840
|
+
function edit(deck, patch, options = {}) {
|
|
841
|
+
const result = applyPatchWithInverse(deck, patch);
|
|
842
|
+
const presentation2 = result.presentation;
|
|
843
|
+
if (options.validate === false) return { presentation: presentation2, findings: [], inverse: result.inverse };
|
|
844
|
+
const report = validate(presentation2, { only: ["format", "references"], ...options.catalogs ? { catalogs: options.catalogs } : {} });
|
|
845
|
+
if (!report.valid) throw new OPFValidationError(report);
|
|
846
|
+
return { presentation: presentation2, findings: report.findings, inverse: result.inverse };
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// src/fill.ts
|
|
850
|
+
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
851
|
+
function fillRecords(raw, options = {}) {
|
|
852
|
+
const format2 = options.format ?? (/^[\s\uFEFF]*[[{]/.test(raw) ? "json" : "csv");
|
|
853
|
+
if (format2 === "json") {
|
|
854
|
+
let value;
|
|
855
|
+
try {
|
|
856
|
+
value = JSON.parse(raw.replace(/^\uFEFF/, ""));
|
|
857
|
+
} catch {
|
|
858
|
+
throw new OPFDataImportError("Invalid JSON data.");
|
|
859
|
+
}
|
|
860
|
+
if (isRecord2(value) && !("columns" in value && "rows" in value)) return [value];
|
|
861
|
+
if (Array.isArray(value) && value.length && value.every(isRecord2)) return value;
|
|
862
|
+
if (Array.isArray(value) && !value.length) throw new OPFDataImportError("Data contains no records.");
|
|
863
|
+
}
|
|
864
|
+
const table = parseTabularData(raw, { format: format2, header: options.header, delimiter: options.delimiter });
|
|
865
|
+
if (!table.rows.length) throw new OPFDataImportError("Data contains no records.");
|
|
866
|
+
return table.rows.map((row) => Object.fromEntries(table.columns.map((column, index) => [column, row[index] === "" ? null : row[index]])));
|
|
867
|
+
}
|
|
868
|
+
function fill(template, data, options = {}) {
|
|
869
|
+
if (!isRecord2(template)) throw new TypeError("fill expects a template object.");
|
|
870
|
+
const records = data === void 0 ? [{}] : typeof data === "string" ? fillRecords(data, options) : Array.isArray(data) ? [...data] : [data];
|
|
871
|
+
if (!records.length) throw new OPFDataImportError("Data contains no records.");
|
|
872
|
+
if (!records.every(isRecord2)) throw new OPFDataImportError("Each record must be an object keyed by variable id.");
|
|
873
|
+
const decks = records.map((record, offset) => ({ index: offset + 1, record, ...resolveVariables(template, record, { template: false, partial: options.partial === true, examples: options.examples === true }) }));
|
|
874
|
+
return {
|
|
875
|
+
decks: decks.map(({ index, record, presentation: presentation2, diagnostics, unfilled, complete }) => ({ index, record, presentation: presentation2, diagnostics, unfilled, complete })),
|
|
876
|
+
...options.combine ? { presentation: combine(decks) } : {},
|
|
877
|
+
complete: decks.every((deck) => deck.complete),
|
|
878
|
+
unfilled: [...new Set(decks.flatMap((deck) => deck.unfilled))],
|
|
879
|
+
diagnostics: summarize(decks)
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
function combine(decks) {
|
|
883
|
+
const first = decks[0];
|
|
884
|
+
const seen = /* @__PURE__ */ new Set();
|
|
885
|
+
const slides = [];
|
|
886
|
+
const assets = {};
|
|
887
|
+
for (const deck of decks) {
|
|
888
|
+
for (const slide of Array.isArray(deck.presentation.slides) ? deck.presentation.slides : []) {
|
|
889
|
+
if (isRecord2(slide) && typeof slide.id === "string") {
|
|
890
|
+
let id = slide.id;
|
|
891
|
+
if (seen.has(id)) {
|
|
892
|
+
id = `${slide.id}-${deck.index}`;
|
|
893
|
+
for (let suffix = 2; seen.has(id); suffix++) id = `${slide.id}-${deck.index}-${suffix}`;
|
|
894
|
+
}
|
|
895
|
+
seen.add(id);
|
|
896
|
+
slides.push(id === slide.id ? slide : { ...slide, id });
|
|
897
|
+
} else slides.push(slide);
|
|
898
|
+
}
|
|
899
|
+
if (isRecord2(deck.presentation.assets)) {
|
|
900
|
+
for (const [key, value] of Object.entries(deck.presentation.assets)) if (!(key in assets)) assets[key] = value;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
return { ...first.presentation, ...Object.keys(assets).length ? { assets } : {}, slides };
|
|
904
|
+
}
|
|
905
|
+
function summarize(decks) {
|
|
906
|
+
const merged = /* @__PURE__ */ new Map();
|
|
907
|
+
for (const deck of decks) {
|
|
908
|
+
for (const diagnostic of deck.diagnostics) {
|
|
909
|
+
if (diagnostic.severity === "info") continue;
|
|
910
|
+
const key = `${diagnostic.code}\0${diagnostic.id}\0${diagnostic.path}`;
|
|
911
|
+
const entry = merged.get(key);
|
|
912
|
+
if (entry) entry.records.push(deck.index);
|
|
913
|
+
else merged.set(key, { ...diagnostic, records: [deck.index] });
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
return [...merged.values()];
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
export { OPFApiError, OPFExportError, OPFImportError, OPFMoveToCustomError, asApiError, copySlides, edit, embed, fill, fillRecords, moveToCustom, parseSlideSelection, sameRecord, stats, updateFromCatalog };
|