@thanh01.pmt/presentation-kit 0.2.0 → 0.2.2

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.
@@ -0,0 +1,124 @@
1
+ import { d as SlideRenderOptions, e as SlideRenderResult, f as SlideRenderAsyncResult, T as ThemeTokens, c as SlideTheme, B as BuiltInTheme } from './types-DnR81ReX.js';
2
+
3
+ interface RenderMarpResult {
4
+ html: string;
5
+ css: string;
6
+ comments: (string[] | undefined)[];
7
+ maxClicks: number;
8
+ }
9
+ /**
10
+ * Low-level synchronous Marp render.
11
+ * Preprocesses clicks, converts arrows, renders Marp, postprocesses clicks.
12
+ */
13
+ declare function renderMarp(markdown: string, containerId?: string, enableClicks?: boolean): RenderMarpResult;
14
+ /**
15
+ * Count slides in rendered Marp HTML by detecting <svg data-marpit-svg> elements.
16
+ */
17
+ declare function countSlides(html: string): number;
18
+ /**
19
+ * High-level synchronous render — resolves theme, generates scoped CSS,
20
+ * detects mermaid blocks. Does NOT apply Shiki or Mermaid rendering.
21
+ */
22
+ declare function renderSlide(markdown: string, options?: SlideRenderOptions): SlideRenderResult;
23
+ /**
24
+ * High-level async render — applies Shiki syntax highlighting.
25
+ * Mermaid blocks are returned separately (DOM-based, consumer renders them).
26
+ */
27
+ declare function renderSlideAsync(markdown: string, options?: SlideRenderOptions): Promise<SlideRenderAsyncResult>;
28
+
29
+ /**
30
+ * Get theme tokens by built-in name.
31
+ */
32
+ declare function getThemeTokens(theme: BuiltInTheme): ThemeTokens;
33
+ /**
34
+ * Resolve a theme (built-in name or custom SlideTheme) to a full SlideTheme object.
35
+ */
36
+ declare function resolveTheme(theme: BuiltInTheme | SlideTheme | undefined): SlideTheme;
37
+ /**
38
+ * Define a custom theme with full token control.
39
+ */
40
+ declare function defineTheme(definition: {
41
+ name: string;
42
+ tokens: ThemeTokens;
43
+ }): SlideTheme;
44
+ /**
45
+ * Generate scoped CSS for a theme.
46
+ */
47
+ declare function generateScopedCss(theme: SlideTheme, containerId?: string): string;
48
+
49
+ interface ClickPreprocessResult {
50
+ /** Processed markdown with HTML click markers */
51
+ markdown: string;
52
+ /** Total number of click groups assigned */
53
+ totalClicks: number;
54
+ }
55
+ /**
56
+ * Preprocess markdown to convert click directives to HTML wrappers.
57
+ *
58
+ * Syntax:
59
+ * - `<!-- click -->` → Block-level: wraps next block in data-click-group="N"
60
+ * - `<!-- clicks -->` → Item-level: marks list for auto-expansion in postprocessor
61
+ *
62
+ * Auto-assigns sequential indices (1, 2, 3, ...) based on order of appearance.
63
+ *
64
+ * IMPORTANT: Skips code fences (``` ... ```) to avoid converting directives
65
+ * inside code blocks.
66
+ *
67
+ * Strategy: Each `<!-- click -->` opens a `<div data-click-group="N">` that wraps
68
+ * all content until the next `<!-- click -->` / `<!-- clicks -->` or end of slide.
69
+ * The postprocessor only needs to handle `<!-- clicks -->` (list expansion).
70
+ */
71
+ declare function preprocessClicks(markdown: string): ClickPreprocessResult;
72
+
73
+ interface ClickPostprocessResult {
74
+ /** HTML with click groups applied */
75
+ html: string;
76
+ /** Total number of individual click groups (after expanding clicks) */
77
+ totalClicks: number;
78
+ }
79
+ /**
80
+ * Post-process rendered Marp HTML to expand clicks (item-level) list items.
81
+ *
82
+ * The preprocessor wraps <!-- click --> blocks in <div data-click-group="N">.
83
+ * This postprocessor handles <!-- clicks --> by splitting list items into
84
+ * individual click groups.
85
+ *
86
+ * Pattern: <div data-clicks="N">...<ul><li>...</li></ul>...</div>
87
+ * Becomes: multiple <div data-click-group="N">...<ul><li>...</li></ul>...</div>
88
+ *
89
+ * @param html - Raw Marp-rendered HTML (with click-group and clicks markers)
90
+ * @returns HTML with all click groups expanded
91
+ */
92
+ declare function postprocessClicks(html: string): ClickPostprocessResult;
93
+ /**
94
+ * Extract max click index from rendered HTML.
95
+ * Scans for all data-click-group="N" attributes and returns the max N.
96
+ */
97
+ declare function extractMaxClicks(html: string): number;
98
+
99
+ interface ClickCssOptions {
100
+ /** Container ID to scope CSS (default: no scope, global) */
101
+ containerId?: string;
102
+ /** Animation duration in ms (default: 300) */
103
+ duration?: number;
104
+ /** Animation easing (default: 'ease') */
105
+ easing?: string;
106
+ /** Y offset for slide-up animation in px (default: 8) */
107
+ offsetY?: number;
108
+ /** Use slide-up animation (default: true) */
109
+ slideUp?: boolean;
110
+ /** Use fade animation (default: true) */
111
+ fade?: boolean;
112
+ }
113
+ /**
114
+ * Generate CSS for click-to-reveal system.
115
+ *
116
+ * Elements with `data-click-group="N"` are hidden by default.
117
+ * Adding class `visible` reveals them with animation.
118
+ *
119
+ * @param options - Animation options
120
+ * @returns CSS string to inject via <style>
121
+ */
122
+ declare function generateClickCss(options?: ClickCssOptions): string;
123
+
124
+ export { type ClickPreprocessResult as C, renderSlideAsync as a, renderMarp as b, countSlides as c, defineTheme as d, resolveTheme as e, generateScopedCss as f, getThemeTokens as g, postprocessClicks as h, extractMaxClicks as i, generateClickCss as j, type ClickPostprocessResult as k, type ClickCssOptions as l, preprocessClicks as p, renderSlide as r };
package/dist/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkO4Y3VEOA_cjs = require('./chunk-O4Y3VEOA.cjs');
3
+ var chunkVLAPHJOC_cjs = require('./chunk-VLAPHJOC.cjs');
4
+ var chunkOEAOYF7C_cjs = require('./chunk-OEAOYF7C.cjs');
4
5
 
5
6
  // src/engine.ts
6
7
  function createEngine(config = {}) {
@@ -17,14 +18,14 @@ function createEngine(config = {}) {
17
18
  }
18
19
  return {
19
20
  render: (markdown, options) => {
20
- return chunkO4Y3VEOA_cjs.renderSlide(markdown, mergeOptions(options));
21
+ return chunkVLAPHJOC_cjs.renderSlide(markdown, mergeOptions(options));
21
22
  },
22
23
  renderAsync: async (markdown, options) => {
23
- return chunkO4Y3VEOA_cjs.renderSlideAsync(markdown, mergeOptions(options));
24
+ return chunkVLAPHJOC_cjs.renderSlideAsync(markdown, mergeOptions(options));
24
25
  },
25
26
  getThemeCss: (theme, containerId) => {
26
- const resolved = chunkO4Y3VEOA_cjs.resolveTheme(theme);
27
- return chunkO4Y3VEOA_cjs.generateScopedCss2(resolved, containerId);
27
+ const resolved = chunkVLAPHJOC_cjs.resolveTheme(theme);
28
+ return chunkVLAPHJOC_cjs.generateScopedCss2(resolved, containerId);
28
29
  }
29
30
  };
30
31
  }
@@ -100,8 +101,8 @@ async function convertMarkdownToPptx(markdown, options) {
100
101
  pptx.layout = "LAYOUT_WIDE";
101
102
  if (options?.title) pptx.title = options.title;
102
103
  if (options?.author) pptx.author = options.author;
103
- const renderResult = chunkO4Y3VEOA_cjs.renderSlide(markdown);
104
- const { slides } = chunkO4Y3VEOA_cjs.splitMarkdownSlides(markdown);
104
+ const renderResult = chunkVLAPHJOC_cjs.renderSlide(markdown);
105
+ const { slides } = chunkOEAOYF7C_cjs.splitMarkdownSlides(markdown);
105
106
  const isDark = options?.theme !== "light";
106
107
  const defaultBg = isDark ? "14151B" : "FFFFFF";
107
108
  const defaultText = isDark ? "F1F5F9" : "1E293B";
@@ -200,127 +201,139 @@ async function convertMarkdownToPptx(markdown, options) {
200
201
 
201
202
  Object.defineProperty(exports, "convertTextArrows", {
202
203
  enumerable: true,
203
- get: function () { return chunkO4Y3VEOA_cjs.convertTextArrows; }
204
+ get: function () { return chunkVLAPHJOC_cjs.convertTextArrows; }
204
205
  });
205
206
  Object.defineProperty(exports, "countSlides", {
206
207
  enumerable: true,
207
- get: function () { return chunkO4Y3VEOA_cjs.countSlides; }
208
+ get: function () { return chunkVLAPHJOC_cjs.countSlides; }
208
209
  });
209
210
  Object.defineProperty(exports, "darkThemeTokens", {
210
211
  enumerable: true,
211
- get: function () { return chunkO4Y3VEOA_cjs.darkThemeTokens; }
212
+ get: function () { return chunkVLAPHJOC_cjs.darkThemeTokens; }
212
213
  });
213
214
  Object.defineProperty(exports, "defineTheme", {
214
215
  enumerable: true,
215
- get: function () { return chunkO4Y3VEOA_cjs.defineTheme; }
216
+ get: function () { return chunkVLAPHJOC_cjs.defineTheme; }
216
217
  });
217
218
  Object.defineProperty(exports, "detectMermaidBlocks", {
218
219
  enumerable: true,
219
- get: function () { return chunkO4Y3VEOA_cjs.detectMermaidBlocks; }
220
+ get: function () { return chunkVLAPHJOC_cjs.detectMermaidBlocks; }
220
221
  });
221
222
  Object.defineProperty(exports, "extractLayoutsAndNotes", {
222
223
  enumerable: true,
223
- get: function () { return chunkO4Y3VEOA_cjs.extractLayoutsAndNotes; }
224
+ get: function () { return chunkVLAPHJOC_cjs.extractLayoutsAndNotes; }
224
225
  });
225
226
  Object.defineProperty(exports, "extractMarpSource", {
226
227
  enumerable: true,
227
- get: function () { return chunkO4Y3VEOA_cjs.extractMarpSource; }
228
+ get: function () { return chunkVLAPHJOC_cjs.extractMarpSource; }
228
229
  });
229
230
  Object.defineProperty(exports, "extractMaxClicks", {
230
231
  enumerable: true,
231
- get: function () { return chunkO4Y3VEOA_cjs.extractMaxClicks; }
232
+ get: function () { return chunkVLAPHJOC_cjs.extractMaxClicks; }
232
233
  });
233
234
  Object.defineProperty(exports, "filterPresenterNotes", {
234
235
  enumerable: true,
235
- get: function () { return chunkO4Y3VEOA_cjs.filterPresenterNotes; }
236
+ get: function () { return chunkVLAPHJOC_cjs.filterPresenterNotes; }
236
237
  });
237
238
  Object.defineProperty(exports, "generateClickCss", {
238
239
  enumerable: true,
239
- get: function () { return chunkO4Y3VEOA_cjs.generateClickCss; }
240
+ get: function () { return chunkVLAPHJOC_cjs.generateClickCss; }
240
241
  });
241
242
  Object.defineProperty(exports, "generateLayoutCss", {
242
243
  enumerable: true,
243
- get: function () { return chunkO4Y3VEOA_cjs.generateLayoutCss; }
244
+ get: function () { return chunkVLAPHJOC_cjs.generateLayoutCss; }
244
245
  });
245
246
  Object.defineProperty(exports, "generateScopedCss", {
246
247
  enumerable: true,
247
- get: function () { return chunkO4Y3VEOA_cjs.generateScopedCss2; }
248
+ get: function () { return chunkVLAPHJOC_cjs.generateScopedCss2; }
248
249
  });
249
250
  Object.defineProperty(exports, "generateScopedCssFromTokens", {
250
251
  enumerable: true,
251
- get: function () { return chunkO4Y3VEOA_cjs.generateScopedCss; }
252
+ get: function () { return chunkVLAPHJOC_cjs.generateScopedCss; }
252
253
  });
253
254
  Object.defineProperty(exports, "getHighlighter", {
254
255
  enumerable: true,
255
- get: function () { return chunkO4Y3VEOA_cjs.getHighlighter; }
256
+ get: function () { return chunkVLAPHJOC_cjs.getHighlighter; }
256
257
  });
257
258
  Object.defineProperty(exports, "getThemeTokens", {
258
259
  enumerable: true,
259
- get: function () { return chunkO4Y3VEOA_cjs.getThemeTokens; }
260
+ get: function () { return chunkVLAPHJOC_cjs.getThemeTokens; }
260
261
  });
261
262
  Object.defineProperty(exports, "highlightCodeBlocks", {
262
263
  enumerable: true,
263
- get: function () { return chunkO4Y3VEOA_cjs.highlightCodeBlocks; }
264
+ get: function () { return chunkVLAPHJOC_cjs.highlightCodeBlocks; }
264
265
  });
265
266
  Object.defineProperty(exports, "isLayoutComment", {
266
267
  enumerable: true,
267
- get: function () { return chunkO4Y3VEOA_cjs.isLayoutComment; }
268
+ get: function () { return chunkVLAPHJOC_cjs.isLayoutComment; }
268
269
  });
269
270
  Object.defineProperty(exports, "lightThemeTokens", {
270
271
  enumerable: true,
271
- get: function () { return chunkO4Y3VEOA_cjs.lightThemeTokens; }
272
+ get: function () { return chunkVLAPHJOC_cjs.lightThemeTokens; }
272
273
  });
273
274
  Object.defineProperty(exports, "navyThemeTokens", {
274
275
  enumerable: true,
275
- get: function () { return chunkO4Y3VEOA_cjs.navyThemeTokens; }
276
+ get: function () { return chunkVLAPHJOC_cjs.navyThemeTokens; }
276
277
  });
277
278
  Object.defineProperty(exports, "parseLayoutFromComment", {
278
279
  enumerable: true,
279
- get: function () { return chunkO4Y3VEOA_cjs.parseLayoutFromComment; }
280
+ get: function () { return chunkVLAPHJOC_cjs.parseLayoutFromComment; }
280
281
  });
281
282
  Object.defineProperty(exports, "postprocessClicks", {
282
283
  enumerable: true,
283
- get: function () { return chunkO4Y3VEOA_cjs.postprocessClicks; }
284
+ get: function () { return chunkVLAPHJOC_cjs.postprocessClicks; }
284
285
  });
285
286
  Object.defineProperty(exports, "preprocessClicks", {
286
287
  enumerable: true,
287
- get: function () { return chunkO4Y3VEOA_cjs.preprocessClicks; }
288
+ get: function () { return chunkVLAPHJOC_cjs.preprocessClicks; }
288
289
  });
289
290
  Object.defineProperty(exports, "renderMarp", {
290
291
  enumerable: true,
291
- get: function () { return chunkO4Y3VEOA_cjs.renderMarp; }
292
+ get: function () { return chunkVLAPHJOC_cjs.renderMarp; }
292
293
  });
293
294
  Object.defineProperty(exports, "renderMermaidDiagrams", {
294
295
  enumerable: true,
295
- get: function () { return chunkO4Y3VEOA_cjs.renderMermaidDiagrams; }
296
+ get: function () { return chunkVLAPHJOC_cjs.renderMermaidDiagrams; }
296
297
  });
297
298
  Object.defineProperty(exports, "renderSlide", {
298
299
  enumerable: true,
299
- get: function () { return chunkO4Y3VEOA_cjs.renderSlide; }
300
+ get: function () { return chunkVLAPHJOC_cjs.renderSlide; }
300
301
  });
301
302
  Object.defineProperty(exports, "renderSlideAsync", {
302
303
  enumerable: true,
303
- get: function () { return chunkO4Y3VEOA_cjs.renderSlideAsync; }
304
+ get: function () { return chunkVLAPHJOC_cjs.renderSlideAsync; }
304
305
  });
305
306
  Object.defineProperty(exports, "resolveTheme", {
306
307
  enumerable: true,
307
- get: function () { return chunkO4Y3VEOA_cjs.resolveTheme; }
308
+ get: function () { return chunkVLAPHJOC_cjs.resolveTheme; }
308
309
  });
309
310
  Object.defineProperty(exports, "sanitizeMermaidCode", {
310
311
  enumerable: true,
311
- get: function () { return chunkO4Y3VEOA_cjs.sanitizeMermaidCode; }
312
+ get: function () { return chunkVLAPHJOC_cjs.sanitizeMermaidCode; }
313
+ });
314
+ Object.defineProperty(exports, "SLIDE_LAYOUT_PRESETS", {
315
+ enumerable: true,
316
+ get: function () { return chunkOEAOYF7C_cjs.SLIDE_LAYOUT_PRESETS; }
317
+ });
318
+ Object.defineProperty(exports, "getSlideLayoutPresetById", {
319
+ enumerable: true,
320
+ get: function () { return chunkOEAOYF7C_cjs.getSlideLayoutPresetById; }
321
+ });
322
+ Object.defineProperty(exports, "getSlideLayoutPresetsByCategory", {
323
+ enumerable: true,
324
+ get: function () { return chunkOEAOYF7C_cjs.getSlideLayoutPresetsByCategory; }
312
325
  });
313
326
  Object.defineProperty(exports, "serializeLayoutToComment", {
314
327
  enumerable: true,
315
- get: function () { return chunkO4Y3VEOA_cjs.serializeLayoutToComment; }
328
+ get: function () { return chunkOEAOYF7C_cjs.serializeLayoutToComment; }
316
329
  });
317
330
  Object.defineProperty(exports, "splitMarkdownSlides", {
318
331
  enumerable: true,
319
- get: function () { return chunkO4Y3VEOA_cjs.splitMarkdownSlides; }
332
+ get: function () { return chunkOEAOYF7C_cjs.splitMarkdownSlides; }
320
333
  });
321
334
  Object.defineProperty(exports, "updateSlideLayoutInMarkdown", {
322
335
  enumerable: true,
323
- get: function () { return chunkO4Y3VEOA_cjs.updateSlideLayoutInMarkdown; }
336
+ get: function () { return chunkOEAOYF7C_cjs.updateSlideLayoutInMarkdown; }
324
337
  });
325
338
  exports.cleanHexColor = cleanHexColor;
326
339
  exports.convertMarkdownToPptx = convertMarkdownToPptx;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine.ts","../src/core/export/pptx-converter.ts"],"names":["renderSlide","renderSlideAsync","resolveTheme","generateScopedCss","splitMarkdownSlides"],"mappings":";;;;;AAyBO,SAAS,YAAA,CAAa,MAAA,GAA4B,EAAC,EAAgB;AACxE,EAAA,MAAM,YAAA,GAAe,OAAO,KAAA,IAAS,MAAA;AACrC,EAAA,MAAM,kBAAA,GAAqB,OAAO,WAAA,IAAe,IAAA;AACjD,EAAA,MAAM,oBAAA,GAAuB,OAAO,aAAA,IAAiB,IAAA;AAErD,EAAA,SAAS,aAAa,OAAA,EAAkD;AACtE,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,SAAS,KAAA,IAAS,YAAA;AAAA,MACzB,WAAA,EAAa,SAAS,WAAA,IAAe,kBAAA;AAAA,MACrC,aAAA,EAAe,SAAS,aAAA,IAAiB,oBAAA;AAAA,MACzC,aAAa,OAAA,EAAS;AAAA,KACxB;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,CAAC,QAAA,EAAkB,OAAA,KAAoD;AAC7E,MAAA,OAAOA,6BAAA,CAAY,QAAA,EAAU,YAAA,CAAa,OAAO,CAAC,CAAA;AAAA,IACpD,CAAA;AAAA,IAEA,WAAA,EAAa,OAAO,QAAA,EAAkB,OAAA,KAAkE;AACtG,MAAA,OAAOC,kCAAA,CAAiB,QAAA,EAAU,YAAA,CAAa,OAAO,CAAC,CAAA;AAAA,IACzD,CAAA;AAAA,IAEA,WAAA,EAAa,CAAC,KAAA,EAAkC,WAAA,KAAiC;AAC/E,MAAA,MAAM,QAAA,GAAWC,+BAAa,KAAK,CAAA;AACnC,MAAA,OAAOC,oCAAAA,CAAkB,UAAU,WAAW,CAAA;AAAA,IAChD;AAAA,GACF;AACF;;;ACjCO,SAAS,iBAAA,CAAkB,OAAA,EAAkB,SAAA,GAAoB,EAAA,EAAY;AAClF,EAAA,IAAI,CAAC,SAAS,OAAO,SAAA;AACrB,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,EAAK,CAAE,WAAA,EAAY;AAE3C,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,GAAA,GAAM,WAAW,OAAO,CAAA;AAC9B,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,EAAA,GAAK,IAAI,CAAA,IAAK,SAAA;AAAA,EACxC;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1B,IAAA,MAAM,EAAA,GAAK,WAAW,OAAO,CAAA;AAC7B,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,IAAI,CAAA,IAAK,SAAA;AAAA,EAClC;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1B,IAAA,OAAO,QAAA,CAAS,OAAA,EAAS,EAAE,CAAA,IAAK,SAAA;AAAA,EAClC;AACA,EAAA,MAAM,GAAA,GAAM,WAAW,OAAO,CAAA;AAC9B,EAAA,OAAO,CAAC,KAAA,CAAM,GAAG,IAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,GAAI,SAAA;AACzC;AAKO,SAAS,aAAA,CAAc,QAAA,EAAmB,UAAA,GAAqB,QAAA,EAAkB;AACtF,EAAA,IAAI,CAAC,UAAU,OAAO,UAAA;AACtB,EAAA,MAAM,MAAM,QAAA,CAAS,IAAA,EAAK,CAAE,OAAA,CAAQ,MAAM,EAAE,CAAA;AAC5C,EAAA,IAAI,mBAAmB,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,IAAI,WAAA,EAAY;AACzD,EAAA,IAAI,kBAAA,CAAmB,IAAA,CAAK,GAAG,CAAA,EAAG;AAChC,IAAA,OAAO,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,GAAI,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,CAAE,WAAA,EAAY;AAAA,EAC5D;AACA,EAAA,OAAO,UAAA;AACT;AAKA,SAAS,mBAAA,CAAoB,SAAiB,YAAA,EAA8B;AAC1E,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,6CAA6C,CAAA;AACzE,EAAA,IAAI,KAAA,IAAS,KAAA,CAAM,CAAC,CAAA,EAAG;AACrB,IAAA,OAAO,aAAA,CAAc,KAAA,CAAM,CAAC,CAAA,EAAG,YAAY,CAAA;AAAA,EAC7C;AACA,EAAA,OAAO,YAAA;AACT;AAWA,SAAS,oBAAoB,EAAA,EAA2B;AACtD,EAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,KAAA,CAAM,IAAI,CAAA;AAC3B,EAAA,MAAM,SAAwB,EAAC;AAE/B,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,IAAI,QAAQ,UAAA,CAAW,MAAM,KAAK,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG;AAG3D,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,mBAAmB,CAAA;AAChD,IAAA,IAAI,UAAU,MAAA,CAAO,CAAC,CAAA,IAAK,MAAA,CAAO,CAAC,CAAA,EAAG;AACpC,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,SAAA;AAAA,QACN,KAAA,EAAO,MAAA,CAAO,CAAC,CAAA,CAAE,MAAA;AAAA,QACjB,IAAA,EAAM,MAAA,CAAO,CAAC,CAAA,CAAE,OAAA,CAAQ,kBAAkB,IAAI,CAAA,CAAE,OAAA,CAAQ,YAAA,EAAc,IAAI;AAAA,OAC3E,CAAA;AACD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA,EAAG;AAC7B,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,QAAA;AAAA,QACN,IAAA,EAAM,QAAQ,OAAA,CAAQ,WAAA,EAAa,EAAE,CAAA,CAAE,OAAA,CAAQ,kBAAkB,IAAI;AAAA,OACtE,CAAA;AACD,MAAA;AAAA,IACF;AAGA,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,IAAA,EAAM,WAAA;AAAA,MACN,IAAA,EAAM,QAAQ,OAAA,CAAQ,gBAAA,EAAkB,IAAI,CAAA,CAAE,OAAA,CAAQ,cAAc,IAAI;AAAA,KACzE,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,MAAA;AACT;AAOA,eAAsB,qBAAA,CACpB,UACA,OAAA,EACqB;AACrB,EAAA,MAAM,aAAA,GAAgB,MAAM,OAAO,WAAW,CAAA;AAC9C,EAAA,MAAM,YAAA,GAAgB,cAAsB,OAAA,IAAW,aAAA;AAEvD,EAAA,MAAM,IAAA,GAAO,IAAK,YAAA,EAAqB;AAEvC,EAAA,IAAA,CAAK,MAAA,GAAS,aAAA;AACd,EAAA,IAAI,OAAA,EAAS,KAAA,EAAO,IAAA,CAAK,KAAA,GAAQ,OAAA,CAAQ,KAAA;AACzC,EAAA,IAAI,OAAA,EAAS,MAAA,EAAQ,IAAA,CAAK,MAAA,GAAS,OAAA,CAAQ,MAAA;AAE3C,EAAA,MAAM,YAAA,GAAeH,8BAAY,QAAQ,CAAA;AACzC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAII,qCAAA,CAAoB,QAAQ,CAAA;AAE/C,EAAA,MAAM,MAAA,GAAS,SAAS,KAAA,KAAU,OAAA;AAClC,EAAA,MAAM,SAAA,GAAY,SAAS,QAAA,GAAW,QAAA;AACtC,EAAA,MAAM,WAAA,GAAc,SAAS,QAAA,GAAW,QAAA;AACxC,EAAA,MAAM,cAAA,GAAiB,SAAS,QAAA,GAAW,QAAA;AAG3C,EAAA,MAAM,SAAS,KAAA,GAAQ,IAAA;AACvB,EAAA,MAAM,SAAS,GAAA,GAAM,GAAA;AAErB,EAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,OAAA,EAAS,UAAA,KAAe;AACtC,IAAA,MAAM,SAAA,GAAY,KAAK,QAAA,EAAS;AAGhC,IAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,OAAA,EAAS,SAAS,CAAA;AACtD,IAAA,SAAA,CAAU,UAAA,GAAa,EAAE,KAAA,EAAO,OAAA,EAAQ;AAGxC,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAA,GAAQ,UAAU,CAAA;AAC7C,IAAA,IAAI,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AAC7B,MAAA,SAAA,CAAU,QAAA,CAAS,KAAA,CAAM,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,IACvC;AAGA,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,GAAU,UAAU,CAAA;AAChD,IAAA,MAAM,MAAA,GAAS,oBAAoB,OAAO,CAAA;AAE1C,IAAA,IAAI,UAAU,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AAErD,MAAA,KAAA,MAAW,GAAA,IAAO,OAAO,KAAA,EAAO;AAC9B,QAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,IAAI,GAAA,CAAI,GAAA;AACzB,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAI,MAAM,CAAA;AACpC,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAI,MAAM,CAAA;AACpC,QAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,KAAA,GAAQ,KAAA,EAAO,IAAI,MAAM,CAAA;AAChD,QAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,GAAA,GAAM,KAAA,EAAO,IAAI,MAAM,CAAA;AAG9C,QAAA,IAAI,WAAA,GAAc,EAAA;AAClB,QAAA,IAAI,GAAA,CAAI,WAAW,IAAA,EAAM;AACvB,UAAA,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,KAAS,aAAa,CAAA,CAAE,KAAA,KAAU,CAAC,CAAA,EAAG,IAAA,IAAQ,SAAA;AAAA,QACjF,CAAA,MAAA,IAAW,GAAA,CAAI,MAAA,KAAW,IAAA,EAAM;AAC9B,UAAA,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,KAAS,aAAa,CAAA,CAAE,KAAA,KAAU,CAAC,CAAA,EAAG,IAAA,IAAQ,YAAA;AAAA,QACjF,CAAA,MAAO;AACL,UAAA,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,KAAS,eAAe,CAAA,CAAE,IAAA,KAAS,QAAQ,CAAA,EAAG,IAAA,IAAQ,eAAA;AAAA,QACzF;AAEA,QAAA,MAAM,UAAA,GAAa,kBAAkB,GAAA,CAAI,QAAA,EAAU,IAAI,MAAA,KAAW,IAAA,GAAO,KAAK,EAAE,CAAA;AAChF,QAAA,MAAM,QAAA,GAAW,cAAc,GAAA,CAAI,KAAA,EAAO,IAAI,MAAA,KAAW,IAAA,GAAO,iBAAiB,WAAW,CAAA;AAE5F,QAAA,SAAA,CAAU,QAAQ,WAAA,EAAa;AAAA,UAC7B,CAAA,EAAG,KAAA;AAAA,UACH,CAAA,EAAG,KAAA;AAAA,UACH,CAAA,EAAG,KAAA;AAAA,UACH,CAAA,EAAG,KAAA;AAAA,UACH,QAAA,EAAU,UAAA;AAAA,UACV,KAAA,EAAO,QAAA;AAAA,UACP,KAAA,EAAO,IAAI,SAAA,IAAa,MAAA;AAAA,UACxB,IAAA,EAAM,GAAA,CAAI,MAAA,EAAQ,UAAA,CAAW,GAAG,CAAA,IAAK,KAAA;AAAA,UACrC,QAAA,EAAU;AAAA,SACX,CAAA;AAAA,MACH;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,IAAI,QAAA,GAAW,GAAA;AACf,MAAA,MAAM,OAAA,GAAU,CAAA;AAChB,MAAA,MAAM,YAAA,GAAe,KAAA;AAErB,MAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,QAAA,IAAI,KAAA,CAAM,SAAS,SAAA,EAAW;AAC5B,UAAA,MAAM,QAAA,GAAW,MAAM,KAAA,KAAU,CAAA,GAAI,KAAK,KAAA,CAAM,KAAA,KAAU,IAAI,EAAA,GAAK,EAAA;AACnE,UAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,KAAU,CAAA,GAAI,cAAA,GAAiB,WAAA;AAEnD,UAAA,SAAA,CAAU,OAAA,CAAQ,MAAM,IAAA,EAAM;AAAA,YAC5B,CAAA,EAAG,OAAA;AAAA,YACH,CAAA,EAAG,QAAA;AAAA,YACH,CAAA,EAAG,YAAA;AAAA,YACH,CAAA,EAAG,GAAA;AAAA,YACH,QAAA;AAAA,YACA,KAAA;AAAA,YACA,IAAA,EAAM,IAAA;AAAA,YACN,QAAA,EAAU;AAAA,WACX,CAAA;AACD,UAAA,QAAA,IAAY,GAAA;AAAA,QACd,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,QAAA,EAAU;AAClC,UAAA,SAAA,CAAU,OAAA,CAAQ,MAAM,IAAA,EAAM;AAAA,YAC5B,GAAG,OAAA,GAAU,GAAA;AAAA,YACb,CAAA,EAAG,QAAA;AAAA,YACH,GAAG,YAAA,GAAe,GAAA;AAAA,YAClB,CAAA,EAAG,IAAA;AAAA,YACH,QAAA,EAAU,EAAA;AAAA,YACV,KAAA,EAAO,WAAA;AAAA,YACP,MAAA,EAAQ,IAAA;AAAA,YACR,QAAA,EAAU;AAAA,WACX,CAAA;AACD,UAAA,QAAA,IAAY,GAAA;AAAA,QACd,CAAA,MAAO;AACL,UAAA,SAAA,CAAU,OAAA,CAAQ,MAAM,IAAA,EAAM;AAAA,YAC5B,CAAA,EAAG,OAAA;AAAA,YACH,CAAA,EAAG,QAAA;AAAA,YACH,CAAA,EAAG,YAAA;AAAA,YACH,CAAA,EAAG,GAAA;AAAA,YACH,QAAA,EAAU,EAAA;AAAA,YACV,KAAA,EAAO,WAAA;AAAA,YACP,QAAA,EAAU;AAAA,WACX,CAAA;AACD,UAAA,QAAA,IAAY,IAAA;AAAA,QACd;AAEA,QAAA,IAAI,WAAW,GAAA,EAAK;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,YAAa,MAAM,IAAA,CAAK,MAAM,EAAE,UAAA,EAAY,eAAe,CAAA;AACjE,EAAA,OAAO,IAAI,WAAW,SAAS,CAAA;AACjC","file":"index.cjs","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════════\n// Engine Factory — createEngine() for advanced usage\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport type { SlideEngine, SlideEngineConfig, SlideRenderOptions, SlideRenderResult, SlideRenderAsyncResult, BuiltInTheme, SlideTheme } from './types.js';\nimport { renderSlide, renderSlideAsync } from './core/render.js';\nimport { resolveTheme, generateScopedCss } from './themes/index.js';\n\n/**\n * Create a slide engine instance with default configuration.\n *\n * @example\n * ```ts\n * const engine = createEngine({ theme: 'dark' });\n *\n * // Synchronous\n * const result = engine.render(markdown);\n *\n * // Async (with Shiki highlighting)\n * const fullResult = await engine.renderAsync(markdown);\n *\n * // Get theme CSS independently\n * const css = engine.getThemeCss('navy');\n * ```\n */\nexport function createEngine(config: SlideEngineConfig = {}): SlideEngine {\n const defaultTheme = config.theme ?? 'dark';\n const defaultEnableShiki = config.enableShiki ?? true;\n const defaultEnableMermaid = config.enableMermaid ?? true;\n\n function mergeOptions(options?: SlideRenderOptions): SlideRenderOptions {\n return {\n theme: options?.theme ?? defaultTheme,\n enableShiki: options?.enableShiki ?? defaultEnableShiki,\n enableMermaid: options?.enableMermaid ?? defaultEnableMermaid,\n containerId: options?.containerId,\n };\n }\n\n return {\n render: (markdown: string, options?: SlideRenderOptions): SlideRenderResult => {\n return renderSlide(markdown, mergeOptions(options));\n },\n\n renderAsync: async (markdown: string, options?: SlideRenderOptions): Promise<SlideRenderAsyncResult> => {\n return renderSlideAsync(markdown, mergeOptions(options));\n },\n\n getThemeCss: (theme: BuiltInTheme | SlideTheme, containerId?: string): string => {\n const resolved = resolveTheme(theme);\n return generateScopedCss(resolved, containerId);\n },\n };\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// pptx-converter.ts — Pure JS converter: Marp Markdown + Layouts → Native PPTX\n//\n// Generates native, fully editable PowerPoint textboxes and shapes\n// that open directly in PowerPoint, Keynote, and Google Slides.\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport { renderSlide } from '../render.js';\nimport { splitMarkdownSlides } from '../layout/serializer.js';\nimport type { LayoutBoxConfig } from '../../types.js';\n\nexport interface PptxExportOptions {\n title?: string;\n author?: string;\n theme?: 'dark' | 'light' | 'navy';\n}\n\n/**\n * Convert font size string ('2.5rem', '32px', '24pt') to pt number for PPTX\n */\nexport function parseFontSizeToPt(sizeStr?: string, defaultPt: number = 18): number {\n if (!sizeStr) return defaultPt;\n const trimmed = sizeStr.trim().toLowerCase();\n\n if (trimmed.endsWith('rem')) {\n const rem = parseFloat(trimmed);\n return Math.round(rem * 16 * 0.75) || defaultPt;\n }\n if (trimmed.endsWith('px')) {\n const px = parseFloat(trimmed);\n return Math.round(px * 0.75) || defaultPt;\n }\n if (trimmed.endsWith('pt')) {\n return parseInt(trimmed, 10) || defaultPt;\n }\n const num = parseFloat(trimmed);\n return !isNaN(num) ? Math.round(num) : defaultPt;\n}\n\n/**\n * Clean hex color string (removes leading #)\n */\nexport function cleanHexColor(colorStr?: string, defaultHex: string = '1F2937'): string {\n if (!colorStr) return defaultHex;\n const hex = colorStr.trim().replace(/^#/, '');\n if (/^[0-9A-Fa-f]{6}$/.test(hex)) return hex.toUpperCase();\n if (/^[0-9A-Fa-f]{3}$/.test(hex)) {\n return hex.split('').map(c => c + c).join('').toUpperCase();\n }\n return defaultHex;\n}\n\n/**\n * Extract slide-level background color directive from slide markdown\n */\nfunction extractSlideBgColor(slideMd: string, defaultColor: string): string {\n const match = slideMd.match(/<!--\\s*_backgroundColor:\\s*([^\\s>]+)\\s*-->/i);\n if (match && match[1]) {\n return cleanHexColor(match[1], defaultColor);\n }\n return defaultColor;\n}\n\n/**\n * Parse plain markdown lines into simple text items\n */\ninterface SimpleBlock {\n type: 'heading' | 'paragraph' | 'bullet' | 'code';\n level?: number;\n text: string;\n}\n\nfunction parseSimpleMarkdown(md: string): SimpleBlock[] {\n const lines = md.split('\\n');\n const blocks: SimpleBlock[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith('<!--') && trimmed.endsWith('-->')) continue;\n\n // Heading\n const hMatch = trimmed.match(/^(#{1,6})\\s+(.*)$/);\n if (hMatch && hMatch[1] && hMatch[2]) {\n blocks.push({\n type: 'heading',\n level: hMatch[1].length,\n text: hMatch[2].replace(/\\*\\*(.*?)\\*\\*/g, '$1').replace(/\\*(.*?)\\*/g, '$1'),\n });\n continue;\n }\n\n // Bullet\n if (/^[-*+]\\s+/.test(trimmed)) {\n blocks.push({\n type: 'bullet',\n text: trimmed.replace(/^[-*+]\\s+/, '').replace(/\\*\\*(.*?)\\*\\*/g, '$1'),\n });\n continue;\n }\n\n // Paragraph\n blocks.push({\n type: 'paragraph',\n text: trimmed.replace(/\\*\\*(.*?)\\*\\*/g, '$1').replace(/\\*(.*?)\\*/g, '$1'),\n });\n }\n\n return blocks;\n}\n\n/**\n * Convert Marp Markdown presentation to an editable PPTX file using pptxgenjs.\n *\n * Each box in `layout.boxes` maps directly from 1280x720 canvas px to 13.33 x 7.5 inch PPTX coordinates.\n */\nexport async function convertMarkdownToPptx(\n markdown: string,\n options?: PptxExportOptions\n): Promise<Uint8Array> {\n const PptxGenModule = await import('pptxgenjs');\n const PptxGenClass = (PptxGenModule as any).default || PptxGenModule;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const pptx = new (PptxGenClass as any)();\n\n pptx.layout = 'LAYOUT_WIDE'; // 16:9 aspect ratio (13.33 x 7.5 inches)\n if (options?.title) pptx.title = options.title;\n if (options?.author) pptx.author = options.author;\n\n const renderResult = renderSlide(markdown);\n const { slides } = splitMarkdownSlides(markdown);\n\n const isDark = options?.theme !== 'light';\n const defaultBg = isDark ? '14151B' : 'FFFFFF';\n const defaultText = isDark ? 'F1F5F9' : '1E293B';\n const defaultHeading = isDark ? '38BDF8' : '0284C7';\n\n // Coordinate scales from 1280x720 to 13.33x7.5 inches\n const scaleX = 13.33 / 1280;\n const scaleY = 7.5 / 720;\n\n slides.forEach((slideMd, slideIndex) => {\n const pptxSlide = pptx.addSlide();\n\n // 1. Set background\n const bgColor = extractSlideBgColor(slideMd, defaultBg);\n pptxSlide.background = { color: bgColor };\n\n // 2. Add Speaker / Teacher Notes\n const notes = renderResult.notes?.[slideIndex];\n if (notes && notes.length > 0) {\n pptxSlide.addNotes(notes.join('\\n\\n'));\n }\n\n // 3. Layout boxes\n const layout = renderResult.layouts?.[slideIndex];\n const blocks = parseSimpleMarkdown(slideMd);\n\n if (layout && layout.boxes && layout.boxes.length > 0) {\n // Freeform layout: Render boxes with exact pos\n for (const box of layout.boxes) {\n const [x, y, w, h] = box.pos;\n const xInch = Math.max(0, x * scaleX);\n const yInch = Math.max(0, y * scaleY);\n const wInch = Math.min(13.33 - xInch, w * scaleX);\n const hInch = Math.min(7.5 - yInch, h * scaleY);\n\n // Find corresponding text\n let contentText = '';\n if (box.target === 'h1') {\n contentText = blocks.find(b => b.type === 'heading' && b.level === 1)?.text || 'Heading';\n } else if (box.target === 'h2') {\n contentText = blocks.find(b => b.type === 'heading' && b.level === 2)?.text || 'Subheading';\n } else {\n contentText = blocks.find(b => b.type === 'paragraph' || b.type === 'bullet')?.text || 'Content block';\n }\n\n const fontSizePt = parseFontSizeToPt(box.fontSize, box.target === 'h1' ? 28 : 16);\n const colorHex = cleanHexColor(box.color, box.target === 'h1' ? defaultHeading : defaultText);\n\n pptxSlide.addText(contentText, {\n x: xInch,\n y: yInch,\n w: wInch,\n h: hInch,\n fontSize: fontSizePt,\n color: colorHex,\n align: box.textAlign ?? 'left',\n bold: box.target?.startsWith('h') ?? false,\n fontFace: 'Arial',\n });\n }\n } else {\n // Flow layout fallback: Stack headings and paragraphs nicely\n let currentY = 0.8;\n const marginX = 1.0;\n const contentWidth = 11.33;\n\n for (const block of blocks) {\n if (block.type === 'heading') {\n const fontSize = block.level === 1 ? 30 : block.level === 2 ? 22 : 18;\n const color = block.level === 1 ? defaultHeading : defaultText;\n\n pptxSlide.addText(block.text, {\n x: marginX,\n y: currentY,\n w: contentWidth,\n h: 0.8,\n fontSize,\n color,\n bold: true,\n fontFace: 'Arial',\n });\n currentY += 0.9;\n } else if (block.type === 'bullet') {\n pptxSlide.addText(block.text, {\n x: marginX + 0.3,\n y: currentY,\n w: contentWidth - 0.3,\n h: 0.45,\n fontSize: 15,\n color: defaultText,\n bullet: true,\n fontFace: 'Arial',\n });\n currentY += 0.5;\n } else {\n pptxSlide.addText(block.text, {\n x: marginX,\n y: currentY,\n w: contentWidth,\n h: 0.5,\n fontSize: 15,\n color: defaultText,\n fontFace: 'Arial',\n });\n currentY += 0.55;\n }\n\n if (currentY > 6.5) break; // Prevent vertical overflow off slide\n }\n }\n });\n\n const pptxArray = (await pptx.write({ outputType: 'arraybuffer' })) as ArrayBuffer;\n return new Uint8Array(pptxArray);\n}\n"]}
1
+ {"version":3,"sources":["../src/engine.ts","../src/core/export/pptx-converter.ts"],"names":["renderSlide","renderSlideAsync","resolveTheme","generateScopedCss","splitMarkdownSlides"],"mappings":"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","file":"index.cjs","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════════\n// Engine Factory — createEngine() for advanced usage\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport type { SlideEngine, SlideEngineConfig, SlideRenderOptions, SlideRenderResult, SlideRenderAsyncResult, BuiltInTheme, SlideTheme } from './types.js';\nimport { renderSlide, renderSlideAsync } from './core/render.js';\nimport { resolveTheme, generateScopedCss } from './themes/index.js';\n\n/**\n * Create a slide engine instance with default configuration.\n *\n * @example\n * ```ts\n * const engine = createEngine({ theme: 'dark' });\n *\n * // Synchronous\n * const result = engine.render(markdown);\n *\n * // Async (with Shiki highlighting)\n * const fullResult = await engine.renderAsync(markdown);\n *\n * // Get theme CSS independently\n * const css = engine.getThemeCss('navy');\n * ```\n */\nexport function createEngine(config: SlideEngineConfig = {}): SlideEngine {\n const defaultTheme = config.theme ?? 'dark';\n const defaultEnableShiki = config.enableShiki ?? true;\n const defaultEnableMermaid = config.enableMermaid ?? true;\n\n function mergeOptions(options?: SlideRenderOptions): SlideRenderOptions {\n return {\n theme: options?.theme ?? defaultTheme,\n enableShiki: options?.enableShiki ?? defaultEnableShiki,\n enableMermaid: options?.enableMermaid ?? defaultEnableMermaid,\n containerId: options?.containerId,\n };\n }\n\n return {\n render: (markdown: string, options?: SlideRenderOptions): SlideRenderResult => {\n return renderSlide(markdown, mergeOptions(options));\n },\n\n renderAsync: async (markdown: string, options?: SlideRenderOptions): Promise<SlideRenderAsyncResult> => {\n return renderSlideAsync(markdown, mergeOptions(options));\n },\n\n getThemeCss: (theme: BuiltInTheme | SlideTheme, containerId?: string): string => {\n const resolved = resolveTheme(theme);\n return generateScopedCss(resolved, containerId);\n },\n };\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// pptx-converter.ts — Pure JS converter: Marp Markdown + Layouts → Native PPTX\n//\n// Generates native, fully editable PowerPoint textboxes and shapes\n// that open directly in PowerPoint, Keynote, and Google Slides.\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport { renderSlide } from '../render.js';\nimport { splitMarkdownSlides } from '../layout/serializer.js';\nimport type { LayoutBoxConfig } from '../../types.js';\n\nexport interface PptxExportOptions {\n title?: string;\n author?: string;\n theme?: 'dark' | 'light' | 'navy';\n}\n\n/**\n * Convert font size string ('2.5rem', '32px', '24pt') to pt number for PPTX\n */\nexport function parseFontSizeToPt(sizeStr?: string, defaultPt: number = 18): number {\n if (!sizeStr) return defaultPt;\n const trimmed = sizeStr.trim().toLowerCase();\n\n if (trimmed.endsWith('rem')) {\n const rem = parseFloat(trimmed);\n return Math.round(rem * 16 * 0.75) || defaultPt;\n }\n if (trimmed.endsWith('px')) {\n const px = parseFloat(trimmed);\n return Math.round(px * 0.75) || defaultPt;\n }\n if (trimmed.endsWith('pt')) {\n return parseInt(trimmed, 10) || defaultPt;\n }\n const num = parseFloat(trimmed);\n return !isNaN(num) ? Math.round(num) : defaultPt;\n}\n\n/**\n * Clean hex color string (removes leading #)\n */\nexport function cleanHexColor(colorStr?: string, defaultHex: string = '1F2937'): string {\n if (!colorStr) return defaultHex;\n const hex = colorStr.trim().replace(/^#/, '');\n if (/^[0-9A-Fa-f]{6}$/.test(hex)) return hex.toUpperCase();\n if (/^[0-9A-Fa-f]{3}$/.test(hex)) {\n return hex.split('').map(c => c + c).join('').toUpperCase();\n }\n return defaultHex;\n}\n\n/**\n * Extract slide-level background color directive from slide markdown\n */\nfunction extractSlideBgColor(slideMd: string, defaultColor: string): string {\n const match = slideMd.match(/<!--\\s*_backgroundColor:\\s*([^\\s>]+)\\s*-->/i);\n if (match && match[1]) {\n return cleanHexColor(match[1], defaultColor);\n }\n return defaultColor;\n}\n\n/**\n * Parse plain markdown lines into simple text items\n */\ninterface SimpleBlock {\n type: 'heading' | 'paragraph' | 'bullet' | 'code';\n level?: number;\n text: string;\n}\n\nfunction parseSimpleMarkdown(md: string): SimpleBlock[] {\n const lines = md.split('\\n');\n const blocks: SimpleBlock[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith('<!--') && trimmed.endsWith('-->')) continue;\n\n // Heading\n const hMatch = trimmed.match(/^(#{1,6})\\s+(.*)$/);\n if (hMatch && hMatch[1] && hMatch[2]) {\n blocks.push({\n type: 'heading',\n level: hMatch[1].length,\n text: hMatch[2].replace(/\\*\\*(.*?)\\*\\*/g, '$1').replace(/\\*(.*?)\\*/g, '$1'),\n });\n continue;\n }\n\n // Bullet\n if (/^[-*+]\\s+/.test(trimmed)) {\n blocks.push({\n type: 'bullet',\n text: trimmed.replace(/^[-*+]\\s+/, '').replace(/\\*\\*(.*?)\\*\\*/g, '$1'),\n });\n continue;\n }\n\n // Paragraph\n blocks.push({\n type: 'paragraph',\n text: trimmed.replace(/\\*\\*(.*?)\\*\\*/g, '$1').replace(/\\*(.*?)\\*/g, '$1'),\n });\n }\n\n return blocks;\n}\n\n/**\n * Convert Marp Markdown presentation to an editable PPTX file using pptxgenjs.\n *\n * Each box in `layout.boxes` maps directly from 1280x720 canvas px to 13.33 x 7.5 inch PPTX coordinates.\n */\nexport async function convertMarkdownToPptx(\n markdown: string,\n options?: PptxExportOptions\n): Promise<Uint8Array> {\n const PptxGenModule = await import('pptxgenjs');\n const PptxGenClass = (PptxGenModule as any).default || PptxGenModule;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const pptx = new (PptxGenClass as any)();\n\n pptx.layout = 'LAYOUT_WIDE'; // 16:9 aspect ratio (13.33 x 7.5 inches)\n if (options?.title) pptx.title = options.title;\n if (options?.author) pptx.author = options.author;\n\n const renderResult = renderSlide(markdown);\n const { slides } = splitMarkdownSlides(markdown);\n\n const isDark = options?.theme !== 'light';\n const defaultBg = isDark ? '14151B' : 'FFFFFF';\n const defaultText = isDark ? 'F1F5F9' : '1E293B';\n const defaultHeading = isDark ? '38BDF8' : '0284C7';\n\n // Coordinate scales from 1280x720 to 13.33x7.5 inches\n const scaleX = 13.33 / 1280;\n const scaleY = 7.5 / 720;\n\n slides.forEach((slideMd, slideIndex) => {\n const pptxSlide = pptx.addSlide();\n\n // 1. Set background\n const bgColor = extractSlideBgColor(slideMd, defaultBg);\n pptxSlide.background = { color: bgColor };\n\n // 2. Add Speaker / Teacher Notes\n const notes = renderResult.notes?.[slideIndex];\n if (notes && notes.length > 0) {\n pptxSlide.addNotes(notes.join('\\n\\n'));\n }\n\n // 3. Layout boxes\n const layout = renderResult.layouts?.[slideIndex];\n const blocks = parseSimpleMarkdown(slideMd);\n\n if (layout && layout.boxes && layout.boxes.length > 0) {\n // Freeform layout: Render boxes with exact pos\n for (const box of layout.boxes) {\n const [x, y, w, h] = box.pos;\n const xInch = Math.max(0, x * scaleX);\n const yInch = Math.max(0, y * scaleY);\n const wInch = Math.min(13.33 - xInch, w * scaleX);\n const hInch = Math.min(7.5 - yInch, h * scaleY);\n\n // Find corresponding text\n let contentText = '';\n if (box.target === 'h1') {\n contentText = blocks.find(b => b.type === 'heading' && b.level === 1)?.text || 'Heading';\n } else if (box.target === 'h2') {\n contentText = blocks.find(b => b.type === 'heading' && b.level === 2)?.text || 'Subheading';\n } else {\n contentText = blocks.find(b => b.type === 'paragraph' || b.type === 'bullet')?.text || 'Content block';\n }\n\n const fontSizePt = parseFontSizeToPt(box.fontSize, box.target === 'h1' ? 28 : 16);\n const colorHex = cleanHexColor(box.color, box.target === 'h1' ? defaultHeading : defaultText);\n\n pptxSlide.addText(contentText, {\n x: xInch,\n y: yInch,\n w: wInch,\n h: hInch,\n fontSize: fontSizePt,\n color: colorHex,\n align: box.textAlign ?? 'left',\n bold: box.target?.startsWith('h') ?? false,\n fontFace: 'Arial',\n });\n }\n } else {\n // Flow layout fallback: Stack headings and paragraphs nicely\n let currentY = 0.8;\n const marginX = 1.0;\n const contentWidth = 11.33;\n\n for (const block of blocks) {\n if (block.type === 'heading') {\n const fontSize = block.level === 1 ? 30 : block.level === 2 ? 22 : 18;\n const color = block.level === 1 ? defaultHeading : defaultText;\n\n pptxSlide.addText(block.text, {\n x: marginX,\n y: currentY,\n w: contentWidth,\n h: 0.8,\n fontSize,\n color,\n bold: true,\n fontFace: 'Arial',\n });\n currentY += 0.9;\n } else if (block.type === 'bullet') {\n pptxSlide.addText(block.text, {\n x: marginX + 0.3,\n y: currentY,\n w: contentWidth - 0.3,\n h: 0.45,\n fontSize: 15,\n color: defaultText,\n bullet: true,\n fontFace: 'Arial',\n });\n currentY += 0.5;\n } else {\n pptxSlide.addText(block.text, {\n x: marginX,\n y: currentY,\n w: contentWidth,\n h: 0.5,\n fontSize: 15,\n color: defaultText,\n fontFace: 'Arial',\n });\n currentY += 0.55;\n }\n\n if (currentY > 6.5) break; // Prevent vertical overflow off slide\n }\n }\n });\n\n const pptxArray = (await pptx.write({ outputType: 'arraybuffer' })) as ArrayBuffer;\n return new Uint8Array(pptxArray);\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,8 @@
1
- import { S as SlideEngineConfig, a as SlideEngine, T as ThemeTokens, M as MermaidBlock, b as SlideLayoutData } from './click-css-C84mdmU0.cjs';
2
- export { B as BuiltInTheme, n as ClickCssOptions, m as ClickPostprocessResult, C as ClickPreprocessResult, L as LayoutBoxConfig, t as SlideRenderAsyncResult, q as SlideRenderOptions, s as SlideRenderResult, o as SlideTheme, e as countSlides, f as defineTheme, k as extractMaxClicks, l as generateClickCss, i as generateScopedCss, h as getThemeTokens, j as postprocessClicks, p as preprocessClicks, d as renderMarp, r as renderSlide, c as renderSlideAsync, g as resolveTheme } from './click-css-C84mdmU0.cjs';
1
+ export { l as ClickCssOptions, k as ClickPostprocessResult, C as ClickPreprocessResult, c as countSlides, d as defineTheme, i as extractMaxClicks, j as generateClickCss, f as generateScopedCss, g as getThemeTokens, h as postprocessClicks, p as preprocessClicks, b as renderMarp, r as renderSlide, a as renderSlideAsync, e as resolveTheme } from './click-css-BGZI3XKk.cjs';
2
+ import { S as SlideEngineConfig, a as SlideEngine, T as ThemeTokens, M as MermaidBlock, b as SlideLayoutData } from './types-DnR81ReX.cjs';
3
+ export { B as BuiltInTheme, L as LayoutBoxConfig, f as SlideRenderAsyncResult, d as SlideRenderOptions, e as SlideRenderResult, c as SlideTheme } from './types-DnR81ReX.cjs';
3
4
  import { Highlighter } from 'shiki';
5
+ export { S as SLIDE_LAYOUT_PRESETS, c as SlideLayoutCategory, b as SlideLayoutPreset, g as getSlideLayoutPresetById, a as getSlideLayoutPresetsByCategory } from './presets-JpoJbNKE.cjs';
4
6
 
5
7
  /**
6
8
  * Create a slide engine instance with default configuration.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { S as SlideEngineConfig, a as SlideEngine, T as ThemeTokens, M as MermaidBlock, b as SlideLayoutData } from './click-css-C84mdmU0.js';
2
- export { B as BuiltInTheme, n as ClickCssOptions, m as ClickPostprocessResult, C as ClickPreprocessResult, L as LayoutBoxConfig, t as SlideRenderAsyncResult, q as SlideRenderOptions, s as SlideRenderResult, o as SlideTheme, e as countSlides, f as defineTheme, k as extractMaxClicks, l as generateClickCss, i as generateScopedCss, h as getThemeTokens, j as postprocessClicks, p as preprocessClicks, d as renderMarp, r as renderSlide, c as renderSlideAsync, g as resolveTheme } from './click-css-C84mdmU0.js';
1
+ export { l as ClickCssOptions, k as ClickPostprocessResult, C as ClickPreprocessResult, c as countSlides, d as defineTheme, i as extractMaxClicks, j as generateClickCss, f as generateScopedCss, g as getThemeTokens, h as postprocessClicks, p as preprocessClicks, b as renderMarp, r as renderSlide, a as renderSlideAsync, e as resolveTheme } from './click-css-eWONB-hS.js';
2
+ import { S as SlideEngineConfig, a as SlideEngine, T as ThemeTokens, M as MermaidBlock, b as SlideLayoutData } from './types-DnR81ReX.js';
3
+ export { B as BuiltInTheme, L as LayoutBoxConfig, f as SlideRenderAsyncResult, d as SlideRenderOptions, e as SlideRenderResult, c as SlideTheme } from './types-DnR81ReX.js';
3
4
  import { Highlighter } from 'shiki';
5
+ export { S as SLIDE_LAYOUT_PRESETS, c as SlideLayoutCategory, b as SlideLayoutPreset, g as getSlideLayoutPresetById, a as getSlideLayoutPresetsByCategory } from './presets-B1N2_jKl.js';
4
6
 
5
7
  /**
6
8
  * Create a slide engine instance with default configuration.
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
- import { resolveTheme, generateScopedCss2, renderSlideAsync, renderSlide, splitMarkdownSlides } from './chunk-FATGZ25L.js';
2
- export { convertTextArrows, countSlides, darkThemeTokens, defineTheme, detectMermaidBlocks, extractLayoutsAndNotes, extractMarpSource, extractMaxClicks, filterPresenterNotes, generateClickCss, generateLayoutCss, generateScopedCss2 as generateScopedCss, generateScopedCss as generateScopedCssFromTokens, getHighlighter, getThemeTokens, highlightCodeBlocks, isLayoutComment, lightThemeTokens, navyThemeTokens, parseLayoutFromComment, postprocessClicks, preprocessClicks, renderMarp, renderMermaidDiagrams, renderSlide, renderSlideAsync, resolveTheme, sanitizeMermaidCode, serializeLayoutToComment, splitMarkdownSlides, updateSlideLayoutInMarkdown } from './chunk-FATGZ25L.js';
1
+ import { resolveTheme, generateScopedCss2, renderSlideAsync, renderSlide } from './chunk-JOW4QWKF.js';
2
+ export { convertTextArrows, countSlides, darkThemeTokens, defineTheme, detectMermaidBlocks, extractLayoutsAndNotes, extractMarpSource, extractMaxClicks, filterPresenterNotes, generateClickCss, generateLayoutCss, generateScopedCss2 as generateScopedCss, generateScopedCss as generateScopedCssFromTokens, getHighlighter, getThemeTokens, highlightCodeBlocks, isLayoutComment, lightThemeTokens, navyThemeTokens, parseLayoutFromComment, postprocessClicks, preprocessClicks, renderMarp, renderMermaidDiagrams, renderSlide, renderSlideAsync, resolveTheme, sanitizeMermaidCode } from './chunk-JOW4QWKF.js';
3
+ import { splitMarkdownSlides } from './chunk-HBMXEPZJ.js';
4
+ export { SLIDE_LAYOUT_PRESETS, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, serializeLayoutToComment, splitMarkdownSlides, updateSlideLayoutInMarkdown } from './chunk-HBMXEPZJ.js';
3
5
 
4
6
  // src/engine.ts
5
7
  function createEngine(config = {}) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine.ts","../src/core/export/pptx-converter.ts"],"names":["generateScopedCss"],"mappings":"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","file":"index.js","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════════\n// Engine Factory — createEngine() for advanced usage\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport type { SlideEngine, SlideEngineConfig, SlideRenderOptions, SlideRenderResult, SlideRenderAsyncResult, BuiltInTheme, SlideTheme } from './types.js';\nimport { renderSlide, renderSlideAsync } from './core/render.js';\nimport { resolveTheme, generateScopedCss } from './themes/index.js';\n\n/**\n * Create a slide engine instance with default configuration.\n *\n * @example\n * ```ts\n * const engine = createEngine({ theme: 'dark' });\n *\n * // Synchronous\n * const result = engine.render(markdown);\n *\n * // Async (with Shiki highlighting)\n * const fullResult = await engine.renderAsync(markdown);\n *\n * // Get theme CSS independently\n * const css = engine.getThemeCss('navy');\n * ```\n */\nexport function createEngine(config: SlideEngineConfig = {}): SlideEngine {\n const defaultTheme = config.theme ?? 'dark';\n const defaultEnableShiki = config.enableShiki ?? true;\n const defaultEnableMermaid = config.enableMermaid ?? true;\n\n function mergeOptions(options?: SlideRenderOptions): SlideRenderOptions {\n return {\n theme: options?.theme ?? defaultTheme,\n enableShiki: options?.enableShiki ?? defaultEnableShiki,\n enableMermaid: options?.enableMermaid ?? defaultEnableMermaid,\n containerId: options?.containerId,\n };\n }\n\n return {\n render: (markdown: string, options?: SlideRenderOptions): SlideRenderResult => {\n return renderSlide(markdown, mergeOptions(options));\n },\n\n renderAsync: async (markdown: string, options?: SlideRenderOptions): Promise<SlideRenderAsyncResult> => {\n return renderSlideAsync(markdown, mergeOptions(options));\n },\n\n getThemeCss: (theme: BuiltInTheme | SlideTheme, containerId?: string): string => {\n const resolved = resolveTheme(theme);\n return generateScopedCss(resolved, containerId);\n },\n };\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// pptx-converter.ts — Pure JS converter: Marp Markdown + Layouts → Native PPTX\n//\n// Generates native, fully editable PowerPoint textboxes and shapes\n// that open directly in PowerPoint, Keynote, and Google Slides.\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport { renderSlide } from '../render.js';\nimport { splitMarkdownSlides } from '../layout/serializer.js';\nimport type { LayoutBoxConfig } from '../../types.js';\n\nexport interface PptxExportOptions {\n title?: string;\n author?: string;\n theme?: 'dark' | 'light' | 'navy';\n}\n\n/**\n * Convert font size string ('2.5rem', '32px', '24pt') to pt number for PPTX\n */\nexport function parseFontSizeToPt(sizeStr?: string, defaultPt: number = 18): number {\n if (!sizeStr) return defaultPt;\n const trimmed = sizeStr.trim().toLowerCase();\n\n if (trimmed.endsWith('rem')) {\n const rem = parseFloat(trimmed);\n return Math.round(rem * 16 * 0.75) || defaultPt;\n }\n if (trimmed.endsWith('px')) {\n const px = parseFloat(trimmed);\n return Math.round(px * 0.75) || defaultPt;\n }\n if (trimmed.endsWith('pt')) {\n return parseInt(trimmed, 10) || defaultPt;\n }\n const num = parseFloat(trimmed);\n return !isNaN(num) ? Math.round(num) : defaultPt;\n}\n\n/**\n * Clean hex color string (removes leading #)\n */\nexport function cleanHexColor(colorStr?: string, defaultHex: string = '1F2937'): string {\n if (!colorStr) return defaultHex;\n const hex = colorStr.trim().replace(/^#/, '');\n if (/^[0-9A-Fa-f]{6}$/.test(hex)) return hex.toUpperCase();\n if (/^[0-9A-Fa-f]{3}$/.test(hex)) {\n return hex.split('').map(c => c + c).join('').toUpperCase();\n }\n return defaultHex;\n}\n\n/**\n * Extract slide-level background color directive from slide markdown\n */\nfunction extractSlideBgColor(slideMd: string, defaultColor: string): string {\n const match = slideMd.match(/<!--\\s*_backgroundColor:\\s*([^\\s>]+)\\s*-->/i);\n if (match && match[1]) {\n return cleanHexColor(match[1], defaultColor);\n }\n return defaultColor;\n}\n\n/**\n * Parse plain markdown lines into simple text items\n */\ninterface SimpleBlock {\n type: 'heading' | 'paragraph' | 'bullet' | 'code';\n level?: number;\n text: string;\n}\n\nfunction parseSimpleMarkdown(md: string): SimpleBlock[] {\n const lines = md.split('\\n');\n const blocks: SimpleBlock[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith('<!--') && trimmed.endsWith('-->')) continue;\n\n // Heading\n const hMatch = trimmed.match(/^(#{1,6})\\s+(.*)$/);\n if (hMatch && hMatch[1] && hMatch[2]) {\n blocks.push({\n type: 'heading',\n level: hMatch[1].length,\n text: hMatch[2].replace(/\\*\\*(.*?)\\*\\*/g, '$1').replace(/\\*(.*?)\\*/g, '$1'),\n });\n continue;\n }\n\n // Bullet\n if (/^[-*+]\\s+/.test(trimmed)) {\n blocks.push({\n type: 'bullet',\n text: trimmed.replace(/^[-*+]\\s+/, '').replace(/\\*\\*(.*?)\\*\\*/g, '$1'),\n });\n continue;\n }\n\n // Paragraph\n blocks.push({\n type: 'paragraph',\n text: trimmed.replace(/\\*\\*(.*?)\\*\\*/g, '$1').replace(/\\*(.*?)\\*/g, '$1'),\n });\n }\n\n return blocks;\n}\n\n/**\n * Convert Marp Markdown presentation to an editable PPTX file using pptxgenjs.\n *\n * Each box in `layout.boxes` maps directly from 1280x720 canvas px to 13.33 x 7.5 inch PPTX coordinates.\n */\nexport async function convertMarkdownToPptx(\n markdown: string,\n options?: PptxExportOptions\n): Promise<Uint8Array> {\n const PptxGenModule = await import('pptxgenjs');\n const PptxGenClass = (PptxGenModule as any).default || PptxGenModule;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const pptx = new (PptxGenClass as any)();\n\n pptx.layout = 'LAYOUT_WIDE'; // 16:9 aspect ratio (13.33 x 7.5 inches)\n if (options?.title) pptx.title = options.title;\n if (options?.author) pptx.author = options.author;\n\n const renderResult = renderSlide(markdown);\n const { slides } = splitMarkdownSlides(markdown);\n\n const isDark = options?.theme !== 'light';\n const defaultBg = isDark ? '14151B' : 'FFFFFF';\n const defaultText = isDark ? 'F1F5F9' : '1E293B';\n const defaultHeading = isDark ? '38BDF8' : '0284C7';\n\n // Coordinate scales from 1280x720 to 13.33x7.5 inches\n const scaleX = 13.33 / 1280;\n const scaleY = 7.5 / 720;\n\n slides.forEach((slideMd, slideIndex) => {\n const pptxSlide = pptx.addSlide();\n\n // 1. Set background\n const bgColor = extractSlideBgColor(slideMd, defaultBg);\n pptxSlide.background = { color: bgColor };\n\n // 2. Add Speaker / Teacher Notes\n const notes = renderResult.notes?.[slideIndex];\n if (notes && notes.length > 0) {\n pptxSlide.addNotes(notes.join('\\n\\n'));\n }\n\n // 3. Layout boxes\n const layout = renderResult.layouts?.[slideIndex];\n const blocks = parseSimpleMarkdown(slideMd);\n\n if (layout && layout.boxes && layout.boxes.length > 0) {\n // Freeform layout: Render boxes with exact pos\n for (const box of layout.boxes) {\n const [x, y, w, h] = box.pos;\n const xInch = Math.max(0, x * scaleX);\n const yInch = Math.max(0, y * scaleY);\n const wInch = Math.min(13.33 - xInch, w * scaleX);\n const hInch = Math.min(7.5 - yInch, h * scaleY);\n\n // Find corresponding text\n let contentText = '';\n if (box.target === 'h1') {\n contentText = blocks.find(b => b.type === 'heading' && b.level === 1)?.text || 'Heading';\n } else if (box.target === 'h2') {\n contentText = blocks.find(b => b.type === 'heading' && b.level === 2)?.text || 'Subheading';\n } else {\n contentText = blocks.find(b => b.type === 'paragraph' || b.type === 'bullet')?.text || 'Content block';\n }\n\n const fontSizePt = parseFontSizeToPt(box.fontSize, box.target === 'h1' ? 28 : 16);\n const colorHex = cleanHexColor(box.color, box.target === 'h1' ? defaultHeading : defaultText);\n\n pptxSlide.addText(contentText, {\n x: xInch,\n y: yInch,\n w: wInch,\n h: hInch,\n fontSize: fontSizePt,\n color: colorHex,\n align: box.textAlign ?? 'left',\n bold: box.target?.startsWith('h') ?? false,\n fontFace: 'Arial',\n });\n }\n } else {\n // Flow layout fallback: Stack headings and paragraphs nicely\n let currentY = 0.8;\n const marginX = 1.0;\n const contentWidth = 11.33;\n\n for (const block of blocks) {\n if (block.type === 'heading') {\n const fontSize = block.level === 1 ? 30 : block.level === 2 ? 22 : 18;\n const color = block.level === 1 ? defaultHeading : defaultText;\n\n pptxSlide.addText(block.text, {\n x: marginX,\n y: currentY,\n w: contentWidth,\n h: 0.8,\n fontSize,\n color,\n bold: true,\n fontFace: 'Arial',\n });\n currentY += 0.9;\n } else if (block.type === 'bullet') {\n pptxSlide.addText(block.text, {\n x: marginX + 0.3,\n y: currentY,\n w: contentWidth - 0.3,\n h: 0.45,\n fontSize: 15,\n color: defaultText,\n bullet: true,\n fontFace: 'Arial',\n });\n currentY += 0.5;\n } else {\n pptxSlide.addText(block.text, {\n x: marginX,\n y: currentY,\n w: contentWidth,\n h: 0.5,\n fontSize: 15,\n color: defaultText,\n fontFace: 'Arial',\n });\n currentY += 0.55;\n }\n\n if (currentY > 6.5) break; // Prevent vertical overflow off slide\n }\n }\n });\n\n const pptxArray = (await pptx.write({ outputType: 'arraybuffer' })) as ArrayBuffer;\n return new Uint8Array(pptxArray);\n}\n"]}
1
+ {"version":3,"sources":["../src/engine.ts","../src/core/export/pptx-converter.ts"],"names":["generateScopedCss"],"mappings":"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","file":"index.js","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════════\n// Engine Factory — createEngine() for advanced usage\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport type { SlideEngine, SlideEngineConfig, SlideRenderOptions, SlideRenderResult, SlideRenderAsyncResult, BuiltInTheme, SlideTheme } from './types.js';\nimport { renderSlide, renderSlideAsync } from './core/render.js';\nimport { resolveTheme, generateScopedCss } from './themes/index.js';\n\n/**\n * Create a slide engine instance with default configuration.\n *\n * @example\n * ```ts\n * const engine = createEngine({ theme: 'dark' });\n *\n * // Synchronous\n * const result = engine.render(markdown);\n *\n * // Async (with Shiki highlighting)\n * const fullResult = await engine.renderAsync(markdown);\n *\n * // Get theme CSS independently\n * const css = engine.getThemeCss('navy');\n * ```\n */\nexport function createEngine(config: SlideEngineConfig = {}): SlideEngine {\n const defaultTheme = config.theme ?? 'dark';\n const defaultEnableShiki = config.enableShiki ?? true;\n const defaultEnableMermaid = config.enableMermaid ?? true;\n\n function mergeOptions(options?: SlideRenderOptions): SlideRenderOptions {\n return {\n theme: options?.theme ?? defaultTheme,\n enableShiki: options?.enableShiki ?? defaultEnableShiki,\n enableMermaid: options?.enableMermaid ?? defaultEnableMermaid,\n containerId: options?.containerId,\n };\n }\n\n return {\n render: (markdown: string, options?: SlideRenderOptions): SlideRenderResult => {\n return renderSlide(markdown, mergeOptions(options));\n },\n\n renderAsync: async (markdown: string, options?: SlideRenderOptions): Promise<SlideRenderAsyncResult> => {\n return renderSlideAsync(markdown, mergeOptions(options));\n },\n\n getThemeCss: (theme: BuiltInTheme | SlideTheme, containerId?: string): string => {\n const resolved = resolveTheme(theme);\n return generateScopedCss(resolved, containerId);\n },\n };\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// pptx-converter.ts — Pure JS converter: Marp Markdown + Layouts → Native PPTX\n//\n// Generates native, fully editable PowerPoint textboxes and shapes\n// that open directly in PowerPoint, Keynote, and Google Slides.\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport { renderSlide } from '../render.js';\nimport { splitMarkdownSlides } from '../layout/serializer.js';\nimport type { LayoutBoxConfig } from '../../types.js';\n\nexport interface PptxExportOptions {\n title?: string;\n author?: string;\n theme?: 'dark' | 'light' | 'navy';\n}\n\n/**\n * Convert font size string ('2.5rem', '32px', '24pt') to pt number for PPTX\n */\nexport function parseFontSizeToPt(sizeStr?: string, defaultPt: number = 18): number {\n if (!sizeStr) return defaultPt;\n const trimmed = sizeStr.trim().toLowerCase();\n\n if (trimmed.endsWith('rem')) {\n const rem = parseFloat(trimmed);\n return Math.round(rem * 16 * 0.75) || defaultPt;\n }\n if (trimmed.endsWith('px')) {\n const px = parseFloat(trimmed);\n return Math.round(px * 0.75) || defaultPt;\n }\n if (trimmed.endsWith('pt')) {\n return parseInt(trimmed, 10) || defaultPt;\n }\n const num = parseFloat(trimmed);\n return !isNaN(num) ? Math.round(num) : defaultPt;\n}\n\n/**\n * Clean hex color string (removes leading #)\n */\nexport function cleanHexColor(colorStr?: string, defaultHex: string = '1F2937'): string {\n if (!colorStr) return defaultHex;\n const hex = colorStr.trim().replace(/^#/, '');\n if (/^[0-9A-Fa-f]{6}$/.test(hex)) return hex.toUpperCase();\n if (/^[0-9A-Fa-f]{3}$/.test(hex)) {\n return hex.split('').map(c => c + c).join('').toUpperCase();\n }\n return defaultHex;\n}\n\n/**\n * Extract slide-level background color directive from slide markdown\n */\nfunction extractSlideBgColor(slideMd: string, defaultColor: string): string {\n const match = slideMd.match(/<!--\\s*_backgroundColor:\\s*([^\\s>]+)\\s*-->/i);\n if (match && match[1]) {\n return cleanHexColor(match[1], defaultColor);\n }\n return defaultColor;\n}\n\n/**\n * Parse plain markdown lines into simple text items\n */\ninterface SimpleBlock {\n type: 'heading' | 'paragraph' | 'bullet' | 'code';\n level?: number;\n text: string;\n}\n\nfunction parseSimpleMarkdown(md: string): SimpleBlock[] {\n const lines = md.split('\\n');\n const blocks: SimpleBlock[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith('<!--') && trimmed.endsWith('-->')) continue;\n\n // Heading\n const hMatch = trimmed.match(/^(#{1,6})\\s+(.*)$/);\n if (hMatch && hMatch[1] && hMatch[2]) {\n blocks.push({\n type: 'heading',\n level: hMatch[1].length,\n text: hMatch[2].replace(/\\*\\*(.*?)\\*\\*/g, '$1').replace(/\\*(.*?)\\*/g, '$1'),\n });\n continue;\n }\n\n // Bullet\n if (/^[-*+]\\s+/.test(trimmed)) {\n blocks.push({\n type: 'bullet',\n text: trimmed.replace(/^[-*+]\\s+/, '').replace(/\\*\\*(.*?)\\*\\*/g, '$1'),\n });\n continue;\n }\n\n // Paragraph\n blocks.push({\n type: 'paragraph',\n text: trimmed.replace(/\\*\\*(.*?)\\*\\*/g, '$1').replace(/\\*(.*?)\\*/g, '$1'),\n });\n }\n\n return blocks;\n}\n\n/**\n * Convert Marp Markdown presentation to an editable PPTX file using pptxgenjs.\n *\n * Each box in `layout.boxes` maps directly from 1280x720 canvas px to 13.33 x 7.5 inch PPTX coordinates.\n */\nexport async function convertMarkdownToPptx(\n markdown: string,\n options?: PptxExportOptions\n): Promise<Uint8Array> {\n const PptxGenModule = await import('pptxgenjs');\n const PptxGenClass = (PptxGenModule as any).default || PptxGenModule;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const pptx = new (PptxGenClass as any)();\n\n pptx.layout = 'LAYOUT_WIDE'; // 16:9 aspect ratio (13.33 x 7.5 inches)\n if (options?.title) pptx.title = options.title;\n if (options?.author) pptx.author = options.author;\n\n const renderResult = renderSlide(markdown);\n const { slides } = splitMarkdownSlides(markdown);\n\n const isDark = options?.theme !== 'light';\n const defaultBg = isDark ? '14151B' : 'FFFFFF';\n const defaultText = isDark ? 'F1F5F9' : '1E293B';\n const defaultHeading = isDark ? '38BDF8' : '0284C7';\n\n // Coordinate scales from 1280x720 to 13.33x7.5 inches\n const scaleX = 13.33 / 1280;\n const scaleY = 7.5 / 720;\n\n slides.forEach((slideMd, slideIndex) => {\n const pptxSlide = pptx.addSlide();\n\n // 1. Set background\n const bgColor = extractSlideBgColor(slideMd, defaultBg);\n pptxSlide.background = { color: bgColor };\n\n // 2. Add Speaker / Teacher Notes\n const notes = renderResult.notes?.[slideIndex];\n if (notes && notes.length > 0) {\n pptxSlide.addNotes(notes.join('\\n\\n'));\n }\n\n // 3. Layout boxes\n const layout = renderResult.layouts?.[slideIndex];\n const blocks = parseSimpleMarkdown(slideMd);\n\n if (layout && layout.boxes && layout.boxes.length > 0) {\n // Freeform layout: Render boxes with exact pos\n for (const box of layout.boxes) {\n const [x, y, w, h] = box.pos;\n const xInch = Math.max(0, x * scaleX);\n const yInch = Math.max(0, y * scaleY);\n const wInch = Math.min(13.33 - xInch, w * scaleX);\n const hInch = Math.min(7.5 - yInch, h * scaleY);\n\n // Find corresponding text\n let contentText = '';\n if (box.target === 'h1') {\n contentText = blocks.find(b => b.type === 'heading' && b.level === 1)?.text || 'Heading';\n } else if (box.target === 'h2') {\n contentText = blocks.find(b => b.type === 'heading' && b.level === 2)?.text || 'Subheading';\n } else {\n contentText = blocks.find(b => b.type === 'paragraph' || b.type === 'bullet')?.text || 'Content block';\n }\n\n const fontSizePt = parseFontSizeToPt(box.fontSize, box.target === 'h1' ? 28 : 16);\n const colorHex = cleanHexColor(box.color, box.target === 'h1' ? defaultHeading : defaultText);\n\n pptxSlide.addText(contentText, {\n x: xInch,\n y: yInch,\n w: wInch,\n h: hInch,\n fontSize: fontSizePt,\n color: colorHex,\n align: box.textAlign ?? 'left',\n bold: box.target?.startsWith('h') ?? false,\n fontFace: 'Arial',\n });\n }\n } else {\n // Flow layout fallback: Stack headings and paragraphs nicely\n let currentY = 0.8;\n const marginX = 1.0;\n const contentWidth = 11.33;\n\n for (const block of blocks) {\n if (block.type === 'heading') {\n const fontSize = block.level === 1 ? 30 : block.level === 2 ? 22 : 18;\n const color = block.level === 1 ? defaultHeading : defaultText;\n\n pptxSlide.addText(block.text, {\n x: marginX,\n y: currentY,\n w: contentWidth,\n h: 0.8,\n fontSize,\n color,\n bold: true,\n fontFace: 'Arial',\n });\n currentY += 0.9;\n } else if (block.type === 'bullet') {\n pptxSlide.addText(block.text, {\n x: marginX + 0.3,\n y: currentY,\n w: contentWidth - 0.3,\n h: 0.45,\n fontSize: 15,\n color: defaultText,\n bullet: true,\n fontFace: 'Arial',\n });\n currentY += 0.5;\n } else {\n pptxSlide.addText(block.text, {\n x: marginX,\n y: currentY,\n w: contentWidth,\n h: 0.5,\n fontSize: 15,\n color: defaultText,\n fontFace: 'Arial',\n });\n currentY += 0.55;\n }\n\n if (currentY > 6.5) break; // Prevent vertical overflow off slide\n }\n }\n });\n\n const pptxArray = (await pptx.write({ outputType: 'arraybuffer' })) as ArrayBuffer;\n return new Uint8Array(pptxArray);\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import { b as SlideLayoutData } from './types-DnR81ReX.js';
2
+
3
+ type SlideLayoutCategory = 'cover' | 'content' | 'split' | 'code' | 'metrics' | 'diagram' | 'quote' | 'assessment';
4
+ interface SlideLayoutPreset {
5
+ id: string;
6
+ name: string;
7
+ category: SlideLayoutCategory;
8
+ description: string;
9
+ layout: SlideLayoutData;
10
+ markdownSnippet: string;
11
+ }
12
+ declare const SLIDE_LAYOUT_PRESETS: SlideLayoutPreset[];
13
+ /**
14
+ * Find a preset by its unique ID
15
+ */
16
+ declare function getSlideLayoutPresetById(id: string): SlideLayoutPreset | undefined;
17
+ /**
18
+ * Filter presets by category
19
+ */
20
+ declare function getSlideLayoutPresetsByCategory(category: SlideLayoutCategory): SlideLayoutPreset[];
21
+
22
+ export { SLIDE_LAYOUT_PRESETS as S, getSlideLayoutPresetsByCategory as a, type SlideLayoutPreset as b, type SlideLayoutCategory as c, getSlideLayoutPresetById as g };
@@ -0,0 +1,22 @@
1
+ import { b as SlideLayoutData } from './types-DnR81ReX.cjs';
2
+
3
+ type SlideLayoutCategory = 'cover' | 'content' | 'split' | 'code' | 'metrics' | 'diagram' | 'quote' | 'assessment';
4
+ interface SlideLayoutPreset {
5
+ id: string;
6
+ name: string;
7
+ category: SlideLayoutCategory;
8
+ description: string;
9
+ layout: SlideLayoutData;
10
+ markdownSnippet: string;
11
+ }
12
+ declare const SLIDE_LAYOUT_PRESETS: SlideLayoutPreset[];
13
+ /**
14
+ * Find a preset by its unique ID
15
+ */
16
+ declare function getSlideLayoutPresetById(id: string): SlideLayoutPreset | undefined;
17
+ /**
18
+ * Filter presets by category
19
+ */
20
+ declare function getSlideLayoutPresetsByCategory(category: SlideLayoutCategory): SlideLayoutPreset[];
21
+
22
+ export { SLIDE_LAYOUT_PRESETS as S, getSlideLayoutPresetsByCategory as a, type SlideLayoutPreset as b, type SlideLayoutCategory as c, getSlideLayoutPresetById as g };