@bendyline/squisq-formats 1.1.0 → 1.2.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.
Files changed (89) hide show
  1. package/README.md +23 -10
  2. package/dist/{chunk-ULLIPBEJ.js → chunk-743COJWQ.js} +6 -2
  3. package/dist/chunk-743COJWQ.js.map +1 -0
  4. package/dist/{chunk-KAK4V57E.js → chunk-BHHEDPRB.js} +16 -112
  5. package/dist/chunk-BHHEDPRB.js.map +1 -0
  6. package/dist/{chunk-MQHCXI56.js → chunk-CLGUOVYR.js} +193 -23
  7. package/dist/chunk-CLGUOVYR.js.map +1 -0
  8. package/dist/chunk-FIFCQN3W.js +630 -0
  9. package/dist/chunk-FIFCQN3W.js.map +1 -0
  10. package/dist/chunk-KJ4NS4DX.js +120 -0
  11. package/dist/chunk-KJ4NS4DX.js.map +1 -0
  12. package/dist/{chunk-TBPD5PCU.js → chunk-S3Y7H2BK.js} +161 -11
  13. package/dist/chunk-S3Y7H2BK.js.map +1 -0
  14. package/dist/docx/export.d.ts +15 -0
  15. package/dist/docx/export.d.ts.map +1 -1
  16. package/dist/docx/export.js +144 -19
  17. package/dist/docx/export.js.map +1 -1
  18. package/dist/docx/import.d.ts +13 -0
  19. package/dist/docx/import.d.ts.map +1 -1
  20. package/dist/docx/import.js +102 -10
  21. package/dist/docx/import.js.map +1 -1
  22. package/dist/docx/index.d.ts +1 -1
  23. package/dist/docx/index.d.ts.map +1 -1
  24. package/dist/docx/index.js +1 -1
  25. package/dist/docx/index.js.map +1 -1
  26. package/dist/html/htmlTemplate.d.ts +6 -0
  27. package/dist/html/htmlTemplate.d.ts.map +1 -1
  28. package/dist/html/htmlTemplate.js +5 -1
  29. package/dist/html/htmlTemplate.js.map +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.js +2 -2
  32. package/dist/index.js.map +1 -1
  33. package/dist/ooxml/index.d.ts +1 -1
  34. package/dist/ooxml/index.d.ts.map +1 -1
  35. package/dist/ooxml/index.js +1 -1
  36. package/dist/ooxml/index.js.map +1 -1
  37. package/dist/ooxml/namespaces.d.ts +10 -0
  38. package/dist/ooxml/namespaces.d.ts.map +1 -1
  39. package/dist/ooxml/namespaces.js +10 -0
  40. package/dist/ooxml/namespaces.js.map +1 -1
  41. package/dist/pdf/export.d.ts +6 -0
  42. package/dist/pdf/export.d.ts.map +1 -1
  43. package/dist/pdf/export.js +37 -9
  44. package/dist/pdf/export.js.map +1 -1
  45. package/dist/pdf/import.d.ts +16 -0
  46. package/dist/pdf/import.d.ts.map +1 -1
  47. package/dist/pdf/import.js +177 -0
  48. package/dist/pdf/import.js.map +1 -1
  49. package/dist/pdf/index.d.ts +1 -1
  50. package/dist/pdf/index.d.ts.map +1 -1
  51. package/dist/pdf/index.js +1 -1
  52. package/dist/pdf/index.js.map +1 -1
  53. package/dist/pptx/export.d.ts +75 -0
  54. package/dist/pptx/export.d.ts.map +1 -0
  55. package/dist/pptx/export.js +722 -0
  56. package/dist/pptx/export.js.map +1 -0
  57. package/dist/pptx/index.d.ts +12 -27
  58. package/dist/pptx/index.d.ts.map +1 -1
  59. package/dist/pptx/index.js +12 -22
  60. package/dist/pptx/index.js.map +1 -1
  61. package/dist/pptx/styles.d.ts +54 -0
  62. package/dist/pptx/styles.d.ts.map +1 -0
  63. package/dist/pptx/styles.js +73 -0
  64. package/dist/pptx/styles.js.map +1 -0
  65. package/dist/pptx/templates.d.ts +24 -0
  66. package/dist/pptx/templates.d.ts.map +1 -0
  67. package/dist/pptx/templates.js +158 -0
  68. package/dist/pptx/templates.js.map +1 -0
  69. package/package.json +2 -2
  70. package/src/docx/export.ts +183 -20
  71. package/src/docx/import.ts +127 -10
  72. package/src/docx/index.ts +1 -1
  73. package/src/html/htmlTemplate.ts +13 -0
  74. package/src/index.ts +2 -2
  75. package/src/ooxml/index.ts +7 -0
  76. package/src/ooxml/namespaces.ts +23 -0
  77. package/src/pdf/export.ts +57 -9
  78. package/src/pdf/import.ts +228 -0
  79. package/src/pdf/index.ts +1 -1
  80. package/src/pptx/export.ts +1041 -0
  81. package/src/pptx/index.ts +15 -37
  82. package/src/pptx/styles.ts +96 -0
  83. package/src/pptx/templates.ts +187 -0
  84. package/dist/chunk-532L4D5D.js +0 -21
  85. package/dist/chunk-532L4D5D.js.map +0 -1
  86. package/dist/chunk-KAK4V57E.js.map +0 -1
  87. package/dist/chunk-MQHCXI56.js.map +0 -1
  88. package/dist/chunk-TBPD5PCU.js.map +0 -1
  89. package/dist/chunk-ULLIPBEJ.js.map +0 -1
@@ -0,0 +1,630 @@
1
+ import {
2
+ CONTENT_TYPE_PPTX_PRESENTATION,
3
+ CONTENT_TYPE_PPTX_SLIDE,
4
+ CONTENT_TYPE_PPTX_SLIDE_LAYOUT,
5
+ CONTENT_TYPE_PPTX_SLIDE_MASTER,
6
+ CONTENT_TYPE_PPTX_THEME,
7
+ NS_DRAWINGML,
8
+ NS_PML,
9
+ NS_R,
10
+ REL_HYPERLINK,
11
+ REL_IMAGE,
12
+ REL_OFFICE_DOCUMENT,
13
+ REL_SLIDE,
14
+ REL_SLIDE_LAYOUT,
15
+ REL_SLIDE_MASTER,
16
+ REL_THEME,
17
+ createPackage,
18
+ escapeXml,
19
+ xmlDeclaration
20
+ } from "./chunk-BHHEDPRB.js";
21
+
22
+ // src/pptx/export.ts
23
+ import { resolveTheme } from "@bendyline/squisq/schemas";
24
+ import { docToMarkdown } from "@bendyline/squisq/doc";
25
+
26
+ // src/pptx/styles.ts
27
+ var SLIDE_WIDTH = 9144e3;
28
+ var SLIDE_HEIGHT = 6858e3;
29
+ var TITLE_LEFT = 457200;
30
+ var TITLE_TOP = 274638;
31
+ var TITLE_WIDTH = 8229600;
32
+ var TITLE_HEIGHT = 1143e3;
33
+ var BODY_LEFT = 457200;
34
+ var BODY_TOP = 1600200;
35
+ var BODY_WIDTH = 8229600;
36
+ var BODY_HEIGHT = 4525963;
37
+ var DEFAULT_FONT = "Calibri";
38
+ var DEFAULT_TITLE_FONT = "Calibri Light";
39
+ var DEFAULT_CODE_FONT = "Consolas";
40
+ var DEFAULT_TITLE_SIZE = 4400;
41
+ var DEFAULT_CODE_SIZE = 1400;
42
+ var HYPERLINK_COLOR = "0563C1";
43
+
44
+ // src/pptx/templates.ts
45
+ function buildPresentationXml(slideCount, slideRelIds, slideMasterRelId, _themeRelId) {
46
+ const sldIdList = [];
47
+ for (let i = 0; i < slideCount; i++) {
48
+ sldIdList.push(`<p:sldId id="${256 + i}" r:id="${slideRelIds[i]}"/>`);
49
+ }
50
+ return xmlDeclaration() + `<p:presentation xmlns:a="${NS_DRAWINGML}" xmlns:r="${NS_R}" xmlns:p="${NS_PML}" saveSubsetFonts="1"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="${slideMasterRelId}"/></p:sldMasterIdLst><p:sldIdLst>${sldIdList.join("")}</p:sldIdLst><p:sldSz cx="${SLIDE_WIDTH}" cy="${SLIDE_HEIGHT}" type="screen4x3"/><p:notesSz cx="${SLIDE_HEIGHT}" cy="${SLIDE_WIDTH}"/></p:presentation>`;
51
+ }
52
+ function buildSlideMasterXml(layoutRelId) {
53
+ return xmlDeclaration() + `<p:sldMaster xmlns:a="${NS_DRAWINGML}" xmlns:r="${NS_R}" xmlns:p="${NS_PML}"><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/></p:spTree></p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLayoutId id="2147483649" r:id="${layoutRelId}"/></p:sldLayoutIdLst></p:sldMaster>`;
54
+ }
55
+ function buildSlideLayoutXml(_masterRelId) {
56
+ return xmlDeclaration() + `<p:sldLayout xmlns:a="${NS_DRAWINGML}" xmlns:r="${NS_R}" xmlns:p="${NS_PML}" type="obj" preserve="1"><p:cSld name="Title and Content"><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/><p:sp><p:nvSpPr><p:cNvPr id="2" name="Title 1"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="title"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="${TITLE_LEFT}" y="${TITLE_TOP}"/><a:ext cx="${TITLE_WIDTH}" cy="${TITLE_HEIGHT}"/></a:xfrm></p:spPr><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="3" name="Content 2"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph idx="1"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="${BODY_LEFT}" y="${BODY_TOP}"/><a:ext cx="${BODY_WIDTH}" cy="${BODY_HEIGHT}"/></a:xfrm></p:spPr><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp></p:spTree></p:cSld></p:sldLayout>`;
57
+ }
58
+ function buildThemeXml() {
59
+ return xmlDeclaration() + `<a:theme xmlns:a="${NS_DRAWINGML}" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="44546A"/></a:dk2><a:lt2><a:srgbClr val="E7E6E6"/></a:lt2><a:accent1><a:srgbClr val="4472C4"/></a:accent1><a:accent2><a:srgbClr val="ED7D31"/></a:accent2><a:accent3><a:srgbClr val="A5A5A5"/></a:accent3><a:accent4><a:srgbClr val="FFC000"/></a:accent4><a:accent5><a:srgbClr val="5B9BD5"/></a:accent5><a:accent6><a:srgbClr val="70AD47"/></a:accent6><a:hlink><a:srgbClr val="0563C1"/></a:hlink><a:folHlink><a:srgbClr val="954F72"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Calibri Light"/><a:ea typeface=""/><a:cs typeface=""/></a:majorFont><a:minorFont><a:latin typeface="Calibri"/><a:ea typeface=""/><a:cs typeface=""/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements></a:theme>`;
60
+ }
61
+
62
+ // src/pptx/export.ts
63
+ async function markdownDocToPptx(doc, options = {}) {
64
+ const themeId = options.themeId ?? doc.frontmatter?.themeId ?? doc.frontmatter?.theme;
65
+ const style = resolveSlideStyle(themeId, options);
66
+ const slides = segmentIntoSlides(doc.children, options.slideBreak ?? "h2");
67
+ if (slides.length === 0) {
68
+ slides.push({ bodyNodes: [] });
69
+ }
70
+ const slideXmls = [];
71
+ const slideContexts = [];
72
+ for (let i = 0; i < slides.length; i++) {
73
+ const ctx = new SlideContext(style, options.images, i);
74
+ const xml = buildSlideXml(slides[i], ctx);
75
+ slideXmls.push(xml);
76
+ slideContexts.push(ctx);
77
+ }
78
+ return buildPptxPackage(slideXmls, slideContexts, options);
79
+ }
80
+ async function docToPptx(doc, options = {}) {
81
+ const markdownDoc = docToMarkdown(doc);
82
+ if (!options.themeId && doc.themeId) {
83
+ options = { ...options, themeId: doc.themeId };
84
+ }
85
+ return markdownDocToPptx(markdownDoc, options);
86
+ }
87
+ function resolveSlideStyle(themeId, options) {
88
+ if (!themeId) {
89
+ return {
90
+ background: "FFFFFF",
91
+ text: "333333",
92
+ titleColor: "333333",
93
+ mutedColor: "666666",
94
+ titleFont: options.defaultFont ?? DEFAULT_TITLE_FONT,
95
+ bodyFont: options.defaultFont ?? DEFAULT_FONT,
96
+ codeFont: DEFAULT_CODE_FONT,
97
+ codeColor: "333333",
98
+ hasTheme: false
99
+ };
100
+ }
101
+ const theme = resolveTheme(themeId);
102
+ const c = theme.colors;
103
+ return {
104
+ background: stripHash(c.background),
105
+ text: stripHash(c.text),
106
+ titleColor: stripHash(c.highlight || c.secondary || c.text),
107
+ mutedColor: stripHash(c.textMuted || c.text),
108
+ titleFont: theme.typography?.titleFontFamily || DEFAULT_TITLE_FONT,
109
+ bodyFont: theme.typography?.bodyFontFamily || options.defaultFont || DEFAULT_FONT,
110
+ codeFont: theme.typography?.monoFontFamily || DEFAULT_CODE_FONT,
111
+ codeColor: stripHash(c.textMuted || c.text),
112
+ hasTheme: true
113
+ };
114
+ }
115
+ function stripHash(color) {
116
+ return color.startsWith("#") ? color.slice(1) : color;
117
+ }
118
+ function segmentIntoSlides(children, slideBreak) {
119
+ const maxDepth = slideBreak === "h1" ? 1 : slideBreak === "h2" ? 2 : 6;
120
+ const slides = [];
121
+ let current;
122
+ for (const node of children) {
123
+ if (node.type === "heading" && node.depth <= maxDepth) {
124
+ if (current) slides.push(current);
125
+ current = {
126
+ title: extractPlainText(node.children),
127
+ titleDepth: node.depth,
128
+ bodyNodes: []
129
+ };
130
+ } else {
131
+ if (!current) {
132
+ current = { bodyNodes: [] };
133
+ }
134
+ current.bodyNodes.push(node);
135
+ }
136
+ }
137
+ if (current) slides.push(current);
138
+ return slides;
139
+ }
140
+ function extractPlainText(nodes) {
141
+ const parts = [];
142
+ for (const node of nodes) {
143
+ switch (node.type) {
144
+ case "text":
145
+ parts.push(node.value);
146
+ break;
147
+ case "inlineCode":
148
+ parts.push(node.value);
149
+ break;
150
+ case "strong":
151
+ case "emphasis":
152
+ case "delete":
153
+ parts.push(extractPlainText(node.children));
154
+ break;
155
+ case "link":
156
+ parts.push(extractPlainText(node.children));
157
+ break;
158
+ case "image":
159
+ parts.push(node.alt ?? "");
160
+ break;
161
+ case "inlineMath":
162
+ parts.push(node.value);
163
+ break;
164
+ default:
165
+ break;
166
+ }
167
+ }
168
+ return parts.join("");
169
+ }
170
+ var SlideContext = class {
171
+ // 1=group, 2=title, 3=body
172
+ constructor(style, images, slideIndex) {
173
+ this.nextRelId = 1;
174
+ this.relationships = [];
175
+ this.embeddedImages = [];
176
+ this.nextShapeId = 4;
177
+ this.style = style;
178
+ this.images = images;
179
+ this.slideIndex = slideIndex;
180
+ }
181
+ allocRelId() {
182
+ return `rId${this.nextRelId++ + 1}`;
183
+ }
184
+ allocShapeId() {
185
+ return this.nextShapeId++;
186
+ }
187
+ addHyperlink(url) {
188
+ const id = this.allocRelId();
189
+ this.relationships.push({
190
+ id,
191
+ type: REL_HYPERLINK,
192
+ target: url,
193
+ targetMode: "External"
194
+ });
195
+ return id;
196
+ }
197
+ /** Register an embedded image and return its relationship ID */
198
+ addImage(src, data, alt) {
199
+ const relId = this.allocRelId();
200
+ const ext = inferExtension(src);
201
+ const contentType = inferMimeType(ext);
202
+ const imgIndex = this.embeddedImages.length + 1;
203
+ const mediaPath = `ppt/media/image_s${this.slideIndex}_${imgIndex}.${ext}`;
204
+ this.embeddedImages.push({ relId, mediaPath, data, contentType, alt });
205
+ this.relationships.push({
206
+ id: relId,
207
+ type: REL_IMAGE,
208
+ target: `../media/image_s${this.slideIndex}_${imgIndex}.${ext}`
209
+ });
210
+ return relId;
211
+ }
212
+ };
213
+ function buildSlideXml(slide, ctx) {
214
+ const shapes = [];
215
+ shapes.push(
216
+ `<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/>`
217
+ );
218
+ if (slide.title) {
219
+ shapes.push(buildTitleShape(slide.title, ctx.style));
220
+ }
221
+ const bodyParas = convertBodyBlocks(slide.bodyNodes, ctx);
222
+ const hasImages = ctx.embeddedImages.length > 0;
223
+ const hasText = bodyParas.length > 0;
224
+ if (hasText && hasImages) {
225
+ const textHeight = Math.round(BODY_HEIGHT * 0.45);
226
+ const imgTop = BODY_TOP + textHeight + 91440;
227
+ const imgHeight = BODY_HEIGHT - textHeight - 91440;
228
+ shapes.push(buildBodyShapeCustom(bodyParas, BODY_TOP, textHeight, ctx.style));
229
+ shapes.push(
230
+ buildImageShape(
231
+ ctx.embeddedImages[0],
232
+ ctx.allocShapeId(),
233
+ BODY_LEFT,
234
+ imgTop,
235
+ BODY_WIDTH,
236
+ imgHeight
237
+ )
238
+ );
239
+ } else if (hasImages && !hasText) {
240
+ shapes.push(
241
+ buildImageShape(
242
+ ctx.embeddedImages[0],
243
+ ctx.allocShapeId(),
244
+ BODY_LEFT,
245
+ BODY_TOP,
246
+ BODY_WIDTH,
247
+ BODY_HEIGHT
248
+ )
249
+ );
250
+ } else {
251
+ shapes.push(
252
+ buildBodyShapeCustom(
253
+ bodyParas || `<a:p><a:endParaRPr lang="en-US"/></a:p>`,
254
+ BODY_TOP,
255
+ BODY_HEIGHT,
256
+ ctx.style
257
+ )
258
+ );
259
+ }
260
+ for (let i = 1; i < ctx.embeddedImages.length; i++) {
261
+ shapes.push(
262
+ buildImageShape(
263
+ ctx.embeddedImages[i],
264
+ ctx.allocShapeId(),
265
+ BODY_LEFT,
266
+ BODY_TOP,
267
+ BODY_WIDTH,
268
+ BODY_HEIGHT
269
+ )
270
+ );
271
+ }
272
+ const bgXml = ctx.style.hasTheme ? `<p:bg><p:bgPr><a:solidFill><a:srgbClr val="${ctx.style.background}"/></a:solidFill><a:effectLst/></p:bgPr></p:bg>` : "";
273
+ return xmlDeclaration() + `<p:sld xmlns:a="${NS_DRAWINGML}" xmlns:r="${NS_R}" xmlns:p="${NS_PML}"><p:cSld>` + bgXml + `<p:spTree>` + shapes.join("") + `</p:spTree></p:cSld></p:sld>`;
274
+ }
275
+ function buildTitleShape(title, style) {
276
+ return `<p:sp><p:nvSpPr><p:cNvPr id="2" name="Title"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="title"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="${TITLE_LEFT}" y="${TITLE_TOP}"/><a:ext cx="${TITLE_WIDTH}" cy="${TITLE_HEIGHT}"/></a:xfrm></p:spPr><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:rPr lang="en-US" sz="${DEFAULT_TITLE_SIZE}" dirty="0"><a:solidFill><a:srgbClr val="${style.titleColor}"/></a:solidFill><a:latin typeface="${escapeXml(style.titleFont)}"/></a:rPr><a:t>${escapeXml(title)}</a:t></a:r></a:p></p:txBody></p:sp>`;
277
+ }
278
+ function buildBodyShapeCustom(bodyContent, top, height, style) {
279
+ const defRPr = style.hasTheme ? `<a:defRPr><a:solidFill><a:srgbClr val="${style.text}"/></a:solidFill><a:latin typeface="${escapeXml(style.bodyFont)}"/></a:defRPr>` : "";
280
+ return `<p:sp><p:nvSpPr><p:cNvPr id="3" name="Content"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph idx="1"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="${BODY_LEFT}" y="${top}"/><a:ext cx="${BODY_WIDTH}" cy="${height}"/></a:xfrm></p:spPr><p:txBody><a:bodyPr/><a:lstStyle><a:lvl1pPr>${defRPr}</a:lvl1pPr></a:lstStyle>` + bodyContent + `</p:txBody></p:sp>`;
281
+ }
282
+ function buildImageShape(img, shapeId, left, top, maxWidth, maxHeight) {
283
+ return `<p:pic><p:nvPicPr><p:cNvPr id="${shapeId}" name="${escapeXml(img.alt || "Picture")}"/><p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="${img.relId}"/><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x="${left}" y="${top}"/><a:ext cx="${maxWidth}" cy="${maxHeight}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>`;
284
+ }
285
+ function convertBodyBlocks(nodes, ctx) {
286
+ const parts = [];
287
+ for (const node of nodes) {
288
+ parts.push(convertBlock(node, ctx, 0));
289
+ }
290
+ return parts.join("");
291
+ }
292
+ function convertBlock(node, ctx, listDepth) {
293
+ switch (node.type) {
294
+ case "heading":
295
+ return convertHeading(node, ctx);
296
+ case "paragraph":
297
+ return convertParagraph(node, ctx);
298
+ case "blockquote":
299
+ return convertBlockquote(node, ctx);
300
+ case "list":
301
+ return convertList(node, ctx, listDepth);
302
+ case "code":
303
+ return convertCodeBlock(node, ctx);
304
+ case "table":
305
+ return convertTable(node, ctx);
306
+ case "thematicBreak":
307
+ return convertThematicBreak(ctx);
308
+ case "htmlBlock":
309
+ return convertHtmlBlock(node, ctx);
310
+ case "math":
311
+ return convertMathBlock(node);
312
+ default:
313
+ return "";
314
+ }
315
+ }
316
+ function convertHeading(node, ctx) {
317
+ const size = headingSizeForDepth(node.depth);
318
+ const runs = convertInlines(node.children, ctx, { bold: true });
319
+ return `<a:p><a:pPr><a:spcBef><a:spcPts val="600"/></a:spcBef><a:defRPr sz="${size}" b="1"><a:solidFill><a:srgbClr val="${ctx.style.titleColor}"/></a:solidFill><a:latin typeface="${escapeXml(ctx.style.titleFont)}"/></a:defRPr></a:pPr>` + runs + `</a:p>`;
320
+ }
321
+ function headingSizeForDepth(depth) {
322
+ const sizes = { 1: 3200, 2: 2800, 3: 2400, 4: 2e3, 5: 1800, 6: 1800 };
323
+ return sizes[depth] ?? 1800;
324
+ }
325
+ function isImageOnlyParagraph(node) {
326
+ if (node.children.length === 1 && node.children[0].type === "image") {
327
+ return node.children[0];
328
+ }
329
+ return null;
330
+ }
331
+ function convertParagraph(node, ctx) {
332
+ const soloImage = isImageOnlyParagraph(node);
333
+ if (soloImage && ctx.images) {
334
+ const data = ctx.images.get(soloImage.url);
335
+ if (data) {
336
+ ctx.addImage(soloImage.url, data, soloImage.alt || "");
337
+ return "";
338
+ }
339
+ }
340
+ const runs = convertInlines(node.children, ctx);
341
+ return `<a:p>${runs}</a:p>`;
342
+ }
343
+ function convertBlockquote(node, ctx) {
344
+ const parts = [];
345
+ for (const child of node.children) {
346
+ if (child.type === "paragraph") {
347
+ const runs = convertInlines(child.children, ctx, { italic: true });
348
+ parts.push(
349
+ `<a:p><a:pPr marL="457200"><a:spcBef><a:spcPts val="200"/></a:spcBef></a:pPr>` + runs + `</a:p>`
350
+ );
351
+ } else {
352
+ parts.push(convertBlock(child, ctx, 0));
353
+ }
354
+ }
355
+ return parts.join("");
356
+ }
357
+ function convertList(node, ctx, depth) {
358
+ const parts = [];
359
+ for (const item of node.children) {
360
+ parts.push(convertListItem(item, ctx, node.ordered ?? false, depth));
361
+ }
362
+ return parts.join("");
363
+ }
364
+ function convertListItem(item, ctx, ordered, depth) {
365
+ const parts = [];
366
+ for (const child of item.children) {
367
+ if (child.type === "paragraph") {
368
+ const runs = convertInlines(child.children, ctx);
369
+ const bullet = ordered ? `<a:buAutoNum type="arabicPeriod"/>` : `<a:buChar char="\u2022"/>`;
370
+ const indent = 457200 * (depth + 1);
371
+ parts.push(
372
+ `<a:p><a:pPr lvl="${depth}" marL="${indent}" indent="-228600">` + bullet + `</a:pPr>` + runs + `</a:p>`
373
+ );
374
+ } else if (child.type === "list") {
375
+ parts.push(convertList(child, ctx, depth + 1));
376
+ } else {
377
+ parts.push(convertBlock(child, ctx, depth));
378
+ }
379
+ }
380
+ return parts.join("");
381
+ }
382
+ function convertCodeBlock(node, ctx) {
383
+ const lines = node.value.split("\n");
384
+ const parts = [];
385
+ for (const line of lines) {
386
+ parts.push(
387
+ `<a:p><a:r><a:rPr lang="en-US" sz="${DEFAULT_CODE_SIZE}" dirty="0"><a:latin typeface="${escapeXml(ctx.style.codeFont)}"/><a:solidFill><a:srgbClr val="${ctx.style.codeColor}"/></a:solidFill></a:rPr><a:t>${escapeXml(line || " ")}</a:t></a:r></a:p>`
388
+ );
389
+ }
390
+ return parts.join("");
391
+ }
392
+ function convertTable(node, ctx) {
393
+ const parts = [];
394
+ for (let ri = 0; ri < node.children.length; ri++) {
395
+ const row = node.children[ri];
396
+ parts.push(convertTableRow(row, ctx, ri === 0));
397
+ }
398
+ return parts.join("");
399
+ }
400
+ function convertTableRow(row, ctx, isHeader) {
401
+ const cells = [];
402
+ for (const cell of row.children) {
403
+ cells.push(extractPlainText(cell.children));
404
+ }
405
+ const text = cells.join(" | ");
406
+ const format = isHeader ? { bold: true } : {};
407
+ return `<a:p>${makeRun(text, format, ctx.style)}</a:p>`;
408
+ }
409
+ function convertThematicBreak(ctx) {
410
+ return `<a:p><a:pPr><a:spcAft><a:spcPts val="1200"/></a:spcAft></a:pPr><a:r><a:rPr lang="en-US" sz="400"><a:solidFill><a:srgbClr val="${ctx.style.mutedColor}"/></a:solidFill></a:rPr><a:t>\u2014\u2014\u2014</a:t></a:r></a:p>`;
411
+ }
412
+ function convertHtmlBlock(node, ctx) {
413
+ const text = stripHtmlTags(node.rawHtml).trim();
414
+ if (!text) return "";
415
+ return `<a:p>${makeRun(text, {}, ctx.style)}</a:p>`;
416
+ }
417
+ function convertMathBlock(node) {
418
+ return `<a:p><a:pPr algn="ctr"/><a:r><a:rPr lang="en-US" i="1"><a:latin typeface="Cambria Math"/></a:rPr><a:t>${escapeXml(node.value)}</a:t></a:r></a:p>`;
419
+ }
420
+ function convertInlines(nodes, ctx, format = {}) {
421
+ const parts = [];
422
+ for (const node of nodes) {
423
+ parts.push(convertInline(node, ctx, format));
424
+ }
425
+ return parts.join("");
426
+ }
427
+ function convertInline(node, ctx, format) {
428
+ switch (node.type) {
429
+ case "text":
430
+ return makeRun(node.value, format, ctx.style);
431
+ case "strong":
432
+ return convertInlines(node.children, ctx, { ...format, bold: true });
433
+ case "emphasis":
434
+ return convertInlines(node.children, ctx, { ...format, italic: true });
435
+ case "delete":
436
+ return convertInlines(node.children, ctx, { ...format, strike: true });
437
+ case "inlineCode":
438
+ return makeRun(node.value, { ...format, code: true }, ctx.style);
439
+ case "link":
440
+ return convertLink(node, ctx, format);
441
+ case "image":
442
+ return convertImage(node, format, ctx);
443
+ case "break":
444
+ return `<a:br/>`;
445
+ case "htmlInline":
446
+ return makeRun(stripHtmlTags(node.rawHtml), format, ctx.style);
447
+ case "inlineMath":
448
+ return makeRun(node.value, { ...format, code: true }, ctx.style);
449
+ default:
450
+ return "";
451
+ }
452
+ }
453
+ function makeRun(text, format, style) {
454
+ if (!text) return "";
455
+ const rPrParts = [`lang="en-US"`, `dirty="0"`];
456
+ if (format.bold) rPrParts.push(`b="1"`);
457
+ if (format.italic) rPrParts.push(`i="1"`);
458
+ if (format.strike) rPrParts.push(`strike="sngStrike"`);
459
+ let innerParts = "";
460
+ if (format.code) {
461
+ innerParts += `<a:latin typeface="${escapeXml(style.codeFont)}"/>`;
462
+ innerParts += `<a:solidFill><a:srgbClr val="${style.codeColor}"/></a:solidFill>`;
463
+ rPrParts.push(`sz="${DEFAULT_CODE_SIZE}"`);
464
+ } else if (style.hasTheme) {
465
+ innerParts += `<a:solidFill><a:srgbClr val="${style.text}"/></a:solidFill>`;
466
+ }
467
+ return `<a:r><a:rPr ${rPrParts.join(" ")}>${innerParts}</a:rPr><a:t>${escapeXml(text)}</a:t></a:r>`;
468
+ }
469
+ function convertLink(node, ctx, format) {
470
+ const rId = ctx.addHyperlink(node.url);
471
+ const parts = [];
472
+ for (const child of node.children) {
473
+ if (child.type === "text") {
474
+ parts.push(makeHyperlinkRun(child.value, rId, format));
475
+ } else {
476
+ parts.push(convertInline(child, ctx, format));
477
+ }
478
+ }
479
+ return parts.join("");
480
+ }
481
+ function makeHyperlinkRun(text, rId, format) {
482
+ if (!text) return "";
483
+ const rPrParts = [`lang="en-US"`, `dirty="0"`];
484
+ if (format.bold) rPrParts.push(`b="1"`);
485
+ if (format.italic) rPrParts.push(`i="1"`);
486
+ return `<a:r><a:rPr ${rPrParts.join(" ")}><a:solidFill><a:srgbClr val="${HYPERLINK_COLOR}"/></a:solidFill><a:hlinkClick r:id="${rId}"/></a:rPr><a:t>${escapeXml(text)}</a:t></a:r>`;
487
+ }
488
+ function convertImage(node, format, ctx) {
489
+ if (ctx.images) {
490
+ const data = ctx.images.get(node.url);
491
+ if (data) {
492
+ ctx.addImage(node.url, data, node.alt || "");
493
+ return "";
494
+ }
495
+ }
496
+ const alt = node.alt || node.url;
497
+ return makeRun(`[Image: ${alt}]`, { ...format, italic: true }, ctx.style);
498
+ }
499
+ async function buildPptxPackage(slideXmls, slideContexts, options) {
500
+ const pkg = createPackage();
501
+ const slideCount = slideXmls.length;
502
+ const slideMasterRelId = "rId100";
503
+ const themeRelId = "rId101";
504
+ const slideRelIds = [];
505
+ for (let i = 0; i < slideCount; i++) {
506
+ slideRelIds.push(`rId${i + 1}`);
507
+ }
508
+ const presentationXml = buildPresentationXml(
509
+ slideCount,
510
+ slideRelIds,
511
+ slideMasterRelId,
512
+ themeRelId
513
+ );
514
+ pkg.addPart("ppt/presentation.xml", presentationXml, CONTENT_TYPE_PPTX_PRESENTATION);
515
+ for (let i = 0; i < slideCount; i++) {
516
+ const slidePath = `ppt/slides/slide${i + 1}.xml`;
517
+ pkg.addPart(slidePath, slideXmls[i], CONTENT_TYPE_PPTX_SLIDE);
518
+ pkg.addRelationship(slidePath, {
519
+ id: "rId1",
520
+ type: REL_SLIDE_LAYOUT,
521
+ target: "../slideLayouts/slideLayout1.xml"
522
+ });
523
+ const ctx = slideContexts[i];
524
+ for (const rel of ctx.relationships) {
525
+ pkg.addRelationship(slidePath, {
526
+ id: rel.id,
527
+ type: rel.type,
528
+ target: rel.target,
529
+ ...rel.targetMode ? { targetMode: rel.targetMode } : {}
530
+ });
531
+ }
532
+ for (const img of ctx.embeddedImages) {
533
+ pkg.addBinaryPart(img.mediaPath, img.data, img.contentType);
534
+ }
535
+ }
536
+ const layoutMasterRelId = "rId1";
537
+ const slideLayoutXml = buildSlideLayoutXml(layoutMasterRelId);
538
+ pkg.addPart("ppt/slideLayouts/slideLayout1.xml", slideLayoutXml, CONTENT_TYPE_PPTX_SLIDE_LAYOUT);
539
+ pkg.addRelationship("ppt/slideLayouts/slideLayout1.xml", {
540
+ id: layoutMasterRelId,
541
+ type: REL_SLIDE_MASTER,
542
+ target: "../slideMasters/slideMaster1.xml"
543
+ });
544
+ const masterLayoutRelId = "rId1";
545
+ const masterThemeRelId = "rId2";
546
+ const slideMasterXml = buildSlideMasterXml(masterLayoutRelId);
547
+ pkg.addPart("ppt/slideMasters/slideMaster1.xml", slideMasterXml, CONTENT_TYPE_PPTX_SLIDE_MASTER);
548
+ pkg.addRelationship("ppt/slideMasters/slideMaster1.xml", {
549
+ id: masterLayoutRelId,
550
+ type: REL_SLIDE_LAYOUT,
551
+ target: "../slideLayouts/slideLayout1.xml"
552
+ });
553
+ pkg.addRelationship("ppt/slideMasters/slideMaster1.xml", {
554
+ id: masterThemeRelId,
555
+ type: REL_THEME,
556
+ target: "../theme/theme1.xml"
557
+ });
558
+ const themeXml = buildThemeXml();
559
+ pkg.addPart("ppt/theme/theme1.xml", themeXml, CONTENT_TYPE_PPTX_THEME);
560
+ pkg.addRelationship("", {
561
+ id: "rId1",
562
+ type: REL_OFFICE_DOCUMENT,
563
+ target: "ppt/presentation.xml"
564
+ });
565
+ for (let i = 0; i < slideCount; i++) {
566
+ pkg.addRelationship("ppt/presentation.xml", {
567
+ id: slideRelIds[i],
568
+ type: REL_SLIDE,
569
+ target: `slides/slide${i + 1}.xml`
570
+ });
571
+ }
572
+ pkg.addRelationship("ppt/presentation.xml", {
573
+ id: slideMasterRelId,
574
+ type: REL_SLIDE_MASTER,
575
+ target: "slideMasters/slideMaster1.xml"
576
+ });
577
+ pkg.addRelationship("ppt/presentation.xml", {
578
+ id: themeRelId,
579
+ type: REL_THEME,
580
+ target: "theme/theme1.xml"
581
+ });
582
+ if (options.title || options.author || options.description) {
583
+ pkg.setCoreProperties({
584
+ title: options.title,
585
+ creator: options.author,
586
+ description: options.description,
587
+ created: (/* @__PURE__ */ new Date()).toISOString(),
588
+ modified: (/* @__PURE__ */ new Date()).toISOString()
589
+ });
590
+ }
591
+ return pkg.toArrayBuffer();
592
+ }
593
+ function stripHtmlTags(html) {
594
+ return html.replace(/<[^>]*>/g, "");
595
+ }
596
+ function inferExtension(path) {
597
+ const dot = path.lastIndexOf(".");
598
+ if (dot === -1) return "png";
599
+ const ext = path.substring(dot + 1).toLowerCase().split("?")[0];
600
+ return ext || "png";
601
+ }
602
+ function inferMimeType(ext) {
603
+ const mimeTypes = {
604
+ jpg: "image/jpeg",
605
+ jpeg: "image/jpeg",
606
+ png: "image/png",
607
+ gif: "image/gif",
608
+ webp: "image/webp",
609
+ svg: "image/svg+xml",
610
+ bmp: "image/bmp",
611
+ avif: "image/avif"
612
+ };
613
+ return mimeTypes[ext] || "image/png";
614
+ }
615
+
616
+ // src/pptx/index.ts
617
+ async function pptxToMarkdownDoc(_data, _options) {
618
+ throw new Error("PPTX import is not yet implemented");
619
+ }
620
+ async function pptxToDoc(_data, _options) {
621
+ throw new Error("PPTX import is not yet implemented");
622
+ }
623
+
624
+ export {
625
+ markdownDocToPptx,
626
+ docToPptx,
627
+ pptxToMarkdownDoc,
628
+ pptxToDoc
629
+ };
630
+ //# sourceMappingURL=chunk-FIFCQN3W.js.map