@thanh01.pmt/presentation-kit 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RCHOTRWI.js → chunk-FATGZ25L.js} +266 -16
- package/dist/chunk-FATGZ25L.js.map +1 -0
- package/dist/{chunk-N4Q6GUAQ.cjs → chunk-O4Y3VEOA.cjs} +277 -15
- package/dist/chunk-O4Y3VEOA.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 +232 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -3
- package/dist/index.d.ts +68 -3
- package/dist/index.js +172 -3
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +700 -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 +690 -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 chunkO4Y3VEOA_cjs = require('./chunk-O4Y3VEOA.cjs');
|
|
4
4
|
|
|
5
5
|
// src/engine.ts
|
|
6
6
|
function createEngine(config = {}) {
|
|
@@ -17,110 +17,314 @@ function createEngine(config = {}) {
|
|
|
17
17
|
}
|
|
18
18
|
return {
|
|
19
19
|
render: (markdown, options) => {
|
|
20
|
-
return
|
|
20
|
+
return chunkO4Y3VEOA_cjs.renderSlide(markdown, mergeOptions(options));
|
|
21
21
|
},
|
|
22
22
|
renderAsync: async (markdown, options) => {
|
|
23
|
-
return
|
|
23
|
+
return chunkO4Y3VEOA_cjs.renderSlideAsync(markdown, mergeOptions(options));
|
|
24
24
|
},
|
|
25
25
|
getThemeCss: (theme, containerId) => {
|
|
26
|
-
const resolved =
|
|
27
|
-
return
|
|
26
|
+
const resolved = chunkO4Y3VEOA_cjs.resolveTheme(theme);
|
|
27
|
+
return chunkO4Y3VEOA_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 = chunkO4Y3VEOA_cjs.renderSlide(markdown);
|
|
104
|
+
const { slides } = chunkO4Y3VEOA_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
|
+
|
|
32
201
|
Object.defineProperty(exports, "convertTextArrows", {
|
|
33
202
|
enumerable: true,
|
|
34
|
-
get: function () { return
|
|
203
|
+
get: function () { return chunkO4Y3VEOA_cjs.convertTextArrows; }
|
|
35
204
|
});
|
|
36
205
|
Object.defineProperty(exports, "countSlides", {
|
|
37
206
|
enumerable: true,
|
|
38
|
-
get: function () { return
|
|
207
|
+
get: function () { return chunkO4Y3VEOA_cjs.countSlides; }
|
|
39
208
|
});
|
|
40
209
|
Object.defineProperty(exports, "darkThemeTokens", {
|
|
41
210
|
enumerable: true,
|
|
42
|
-
get: function () { return
|
|
211
|
+
get: function () { return chunkO4Y3VEOA_cjs.darkThemeTokens; }
|
|
43
212
|
});
|
|
44
213
|
Object.defineProperty(exports, "defineTheme", {
|
|
45
214
|
enumerable: true,
|
|
46
|
-
get: function () { return
|
|
215
|
+
get: function () { return chunkO4Y3VEOA_cjs.defineTheme; }
|
|
47
216
|
});
|
|
48
217
|
Object.defineProperty(exports, "detectMermaidBlocks", {
|
|
49
218
|
enumerable: true,
|
|
50
|
-
get: function () { return
|
|
219
|
+
get: function () { return chunkO4Y3VEOA_cjs.detectMermaidBlocks; }
|
|
220
|
+
});
|
|
221
|
+
Object.defineProperty(exports, "extractLayoutsAndNotes", {
|
|
222
|
+
enumerable: true,
|
|
223
|
+
get: function () { return chunkO4Y3VEOA_cjs.extractLayoutsAndNotes; }
|
|
51
224
|
});
|
|
52
225
|
Object.defineProperty(exports, "extractMarpSource", {
|
|
53
226
|
enumerable: true,
|
|
54
|
-
get: function () { return
|
|
227
|
+
get: function () { return chunkO4Y3VEOA_cjs.extractMarpSource; }
|
|
55
228
|
});
|
|
56
229
|
Object.defineProperty(exports, "extractMaxClicks", {
|
|
57
230
|
enumerable: true,
|
|
58
|
-
get: function () { return
|
|
231
|
+
get: function () { return chunkO4Y3VEOA_cjs.extractMaxClicks; }
|
|
232
|
+
});
|
|
233
|
+
Object.defineProperty(exports, "filterPresenterNotes", {
|
|
234
|
+
enumerable: true,
|
|
235
|
+
get: function () { return chunkO4Y3VEOA_cjs.filterPresenterNotes; }
|
|
59
236
|
});
|
|
60
237
|
Object.defineProperty(exports, "generateClickCss", {
|
|
61
238
|
enumerable: true,
|
|
62
|
-
get: function () { return
|
|
239
|
+
get: function () { return chunkO4Y3VEOA_cjs.generateClickCss; }
|
|
240
|
+
});
|
|
241
|
+
Object.defineProperty(exports, "generateLayoutCss", {
|
|
242
|
+
enumerable: true,
|
|
243
|
+
get: function () { return chunkO4Y3VEOA_cjs.generateLayoutCss; }
|
|
63
244
|
});
|
|
64
245
|
Object.defineProperty(exports, "generateScopedCss", {
|
|
65
246
|
enumerable: true,
|
|
66
|
-
get: function () { return
|
|
247
|
+
get: function () { return chunkO4Y3VEOA_cjs.generateScopedCss2; }
|
|
67
248
|
});
|
|
68
249
|
Object.defineProperty(exports, "generateScopedCssFromTokens", {
|
|
69
250
|
enumerable: true,
|
|
70
|
-
get: function () { return
|
|
251
|
+
get: function () { return chunkO4Y3VEOA_cjs.generateScopedCss; }
|
|
71
252
|
});
|
|
72
253
|
Object.defineProperty(exports, "getHighlighter", {
|
|
73
254
|
enumerable: true,
|
|
74
|
-
get: function () { return
|
|
255
|
+
get: function () { return chunkO4Y3VEOA_cjs.getHighlighter; }
|
|
75
256
|
});
|
|
76
257
|
Object.defineProperty(exports, "getThemeTokens", {
|
|
77
258
|
enumerable: true,
|
|
78
|
-
get: function () { return
|
|
259
|
+
get: function () { return chunkO4Y3VEOA_cjs.getThemeTokens; }
|
|
79
260
|
});
|
|
80
261
|
Object.defineProperty(exports, "highlightCodeBlocks", {
|
|
81
262
|
enumerable: true,
|
|
82
|
-
get: function () { return
|
|
263
|
+
get: function () { return chunkO4Y3VEOA_cjs.highlightCodeBlocks; }
|
|
264
|
+
});
|
|
265
|
+
Object.defineProperty(exports, "isLayoutComment", {
|
|
266
|
+
enumerable: true,
|
|
267
|
+
get: function () { return chunkO4Y3VEOA_cjs.isLayoutComment; }
|
|
83
268
|
});
|
|
84
269
|
Object.defineProperty(exports, "lightThemeTokens", {
|
|
85
270
|
enumerable: true,
|
|
86
|
-
get: function () { return
|
|
271
|
+
get: function () { return chunkO4Y3VEOA_cjs.lightThemeTokens; }
|
|
87
272
|
});
|
|
88
273
|
Object.defineProperty(exports, "navyThemeTokens", {
|
|
89
274
|
enumerable: true,
|
|
90
|
-
get: function () { return
|
|
275
|
+
get: function () { return chunkO4Y3VEOA_cjs.navyThemeTokens; }
|
|
276
|
+
});
|
|
277
|
+
Object.defineProperty(exports, "parseLayoutFromComment", {
|
|
278
|
+
enumerable: true,
|
|
279
|
+
get: function () { return chunkO4Y3VEOA_cjs.parseLayoutFromComment; }
|
|
91
280
|
});
|
|
92
281
|
Object.defineProperty(exports, "postprocessClicks", {
|
|
93
282
|
enumerable: true,
|
|
94
|
-
get: function () { return
|
|
283
|
+
get: function () { return chunkO4Y3VEOA_cjs.postprocessClicks; }
|
|
95
284
|
});
|
|
96
285
|
Object.defineProperty(exports, "preprocessClicks", {
|
|
97
286
|
enumerable: true,
|
|
98
|
-
get: function () { return
|
|
287
|
+
get: function () { return chunkO4Y3VEOA_cjs.preprocessClicks; }
|
|
99
288
|
});
|
|
100
289
|
Object.defineProperty(exports, "renderMarp", {
|
|
101
290
|
enumerable: true,
|
|
102
|
-
get: function () { return
|
|
291
|
+
get: function () { return chunkO4Y3VEOA_cjs.renderMarp; }
|
|
103
292
|
});
|
|
104
293
|
Object.defineProperty(exports, "renderMermaidDiagrams", {
|
|
105
294
|
enumerable: true,
|
|
106
|
-
get: function () { return
|
|
295
|
+
get: function () { return chunkO4Y3VEOA_cjs.renderMermaidDiagrams; }
|
|
107
296
|
});
|
|
108
297
|
Object.defineProperty(exports, "renderSlide", {
|
|
109
298
|
enumerable: true,
|
|
110
|
-
get: function () { return
|
|
299
|
+
get: function () { return chunkO4Y3VEOA_cjs.renderSlide; }
|
|
111
300
|
});
|
|
112
301
|
Object.defineProperty(exports, "renderSlideAsync", {
|
|
113
302
|
enumerable: true,
|
|
114
|
-
get: function () { return
|
|
303
|
+
get: function () { return chunkO4Y3VEOA_cjs.renderSlideAsync; }
|
|
115
304
|
});
|
|
116
305
|
Object.defineProperty(exports, "resolveTheme", {
|
|
117
306
|
enumerable: true,
|
|
118
|
-
get: function () { return
|
|
307
|
+
get: function () { return chunkO4Y3VEOA_cjs.resolveTheme; }
|
|
119
308
|
});
|
|
120
309
|
Object.defineProperty(exports, "sanitizeMermaidCode", {
|
|
121
310
|
enumerable: true,
|
|
122
|
-
get: function () { return
|
|
311
|
+
get: function () { return chunkO4Y3VEOA_cjs.sanitizeMermaidCode; }
|
|
312
|
+
});
|
|
313
|
+
Object.defineProperty(exports, "serializeLayoutToComment", {
|
|
314
|
+
enumerable: true,
|
|
315
|
+
get: function () { return chunkO4Y3VEOA_cjs.serializeLayoutToComment; }
|
|
316
|
+
});
|
|
317
|
+
Object.defineProperty(exports, "splitMarkdownSlides", {
|
|
318
|
+
enumerable: true,
|
|
319
|
+
get: function () { return chunkO4Y3VEOA_cjs.splitMarkdownSlides; }
|
|
320
|
+
});
|
|
321
|
+
Object.defineProperty(exports, "updateSlideLayoutInMarkdown", {
|
|
322
|
+
enumerable: true,
|
|
323
|
+
get: function () { return chunkO4Y3VEOA_cjs.updateSlideLayoutInMarkdown; }
|
|
123
324
|
});
|
|
325
|
+
exports.cleanHexColor = cleanHexColor;
|
|
326
|
+
exports.convertMarkdownToPptx = convertMarkdownToPptx;
|
|
124
327
|
exports.createEngine = createEngine;
|
|
328
|
+
exports.parseFontSizeToPt = parseFontSizeToPt;
|
|
125
329
|
//# sourceMappingURL=index.cjs.map
|
|
126
330
|
//# 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":";;;;;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"]}
|
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,71 @@ 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
|
+
interface PptxExportOptions {
|
|
115
|
+
title?: string;
|
|
116
|
+
author?: string;
|
|
117
|
+
theme?: 'dark' | 'light' | 'navy';
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Convert font size string ('2.5rem', '32px', '24pt') to pt number for PPTX
|
|
121
|
+
*/
|
|
122
|
+
declare function parseFontSizeToPt(sizeStr?: string, defaultPt?: number): number;
|
|
123
|
+
/**
|
|
124
|
+
* Clean hex color string (removes leading #)
|
|
125
|
+
*/
|
|
126
|
+
declare function cleanHexColor(colorStr?: string, defaultHex?: string): string;
|
|
127
|
+
/**
|
|
128
|
+
* Convert Marp Markdown presentation to an editable PPTX file using pptxgenjs.
|
|
129
|
+
*
|
|
130
|
+
* Each box in `layout.boxes` maps directly from 1280x720 canvas px to 13.33 x 7.5 inch PPTX coordinates.
|
|
131
|
+
*/
|
|
132
|
+
declare function convertMarkdownToPptx(markdown: string, options?: PptxExportOptions): Promise<Uint8Array>;
|
|
133
|
+
|
|
69
134
|
/**
|
|
70
135
|
* Converts text arrows (->, -->, --->, =>, ==>, <->, etc.) into clean Unicode
|
|
71
136
|
* arrows while strictly preserving YAML frontmatter, code fences, inline code,
|
|
@@ -83,4 +148,4 @@ declare function convertTextArrows(text: string): string;
|
|
|
83
148
|
*/
|
|
84
149
|
declare function extractMarpSource(raw: string): string;
|
|
85
150
|
|
|
86
|
-
export { MermaidBlock, SlideEngine, SlideEngineConfig, ThemeTokens, convertTextArrows, createEngine, darkThemeTokens, detectMermaidBlocks, extractMarpSource, generateScopedCss as generateScopedCssFromTokens, getHighlighter, highlightCodeBlocks, lightThemeTokens, navyThemeTokens, renderMermaidDiagrams, sanitizeMermaidCode };
|
|
151
|
+
export { MermaidBlock, type PptxExportOptions, SlideEngine, SlideEngineConfig, SlideLayoutData, ThemeTokens, cleanHexColor, convertMarkdownToPptx, convertTextArrows, createEngine, darkThemeTokens, detectMermaidBlocks, extractLayoutsAndNotes, extractMarpSource, filterPresenterNotes, generateLayoutCss, generateScopedCss as generateScopedCssFromTokens, getHighlighter, 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,71 @@ 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
|
+
interface PptxExportOptions {
|
|
115
|
+
title?: string;
|
|
116
|
+
author?: string;
|
|
117
|
+
theme?: 'dark' | 'light' | 'navy';
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Convert font size string ('2.5rem', '32px', '24pt') to pt number for PPTX
|
|
121
|
+
*/
|
|
122
|
+
declare function parseFontSizeToPt(sizeStr?: string, defaultPt?: number): number;
|
|
123
|
+
/**
|
|
124
|
+
* Clean hex color string (removes leading #)
|
|
125
|
+
*/
|
|
126
|
+
declare function cleanHexColor(colorStr?: string, defaultHex?: string): string;
|
|
127
|
+
/**
|
|
128
|
+
* Convert Marp Markdown presentation to an editable PPTX file using pptxgenjs.
|
|
129
|
+
*
|
|
130
|
+
* Each box in `layout.boxes` maps directly from 1280x720 canvas px to 13.33 x 7.5 inch PPTX coordinates.
|
|
131
|
+
*/
|
|
132
|
+
declare function convertMarkdownToPptx(markdown: string, options?: PptxExportOptions): Promise<Uint8Array>;
|
|
133
|
+
|
|
69
134
|
/**
|
|
70
135
|
* Converts text arrows (->, -->, --->, =>, ==>, <->, etc.) into clean Unicode
|
|
71
136
|
* arrows while strictly preserving YAML frontmatter, code fences, inline code,
|
|
@@ -83,4 +148,4 @@ declare function convertTextArrows(text: string): string;
|
|
|
83
148
|
*/
|
|
84
149
|
declare function extractMarpSource(raw: string): string;
|
|
85
150
|
|
|
86
|
-
export { MermaidBlock, SlideEngine, SlideEngineConfig, ThemeTokens, convertTextArrows, createEngine, darkThemeTokens, detectMermaidBlocks, extractMarpSource, generateScopedCss as generateScopedCssFromTokens, getHighlighter, highlightCodeBlocks, lightThemeTokens, navyThemeTokens, renderMermaidDiagrams, sanitizeMermaidCode };
|
|
151
|
+
export { MermaidBlock, type PptxExportOptions, SlideEngine, SlideEngineConfig, SlideLayoutData, ThemeTokens, cleanHexColor, convertMarkdownToPptx, convertTextArrows, createEngine, darkThemeTokens, detectMermaidBlocks, extractLayoutsAndNotes, extractMarpSource, filterPresenterNotes, generateLayoutCss, generateScopedCss as generateScopedCssFromTokens, getHighlighter, highlightCodeBlocks, isLayoutComment, lightThemeTokens, navyThemeTokens, parseFontSizeToPt, parseLayoutFromComment, renderMermaidDiagrams, sanitizeMermaidCode, serializeLayoutToComment, splitMarkdownSlides, updateSlideLayoutInMarkdown };
|