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,202 @@
1
+ import { strFromU8, strToU8, unzipSync, zipSync } from 'fflate';
2
+ import { NS, XML_HEADER, childElements, escapeXmlAttr, parseXml, rootElement } from './xml.js';
3
+ const CONTENT_TYPES = '[Content_Types].xml';
4
+ /** Parts that are already compressed; deflating them again only costs time. */
5
+ const STORE_ONLY = /\.(png|jpe?g|gif|webp|fntdata|mp4|m4a|mp3|wmv|xlsx|docx|zip)$/i;
6
+ /** An Office Open XML package: a flat map of part path to bytes. */
7
+ export class PptxPackage {
8
+ files;
9
+ constructor(files) {
10
+ this.files = files;
11
+ }
12
+ static load(bytes) {
13
+ const entries = unzipSync(bytes);
14
+ const files = new Map();
15
+ for (const [name, data] of Object.entries(entries)) {
16
+ if (name.endsWith('/'))
17
+ continue;
18
+ files.set(name, data);
19
+ }
20
+ if (!files.has(CONTENT_TYPES)) {
21
+ throw new Error('Not an Office Open XML package: [Content_Types].xml is missing');
22
+ }
23
+ return new PptxPackage(files);
24
+ }
25
+ /** Cheap copy: the byte arrays are shared and must be treated as immutable. */
26
+ clone() {
27
+ return new PptxPackage(new Map(this.files));
28
+ }
29
+ has(partPath) {
30
+ return this.files.has(partPath);
31
+ }
32
+ paths() {
33
+ return [...this.files.keys()];
34
+ }
35
+ read(partPath) {
36
+ const data = this.files.get(partPath);
37
+ if (!data)
38
+ throw new Error(`Part not found in package: ${partPath}`);
39
+ return data;
40
+ }
41
+ readText(partPath) {
42
+ const text = strFromU8(this.read(partPath));
43
+ return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
44
+ }
45
+ write(partPath, data) {
46
+ this.files.set(partPath, typeof data === 'string' ? strToU8(data) : data);
47
+ }
48
+ delete(partPath) {
49
+ this.files.delete(partPath);
50
+ }
51
+ save() {
52
+ const zippable = {};
53
+ const names = [CONTENT_TYPES, ...this.paths().filter((name) => name !== CONTENT_TYPES)];
54
+ for (const name of names) {
55
+ zippable[name] = [this.read(name), { level: STORE_ONLY.test(name) ? 0 : 6 }];
56
+ }
57
+ // Entries carry a fixed timestamp, so the same content always gives the same bytes.
58
+ return zipSync(zippable, { mtime: new Date(1980, 0, 1) });
59
+ }
60
+ }
61
+ /** `ppt/slides/slide1.xml` -> `ppt/slides/_rels/slide1.xml.rels`; the package root is `''`. */
62
+ export function relsPath(partPath) {
63
+ const slash = partPath.lastIndexOf('/');
64
+ return `${partPath.slice(0, slash + 1)}_rels/${partPath.slice(slash + 1)}.rels`;
65
+ }
66
+ /** Inverse of {@link relsPath}, or `undefined` when the path is not a relationships part. */
67
+ export function relsOwner(path) {
68
+ const match = /^(.*\/)?_rels\/([^/]*)\.rels$/.exec(path);
69
+ return match ? `${match[1] ?? ''}${match[2]}` : undefined;
70
+ }
71
+ export function readRels(pkg, partPath) {
72
+ const file = relsPath(partPath);
73
+ if (!pkg.has(file))
74
+ return [];
75
+ const root = rootElement(parseXml(pkg.readText(file)));
76
+ return childElements(root, NS.rels, 'Relationship').map((el) => ({
77
+ id: el.getAttribute('Id') ?? '',
78
+ type: el.getAttribute('Type') ?? '',
79
+ target: el.getAttribute('Target') ?? '',
80
+ external: el.getAttribute('TargetMode') === 'External',
81
+ }));
82
+ }
83
+ export function writeRels(pkg, partPath, rels) {
84
+ const body = rels
85
+ .map((rel) => `<Relationship Id="${escapeXmlAttr(rel.id)}" Type="${escapeXmlAttr(rel.type)}" Target="${escapeXmlAttr(rel.target)}"` +
86
+ (rel.external ? ' TargetMode="External"' : '') +
87
+ '/>')
88
+ .join('');
89
+ pkg.write(relsPath(partPath), `${XML_HEADER}<Relationships xmlns="${NS.rels}">${body}</Relationships>`);
90
+ }
91
+ /** True when the relationship type ends with the given name, e.g. `isRelType(rel, 'slide')`. */
92
+ export function isRelType(rel, name) {
93
+ return rel.type.endsWith(`/${name}`);
94
+ }
95
+ export function nextRelId(rels) {
96
+ let max = 0;
97
+ for (const rel of rels) {
98
+ const match = /^rId(\d+)$/.exec(rel.id);
99
+ if (match)
100
+ max = Math.max(max, Number(match[1]));
101
+ }
102
+ return `rId${max + 1}`;
103
+ }
104
+ /** Resolves a relationship target against the part that owns it. */
105
+ export function resolveTarget(partPath, target) {
106
+ if (target.startsWith('/'))
107
+ return target.slice(1);
108
+ const segments = partPath.split('/').slice(0, -1);
109
+ for (const segment of target.split('/')) {
110
+ if (segment === '..')
111
+ segments.pop();
112
+ else if (segment !== '.' && segment !== '')
113
+ segments.push(segment);
114
+ }
115
+ return segments.join('/');
116
+ }
117
+ /** The relative target that points from one part to another. */
118
+ export function relativeTarget(fromPart, toPart) {
119
+ const from = fromPart.split('/').slice(0, -1);
120
+ const to = toPart.split('/');
121
+ let common = 0;
122
+ while (common < from.length && common < to.length - 1 && from[common] === to[common])
123
+ common++;
124
+ return [...from.slice(common).map(() => '..'), ...to.slice(common)].join('/');
125
+ }
126
+ // ---------------------------------------------------------------------------
127
+ // Content types
128
+ export class ContentTypes {
129
+ defaults = new Map();
130
+ overrides = new Map();
131
+ static read(pkg) {
132
+ const types = new ContentTypes();
133
+ const root = rootElement(parseXml(pkg.readText(CONTENT_TYPES)));
134
+ for (const el of childElements(root, NS.contentTypes, 'Default')) {
135
+ types.defaults.set((el.getAttribute('Extension') ?? '').toLowerCase(), el.getAttribute('ContentType') ?? '');
136
+ }
137
+ for (const el of childElements(root, NS.contentTypes, 'Override')) {
138
+ types.overrides.set(el.getAttribute('PartName') ?? '', el.getAttribute('ContentType') ?? '');
139
+ }
140
+ return types;
141
+ }
142
+ ensureDefault(extension, contentType) {
143
+ const key = extension.toLowerCase();
144
+ if (!this.defaults.has(key))
145
+ this.defaults.set(key, contentType);
146
+ }
147
+ /** `partPath` is the package path without a leading slash. */
148
+ setOverride(partPath, contentType) {
149
+ this.overrides.set(`/${partPath}`, contentType);
150
+ }
151
+ removeOverride(partPath) {
152
+ this.overrides.delete(`/${partPath}`);
153
+ }
154
+ save(pkg) {
155
+ const defaults = [...this.defaults]
156
+ .map(([ext, type]) => `<Default Extension="${escapeXmlAttr(ext)}" ContentType="${escapeXmlAttr(type)}"/>`)
157
+ .join('');
158
+ const overrides = [...this.overrides]
159
+ .map(([part, type]) => `<Override PartName="${escapeXmlAttr(part)}" ContentType="${escapeXmlAttr(type)}"/>`)
160
+ .join('');
161
+ pkg.write(CONTENT_TYPES, `${XML_HEADER}<Types xmlns="${NS.contentTypes}">${defaults}${overrides}</Types>`);
162
+ }
163
+ }
164
+ // ---------------------------------------------------------------------------
165
+ // Reachability
166
+ /** Every part that can be reached from the package root by following relationships. */
167
+ export function reachableParts(pkg) {
168
+ const seen = new Set();
169
+ const queue = [''];
170
+ while (queue.length > 0) {
171
+ const part = queue.pop();
172
+ for (const rel of readRels(pkg, part)) {
173
+ if (rel.external)
174
+ continue;
175
+ const target = resolveTarget(part, rel.target);
176
+ if (seen.has(target) || !pkg.has(target))
177
+ continue;
178
+ seen.add(target);
179
+ queue.push(target);
180
+ }
181
+ }
182
+ return seen;
183
+ }
184
+ /** Deletes parts nothing points to any more (old slides, their notes, unused media). */
185
+ export function pruneUnreachable(pkg, types) {
186
+ const reachable = reachableParts(pkg);
187
+ for (const file of pkg.paths()) {
188
+ if (file === CONTENT_TYPES)
189
+ continue;
190
+ const owner = relsOwner(file);
191
+ if (owner !== undefined) {
192
+ if (owner !== '' && !reachable.has(owner))
193
+ pkg.delete(file);
194
+ continue;
195
+ }
196
+ if (!reachable.has(file)) {
197
+ pkg.delete(file);
198
+ types.removeOverride(file);
199
+ }
200
+ }
201
+ }
202
+ //# sourceMappingURL=package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.js","sourceRoot":"","sources":["../../src/pptx/package.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { PptxPackage } from './package.ts';
2
+ export interface SlideRef {
3
+ /** `p:sldId/@id` */
4
+ id: string;
5
+ relId: string;
6
+ /** Package path, e.g. `ppt/slides/slide3.xml` */
7
+ part: string;
8
+ }
9
+ export interface PresentationInfo {
10
+ /** Package path of the main presentation part. */
11
+ part: string;
12
+ /** Slides in presentation order. */
13
+ slides: SlideRef[];
14
+ /** Slide size in EMU. */
15
+ slideWidth: number;
16
+ slideHeight: number;
17
+ /** Size in points of text that sets no size of its own, when the presentation states one. */
18
+ defaultFontSize?: number;
19
+ }
20
+ export declare function readPresentation(pkg: PptxPackage): PresentationInfo;
@@ -0,0 +1,31 @@
1
+ import { isRelType, readRels, resolveTarget } from './package.js';
2
+ import { NS, childElement, childElements, parseXml, path, rootElement } from './xml.js';
3
+ export function readPresentation(pkg) {
4
+ const main = readRels(pkg, '').find((rel) => isRelType(rel, 'officeDocument'));
5
+ if (!main)
6
+ throw new Error('Package has no main document relationship');
7
+ const part = resolveTarget('', main.target);
8
+ const root = rootElement(parseXml(pkg.readText(part)));
9
+ const targets = new Map(readRels(pkg, part).map((rel) => [rel.id, resolveTarget(part, rel.target)]));
10
+ const list = childElement(root, NS.p, 'sldIdLst');
11
+ const slides = [];
12
+ for (const el of list ? childElements(list, NS.p, 'sldId') : []) {
13
+ const relId = el.getAttributeNS(NS.r, 'id') ?? '';
14
+ const target = targets.get(relId);
15
+ if (!target)
16
+ throw new Error(`Slide relationship ${relId} is missing from ${part}`);
17
+ slides.push({ id: el.getAttribute('id') ?? '', relId, part: target });
18
+ }
19
+ const size = childElement(root, NS.p, 'sldSz');
20
+ const info = {
21
+ part,
22
+ slides,
23
+ slideWidth: Number(size?.getAttribute('cx') ?? 0),
24
+ slideHeight: Number(size?.getAttribute('cy') ?? 0),
25
+ };
26
+ const defaultSize = Number(path(root, [NS.p, 'defaultTextStyle'], [NS.a, 'lvl1pPr'], [NS.a, 'defRPr'])?.getAttribute('sz') ?? 0);
27
+ if (defaultSize > 0)
28
+ info.defaultFontSize = defaultSize / 100;
29
+ return info;
30
+ }
31
+ //# sourceMappingURL=presentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation.js","sourceRoot":"","sources":["../../src/pptx/presentation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAsBxF,MAAM,UAAU,gBAAgB,CAAC,GAAgB;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5C,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvD,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;IAErG,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAClD,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAChE,MAAM,KAAK,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,oBAAoB,IAAI,EAAE,CAAC,CAAC;QACpF,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAqB;QAC7B,IAAI;QACJ,MAAM;QACN,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACnD,CAAC;IACF,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjI,IAAI,WAAW,GAAG,CAAC;QAAE,IAAI,CAAC,eAAe,GAAG,WAAW,GAAG,GAAG,CAAC;IAC9D,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { Document, Element, Node } from '@xmldom/xmldom';
2
+ export type { Document, Element, Node };
3
+ export declare const NS: {
4
+ readonly a: 'http://schemas.openxmlformats.org/drawingml/2006/main';
5
+ readonly p: 'http://schemas.openxmlformats.org/presentationml/2006/main';
6
+ readonly r: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
7
+ readonly rels: 'http://schemas.openxmlformats.org/package/2006/relationships';
8
+ readonly contentTypes: 'http://schemas.openxmlformats.org/package/2006/content-types';
9
+ };
10
+ export declare const XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
11
+ export declare function parseXml(text: string): Document;
12
+ export declare function serializeXml(doc: Document): string;
13
+ export declare function rootElement(doc: Document): Element;
14
+ export declare function isElement(node: Node | null | undefined): node is Element;
15
+ /** Direct child elements, optionally filtered by namespace and local name. */
16
+ export declare function childElements(parent: Node, ns?: string, local?: string): Element[];
17
+ export declare function childElement(parent: Node, ns: string, local: string): Element | undefined;
18
+ /** Follows a chain of child element names, e.g. `path(sp, [NS.p, 'spPr'], [NS.a, 'xfrm'])`. */
19
+ export declare function path(parent: Node, ...steps: Array<readonly [string, string]>): Element | undefined;
20
+ /** All descendant elements with the given name, as a static array (safe to mutate the tree while iterating). */
21
+ export declare function descendants(parent: Element | Document, ns: string, local: string): Element[];
22
+ export declare function removeNode(node: Node): void;
23
+ export declare function escapeXmlAttr(value: string): string;
@@ -0,0 +1,67 @@
1
+ import { DOMParser, XMLSerializer } from '@xmldom/xmldom';
2
+ export const NS = {
3
+ a: 'http://schemas.openxmlformats.org/drawingml/2006/main',
4
+ p: 'http://schemas.openxmlformats.org/presentationml/2006/main',
5
+ r: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',
6
+ rels: 'http://schemas.openxmlformats.org/package/2006/relationships',
7
+ contentTypes: 'http://schemas.openxmlformats.org/package/2006/content-types',
8
+ };
9
+ export const XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
10
+ export function parseXml(text) {
11
+ return new DOMParser().parseFromString(text, 'text/xml');
12
+ }
13
+ export function serializeXml(doc) {
14
+ return new XMLSerializer().serializeToString(doc);
15
+ }
16
+ export function rootElement(doc) {
17
+ const root = doc.documentElement;
18
+ if (!root)
19
+ throw new Error('XML document has no root element');
20
+ return root;
21
+ }
22
+ const ELEMENT_NODE = 1;
23
+ export function isElement(node) {
24
+ return !!node && node.nodeType === ELEMENT_NODE;
25
+ }
26
+ /** Direct child elements, optionally filtered by namespace and local name. */
27
+ export function childElements(parent, ns, local) {
28
+ const out = [];
29
+ for (let node = parent.firstChild; node; node = node.nextSibling) {
30
+ if (!isElement(node))
31
+ continue;
32
+ if (ns !== undefined && node.namespaceURI !== ns)
33
+ continue;
34
+ if (local !== undefined && node.localName !== local)
35
+ continue;
36
+ out.push(node);
37
+ }
38
+ return out;
39
+ }
40
+ export function childElement(parent, ns, local) {
41
+ return childElements(parent, ns, local)[0];
42
+ }
43
+ /** Follows a chain of child element names, e.g. `path(sp, [NS.p, 'spPr'], [NS.a, 'xfrm'])`. */
44
+ export function path(parent, ...steps) {
45
+ let current = parent;
46
+ for (const [ns, local] of steps) {
47
+ if (!current)
48
+ return undefined;
49
+ current = childElement(current, ns, local);
50
+ }
51
+ return current;
52
+ }
53
+ /** All descendant elements with the given name, as a static array (safe to mutate the tree while iterating). */
54
+ export function descendants(parent, ns, local) {
55
+ return Array.from(parent.getElementsByTagNameNS(ns, local));
56
+ }
57
+ export function removeNode(node) {
58
+ node.parentNode?.removeChild(node);
59
+ }
60
+ export function escapeXmlAttr(value) {
61
+ return value
62
+ .replace(/&/g, '&amp;')
63
+ .replace(/</g, '&lt;')
64
+ .replace(/>/g, '&gt;')
65
+ .replace(/"/g, '&quot;');
66
+ }
67
+ //# sourceMappingURL=xml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml.js","sourceRoot":"","sources":["../../src/pptx/xml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { ChartValue } from '../deck/spec.ts';
2
+ import type { ChartSlotDef } from '../template/manifest.ts';
3
+ export declare const CHART_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml";
4
+ export declare const CHART_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart";
5
+ export declare const WORKBOOK_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
6
+ export declare const WORKBOOK_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
7
+ export declare const CHART_GRAPHIC_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
8
+ /** The chart part. `workbookRelId` is the relationship from the chart to its workbook. */
9
+ export declare function buildChartXml(chart: ChartValue, slot: ChartSlotDef, workbookRelId: string, direction?: 'rtl' | 'ltr'): string;
10
+ /** The data as an Excel workbook: categories down column A, one series per column from B, names in row 1. */
11
+ export declare function buildChartWorkbook(chart: ChartValue): Uint8Array;
12
+ /** The frame that puts a chart on a slide, in place of the sample picture. Sizes are in EMU. */
13
+ export declare function chartFrameXml(shapeId: string, relId: string, area: {
14
+ x: number;
15
+ y: number;
16
+ cx: number;
17
+ cy: number;
18
+ }, alt: string): string;
@@ -0,0 +1,158 @@
1
+ // Builds a native PowerPoint chart: the chart part, and the small Excel workbook that holds its
2
+ // data so the chart can be edited with "Edit Data".
3
+ import { strToU8, zipSync } from 'fflate';
4
+ import { XML_HEADER, escapeXmlAttr } from '../pptx/xml.js';
5
+ const NS_C = 'http://schemas.openxmlformats.org/drawingml/2006/chart';
6
+ const NS_A = 'http://schemas.openxmlformats.org/drawingml/2006/main';
7
+ const NS_R = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
8
+ export const CHART_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml';
9
+ export const CHART_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart';
10
+ export const WORKBOOK_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/package';
11
+ export const WORKBOOK_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
12
+ export const CHART_GRAPHIC_URI = NS_C;
13
+ /** The earliest date a zip entry can carry. */
14
+ const ZIP_EPOCH = new Date(1980, 0, 1);
15
+ const DEFAULT_COLORS = ['4472C4', 'ED7D31', 'A5A5A5', 'FFC000', '5B9BD5', '70AD47'];
16
+ const SHEET = 'Sheet1';
17
+ const text = (value) => value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
18
+ const hex = (value) => value.replace(/^#/, '').toUpperCase();
19
+ /** Spreadsheet column name for a zero-based index: 0 is A, 26 is AA. */
20
+ function columnName(index) {
21
+ let name = '';
22
+ for (let n = index + 1; n > 0; n = Math.floor((n - 1) / 26))
23
+ name = String.fromCharCode(65 + ((n - 1) % 26)) + name;
24
+ return name;
25
+ }
26
+ const fill = (color) => `<a:solidFill><a:srgbClr val="${hex(color)}"/></a:solidFill>`;
27
+ const line = (color, width = 9525) => `<a:ln w="${width}" cap="flat">${fill(color)}<a:round/></a:ln>`;
28
+ const noLine = '<a:ln><a:noFill/></a:ln>';
29
+ /** The workbook cell range of a series' values, of its name, and of the categories. */
30
+ const ranges = (chart) => {
31
+ const last = chart.categories.length + 1;
32
+ return {
33
+ categories: `${SHEET}!$A$2:$A$${last}`,
34
+ name: (series) => `${SHEET}!$${columnName(series + 1)}$1`,
35
+ values: (series) => `${SHEET}!$${columnName(series + 1)}$2:$${columnName(series + 1)}$${last}`,
36
+ };
37
+ };
38
+ function stringRef(formula, values) {
39
+ const points = values.map((value, index) => `<c:pt idx="${index}"><c:v>${text(value)}</c:v></c:pt>`).join('');
40
+ return `<c:strRef><c:f>${text(formula)}</c:f><c:strCache><c:ptCount val="${values.length}"/>${points}</c:strCache></c:strRef>`;
41
+ }
42
+ function numberRef(formula, values, format) {
43
+ const points = values.map((value, index) => `<c:pt idx="${index}"><c:v>${value}</c:v></c:pt>`).join('');
44
+ return `<c:numRef><c:f>${text(formula)}</c:f><c:numCache><c:formatCode>${text(format)}</c:formatCode><c:ptCount val="${values.length}"/>${points}</c:numCache></c:numRef>`;
45
+ }
46
+ function dataLabels(format, show, position) {
47
+ if (show === 'none')
48
+ return '<c:dLbls><c:delete val="1"/></c:dLbls>';
49
+ return (`<c:dLbls><c:numFmt formatCode="${escapeXmlAttr(format)}" sourceLinked="0"/><c:spPr><a:noFill/>${noLine}</c:spPr>` +
50
+ (position ? `<c:dLblPos val="${position}"/>` : '') +
51
+ `<c:showLegendKey val="0"/><c:showVal val="1"/><c:showCatName val="0"/><c:showSerName val="0"/><c:showPercent val="0"/><c:showBubbleSize val="0"/></c:dLbls>`);
52
+ }
53
+ /** The chart part. `workbookRelId` is the relationship from the chart to its workbook. */
54
+ export function buildChartXml(chart, slot, workbookRelId, direction = 'ltr') {
55
+ const colors = slot.colors && slot.colors.length > 0 ? slot.colors : DEFAULT_COLORS;
56
+ const color = (index) => colors[index % colors.length];
57
+ const lineColor = slot.lineColor ?? 'D9D9D9';
58
+ const format = chart.format === 'percent' ? '0"%"' : 'General';
59
+ const range = ranges(chart);
60
+ const several = chart.series.length > 1;
61
+ const seriesHead = (index) => `<c:idx val="${index}"/><c:order val="${index}"/><c:tx>${stringRef(range.name(index), [chart.series[index]?.name ?? ''])}</c:tx>`;
62
+ const seriesData = (index) => `<c:cat>${stringRef(range.categories, chart.categories)}</c:cat>` +
63
+ `<c:val>${numberRef(range.values(index), chart.series[index]?.values ?? [], format)}</c:val>`;
64
+ const axisText = '<c:majorTickMark val="none"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/>';
65
+ const axisLine = `<c:spPr>${line(lineColor)}</c:spPr>`;
66
+ const gridlines = `<c:majorGridlines><c:spPr>${line(lineColor)}</c:spPr></c:majorGridlines>`;
67
+ const [categoryAxisId, valueAxisId] = [50010001, 50010002];
68
+ // Bars are read by their length, so their axis starts at zero; left to itself PowerPoint
69
+ // starts it near the smallest value, which exaggerates differences.
70
+ const zeroBased = chart.type !== 'line' && chart.series.every((series) => series.values.every((value) => value >= 0));
71
+ /** Category and value axes. Horizontal bars list their categories top to bottom, as a table would. */
72
+ const axes = (horizontal) => `<c:catAx><c:axId val="${categoryAxisId}"/><c:scaling><c:orientation val="${horizontal ? 'maxMin' : 'minMax'}"/></c:scaling>` +
73
+ `<c:delete val="0"/><c:axPos val="${horizontal ? 'l' : 'b'}"/><c:numFmt formatCode="General" sourceLinked="0"/>${axisText}${axisLine}` +
74
+ `<c:crossAx val="${valueAxisId}"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffset val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>` +
75
+ `<c:valAx><c:axId val="${valueAxisId}"/><c:scaling><c:orientation val="minMax"/>${zeroBased ? '<c:min val="0"/>' : ''}</c:scaling>` +
76
+ `<c:delete val="0"/><c:axPos val="${horizontal ? 'b' : 'l'}"/>${gridlines}<c:numFmt formatCode="${escapeXmlAttr(format)}" sourceLinked="0"/>${axisText}` +
77
+ `<c:spPr>${noLine}</c:spPr><c:crossAx val="${categoryAxisId}"/><c:crosses val="${horizontal ? 'max' : 'autoZero'}"/><c:crossBetween val="between"/></c:valAx>`;
78
+ const axisIds = `<c:axId val="${categoryAxisId}"/><c:axId val="${valueAxisId}"/>`;
79
+ let plot;
80
+ if (chart.type === 'pie') {
81
+ const slices = chart.categories
82
+ .map((_, index) => `<c:dPt><c:idx val="${index}"/><c:bubble3D val="0"/><c:spPr>${fill(color(index))}<a:ln w="19050">${fill('FFFFFF')}</a:ln></c:spPr></c:dPt>`)
83
+ .join('');
84
+ plot =
85
+ `<c:pieChart><c:varyColors val="1"/><c:ser>${seriesHead(0)}${slices}${dataLabels(format, 'value', 'outEnd')}${seriesData(0)}</c:ser>` +
86
+ `<c:firstSliceAng val="0"/></c:pieChart>`;
87
+ }
88
+ else if (chart.type === 'line') {
89
+ const series = chart.series
90
+ .map((_, index) => `<c:ser>${seriesHead(index)}<c:spPr><a:ln w="28575" cap="rnd">${fill(color(index))}<a:round/></a:ln></c:spPr>` +
91
+ `<c:marker><c:symbol val="circle"/><c:size val="6"/><c:spPr>${fill(color(index))}${noLine}</c:spPr></c:marker>` +
92
+ `${seriesData(index)}<c:smooth val="0"/></c:ser>`)
93
+ .join('');
94
+ plot = `<c:lineChart><c:grouping val="standard"/><c:varyColors val="0"/>${series}${dataLabels(format, 'none')}<c:marker val="1"/>${axisIds}</c:lineChart>${axes(false)}`;
95
+ }
96
+ else {
97
+ const horizontal = chart.type === 'bar';
98
+ const series = chart.series
99
+ .map((_, index) => `<c:ser>${seriesHead(index)}<c:spPr>${fill(color(index))}</c:spPr><c:invertIfNegative val="0"/>${seriesData(index)}</c:ser>`)
100
+ .join('');
101
+ plot =
102
+ `<c:barChart><c:barDir val="${horizontal ? 'bar' : 'col'}"/><c:grouping val="clustered"/><c:varyColors val="0"/>${series}` +
103
+ `${dataLabels(format, 'value', 'outEnd')}<c:gapWidth val="${several ? 80 : 60}"/>${axisIds}</c:barChart>${axes(horizontal)}`;
104
+ }
105
+ const legend = several || chart.type === 'pie' ? '<c:legend><c:legendPos val="b"/><c:overlay val="0"/></c:legend>' : '';
106
+ const style = slot.text ?? {};
107
+ const font = style.font ? `<a:latin typeface="${escapeXmlAttr(style.font)}"/><a:ea typeface="${escapeXmlAttr(style.font)}"/><a:cs typeface="${escapeXmlAttr(style.font)}"/>` : '';
108
+ const defaults =
109
+ // The paragraph direction makes mixed labels such as "רבעון 1" read in the right order.
110
+ `<c:txPr><a:bodyPr/><a:lstStyle/><a:p><a:pPr${direction === 'rtl' ? ' rtl="1"' : ''}><a:defRPr sz="${Math.round((style.size ?? 10) * 100)}"${style.bold ? ' b="1"' : ''}>` +
111
+ `${style.color ? fill(style.color) : ''}${font}</a:defRPr></a:pPr><a:endParaRPr lang="en-US"/></a:p></c:txPr>`;
112
+ return (`${XML_HEADER}<c:chartSpace xmlns:c="${NS_C}" xmlns:a="${NS_A}" xmlns:r="${NS_R}">` +
113
+ `<c:date1904 val="0"/><c:roundedCorners val="0"/>` +
114
+ `<c:chart><c:autoTitleDeleted val="1"/><c:plotArea><c:layout/>${plot}<c:spPr><a:noFill/>${noLine}</c:spPr></c:plotArea>${legend}` +
115
+ `<c:plotVisOnly val="1"/><c:dispBlanksAs val="gap"/></c:chart>` +
116
+ `<c:spPr><a:noFill/>${noLine}</c:spPr>${defaults}` +
117
+ `<c:externalData r:id="${escapeXmlAttr(workbookRelId)}"><c:autoUpdate val="0"/></c:externalData>` +
118
+ `</c:chartSpace>`);
119
+ }
120
+ /** The data as an Excel workbook: categories down column A, one series per column from B, names in row 1. */
121
+ export function buildChartWorkbook(chart) {
122
+ const stringCell = (reference, value) => `<c r="${reference}" t="inlineStr"><is><t xml:space="preserve">${text(value)}</t></is></c>`;
123
+ const header = `<row r="1">${chart.series.map((series, index) => stringCell(`${columnName(index + 1)}1`, series.name)).join('')}</row>`;
124
+ const rows = chart.categories
125
+ .map((category, row) => {
126
+ const cells = chart.series.map((series, index) => `<c r="${columnName(index + 1)}${row + 2}"><v>${series.values[row] ?? 0}</v></c>`).join('');
127
+ return `<row r="${row + 2}">${stringCell(`A${row + 2}`, category)}${cells}</row>`;
128
+ })
129
+ .join('');
130
+ const main = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';
131
+ const packageRels = 'http://schemas.openxmlformats.org/package/2006/relationships';
132
+ const files = {
133
+ '[Content_Types].xml': `${XML_HEADER}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">` +
134
+ `<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>` +
135
+ `<Default Extension="xml" ContentType="application/xml"/>` +
136
+ `<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>` +
137
+ `<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>` +
138
+ `</Types>`,
139
+ '_rels/.rels': `${XML_HEADER}<Relationships xmlns="${packageRels}">` +
140
+ `<Relationship Id="rId1" Type="${NS_R}/officeDocument" Target="xl/workbook.xml"/></Relationships>`,
141
+ 'xl/workbook.xml': `${XML_HEADER}<workbook xmlns="${main}" xmlns:r="${NS_R}"><sheets><sheet name="${SHEET}" sheetId="1" r:id="rId1"/></sheets></workbook>`,
142
+ 'xl/_rels/workbook.xml.rels': `${XML_HEADER}<Relationships xmlns="${packageRels}">` +
143
+ `<Relationship Id="rId1" Type="${NS_R}/worksheet" Target="worksheets/sheet1.xml"/></Relationships>`,
144
+ 'xl/worksheets/sheet1.xml': `${XML_HEADER}<worksheet xmlns="${main}"><sheetData>${header}${rows}</sheetData></worksheet>`,
145
+ };
146
+ // A fixed timestamp, so the same chart always gives the same bytes.
147
+ return zipSync(Object.fromEntries(Object.entries(files).map(([name, content]) => [name, strToU8(content)])), { mtime: ZIP_EPOCH });
148
+ }
149
+ /** The frame that puts a chart on a slide, in place of the sample picture. Sizes are in EMU. */
150
+ export function chartFrameXml(shapeId, relId, area, alt) {
151
+ return (`<p:graphicFrame xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:a="${NS_A}" xmlns:r="${NS_R}">` +
152
+ `<p:nvGraphicFramePr><p:cNvPr id="${escapeXmlAttr(shapeId)}" name="Chart" descr="${escapeXmlAttr(alt)}"/>` +
153
+ `<p:cNvGraphicFramePr><a:graphicFrameLocks noGrp="1"/></p:cNvGraphicFramePr><p:nvPr/></p:nvGraphicFramePr>` +
154
+ `<p:xfrm><a:off x="${Math.round(area.x)}" y="${Math.round(area.y)}"/><a:ext cx="${Math.round(area.cx)}" cy="${Math.round(area.cy)}"/></p:xfrm>` +
155
+ `<a:graphic><a:graphicData uri="${CHART_GRAPHIC_URI}"><c:chart xmlns:c="${NS_C}" r:id="${escapeXmlAttr(relId)}"/></a:graphicData></a:graphic>` +
156
+ `</p:graphicFrame>`);
157
+ }
158
+ //# sourceMappingURL=chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.js","sourceRoot":"","sources":["../../src/render/chart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { DeckSpec } from '../deck/spec.ts';
2
+ import type { Template } from './render.ts';
3
+ /**
4
+ * Recovers the pictures of a deck from a pptx that was rendered from it, keyed by asset id.
5
+ * With this, a deck's JSON and its pptx are all that has to be stored between edits: generated
6
+ * photos are read back instead of being generated, and paid for, again.
7
+ *
8
+ * Only slides that still match the deck are used. If the file was changed by hand (slides
9
+ * added, removed or reordered, or a title retyped), those slides are skipped.
10
+ */
11
+ export declare function extractAssets(template: Template, deck: DeckSpec, pptx: Uint8Array): Record<string, Uint8Array>;