@thanh01.pmt/presentation-kit 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RCHOTRWI.js → chunk-PAHIW5IX.js} +906 -16
- package/dist/chunk-PAHIW5IX.js.map +1 -0
- package/dist/{chunk-N4Q6GUAQ.cjs → chunk-RJMPTRL3.cjs} +920 -15
- package/dist/chunk-RJMPTRL3.cjs.map +1 -0
- package/dist/{click-css-CadkoJ_A.d.cts → click-css-C84mdmU0.d.cts} +37 -8
- package/dist/{click-css-CadkoJ_A.d.ts → click-css-C84mdmU0.d.ts} +37 -8
- package/dist/index.cjs +244 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -3
- package/dist/index.d.ts +87 -3
- package/dist/index.js +172 -3
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +726 -21
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +50 -6
- package/dist/react/index.d.ts +50 -6
- package/dist/react/index.js +716 -13
- package/dist/react/index.js.map +1 -1
- package/package.json +11 -3
- package/dist/chunk-N4Q6GUAQ.cjs.map +0 -1
- package/dist/chunk-RCHOTRWI.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkRJMPTRL3_cjs = require('./chunk-RJMPTRL3.cjs');
|
|
4
4
|
|
|
5
5
|
// src/engine.ts
|
|
6
6
|
function createEngine(config = {}) {
|
|
@@ -17,110 +17,326 @@ function createEngine(config = {}) {
|
|
|
17
17
|
}
|
|
18
18
|
return {
|
|
19
19
|
render: (markdown, options) => {
|
|
20
|
-
return
|
|
20
|
+
return chunkRJMPTRL3_cjs.renderSlide(markdown, mergeOptions(options));
|
|
21
21
|
},
|
|
22
22
|
renderAsync: async (markdown, options) => {
|
|
23
|
-
return
|
|
23
|
+
return chunkRJMPTRL3_cjs.renderSlideAsync(markdown, mergeOptions(options));
|
|
24
24
|
},
|
|
25
25
|
getThemeCss: (theme, containerId) => {
|
|
26
|
-
const resolved =
|
|
27
|
-
return
|
|
26
|
+
const resolved = chunkRJMPTRL3_cjs.resolveTheme(theme);
|
|
27
|
+
return chunkRJMPTRL3_cjs.generateScopedCss2(resolved, containerId);
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// src/core/export/pptx-converter.ts
|
|
33
|
+
function parseFontSizeToPt(sizeStr, defaultPt = 18) {
|
|
34
|
+
if (!sizeStr) return defaultPt;
|
|
35
|
+
const trimmed = sizeStr.trim().toLowerCase();
|
|
36
|
+
if (trimmed.endsWith("rem")) {
|
|
37
|
+
const rem = parseFloat(trimmed);
|
|
38
|
+
return Math.round(rem * 16 * 0.75) || defaultPt;
|
|
39
|
+
}
|
|
40
|
+
if (trimmed.endsWith("px")) {
|
|
41
|
+
const px = parseFloat(trimmed);
|
|
42
|
+
return Math.round(px * 0.75) || defaultPt;
|
|
43
|
+
}
|
|
44
|
+
if (trimmed.endsWith("pt")) {
|
|
45
|
+
return parseInt(trimmed, 10) || defaultPt;
|
|
46
|
+
}
|
|
47
|
+
const num = parseFloat(trimmed);
|
|
48
|
+
return !isNaN(num) ? Math.round(num) : defaultPt;
|
|
49
|
+
}
|
|
50
|
+
function cleanHexColor(colorStr, defaultHex = "1F2937") {
|
|
51
|
+
if (!colorStr) return defaultHex;
|
|
52
|
+
const hex = colorStr.trim().replace(/^#/, "");
|
|
53
|
+
if (/^[0-9A-Fa-f]{6}$/.test(hex)) return hex.toUpperCase();
|
|
54
|
+
if (/^[0-9A-Fa-f]{3}$/.test(hex)) {
|
|
55
|
+
return hex.split("").map((c) => c + c).join("").toUpperCase();
|
|
56
|
+
}
|
|
57
|
+
return defaultHex;
|
|
58
|
+
}
|
|
59
|
+
function extractSlideBgColor(slideMd, defaultColor) {
|
|
60
|
+
const match = slideMd.match(/<!--\s*_backgroundColor:\s*([^\s>]+)\s*-->/i);
|
|
61
|
+
if (match && match[1]) {
|
|
62
|
+
return cleanHexColor(match[1], defaultColor);
|
|
63
|
+
}
|
|
64
|
+
return defaultColor;
|
|
65
|
+
}
|
|
66
|
+
function parseSimpleMarkdown(md) {
|
|
67
|
+
const lines = md.split("\n");
|
|
68
|
+
const blocks = [];
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
const trimmed = line.trim();
|
|
71
|
+
if (!trimmed) continue;
|
|
72
|
+
if (trimmed.startsWith("<!--") && trimmed.endsWith("-->")) continue;
|
|
73
|
+
const hMatch = trimmed.match(/^(#{1,6})\s+(.*)$/);
|
|
74
|
+
if (hMatch && hMatch[1] && hMatch[2]) {
|
|
75
|
+
blocks.push({
|
|
76
|
+
type: "heading",
|
|
77
|
+
level: hMatch[1].length,
|
|
78
|
+
text: hMatch[2].replace(/\*\*(.*?)\*\*/g, "$1").replace(/\*(.*?)\*/g, "$1")
|
|
79
|
+
});
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (/^[-*+]\s+/.test(trimmed)) {
|
|
83
|
+
blocks.push({
|
|
84
|
+
type: "bullet",
|
|
85
|
+
text: trimmed.replace(/^[-*+]\s+/, "").replace(/\*\*(.*?)\*\*/g, "$1")
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
blocks.push({
|
|
90
|
+
type: "paragraph",
|
|
91
|
+
text: trimmed.replace(/\*\*(.*?)\*\*/g, "$1").replace(/\*(.*?)\*/g, "$1")
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return blocks;
|
|
95
|
+
}
|
|
96
|
+
async function convertMarkdownToPptx(markdown, options) {
|
|
97
|
+
const PptxGenModule = await import('pptxgenjs');
|
|
98
|
+
const PptxGenClass = PptxGenModule.default || PptxGenModule;
|
|
99
|
+
const pptx = new PptxGenClass();
|
|
100
|
+
pptx.layout = "LAYOUT_WIDE";
|
|
101
|
+
if (options?.title) pptx.title = options.title;
|
|
102
|
+
if (options?.author) pptx.author = options.author;
|
|
103
|
+
const renderResult = chunkRJMPTRL3_cjs.renderSlide(markdown);
|
|
104
|
+
const { slides } = chunkRJMPTRL3_cjs.splitMarkdownSlides(markdown);
|
|
105
|
+
const isDark = options?.theme !== "light";
|
|
106
|
+
const defaultBg = isDark ? "14151B" : "FFFFFF";
|
|
107
|
+
const defaultText = isDark ? "F1F5F9" : "1E293B";
|
|
108
|
+
const defaultHeading = isDark ? "38BDF8" : "0284C7";
|
|
109
|
+
const scaleX = 13.33 / 1280;
|
|
110
|
+
const scaleY = 7.5 / 720;
|
|
111
|
+
slides.forEach((slideMd, slideIndex) => {
|
|
112
|
+
const pptxSlide = pptx.addSlide();
|
|
113
|
+
const bgColor = extractSlideBgColor(slideMd, defaultBg);
|
|
114
|
+
pptxSlide.background = { color: bgColor };
|
|
115
|
+
const notes = renderResult.notes?.[slideIndex];
|
|
116
|
+
if (notes && notes.length > 0) {
|
|
117
|
+
pptxSlide.addNotes(notes.join("\n\n"));
|
|
118
|
+
}
|
|
119
|
+
const layout = renderResult.layouts?.[slideIndex];
|
|
120
|
+
const blocks = parseSimpleMarkdown(slideMd);
|
|
121
|
+
if (layout && layout.boxes && layout.boxes.length > 0) {
|
|
122
|
+
for (const box of layout.boxes) {
|
|
123
|
+
const [x, y, w, h] = box.pos;
|
|
124
|
+
const xInch = Math.max(0, x * scaleX);
|
|
125
|
+
const yInch = Math.max(0, y * scaleY);
|
|
126
|
+
const wInch = Math.min(13.33 - xInch, w * scaleX);
|
|
127
|
+
const hInch = Math.min(7.5 - yInch, h * scaleY);
|
|
128
|
+
let contentText = "";
|
|
129
|
+
if (box.target === "h1") {
|
|
130
|
+
contentText = blocks.find((b) => b.type === "heading" && b.level === 1)?.text || "Heading";
|
|
131
|
+
} else if (box.target === "h2") {
|
|
132
|
+
contentText = blocks.find((b) => b.type === "heading" && b.level === 2)?.text || "Subheading";
|
|
133
|
+
} else {
|
|
134
|
+
contentText = blocks.find((b) => b.type === "paragraph" || b.type === "bullet")?.text || "Content block";
|
|
135
|
+
}
|
|
136
|
+
const fontSizePt = parseFontSizeToPt(box.fontSize, box.target === "h1" ? 28 : 16);
|
|
137
|
+
const colorHex = cleanHexColor(box.color, box.target === "h1" ? defaultHeading : defaultText);
|
|
138
|
+
pptxSlide.addText(contentText, {
|
|
139
|
+
x: xInch,
|
|
140
|
+
y: yInch,
|
|
141
|
+
w: wInch,
|
|
142
|
+
h: hInch,
|
|
143
|
+
fontSize: fontSizePt,
|
|
144
|
+
color: colorHex,
|
|
145
|
+
align: box.textAlign ?? "left",
|
|
146
|
+
bold: box.target?.startsWith("h") ?? false,
|
|
147
|
+
fontFace: "Arial"
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
let currentY = 0.8;
|
|
152
|
+
const marginX = 1;
|
|
153
|
+
const contentWidth = 11.33;
|
|
154
|
+
for (const block of blocks) {
|
|
155
|
+
if (block.type === "heading") {
|
|
156
|
+
const fontSize = block.level === 1 ? 30 : block.level === 2 ? 22 : 18;
|
|
157
|
+
const color = block.level === 1 ? defaultHeading : defaultText;
|
|
158
|
+
pptxSlide.addText(block.text, {
|
|
159
|
+
x: marginX,
|
|
160
|
+
y: currentY,
|
|
161
|
+
w: contentWidth,
|
|
162
|
+
h: 0.8,
|
|
163
|
+
fontSize,
|
|
164
|
+
color,
|
|
165
|
+
bold: true,
|
|
166
|
+
fontFace: "Arial"
|
|
167
|
+
});
|
|
168
|
+
currentY += 0.9;
|
|
169
|
+
} else if (block.type === "bullet") {
|
|
170
|
+
pptxSlide.addText(block.text, {
|
|
171
|
+
x: marginX + 0.3,
|
|
172
|
+
y: currentY,
|
|
173
|
+
w: contentWidth - 0.3,
|
|
174
|
+
h: 0.45,
|
|
175
|
+
fontSize: 15,
|
|
176
|
+
color: defaultText,
|
|
177
|
+
bullet: true,
|
|
178
|
+
fontFace: "Arial"
|
|
179
|
+
});
|
|
180
|
+
currentY += 0.5;
|
|
181
|
+
} else {
|
|
182
|
+
pptxSlide.addText(block.text, {
|
|
183
|
+
x: marginX,
|
|
184
|
+
y: currentY,
|
|
185
|
+
w: contentWidth,
|
|
186
|
+
h: 0.5,
|
|
187
|
+
fontSize: 15,
|
|
188
|
+
color: defaultText,
|
|
189
|
+
fontFace: "Arial"
|
|
190
|
+
});
|
|
191
|
+
currentY += 0.55;
|
|
192
|
+
}
|
|
193
|
+
if (currentY > 6.5) break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
const pptxArray = await pptx.write({ outputType: "arraybuffer" });
|
|
198
|
+
return new Uint8Array(pptxArray);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
Object.defineProperty(exports, "SLIDE_LAYOUT_PRESETS", {
|
|
202
|
+
enumerable: true,
|
|
203
|
+
get: function () { return chunkRJMPTRL3_cjs.SLIDE_LAYOUT_PRESETS; }
|
|
204
|
+
});
|
|
32
205
|
Object.defineProperty(exports, "convertTextArrows", {
|
|
33
206
|
enumerable: true,
|
|
34
|
-
get: function () { return
|
|
207
|
+
get: function () { return chunkRJMPTRL3_cjs.convertTextArrows; }
|
|
35
208
|
});
|
|
36
209
|
Object.defineProperty(exports, "countSlides", {
|
|
37
210
|
enumerable: true,
|
|
38
|
-
get: function () { return
|
|
211
|
+
get: function () { return chunkRJMPTRL3_cjs.countSlides; }
|
|
39
212
|
});
|
|
40
213
|
Object.defineProperty(exports, "darkThemeTokens", {
|
|
41
214
|
enumerable: true,
|
|
42
|
-
get: function () { return
|
|
215
|
+
get: function () { return chunkRJMPTRL3_cjs.darkThemeTokens; }
|
|
43
216
|
});
|
|
44
217
|
Object.defineProperty(exports, "defineTheme", {
|
|
45
218
|
enumerable: true,
|
|
46
|
-
get: function () { return
|
|
219
|
+
get: function () { return chunkRJMPTRL3_cjs.defineTheme; }
|
|
47
220
|
});
|
|
48
221
|
Object.defineProperty(exports, "detectMermaidBlocks", {
|
|
49
222
|
enumerable: true,
|
|
50
|
-
get: function () { return
|
|
223
|
+
get: function () { return chunkRJMPTRL3_cjs.detectMermaidBlocks; }
|
|
224
|
+
});
|
|
225
|
+
Object.defineProperty(exports, "extractLayoutsAndNotes", {
|
|
226
|
+
enumerable: true,
|
|
227
|
+
get: function () { return chunkRJMPTRL3_cjs.extractLayoutsAndNotes; }
|
|
51
228
|
});
|
|
52
229
|
Object.defineProperty(exports, "extractMarpSource", {
|
|
53
230
|
enumerable: true,
|
|
54
|
-
get: function () { return
|
|
231
|
+
get: function () { return chunkRJMPTRL3_cjs.extractMarpSource; }
|
|
55
232
|
});
|
|
56
233
|
Object.defineProperty(exports, "extractMaxClicks", {
|
|
57
234
|
enumerable: true,
|
|
58
|
-
get: function () { return
|
|
235
|
+
get: function () { return chunkRJMPTRL3_cjs.extractMaxClicks; }
|
|
236
|
+
});
|
|
237
|
+
Object.defineProperty(exports, "filterPresenterNotes", {
|
|
238
|
+
enumerable: true,
|
|
239
|
+
get: function () { return chunkRJMPTRL3_cjs.filterPresenterNotes; }
|
|
59
240
|
});
|
|
60
241
|
Object.defineProperty(exports, "generateClickCss", {
|
|
61
242
|
enumerable: true,
|
|
62
|
-
get: function () { return
|
|
243
|
+
get: function () { return chunkRJMPTRL3_cjs.generateClickCss; }
|
|
244
|
+
});
|
|
245
|
+
Object.defineProperty(exports, "generateLayoutCss", {
|
|
246
|
+
enumerable: true,
|
|
247
|
+
get: function () { return chunkRJMPTRL3_cjs.generateLayoutCss; }
|
|
63
248
|
});
|
|
64
249
|
Object.defineProperty(exports, "generateScopedCss", {
|
|
65
250
|
enumerable: true,
|
|
66
|
-
get: function () { return
|
|
251
|
+
get: function () { return chunkRJMPTRL3_cjs.generateScopedCss2; }
|
|
67
252
|
});
|
|
68
253
|
Object.defineProperty(exports, "generateScopedCssFromTokens", {
|
|
69
254
|
enumerable: true,
|
|
70
|
-
get: function () { return
|
|
255
|
+
get: function () { return chunkRJMPTRL3_cjs.generateScopedCss; }
|
|
71
256
|
});
|
|
72
257
|
Object.defineProperty(exports, "getHighlighter", {
|
|
73
258
|
enumerable: true,
|
|
74
|
-
get: function () { return
|
|
259
|
+
get: function () { return chunkRJMPTRL3_cjs.getHighlighter; }
|
|
260
|
+
});
|
|
261
|
+
Object.defineProperty(exports, "getSlideLayoutPresetById", {
|
|
262
|
+
enumerable: true,
|
|
263
|
+
get: function () { return chunkRJMPTRL3_cjs.getSlideLayoutPresetById; }
|
|
264
|
+
});
|
|
265
|
+
Object.defineProperty(exports, "getSlideLayoutPresetsByCategory", {
|
|
266
|
+
enumerable: true,
|
|
267
|
+
get: function () { return chunkRJMPTRL3_cjs.getSlideLayoutPresetsByCategory; }
|
|
75
268
|
});
|
|
76
269
|
Object.defineProperty(exports, "getThemeTokens", {
|
|
77
270
|
enumerable: true,
|
|
78
|
-
get: function () { return
|
|
271
|
+
get: function () { return chunkRJMPTRL3_cjs.getThemeTokens; }
|
|
79
272
|
});
|
|
80
273
|
Object.defineProperty(exports, "highlightCodeBlocks", {
|
|
81
274
|
enumerable: true,
|
|
82
|
-
get: function () { return
|
|
275
|
+
get: function () { return chunkRJMPTRL3_cjs.highlightCodeBlocks; }
|
|
276
|
+
});
|
|
277
|
+
Object.defineProperty(exports, "isLayoutComment", {
|
|
278
|
+
enumerable: true,
|
|
279
|
+
get: function () { return chunkRJMPTRL3_cjs.isLayoutComment; }
|
|
83
280
|
});
|
|
84
281
|
Object.defineProperty(exports, "lightThemeTokens", {
|
|
85
282
|
enumerable: true,
|
|
86
|
-
get: function () { return
|
|
283
|
+
get: function () { return chunkRJMPTRL3_cjs.lightThemeTokens; }
|
|
87
284
|
});
|
|
88
285
|
Object.defineProperty(exports, "navyThemeTokens", {
|
|
89
286
|
enumerable: true,
|
|
90
|
-
get: function () { return
|
|
287
|
+
get: function () { return chunkRJMPTRL3_cjs.navyThemeTokens; }
|
|
288
|
+
});
|
|
289
|
+
Object.defineProperty(exports, "parseLayoutFromComment", {
|
|
290
|
+
enumerable: true,
|
|
291
|
+
get: function () { return chunkRJMPTRL3_cjs.parseLayoutFromComment; }
|
|
91
292
|
});
|
|
92
293
|
Object.defineProperty(exports, "postprocessClicks", {
|
|
93
294
|
enumerable: true,
|
|
94
|
-
get: function () { return
|
|
295
|
+
get: function () { return chunkRJMPTRL3_cjs.postprocessClicks; }
|
|
95
296
|
});
|
|
96
297
|
Object.defineProperty(exports, "preprocessClicks", {
|
|
97
298
|
enumerable: true,
|
|
98
|
-
get: function () { return
|
|
299
|
+
get: function () { return chunkRJMPTRL3_cjs.preprocessClicks; }
|
|
99
300
|
});
|
|
100
301
|
Object.defineProperty(exports, "renderMarp", {
|
|
101
302
|
enumerable: true,
|
|
102
|
-
get: function () { return
|
|
303
|
+
get: function () { return chunkRJMPTRL3_cjs.renderMarp; }
|
|
103
304
|
});
|
|
104
305
|
Object.defineProperty(exports, "renderMermaidDiagrams", {
|
|
105
306
|
enumerable: true,
|
|
106
|
-
get: function () { return
|
|
307
|
+
get: function () { return chunkRJMPTRL3_cjs.renderMermaidDiagrams; }
|
|
107
308
|
});
|
|
108
309
|
Object.defineProperty(exports, "renderSlide", {
|
|
109
310
|
enumerable: true,
|
|
110
|
-
get: function () { return
|
|
311
|
+
get: function () { return chunkRJMPTRL3_cjs.renderSlide; }
|
|
111
312
|
});
|
|
112
313
|
Object.defineProperty(exports, "renderSlideAsync", {
|
|
113
314
|
enumerable: true,
|
|
114
|
-
get: function () { return
|
|
315
|
+
get: function () { return chunkRJMPTRL3_cjs.renderSlideAsync; }
|
|
115
316
|
});
|
|
116
317
|
Object.defineProperty(exports, "resolveTheme", {
|
|
117
318
|
enumerable: true,
|
|
118
|
-
get: function () { return
|
|
319
|
+
get: function () { return chunkRJMPTRL3_cjs.resolveTheme; }
|
|
119
320
|
});
|
|
120
321
|
Object.defineProperty(exports, "sanitizeMermaidCode", {
|
|
121
322
|
enumerable: true,
|
|
122
|
-
get: function () { return
|
|
323
|
+
get: function () { return chunkRJMPTRL3_cjs.sanitizeMermaidCode; }
|
|
324
|
+
});
|
|
325
|
+
Object.defineProperty(exports, "serializeLayoutToComment", {
|
|
326
|
+
enumerable: true,
|
|
327
|
+
get: function () { return chunkRJMPTRL3_cjs.serializeLayoutToComment; }
|
|
328
|
+
});
|
|
329
|
+
Object.defineProperty(exports, "splitMarkdownSlides", {
|
|
330
|
+
enumerable: true,
|
|
331
|
+
get: function () { return chunkRJMPTRL3_cjs.splitMarkdownSlides; }
|
|
332
|
+
});
|
|
333
|
+
Object.defineProperty(exports, "updateSlideLayoutInMarkdown", {
|
|
334
|
+
enumerable: true,
|
|
335
|
+
get: function () { return chunkRJMPTRL3_cjs.updateSlideLayoutInMarkdown; }
|
|
123
336
|
});
|
|
337
|
+
exports.cleanHexColor = cleanHexColor;
|
|
338
|
+
exports.convertMarkdownToPptx = convertMarkdownToPptx;
|
|
124
339
|
exports.createEngine = createEngine;
|
|
340
|
+
exports.parseFontSizeToPt = parseFontSizeToPt;
|
|
125
341
|
//# sourceMappingURL=index.cjs.map
|
|
126
342
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/engine.ts"],"names":["renderSlide","renderSlideAsync","resolveTheme","generateScopedCss"],"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","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"]}
|
|
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,5 +1,5 @@
|
|
|
1
|
-
import { S as SlideEngineConfig, a as SlideEngine, T as ThemeTokens, M as MermaidBlock } from './click-css-
|
|
2
|
-
export { B as BuiltInTheme,
|
|
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';
|
|
3
3
|
import { Highlighter } from 'shiki';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -66,6 +66,90 @@ declare function sanitizeMermaidCode(chart: string, isDark?: boolean): string;
|
|
|
66
66
|
*/
|
|
67
67
|
declare function renderMermaidDiagrams(container: HTMLElement, theme?: 'dark' | 'light' | 'navy'): Promise<void>;
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Check if a comment string represents a layout definition
|
|
71
|
+
*/
|
|
72
|
+
declare function isLayoutComment(comment: string): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Parse YAML layout data from a comment string
|
|
75
|
+
*/
|
|
76
|
+
declare function parseLayoutFromComment(comment: string): SlideLayoutData | null;
|
|
77
|
+
/**
|
|
78
|
+
* Filter presenter notes from a slide's comment list,
|
|
79
|
+
* excluding layout blocks and Marp system directives.
|
|
80
|
+
*/
|
|
81
|
+
declare function filterPresenterNotes(comments: string[]): string[];
|
|
82
|
+
/**
|
|
83
|
+
* Extract per-slide layout data and presenter notes from Marp's comments array.
|
|
84
|
+
*/
|
|
85
|
+
declare function extractLayoutsAndNotes(rawComments: (string[] | undefined)[]): {
|
|
86
|
+
layouts: (SlideLayoutData | null)[];
|
|
87
|
+
notes: string[][];
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Serialize a SlideLayoutData object into a Markdown HTML comment
|
|
92
|
+
*/
|
|
93
|
+
declare function serializeLayoutToComment(layout: SlideLayoutData): string;
|
|
94
|
+
/**
|
|
95
|
+
* Split a Markdown presentation into individual slide strings,
|
|
96
|
+
* properly handling frontmatter and code blocks.
|
|
97
|
+
*/
|
|
98
|
+
declare function splitMarkdownSlides(markdown: string): {
|
|
99
|
+
frontmatter: string | null;
|
|
100
|
+
slides: string[];
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Update or insert a layout comment inside a specific slide's markdown
|
|
104
|
+
*/
|
|
105
|
+
declare function updateSlideLayoutInMarkdown(markdown: string, slideIndex: number, layout: SlideLayoutData | null): string;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Generate scoped CSS for per-slide layout overrides.
|
|
109
|
+
*
|
|
110
|
+
* Targets each slide's section within Marp's 1280x720 SVG coordinate space.
|
|
111
|
+
*/
|
|
112
|
+
declare function generateLayoutCss(layouts: (SlideLayoutData | null)[], containerId?: string): string;
|
|
113
|
+
|
|
114
|
+
type SlideLayoutCategory = 'cover' | 'content' | 'split' | 'code' | 'metrics' | 'diagram' | 'quote' | 'assessment';
|
|
115
|
+
interface SlideLayoutPreset {
|
|
116
|
+
id: string;
|
|
117
|
+
name: string;
|
|
118
|
+
category: SlideLayoutCategory;
|
|
119
|
+
description: string;
|
|
120
|
+
layout: SlideLayoutData;
|
|
121
|
+
markdownSnippet: string;
|
|
122
|
+
}
|
|
123
|
+
declare const SLIDE_LAYOUT_PRESETS: SlideLayoutPreset[];
|
|
124
|
+
/**
|
|
125
|
+
* Find a preset by its unique ID
|
|
126
|
+
*/
|
|
127
|
+
declare function getSlideLayoutPresetById(id: string): SlideLayoutPreset | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* Filter presets by category
|
|
130
|
+
*/
|
|
131
|
+
declare function getSlideLayoutPresetsByCategory(category: SlideLayoutCategory): SlideLayoutPreset[];
|
|
132
|
+
|
|
133
|
+
interface PptxExportOptions {
|
|
134
|
+
title?: string;
|
|
135
|
+
author?: string;
|
|
136
|
+
theme?: 'dark' | 'light' | 'navy';
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Convert font size string ('2.5rem', '32px', '24pt') to pt number for PPTX
|
|
140
|
+
*/
|
|
141
|
+
declare function parseFontSizeToPt(sizeStr?: string, defaultPt?: number): number;
|
|
142
|
+
/**
|
|
143
|
+
* Clean hex color string (removes leading #)
|
|
144
|
+
*/
|
|
145
|
+
declare function cleanHexColor(colorStr?: string, defaultHex?: string): string;
|
|
146
|
+
/**
|
|
147
|
+
* Convert Marp Markdown presentation to an editable PPTX file using pptxgenjs.
|
|
148
|
+
*
|
|
149
|
+
* Each box in `layout.boxes` maps directly from 1280x720 canvas px to 13.33 x 7.5 inch PPTX coordinates.
|
|
150
|
+
*/
|
|
151
|
+
declare function convertMarkdownToPptx(markdown: string, options?: PptxExportOptions): Promise<Uint8Array>;
|
|
152
|
+
|
|
69
153
|
/**
|
|
70
154
|
* Converts text arrows (->, -->, --->, =>, ==>, <->, etc.) into clean Unicode
|
|
71
155
|
* arrows while strictly preserving YAML frontmatter, code fences, inline code,
|
|
@@ -83,4 +167,4 @@ declare function convertTextArrows(text: string): string;
|
|
|
83
167
|
*/
|
|
84
168
|
declare function extractMarpSource(raw: string): string;
|
|
85
169
|
|
|
86
|
-
export { MermaidBlock, SlideEngine, SlideEngineConfig, ThemeTokens, convertTextArrows, createEngine, darkThemeTokens, detectMermaidBlocks, extractMarpSource, generateScopedCss as generateScopedCssFromTokens, getHighlighter, highlightCodeBlocks, lightThemeTokens, navyThemeTokens, renderMermaidDiagrams, sanitizeMermaidCode };
|
|
170
|
+
export { MermaidBlock, type PptxExportOptions, SLIDE_LAYOUT_PRESETS, SlideEngine, SlideEngineConfig, type SlideLayoutCategory, SlideLayoutData, type SlideLayoutPreset, ThemeTokens, cleanHexColor, convertMarkdownToPptx, convertTextArrows, createEngine, darkThemeTokens, detectMermaidBlocks, extractLayoutsAndNotes, extractMarpSource, filterPresenterNotes, generateLayoutCss, generateScopedCss as generateScopedCssFromTokens, getHighlighter, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, highlightCodeBlocks, isLayoutComment, lightThemeTokens, navyThemeTokens, parseFontSizeToPt, parseLayoutFromComment, renderMermaidDiagrams, sanitizeMermaidCode, serializeLayoutToComment, splitMarkdownSlides, updateSlideLayoutInMarkdown };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SlideEngineConfig, a as SlideEngine, T as ThemeTokens, M as MermaidBlock } from './click-css-
|
|
2
|
-
export { B as BuiltInTheme,
|
|
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';
|
|
3
3
|
import { Highlighter } from 'shiki';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -66,6 +66,90 @@ declare function sanitizeMermaidCode(chart: string, isDark?: boolean): string;
|
|
|
66
66
|
*/
|
|
67
67
|
declare function renderMermaidDiagrams(container: HTMLElement, theme?: 'dark' | 'light' | 'navy'): Promise<void>;
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Check if a comment string represents a layout definition
|
|
71
|
+
*/
|
|
72
|
+
declare function isLayoutComment(comment: string): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Parse YAML layout data from a comment string
|
|
75
|
+
*/
|
|
76
|
+
declare function parseLayoutFromComment(comment: string): SlideLayoutData | null;
|
|
77
|
+
/**
|
|
78
|
+
* Filter presenter notes from a slide's comment list,
|
|
79
|
+
* excluding layout blocks and Marp system directives.
|
|
80
|
+
*/
|
|
81
|
+
declare function filterPresenterNotes(comments: string[]): string[];
|
|
82
|
+
/**
|
|
83
|
+
* Extract per-slide layout data and presenter notes from Marp's comments array.
|
|
84
|
+
*/
|
|
85
|
+
declare function extractLayoutsAndNotes(rawComments: (string[] | undefined)[]): {
|
|
86
|
+
layouts: (SlideLayoutData | null)[];
|
|
87
|
+
notes: string[][];
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Serialize a SlideLayoutData object into a Markdown HTML comment
|
|
92
|
+
*/
|
|
93
|
+
declare function serializeLayoutToComment(layout: SlideLayoutData): string;
|
|
94
|
+
/**
|
|
95
|
+
* Split a Markdown presentation into individual slide strings,
|
|
96
|
+
* properly handling frontmatter and code blocks.
|
|
97
|
+
*/
|
|
98
|
+
declare function splitMarkdownSlides(markdown: string): {
|
|
99
|
+
frontmatter: string | null;
|
|
100
|
+
slides: string[];
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Update or insert a layout comment inside a specific slide's markdown
|
|
104
|
+
*/
|
|
105
|
+
declare function updateSlideLayoutInMarkdown(markdown: string, slideIndex: number, layout: SlideLayoutData | null): string;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Generate scoped CSS for per-slide layout overrides.
|
|
109
|
+
*
|
|
110
|
+
* Targets each slide's section within Marp's 1280x720 SVG coordinate space.
|
|
111
|
+
*/
|
|
112
|
+
declare function generateLayoutCss(layouts: (SlideLayoutData | null)[], containerId?: string): string;
|
|
113
|
+
|
|
114
|
+
type SlideLayoutCategory = 'cover' | 'content' | 'split' | 'code' | 'metrics' | 'diagram' | 'quote' | 'assessment';
|
|
115
|
+
interface SlideLayoutPreset {
|
|
116
|
+
id: string;
|
|
117
|
+
name: string;
|
|
118
|
+
category: SlideLayoutCategory;
|
|
119
|
+
description: string;
|
|
120
|
+
layout: SlideLayoutData;
|
|
121
|
+
markdownSnippet: string;
|
|
122
|
+
}
|
|
123
|
+
declare const SLIDE_LAYOUT_PRESETS: SlideLayoutPreset[];
|
|
124
|
+
/**
|
|
125
|
+
* Find a preset by its unique ID
|
|
126
|
+
*/
|
|
127
|
+
declare function getSlideLayoutPresetById(id: string): SlideLayoutPreset | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* Filter presets by category
|
|
130
|
+
*/
|
|
131
|
+
declare function getSlideLayoutPresetsByCategory(category: SlideLayoutCategory): SlideLayoutPreset[];
|
|
132
|
+
|
|
133
|
+
interface PptxExportOptions {
|
|
134
|
+
title?: string;
|
|
135
|
+
author?: string;
|
|
136
|
+
theme?: 'dark' | 'light' | 'navy';
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Convert font size string ('2.5rem', '32px', '24pt') to pt number for PPTX
|
|
140
|
+
*/
|
|
141
|
+
declare function parseFontSizeToPt(sizeStr?: string, defaultPt?: number): number;
|
|
142
|
+
/**
|
|
143
|
+
* Clean hex color string (removes leading #)
|
|
144
|
+
*/
|
|
145
|
+
declare function cleanHexColor(colorStr?: string, defaultHex?: string): string;
|
|
146
|
+
/**
|
|
147
|
+
* Convert Marp Markdown presentation to an editable PPTX file using pptxgenjs.
|
|
148
|
+
*
|
|
149
|
+
* Each box in `layout.boxes` maps directly from 1280x720 canvas px to 13.33 x 7.5 inch PPTX coordinates.
|
|
150
|
+
*/
|
|
151
|
+
declare function convertMarkdownToPptx(markdown: string, options?: PptxExportOptions): Promise<Uint8Array>;
|
|
152
|
+
|
|
69
153
|
/**
|
|
70
154
|
* Converts text arrows (->, -->, --->, =>, ==>, <->, etc.) into clean Unicode
|
|
71
155
|
* arrows while strictly preserving YAML frontmatter, code fences, inline code,
|
|
@@ -83,4 +167,4 @@ declare function convertTextArrows(text: string): string;
|
|
|
83
167
|
*/
|
|
84
168
|
declare function extractMarpSource(raw: string): string;
|
|
85
169
|
|
|
86
|
-
export { MermaidBlock, SlideEngine, SlideEngineConfig, ThemeTokens, convertTextArrows, createEngine, darkThemeTokens, detectMermaidBlocks, extractMarpSource, generateScopedCss as generateScopedCssFromTokens, getHighlighter, highlightCodeBlocks, lightThemeTokens, navyThemeTokens, renderMermaidDiagrams, sanitizeMermaidCode };
|
|
170
|
+
export { MermaidBlock, type PptxExportOptions, SLIDE_LAYOUT_PRESETS, SlideEngine, SlideEngineConfig, type SlideLayoutCategory, SlideLayoutData, type SlideLayoutPreset, ThemeTokens, cleanHexColor, convertMarkdownToPptx, convertTextArrows, createEngine, darkThemeTokens, detectMermaidBlocks, extractLayoutsAndNotes, extractMarpSource, filterPresenterNotes, generateLayoutCss, generateScopedCss as generateScopedCssFromTokens, getHighlighter, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, highlightCodeBlocks, isLayoutComment, lightThemeTokens, navyThemeTokens, parseFontSizeToPt, parseLayoutFromComment, renderMermaidDiagrams, sanitizeMermaidCode, serializeLayoutToComment, splitMarkdownSlides, updateSlideLayoutInMarkdown };
|