slotdeck 0.0.0-stage → 0.1.1

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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +495 -2
  3. package/dist/deck/numbers.d.ts +14 -0
  4. package/dist/deck/numbers.js +48 -0
  5. package/dist/deck/numbers.js.map +1 -0
  6. package/dist/deck/spec.d.ts +73 -0
  7. package/dist/deck/spec.js +21 -0
  8. package/dist/deck/spec.js.map +1 -0
  9. package/dist/deck/validate.d.ts +49 -0
  10. package/dist/deck/validate.js +194 -0
  11. package/dist/deck/validate.js.map +1 -0
  12. package/dist/generate.d.ts +53 -0
  13. package/dist/generate.js +44 -0
  14. package/dist/generate.js.map +1 -0
  15. package/dist/index.d.ts +42 -0
  16. package/dist/index.js +27 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/llm/gemini.d.ts +39 -0
  19. package/dist/llm/gemini.js +147 -0
  20. package/dist/llm/gemini.js.map +1 -0
  21. package/dist/llm/provider.d.ts +38 -0
  22. package/dist/llm/provider.js +2 -0
  23. package/dist/llm/provider.js.map +1 -0
  24. package/dist/node.d.ts +3 -0
  25. package/dist/node.js +31 -0
  26. package/dist/node.js.map +1 -0
  27. package/dist/plan/assets.d.ts +28 -0
  28. package/dist/plan/assets.js +80 -0
  29. package/dist/plan/assets.js.map +1 -0
  30. package/dist/plan/catalog.d.ts +106 -0
  31. package/dist/plan/catalog.js +302 -0
  32. package/dist/plan/catalog.js.map +1 -0
  33. package/dist/plan/edit.d.ts +31 -0
  34. package/dist/plan/edit.js +364 -0
  35. package/dist/plan/edit.js.map +1 -0
  36. package/dist/plan/plan.d.ts +106 -0
  37. package/dist/plan/plan.js +243 -0
  38. package/dist/plan/plan.js.map +1 -0
  39. package/dist/plan/write.d.ts +39 -0
  40. package/dist/plan/write.js +179 -0
  41. package/dist/plan/write.js.map +1 -0
  42. package/dist/pptx/package.d.ts +48 -0
  43. package/dist/pptx/package.js +202 -0
  44. package/dist/pptx/package.js.map +1 -0
  45. package/dist/pptx/presentation.d.ts +20 -0
  46. package/dist/pptx/presentation.js +31 -0
  47. package/dist/pptx/presentation.js.map +1 -0
  48. package/dist/pptx/xml.d.ts +23 -0
  49. package/dist/pptx/xml.js +67 -0
  50. package/dist/pptx/xml.js.map +1 -0
  51. package/dist/render/chart.d.ts +18 -0
  52. package/dist/render/chart.js +158 -0
  53. package/dist/render/chart.js.map +1 -0
  54. package/dist/render/extract.d.ts +11 -0
  55. package/dist/render/extract.js +65 -0
  56. package/dist/render/extract.js.map +1 -0
  57. package/dist/render/picture.d.ts +20 -0
  58. package/dist/render/picture.js +114 -0
  59. package/dist/render/picture.js.map +1 -0
  60. package/dist/render/render.d.ts +32 -0
  61. package/dist/render/render.js +247 -0
  62. package/dist/render/render.js.map +1 -0
  63. package/dist/render/repeat.d.ts +15 -0
  64. package/dist/render/repeat.js +118 -0
  65. package/dist/render/repeat.js.map +1 -0
  66. package/dist/render/table.d.ts +12 -0
  67. package/dist/render/table.js +84 -0
  68. package/dist/render/table.js.map +1 -0
  69. package/dist/render/text.d.ts +31 -0
  70. package/dist/render/text.js +210 -0
  71. package/dist/render/text.js.map +1 -0
  72. package/dist/store.d.ts +18 -0
  73. package/dist/store.js +23 -0
  74. package/dist/store.js.map +1 -0
  75. package/dist/template/change.d.ts +138 -0
  76. package/dist/template/change.js +406 -0
  77. package/dist/template/change.js.map +1 -0
  78. package/dist/template/check.d.ts +15 -0
  79. package/dist/template/check.js +97 -0
  80. package/dist/template/check.js.map +1 -0
  81. package/dist/template/draft.d.ts +47 -0
  82. package/dist/template/draft.js +276 -0
  83. package/dist/template/draft.js.map +1 -0
  84. package/dist/template/inspect.d.ts +53 -0
  85. package/dist/template/inspect.js +157 -0
  86. package/dist/template/inspect.js.map +1 -0
  87. package/dist/template/instruct.d.ts +26 -0
  88. package/dist/template/instruct.js +278 -0
  89. package/dist/template/instruct.js.map +1 -0
  90. package/dist/template/manifest.d.ts +226 -0
  91. package/dist/template/manifest.js +116 -0
  92. package/dist/template/manifest.js.map +1 -0
  93. package/dist/template/measure.d.ts +80 -0
  94. package/dist/template/measure.js +212 -0
  95. package/dist/template/measure.js.map +1 -0
  96. package/dist/template/sample.d.ts +17 -0
  97. package/dist/template/sample.js +96 -0
  98. package/dist/template/sample.js.map +1 -0
  99. package/dist/template/view.d.ts +46 -0
  100. package/dist/template/view.js +38 -0
  101. package/dist/template/view.js.map +1 -0
  102. package/dist/tools.d.ts +68 -0
  103. package/dist/tools.js +266 -0
  104. package/dist/tools.js.map +1 -0
  105. package/dist/util/image.d.ts +11 -0
  106. package/dist/util/image.js +58 -0
  107. package/dist/util/image.js.map +1 -0
  108. package/dist/util/png.d.ts +2 -0
  109. package/dist/util/png.js +50 -0
  110. package/dist/util/png.js.map +1 -0
  111. package/docs/README.md +76 -0
  112. package/docs/api-reference.md +668 -0
  113. package/docs/chat-tools.md +253 -0
  114. package/docs/concepts.md +126 -0
  115. package/docs/deck-format.md +225 -0
  116. package/docs/generating.md +218 -0
  117. package/docs/getting-started.md +139 -0
  118. package/docs/languages.md +83 -0
  119. package/docs/layout-freedom.md +113 -0
  120. package/docs/manifest-format.md +207 -0
  121. package/docs/providers.md +236 -0
  122. package/docs/rendering.md +172 -0
  123. package/docs/template-studio.md +369 -0
  124. package/docs/troubleshooting.md +166 -0
  125. package/package.json +64 -4
@@ -0,0 +1,65 @@
1
+ import { isImageRef, toParagraphs } from '../deck/spec.js';
2
+ import { PptxPackage, readRels, resolveTarget } from '../pptx/package.js';
3
+ import { readPresentation } from '../pptx/presentation.js';
4
+ import { NS, descendants, parseXml, path, rootElement } from '../pptx/xml.js';
5
+ import { effectiveSlots, slotSources } from '../template/manifest.js';
6
+ import { indexShapes } from './render.js';
7
+ const normalize = (text) => text.replace(/\s+/g, ' ').trim();
8
+ /**
9
+ * Recovers the pictures of a deck from a pptx that was rendered from it, keyed by asset id.
10
+ * With this, a deck's JSON and its pptx are all that has to be stored between edits: generated
11
+ * photos are read back instead of being generated, and paid for, again.
12
+ *
13
+ * Only slides that still match the deck are used. If the file was changed by hand (slides
14
+ * added, removed or reordered, or a title retyped), those slides are skipped.
15
+ */
16
+ export function extractAssets(template, deck, pptx) {
17
+ const assets = {};
18
+ const pkg = PptxPackage.load(pptx);
19
+ const slides = readPresentation(pkg).slides;
20
+ if (slides.length !== deck.slides.length)
21
+ return assets;
22
+ const patterns = new Map(template.manifest.patterns.map((pattern) => [pattern.id, pattern]));
23
+ const mirrored = (deck.direction ?? template.manifest.direction) !== template.manifest.direction;
24
+ deck.slides.forEach((slide, index) => {
25
+ const pattern = patterns.get(slide.pattern);
26
+ const part = slides[index]?.part;
27
+ if (!pattern || !part || !pkg.has(part))
28
+ return;
29
+ const shapes = indexShapes(rootElement(parseXml(pkg.readText(part))));
30
+ const sources = slotSources(pattern, mirrored, slide.items);
31
+ const slots = effectiveSlots(pattern, slide.items);
32
+ const valueOf = (slotName) => slide.slots[sources.get(slotName) ?? slotName];
33
+ // Check one text slot to be sure this is still the slide the deck describes.
34
+ const probe = slots.find((slot) => {
35
+ const value = valueOf(slot.name);
36
+ return slot.kind === 'text' && (typeof value === 'string' || Array.isArray(value));
37
+ });
38
+ if (probe) {
39
+ const shape = shapes.get(probe.shapeId);
40
+ const expected = normalize(toParagraphs(valueOf(probe.name)).join(' '));
41
+ const actual = shape
42
+ ? normalize(descendants(shape, NS.a, 'p')
43
+ .map((paragraph) => descendants(paragraph, NS.a, 't')
44
+ .map((node) => node.textContent ?? '')
45
+ .join(''))
46
+ .join(' '))
47
+ : undefined;
48
+ if (actual !== expected)
49
+ return;
50
+ }
51
+ const targets = new Map(readRels(pkg, part).map((rel) => [rel.id, resolveTarget(part, rel.target)]));
52
+ for (const slot of slots) {
53
+ const value = valueOf(slot.name);
54
+ if (slot.kind !== 'image' || !isImageRef(value))
55
+ continue;
56
+ const shape = shapes.get(slot.shapeId);
57
+ const blip = shape && path(shape, [NS.p, 'blipFill'], [NS.a, 'blip']);
58
+ const target = targets.get(blip?.getAttributeNS(NS.r, 'embed') ?? '');
59
+ if (target && pkg.has(target))
60
+ assets[value.asset] = pkg.read(target);
61
+ }
62
+ });
63
+ return assets;
64
+ }
65
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/render/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAErE;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,QAAkB,EAAE,IAAc,EAAE,IAAgB;IAChF,MAAM,MAAM,GAA+B,EAAE,CAAC;IAC9C,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IAExD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;IAEjG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;QACjC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAChD,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC;QAErF,6EAA6E;QAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YAChC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACrF,CAAC,CAAC,CAAC;QACH,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAsB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7F,MAAM,MAAM,GAAG,KAAK;gBAClB,CAAC,CAAC,SAAS,CACP,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC;qBAC1B,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CACjB,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC;qBAC9B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;qBACrC,IAAI,CAAC,EAAE,CAAC,CACZ;qBACA,IAAI,CAAC,GAAG,CAAC,CACb;gBACH,CAAC,CAAC,SAAS,CAAC;YACd,IAAI,MAAM,KAAK,QAAQ;gBAAE,OAAO;QAClC,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACrG,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YACtE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACtE,IAAI,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Element } from '../pptx/xml.ts';
2
+ export interface PictureFill {
3
+ /** Relationship id of the new image on the slide. */
4
+ relId: string;
5
+ /** Pixel size of the new image. */
6
+ width: number;
7
+ height: number;
8
+ /** `cover` crops the image to the frame; `contain` shrinks the frame to the image. */
9
+ fit: 'cover' | 'contain';
10
+ alt?: string;
11
+ /** Area the picture may use, in slide units (EMU), replacing the sample picture's own frame. */
12
+ area?: {
13
+ x: number;
14
+ y: number;
15
+ cx: number;
16
+ cy: number;
17
+ };
18
+ }
19
+ /** Swaps the image of a `p:pic`, keeping its frame, geometry (e.g. rounded corners) and effects. */
20
+ export declare function setPicture(pic: Element, fill: PictureFill): void;
@@ -0,0 +1,114 @@
1
+ import { NS, childElement, childElements, descendants, isElement, path, removeNode } from '../pptx/xml.js';
2
+ /** Swaps the image of a `p:pic`, keeping its frame, geometry (e.g. rounded corners) and effects. */
3
+ export function setPicture(pic, fill) {
4
+ if (pic.namespaceURI !== NS.p || pic.localName !== 'pic') {
5
+ throw new Error('image slots must point at a picture shape');
6
+ }
7
+ const blipFill = childElement(pic, NS.p, 'blipFill');
8
+ const blip = blipFill && childElement(blipFill, NS.a, 'blip');
9
+ const xfrm = path(pic, [NS.p, 'spPr'], [NS.a, 'xfrm']);
10
+ const off = xfrm && childElement(xfrm, NS.a, 'off');
11
+ const ext = xfrm && childElement(xfrm, NS.a, 'ext');
12
+ if (!blipFill || !blip || !off || !ext)
13
+ throw new Error('picture shape is missing its image or its frame');
14
+ const doc = pic.ownerDocument;
15
+ if (!doc)
16
+ throw new Error('picture is detached from its document');
17
+ const relPrefix = pic.lookupPrefix(NS.r) ?? 'r';
18
+ blip.setAttributeNS(NS.r, `${relPrefix}:embed`, fill.relId);
19
+ blip.removeAttributeNS(NS.r, 'link');
20
+ // An SVG variant stored next to the old image would win over the new bitmap.
21
+ for (const extension of descendants(blip, NS.a, 'ext')) {
22
+ if (childElements(extension).some((child) => child.localName === 'svgBlip'))
23
+ removeNode(extension);
24
+ }
25
+ const extensionList = childElement(blip, NS.a, 'extLst');
26
+ if (extensionList && childElements(extensionList).length === 0)
27
+ removeNode(extensionList);
28
+ if (fill.area) {
29
+ const parent = pic.parentNode;
30
+ if (!parent || parent.localName !== 'spTree')
31
+ throw new Error('a picture area can only be set for a picture that is not inside a group');
32
+ off.setAttribute('x', String(Math.round(fill.area.x)));
33
+ off.setAttribute('y', String(Math.round(fill.area.y)));
34
+ ext.setAttribute('cx', String(Math.round(fill.area.cx)));
35
+ ext.setAttribute('cy', String(Math.round(fill.area.cy)));
36
+ }
37
+ const frame = {
38
+ x: Number(off.getAttribute('x') ?? 0),
39
+ y: Number(off.getAttribute('y') ?? 0),
40
+ cx: Number(ext.getAttribute('cx') ?? 0),
41
+ cy: Number(ext.getAttribute('cy') ?? 0),
42
+ };
43
+ const scale = ancestorScale(pic);
44
+ const frameAspect = (frame.cx * scale.sx) / (frame.cy * scale.sy);
45
+ const imageAspect = fill.width / fill.height;
46
+ const usable = Number.isFinite(frameAspect) && frameAspect > 0 && Number.isFinite(imageAspect) && imageAspect > 0;
47
+ const oldCrop = childElement(blipFill, NS.a, 'srcRect');
48
+ if (oldCrop)
49
+ removeNode(oldCrop);
50
+ if (usable && fill.fit === 'cover') {
51
+ // Crop the image symmetrically until its aspect ratio matches the frame.
52
+ const crop = doc.createElementNS(NS.a, `${blip.prefix ? `${blip.prefix}:` : ''}srcRect`);
53
+ if (imageAspect > frameAspect) {
54
+ const side = Math.round(((1 - frameAspect / imageAspect) / 2) * 100000);
55
+ if (side > 0) {
56
+ crop.setAttribute('l', String(side));
57
+ crop.setAttribute('r', String(side));
58
+ }
59
+ }
60
+ else {
61
+ const side = Math.round(((1 - imageAspect / frameAspect) / 2) * 100000);
62
+ if (side > 0) {
63
+ crop.setAttribute('t', String(side));
64
+ crop.setAttribute('b', String(side));
65
+ }
66
+ }
67
+ if (crop.attributes.length > 0)
68
+ blipFill.insertBefore(crop, blip.nextSibling);
69
+ }
70
+ else if (usable) {
71
+ // Shrink the frame around its centre so the whole image shows undistorted.
72
+ if (imageAspect > frameAspect) {
73
+ const cy = Math.round((frame.cx * scale.sx) / imageAspect / scale.sy);
74
+ off.setAttribute('y', String(Math.round(frame.y + (frame.cy - cy) / 2)));
75
+ ext.setAttribute('cy', String(cy));
76
+ }
77
+ else {
78
+ const cx = Math.round((frame.cy * scale.sy * imageAspect) / scale.sx);
79
+ off.setAttribute('x', String(Math.round(frame.x + (frame.cx - cx) / 2)));
80
+ ext.setAttribute('cx', String(cx));
81
+ }
82
+ }
83
+ if (!childElement(blipFill, NS.a, 'stretch') && !childElement(blipFill, NS.a, 'tile')) {
84
+ const prefix = blip.prefix ? `${blip.prefix}:` : '';
85
+ const stretch = doc.createElementNS(NS.a, `${prefix}stretch`);
86
+ stretch.appendChild(doc.createElementNS(NS.a, `${prefix}fillRect`));
87
+ blipFill.appendChild(stretch);
88
+ }
89
+ const props = path(pic, [NS.p, 'nvPicPr'], [NS.p, 'cNvPr']);
90
+ if (props) {
91
+ props.removeAttribute('title');
92
+ props.setAttribute('descr', fill.alt ?? '');
93
+ }
94
+ }
95
+ /** Combined scale of every group the element sits in (child units to slide units). */
96
+ function ancestorScale(element) {
97
+ let sx = 1;
98
+ let sy = 1;
99
+ for (let node = element.parentNode; node && isElement(node); node = node.parentNode) {
100
+ if (node.namespaceURI !== NS.p || node.localName !== 'grpSp')
101
+ continue;
102
+ const xfrm = path(node, [NS.p, 'grpSpPr'], [NS.a, 'xfrm']);
103
+ const ext = xfrm && childElement(xfrm, NS.a, 'ext');
104
+ const childExt = xfrm && childElement(xfrm, NS.a, 'chExt');
105
+ const cx = Number(childExt?.getAttribute('cx') ?? 0);
106
+ const cy = Number(childExt?.getAttribute('cy') ?? 0);
107
+ if (cx > 0)
108
+ sx *= Number(ext?.getAttribute('cx') ?? cx) / cx;
109
+ if (cy > 0)
110
+ sy *= Number(ext?.getAttribute('cy') ?? cy) / cy;
111
+ }
112
+ return { sx, sy };
113
+ }
114
+ //# sourceMappingURL=picture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picture.js","sourceRoot":"","sources":["../../src/render/picture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { Issue, LayoutMode } from '../deck/validate.ts';
2
+ import type { DeckSpec } from '../deck/spec.ts';
3
+ import { PptxPackage } from '../pptx/package.ts';
4
+ import type { Element } from '../pptx/xml.ts';
5
+ import type { TemplateManifest } from '../template/manifest.ts';
6
+ /** A template pptx, unzipped once, together with its manifest. Reuse it across renders. */
7
+ export interface Template {
8
+ pkg: PptxPackage;
9
+ manifest: TemplateManifest;
10
+ }
11
+ export declare function loadTemplate(pptx: Uint8Array, manifest: TemplateManifest): Template;
12
+ export interface RenderOptions {
13
+ /** Image bytes by asset id, for the image references in the deck. */
14
+ assets?: Record<string, Uint8Array>;
15
+ /**
16
+ * `strict` (default): every slot must be filled; nothing on a slide moves or disappears.
17
+ * `adaptive`: optional slots may be left out, and their shapes are removed.
18
+ */
19
+ layout?: LayoutMode;
20
+ }
21
+ export interface RenderResult {
22
+ pptx: Uint8Array;
23
+ /** Non-blocking findings, e.g. text longer than a slot's budget. */
24
+ warnings: Issue[];
25
+ }
26
+ /**
27
+ * Builds a pptx from a deck spec by cloning the template slide of each pattern
28
+ * and filling its slots. Deterministic: no model calls, no network.
29
+ */
30
+ export declare function renderDeck(template: Template, deck: DeckSpec, options?: RenderOptions): RenderResult;
31
+ /** Maps `p:cNvPr/@id` to the shape element that owns it. */
32
+ export declare function indexShapes(root: Element): Map<string, Element>;
@@ -0,0 +1,247 @@
1
+ import { DeckValidationError, resolveSlot, validateDeck } from '../deck/validate.js';
2
+ import { ContentTypes, PptxPackage, isRelType, nextRelId, pruneUnreachable, readRels, relativeTarget, relsPath, writeRels, } from '../pptx/package.js';
3
+ import { readPresentation } from '../pptx/presentation.js';
4
+ import { NS, childElement, childElements, descendants, parseXml, removeNode, rootElement, serializeXml } from '../pptx/xml.js';
5
+ import { defaultFit, effectiveSlots, itemCount, scalesWithText, slotSources } from '../template/manifest.js';
6
+ import { readImageInfo } from '../util/image.js';
7
+ import { CHART_CONTENT_TYPE, CHART_REL_TYPE, WORKBOOK_CONTENT_TYPE, WORKBOOK_REL_TYPE, buildChartWorkbook, buildChartXml, chartFrameXml } from './chart.js';
8
+ import { setPicture } from './picture.js';
9
+ import { setTable } from './table.js';
10
+ import { applyRepeat, placeShape } from './repeat.js';
11
+ import { adjustText, setShapeText } from './text.js';
12
+ const SLIDE_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml';
13
+ const IMAGE_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image';
14
+ const SLIDE_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide';
15
+ const P14 = 'http://schemas.microsoft.com/office/powerpoint/2010/main';
16
+ const FIRST_SLIDE_ID = 256;
17
+ export function loadTemplate(pptx, manifest) {
18
+ return { pkg: PptxPackage.load(pptx), manifest };
19
+ }
20
+ /**
21
+ * Builds a pptx from a deck spec by cloning the template slide of each pattern
22
+ * and filling its slots. Deterministic: no model calls, no network.
23
+ */
24
+ export function renderDeck(template, deck, options = {}) {
25
+ const { manifest } = template;
26
+ const layout = options.layout ?? 'strict';
27
+ const assets = options.assets ?? {};
28
+ const issues = validateDeck(manifest, deck, { layout, assets: Object.keys(assets) });
29
+ const errors = issues.filter((issue) => issue.severity === 'error');
30
+ if (errors.length > 0)
31
+ throw new DeckValidationError(errors);
32
+ const source = template.pkg;
33
+ const out = source.clone();
34
+ const pres = readPresentation(source);
35
+ const types = ContentTypes.read(source);
36
+ const patterns = new Map(manifest.patterns.map((pattern) => [pattern.id, pattern]));
37
+ const directionChanged = (deck.direction ?? manifest.direction) !== manifest.direction;
38
+ const firstSlide = pres.slides[0];
39
+ if (!firstSlide)
40
+ throw new Error('The template has no slides');
41
+ const slideDir = firstSlide.part.slice(0, firstSlide.part.lastIndexOf('/'));
42
+ const mediaDir = `${pres.part.slice(0, pres.part.lastIndexOf('/') + 1)}media`;
43
+ // The template's own slides are replaced wholesale by the deck's slides.
44
+ for (const slide of pres.slides) {
45
+ out.delete(slide.part);
46
+ out.delete(relsPath(slide.part));
47
+ types.removeOverride(slide.part);
48
+ }
49
+ const media = new Map();
50
+ const addMedia = (assetId) => {
51
+ const known = media.get(assetId);
52
+ if (known)
53
+ return known;
54
+ const data = assets[assetId];
55
+ const info = readImageInfo(data);
56
+ let index = media.size + 1;
57
+ let part = `${mediaDir}/slotdeck-${index}.${info.extension}`;
58
+ while (out.has(part))
59
+ part = `${mediaDir}/slotdeck-${++index}.${info.extension}`;
60
+ out.write(part, data);
61
+ types.ensureDefault(info.extension, info.contentType);
62
+ const entry = { part, info };
63
+ media.set(assetId, entry);
64
+ return entry;
65
+ };
66
+ // A native chart is two new parts: the chart itself and the workbook that holds its data.
67
+ const partsDir = pres.part.slice(0, pres.part.lastIndexOf('/') + 1);
68
+ let chartCount = 0;
69
+ const addChart = (chart, slot) => {
70
+ let chartPart;
71
+ let workbookPart;
72
+ do {
73
+ chartCount++;
74
+ chartPart = `${partsDir}charts/chart${chartCount}.xml`;
75
+ workbookPart = `${partsDir}embeddings/Microsoft_Excel_Sheet${chartCount}.xlsx`;
76
+ } while (out.has(chartPart) || out.has(workbookPart));
77
+ out.write(workbookPart, buildChartWorkbook(chart));
78
+ out.write(chartPart, buildChartXml(chart, slot, 'rId1', deck.direction ?? manifest.direction));
79
+ writeRels(out, chartPart, [{ id: 'rId1', type: WORKBOOK_REL_TYPE, target: relativeTarget(chartPart, workbookPart), external: false }]);
80
+ types.setOverride(chartPart, CHART_CONTENT_TYPE);
81
+ types.ensureDefault('xlsx', WORKBOOK_CONTENT_TYPE);
82
+ return chartPart;
83
+ };
84
+ const newSlideParts = [];
85
+ deck.slides.forEach((slide, index) => {
86
+ const number = index + 1;
87
+ const pattern = patterns.get(slide.pattern);
88
+ const sourceSlide = pres.slides[pattern.sourceSlide - 1];
89
+ if (!sourceSlide) {
90
+ throw new Error(`Pattern "${pattern.id}" points at slide ${pattern.sourceSlide}, but the template has ${pres.slides.length} slides`);
91
+ }
92
+ const doc = parseXml(source.readText(sourceSlide.part));
93
+ const root = rootElement(doc);
94
+ // Notes belong to the template's sample content, so they are not carried over.
95
+ let rels = readRels(source, sourceSlide.part).filter((rel) => !isRelType(rel, 'notesSlide'));
96
+ const part = `${slideDir}/slide${number}.xml`;
97
+ // A row of items is first brought to the number the slide asks for; the shapes it copies get new ids.
98
+ if (pattern.repeat)
99
+ applyRepeat(indexShapes(root), pattern.repeat, itemCount(pattern, slide.items), pres.slideWidth);
100
+ const shapes = indexShapes(root);
101
+ const sources = slotSources(pattern, directionChanged, slide.items);
102
+ const textScale = deck.textScale ?? 1;
103
+ for (const slot of effectiveSlots(pattern, slide.items)) {
104
+ const shape = shapes.get(slot.shapeId);
105
+ if (!shape) {
106
+ throw new Error(`Pattern "${pattern.id}": slot "${slot.name}" points at shape #${slot.shapeId}, which is not on template slide ${pattern.sourceSlide}`);
107
+ }
108
+ const resolved = resolveSlot(slot, { ...slide, slots: slide.slots ?? {} }, deck, layout, sources.get(slot.name));
109
+ if ('error' in resolved)
110
+ throw new Error(`slide ${number} / ${slot.name}: ${resolved.error}`);
111
+ const action = resolved.action;
112
+ if (action.type === 'remove') {
113
+ removeNode(shape);
114
+ }
115
+ else if (action.type === 'text' && slot.kind === 'text') {
116
+ const align = slot.alignOnDirectionChange ?? manifest.alignOnDirectionChange ?? 'flip';
117
+ const text = { flipAlign: directionChanged && align === 'flip' };
118
+ setShapeText(shape, action.paragraphs, slot.styleRun ? { ...text, styleRun: slot.styleRun } : text);
119
+ if (slot.box)
120
+ placeShape(shape, slot.box, pres.slideWidth, pres.slideHeight);
121
+ const change = {};
122
+ if (slot.fontSize !== undefined)
123
+ change.size = slot.fontSize;
124
+ if (textScale !== 1 && scalesWithText(slot))
125
+ change.scale = textScale;
126
+ if (slot.paragraphGap !== undefined)
127
+ change.paragraphGap = slot.paragraphGap;
128
+ if (Object.keys(change).length > 0)
129
+ adjustText(shape, change);
130
+ }
131
+ else if (action.type === 'image' && slot.kind === 'image') {
132
+ const image = addMedia(action.image.asset);
133
+ const relId = nextRelId(rels);
134
+ rels.push({ id: relId, type: IMAGE_REL_TYPE, target: relativeTarget(part, image.part), external: false });
135
+ const fill = { relId, width: image.info.width, height: image.info.height, fit: defaultFit(slot) };
136
+ if (action.image.alt !== undefined)
137
+ fill.alt = action.image.alt;
138
+ if (slot.box) {
139
+ fill.area = {
140
+ x: slot.box.x * pres.slideWidth,
141
+ y: slot.box.y * pres.slideHeight,
142
+ cx: slot.box.w * pres.slideWidth,
143
+ cy: slot.box.h * pres.slideHeight,
144
+ };
145
+ }
146
+ setPicture(shape, fill);
147
+ }
148
+ else if (action.type === 'table' && slot.kind === 'table') {
149
+ setTable(shape, action.table, slot, deck.direction ?? manifest.direction);
150
+ }
151
+ else if (action.type === 'chart' && slot.kind === 'chart') {
152
+ // The chart takes the place of the sample picture, in the same stacking position.
153
+ const parent = shape.parentNode;
154
+ if (!parent || parent.localName !== 'spTree')
155
+ throw new Error(`slide ${number} / ${slot.name}: a chart slot must point at a shape that is not inside a group`);
156
+ const xfrm = descendants(shape, NS.a, 'xfrm')[0] ?? childElement(shape, NS.p, 'xfrm');
157
+ const off = xfrm && childElement(xfrm, NS.a, 'off');
158
+ const ext = xfrm && childElement(xfrm, NS.a, 'ext');
159
+ const area = slot.box
160
+ ? { x: slot.box.x * pres.slideWidth, y: slot.box.y * pres.slideHeight, cx: slot.box.w * pres.slideWidth, cy: slot.box.h * pres.slideHeight }
161
+ : { x: Number(off?.getAttribute('x') ?? 0), y: Number(off?.getAttribute('y') ?? 0), cx: Number(ext?.getAttribute('cx') ?? 0), cy: Number(ext?.getAttribute('cy') ?? 0) };
162
+ if (!(area.cx > 0 && area.cy > 0))
163
+ throw new Error(`slide ${number} / ${slot.name}: the chart slot has no area`);
164
+ const chartPart = addChart(action.chart, slot);
165
+ const relId = nextRelId(rels);
166
+ rels.push({ id: relId, type: CHART_REL_TYPE, target: relativeTarget(part, chartPart), external: false });
167
+ const alt = `${action.chart.type} chart: ${action.chart.series.map((series) => series.name).filter(Boolean).join(', ')}`;
168
+ const frame = doc.importNode(rootElement(parseXml(chartFrameXml(slot.shapeId, relId, area, alt))), true);
169
+ parent.replaceChild(frame, shape);
170
+ }
171
+ }
172
+ setSlideNumber(root, number);
173
+ // Images that were replaced leave relationships nobody uses; drop them so their media can go too.
174
+ const used = usedRelationshipIds(root);
175
+ rels = rels.filter((rel) => !isRelType(rel, 'image') || used.has(rel.id));
176
+ out.write(part, serializeXml(doc));
177
+ writeRels(out, part, rels);
178
+ types.setOverride(part, SLIDE_CONTENT_TYPE);
179
+ newSlideParts.push(part);
180
+ });
181
+ // Point the presentation at the new slides.
182
+ const sourcePresRels = readRels(source, pres.part);
183
+ const slideRelType = sourcePresRels.find((rel) => isRelType(rel, 'slide'))?.type ?? SLIDE_REL_TYPE;
184
+ const presRels = sourcePresRels.filter(
185
+ // Revision history describes the template's slides, not the new ones.
186
+ (rel) => !isRelType(rel, 'slide') && !isRelType(rel, 'changesInfo') && !isRelType(rel, 'revisionInfo'));
187
+ const presDoc = parseXml(source.readText(pres.part));
188
+ const presRoot = rootElement(presDoc);
189
+ const slideList = childElement(presRoot, NS.p, 'sldIdLst');
190
+ if (!slideList)
191
+ throw new Error('The template presentation has no slide list');
192
+ for (const entry of childElements(slideList))
193
+ removeNode(entry);
194
+ const prefix = presRoot.prefix ? `${presRoot.prefix}:` : '';
195
+ const relPrefix = presRoot.lookupPrefix(NS.r) ?? 'r';
196
+ newSlideParts.forEach((part, index) => {
197
+ const relId = nextRelId(presRels);
198
+ presRels.push({ id: relId, type: slideRelType, target: relativeTarget(pres.part, part), external: false });
199
+ const entry = presDoc.createElementNS(NS.p, `${prefix}sldId`);
200
+ entry.setAttribute('id', String(FIRST_SLIDE_ID + index));
201
+ entry.setAttributeNS(NS.r, `${relPrefix}:id`, relId);
202
+ slideList.appendChild(entry);
203
+ });
204
+ // Named sections list the template's slide ids, which no longer exist.
205
+ for (const sections of descendants(presRoot, P14, 'sectionLst')) {
206
+ if (sections.parentNode)
207
+ removeNode(sections.parentNode);
208
+ }
209
+ out.write(pres.part, serializeXml(presDoc));
210
+ writeRels(out, pres.part, presRels);
211
+ pruneUnreachable(out, types);
212
+ types.save(out);
213
+ return { pptx: out.save(), warnings: issues.filter((issue) => issue.severity === 'warning') };
214
+ }
215
+ /** Maps `p:cNvPr/@id` to the shape element that owns it. */
216
+ export function indexShapes(root) {
217
+ const shapes = new Map();
218
+ for (const props of descendants(root, NS.p, 'cNvPr')) {
219
+ const shape = props.parentNode?.parentNode;
220
+ const id = props.getAttribute('id');
221
+ if (id && shape && shape.nodeType === 1)
222
+ shapes.set(id, shape);
223
+ }
224
+ return shapes;
225
+ }
226
+ /** PowerPoint recomputes slide-number fields, but other viewers show the cached text. */
227
+ function setSlideNumber(root, number) {
228
+ for (const field of descendants(root, NS.a, 'fld')) {
229
+ if (field.getAttribute('type') !== 'slidenum')
230
+ continue;
231
+ const text = childElement(field, NS.a, 't');
232
+ if (text)
233
+ text.textContent = String(number);
234
+ }
235
+ }
236
+ function usedRelationshipIds(root) {
237
+ const used = new Set();
238
+ for (const element of [root, ...Array.from(root.getElementsByTagNameNS('*', '*'))]) {
239
+ for (let i = 0; i < element.attributes.length; i++) {
240
+ const attr = element.attributes.item(i);
241
+ if (attr && attr.namespaceURI === NS.r)
242
+ used.add(attr.value);
243
+ }
244
+ }
245
+ return used;
246
+ }
247
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/render/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Element } from '../pptx/xml.ts';
2
+ import type { RepeatDef, SlideBox } from '../template/manifest.ts';
3
+ /** The transform element that positions a shape within its parent. */
4
+ export declare function shapeTransform(shape: Element): Element | undefined;
5
+ /** Places a shape that is not inside a group at a given area of the slide. Sizes are in EMU. */
6
+ export declare function placeShape(shape: Element, box: SlideBox, slideWidth: number, slideHeight: number): void;
7
+ /**
8
+ * Gives a row or grid of items the requested number: removes the surplus or copies the last
9
+ * item, then lays the items out again around the centre of the area they occupied. Rows keep
10
+ * the template's spacing when there is room and tighten when there is not; a grid uses as few
11
+ * rows as the count needs, each row centred.
12
+ *
13
+ * Copied shapes get the id of their original plus a multiple of {@link COPY_ID_STEP}.
14
+ */
15
+ export declare function applyRepeat(shapes: Map<string, Element>, repeat: RepeatDef, count: number, slideWidth: number): void;