yumiamd 0.1.20 → 0.1.21
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/bin.js +1 -1
- package/dist/{chunk-KZLRNRVU.js → chunk-TJR6MU2I.js} +2328 -112
- package/dist/index.d.ts +1 -1
- package/dist/index.js +37 -1
- package/package.json +10 -10
|
@@ -143,6 +143,21 @@ function createColumns(columns, ratios, gap) {
|
|
|
143
143
|
...gap !== void 0 ? { gap } : {}
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
|
+
function createSection(title, subtitle, number) {
|
|
147
|
+
return {
|
|
148
|
+
type: "section",
|
|
149
|
+
title,
|
|
150
|
+
...subtitle ? { subtitle } : {},
|
|
151
|
+
...number !== void 0 ? { number } : {}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function createToc(title, items) {
|
|
155
|
+
return {
|
|
156
|
+
type: "toc",
|
|
157
|
+
...title ? { title } : {},
|
|
158
|
+
...items ? { items } : {}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
146
161
|
function createMath(expression, displayMode = true) {
|
|
147
162
|
return {
|
|
148
163
|
type: "math",
|
|
@@ -157,8 +172,75 @@ function createLayoutDirective(mode, attributes) {
|
|
|
157
172
|
...attributes ? { attributes } : {}
|
|
158
173
|
};
|
|
159
174
|
}
|
|
175
|
+
function createIcon(name, provider, size, color) {
|
|
176
|
+
return {
|
|
177
|
+
type: "icon",
|
|
178
|
+
name,
|
|
179
|
+
...provider ? { provider } : {},
|
|
180
|
+
...size !== void 0 ? { size } : {},
|
|
181
|
+
...color ? { color } : {}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function createGrid(elements, columns = 2, gap) {
|
|
185
|
+
return {
|
|
186
|
+
type: "grid",
|
|
187
|
+
columns,
|
|
188
|
+
elements,
|
|
189
|
+
...gap !== void 0 ? { gap } : {}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function createStack(elements, direction = "vertical", gap, align, justify) {
|
|
193
|
+
return {
|
|
194
|
+
type: "stack",
|
|
195
|
+
direction,
|
|
196
|
+
elements,
|
|
197
|
+
...gap !== void 0 ? { gap } : {},
|
|
198
|
+
...align ? { align } : {},
|
|
199
|
+
...justify ? { justify } : {}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function createComponent(name, props, elements) {
|
|
203
|
+
return {
|
|
204
|
+
type: "component",
|
|
205
|
+
name,
|
|
206
|
+
...props ? { props } : {},
|
|
207
|
+
...elements ? { elements } : {}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function createSlot(name, elements) {
|
|
211
|
+
return {
|
|
212
|
+
type: "slot",
|
|
213
|
+
...name ? { name } : {},
|
|
214
|
+
...elements ? { elements } : {}
|
|
215
|
+
};
|
|
216
|
+
}
|
|
160
217
|
|
|
161
218
|
// ../parser/dist/parser.js
|
|
219
|
+
function parseHighlightLines(highlightStr) {
|
|
220
|
+
if (!highlightStr)
|
|
221
|
+
return [];
|
|
222
|
+
const lines = /* @__PURE__ */ new Set();
|
|
223
|
+
const parts = highlightStr.split(",");
|
|
224
|
+
for (const part of parts) {
|
|
225
|
+
const trimmed = part.trim();
|
|
226
|
+
if (!trimmed)
|
|
227
|
+
continue;
|
|
228
|
+
if (trimmed.includes("-")) {
|
|
229
|
+
const [startStr, endStr] = trimmed.split("-");
|
|
230
|
+
const start = parseInt(startStr || "0", 10);
|
|
231
|
+
const end = parseInt(endStr || "0", 10);
|
|
232
|
+
if (!isNaN(start) && !isNaN(end) && start <= end) {
|
|
233
|
+
for (let n = start; n <= end; n++)
|
|
234
|
+
lines.add(n);
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
const num = parseInt(trimmed, 10);
|
|
238
|
+
if (!isNaN(num))
|
|
239
|
+
lines.add(num);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return Array.from(lines).sort((a, b) => a - b);
|
|
243
|
+
}
|
|
162
244
|
var DefaultYumiaParser = class {
|
|
163
245
|
diagnostics = [];
|
|
164
246
|
parse(source, options) {
|
|
@@ -166,6 +248,11 @@ var DefaultYumiaParser = class {
|
|
|
166
248
|
if (!source || typeof source !== "string") {
|
|
167
249
|
return createPresentation({}, []);
|
|
168
250
|
}
|
|
251
|
+
const trimmed = source.trimStart();
|
|
252
|
+
if (trimmed.startsWith("document ") || trimmed.startsWith("document\n") || trimmed.startsWith("slide ") || trimmed.startsWith("slide\n")) {
|
|
253
|
+
const nativeParser = new NativeYumiaParser();
|
|
254
|
+
return nativeParser.parse(source);
|
|
255
|
+
}
|
|
169
256
|
const normalized = source.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
170
257
|
const { metadata, content, lineOffset } = this.extractFrontmatter(normalized);
|
|
171
258
|
if (!content.trim()) {
|
|
@@ -234,16 +321,34 @@ var DefaultYumiaParser = class {
|
|
|
234
321
|
parseYamlMetadata(block) {
|
|
235
322
|
const metadata = {};
|
|
236
323
|
const lines = block.split("\n");
|
|
324
|
+
let currentKey = null;
|
|
237
325
|
for (const line of lines) {
|
|
238
326
|
const trimmed = line.trim();
|
|
239
327
|
if (!trimmed || trimmed.startsWith("#"))
|
|
240
328
|
continue;
|
|
329
|
+
if (trimmed.startsWith("- ") && currentKey) {
|
|
330
|
+
const itemVal = trimmed.slice(2).trim().replace(/^['"](.*)['"]$/, "$1");
|
|
331
|
+
if (Array.isArray(metadata[currentKey])) {
|
|
332
|
+
metadata[currentKey].push(itemVal);
|
|
333
|
+
} else {
|
|
334
|
+
metadata[currentKey] = [itemVal];
|
|
335
|
+
}
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
241
338
|
const colonIndex = trimmed.indexOf(":");
|
|
242
339
|
if (colonIndex > 0) {
|
|
243
340
|
const key = trimmed.slice(0, colonIndex).trim();
|
|
244
341
|
const rawVal = trimmed.slice(colonIndex + 1).trim();
|
|
245
|
-
|
|
246
|
-
|
|
342
|
+
currentKey = key;
|
|
343
|
+
if (rawVal.startsWith("[") && rawVal.endsWith("]")) {
|
|
344
|
+
const listItems = rawVal.slice(1, -1).split(",").map((item) => item.trim().replace(/^['"](.*)['"]$/, "$1")).filter(Boolean);
|
|
345
|
+
metadata[key] = listItems;
|
|
346
|
+
} else if (rawVal) {
|
|
347
|
+
const unquoted = rawVal.replace(/^['"](.*)['"]$/, "$1");
|
|
348
|
+
metadata[key] = unquoted;
|
|
349
|
+
} else {
|
|
350
|
+
metadata[key] = [];
|
|
351
|
+
}
|
|
247
352
|
}
|
|
248
353
|
}
|
|
249
354
|
const result = {};
|
|
@@ -268,6 +373,23 @@ var DefaultYumiaParser = class {
|
|
|
268
373
|
} else if (typeof metadata["embedFonts"] === "boolean") {
|
|
269
374
|
result.embedFonts = metadata["embedFonts"];
|
|
270
375
|
}
|
|
376
|
+
if (typeof metadata["watermark"] === "string") {
|
|
377
|
+
if (metadata["watermark"] === "false" || metadata["watermark"] === "none" || metadata["watermark"] === "off") {
|
|
378
|
+
result.watermark = false;
|
|
379
|
+
} else if (metadata["watermark"] === "true" || metadata["watermark"] === "yes" || metadata["watermark"] === "on") {
|
|
380
|
+
result.watermark = true;
|
|
381
|
+
} else {
|
|
382
|
+
result.watermark = metadata["watermark"];
|
|
383
|
+
}
|
|
384
|
+
} else if (typeof metadata["watermark"] === "boolean") {
|
|
385
|
+
result.watermark = metadata["watermark"];
|
|
386
|
+
}
|
|
387
|
+
if (metadata["styles"] || metadata["stylesheets"] || metadata["css"]) {
|
|
388
|
+
result.styles = metadata["styles"] || metadata["stylesheets"] || metadata["css"];
|
|
389
|
+
}
|
|
390
|
+
if (metadata["scripts"] || metadata["js"]) {
|
|
391
|
+
result.scripts = metadata["scripts"] || metadata["js"];
|
|
392
|
+
}
|
|
271
393
|
const colors = {};
|
|
272
394
|
if (typeof metadata["background"] === "string")
|
|
273
395
|
colors.background = metadata["background"];
|
|
@@ -386,7 +508,16 @@ var DefaultYumiaParser = class {
|
|
|
386
508
|
}
|
|
387
509
|
if (line.startsWith("```")) {
|
|
388
510
|
flushAll();
|
|
389
|
-
|
|
511
|
+
let rawLang = line.slice(3).trim() || void 0;
|
|
512
|
+
let highlight;
|
|
513
|
+
if (rawLang) {
|
|
514
|
+
const hlMatch = rawLang.match(/\{([\d,\s-]+)\}/) || rawLang.match(/highlight=['"]([\d,\s-]+)['"]/);
|
|
515
|
+
if (hlMatch) {
|
|
516
|
+
highlight = hlMatch[1]?.trim();
|
|
517
|
+
rawLang = rawLang.replace(hlMatch[0], "").trim() || void 0;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
const language = rawLang;
|
|
390
521
|
const codeLines = [];
|
|
391
522
|
const codeStartLine = currentLineNum;
|
|
392
523
|
i++;
|
|
@@ -413,6 +544,10 @@ var DefaultYumiaParser = class {
|
|
|
413
544
|
});
|
|
414
545
|
}
|
|
415
546
|
const el = createCode(codeLines.join("\n"), language);
|
|
547
|
+
if (highlight) {
|
|
548
|
+
el.highlight = highlight;
|
|
549
|
+
el.highlightLines = parseHighlightLines(highlight);
|
|
550
|
+
}
|
|
416
551
|
el.loc = {
|
|
417
552
|
start: { line: codeStartLine, column: 1 },
|
|
418
553
|
end: { line: baseLine + i - 1, column: 1 }
|
|
@@ -462,7 +597,7 @@ var DefaultYumiaParser = class {
|
|
|
462
597
|
const variantMatch = directiveHeader.match(/variant=['"](.*?)['"]/);
|
|
463
598
|
const descMatch = directiveHeader.match(/description=['"](.*?)['"]/);
|
|
464
599
|
const unitMatch = directiveHeader.match(/unit=['"](.*?)['"]/);
|
|
465
|
-
const changeMatch = directiveHeader.match(/change=['"](.*?)['"]/);
|
|
600
|
+
const changeMatch = directiveHeader.match(/(?:change|diff)=['"](.*?)['"]/);
|
|
466
601
|
const value = valueMatch ? valueMatch[1] : "0";
|
|
467
602
|
const label = labelMatch ? labelMatch[1] : "";
|
|
468
603
|
const variant = variantMatch ? variantMatch[1] : void 0;
|
|
@@ -606,6 +741,82 @@ var DefaultYumiaParser = class {
|
|
|
606
741
|
end: { line: baseLine + i - 1, column: 1 }
|
|
607
742
|
};
|
|
608
743
|
elements.push(el);
|
|
744
|
+
} else if (directiveName === "code") {
|
|
745
|
+
const langMatch = directiveArg.match(/lang(?:uage)?=['"](.*?)['"]/);
|
|
746
|
+
const hlMatch = directiveArg.match(/highlight=['"](.*?)['"]/);
|
|
747
|
+
let lang = langMatch ? langMatch[1] : directiveArg.split(" ")[0] || void 0;
|
|
748
|
+
if (lang && (lang.includes("=") || lang.startsWith("{")))
|
|
749
|
+
lang = void 0;
|
|
750
|
+
const hlBraceMatch = directiveArg.match(/\{([\d,\s-]+)\}/);
|
|
751
|
+
const highlight = hlMatch ? hlMatch[1] : hlBraceMatch ? hlBraceMatch[1] : void 0;
|
|
752
|
+
const codeContent = blockLines.join("\n");
|
|
753
|
+
const el = createCode(codeContent, lang);
|
|
754
|
+
if (highlight) {
|
|
755
|
+
el.highlight = highlight;
|
|
756
|
+
el.highlightLines = parseHighlightLines(highlight);
|
|
757
|
+
}
|
|
758
|
+
el.loc = {
|
|
759
|
+
start: { line: directiveStartLine, column: 1 },
|
|
760
|
+
end: { line: baseLine + i - 1, column: 1 }
|
|
761
|
+
};
|
|
762
|
+
elements.push(el);
|
|
763
|
+
} else if (directiveName === "section") {
|
|
764
|
+
const allSectionText = [directiveArg, ...blockLines].join(" ");
|
|
765
|
+
const titleMatch = allSectionText.match(/\btitle=(?:"([^"]*)"|'([^']*)'|(\S+))/);
|
|
766
|
+
const subtitleMatch = allSectionText.match(/\bsubtitle=(?:"([^"]*)"|'([^']*)'|(\S+))/);
|
|
767
|
+
const numberMatch = allSectionText.match(/\bnumber=(?:"([^"]*)"|'([^']*)'|(\S+))/);
|
|
768
|
+
let subtitle = subtitleMatch ? subtitleMatch[1] ?? subtitleMatch[2] ?? subtitleMatch[3] : void 0;
|
|
769
|
+
const number = numberMatch ? numberMatch[1] ?? numberMatch[2] ?? numberMatch[3] : void 0;
|
|
770
|
+
let title = titleMatch ? titleMatch[1] ?? titleMatch[2] ?? titleMatch[3] : void 0;
|
|
771
|
+
if (!title) {
|
|
772
|
+
const stripped = directiveArg.replace(/\bsubtitle=(?:"[^"]*"|'[^']*'|\S+)/g, "").replace(/\bnumber=(?:"[^"]*"|'[^']*'|\S+)/g, "").trim();
|
|
773
|
+
title = stripped.replace(/^['"](.*)['"]$/, "$1").trim() || void 0;
|
|
774
|
+
}
|
|
775
|
+
if (!title && blockLines.length > 0) {
|
|
776
|
+
const plainLines = blockLines.filter((l) => !l.includes("subtitle=") && !l.includes("number="));
|
|
777
|
+
if (plainLines.length > 0)
|
|
778
|
+
title = plainLines[0]?.trim();
|
|
779
|
+
if (!subtitle && plainLines.length > 1)
|
|
780
|
+
subtitle = plainLines.slice(1).join("\n").trim();
|
|
781
|
+
}
|
|
782
|
+
const el = createSection(title || "Section", subtitle, number);
|
|
783
|
+
el.loc = {
|
|
784
|
+
start: { line: directiveStartLine, column: 1 },
|
|
785
|
+
end: { line: baseLine + i - 1, column: 1 }
|
|
786
|
+
};
|
|
787
|
+
elements.push(el);
|
|
788
|
+
} else if (directiveName === "toc") {
|
|
789
|
+
const titleMatch = directiveArg.match(/\btitle=(?:"([^"]*)"|'([^']*)'|(\S+))/);
|
|
790
|
+
let title = titleMatch ? titleMatch[1] ?? titleMatch[2] ?? titleMatch[3] : void 0;
|
|
791
|
+
if (!title) {
|
|
792
|
+
title = directiveArg.replace(/^['"](.*)['"]$/, "$1").trim() || void 0;
|
|
793
|
+
}
|
|
794
|
+
const items = [];
|
|
795
|
+
for (const bl of blockLines) {
|
|
796
|
+
const trimmed = bl.trim();
|
|
797
|
+
if (!trimmed)
|
|
798
|
+
continue;
|
|
799
|
+
const matchOrdered = trimmed.match(/^(\d+)\.\s+(.*?)(?:\s+[-–—:]\s+(.*))?$/);
|
|
800
|
+
const matchUnordered = trimmed.match(/^[-*]\s+(.*?)(?:\s+[-–—:]\s+(.*))?$/);
|
|
801
|
+
if (matchOrdered && matchOrdered[1] && matchOrdered[2]) {
|
|
802
|
+
items.push({
|
|
803
|
+
number: matchOrdered[1],
|
|
804
|
+
title: matchOrdered[2].trim(),
|
|
805
|
+
description: matchOrdered[3]?.trim() || void 0
|
|
806
|
+
});
|
|
807
|
+
} else if (matchUnordered && matchUnordered[1]) {
|
|
808
|
+
items.push({
|
|
809
|
+
title: matchUnordered[1].trim(),
|
|
810
|
+
description: matchUnordered[2]?.trim() || void 0
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
const el = createToc(title, items.length > 0 ? items : void 0);
|
|
815
|
+
el.loc = {
|
|
816
|
+
start: { line: directiveStartLine, column: 1 },
|
|
817
|
+
end: { line: baseLine + i - 1, column: 1 }
|
|
818
|
+
};
|
|
819
|
+
elements.push(el);
|
|
609
820
|
} else if (directiveName === "step") {
|
|
610
821
|
const { elements: stepElements } = this.parseLines(blockLines, blockBaseLine);
|
|
611
822
|
for (const sEl of stepElements) {
|
|
@@ -620,6 +831,39 @@ var DefaultYumiaParser = class {
|
|
|
620
831
|
end: { line: baseLine + i - 1, column: 1 }
|
|
621
832
|
};
|
|
622
833
|
elements.push(el);
|
|
834
|
+
} else if (directiveName === "icon") {
|
|
835
|
+
const nameMatch = directiveArg.match(/^(?:name=)?["']?([^"'\s]+)["']?/);
|
|
836
|
+
const name = nameMatch ? nameMatch[1] : directiveArg.trim();
|
|
837
|
+
const sizeMatch = directiveArg.match(/\bsize=["']?([^"'\s]+)["']?/);
|
|
838
|
+
const colorMatch = directiveArg.match(/\bcolor=["']?([^"'\s]+)["']?/);
|
|
839
|
+
const el = createIcon(name, void 0, sizeMatch ? sizeMatch[1] : void 0, colorMatch ? colorMatch[1] : void 0);
|
|
840
|
+
el.loc = {
|
|
841
|
+
start: { line: directiveStartLine, column: 1 },
|
|
842
|
+
end: { line: baseLine + i - 1, column: 1 }
|
|
843
|
+
};
|
|
844
|
+
elements.push(el);
|
|
845
|
+
} else if (directiveName === "grid") {
|
|
846
|
+
const colsMatch = directiveArg.match(/\bcolumns=["']?([^"'\s]+)["']?/);
|
|
847
|
+
const gapMatch = directiveArg.match(/\bgap=["']?([^"'\s]+)["']?/);
|
|
848
|
+
const columns = colsMatch ? parseInt(colsMatch[1], 10) || colsMatch[1] : 2;
|
|
849
|
+
const { elements: gridChildren } = this.parseLines(blockLines, blockBaseLine);
|
|
850
|
+
const el = createGrid(gridChildren, columns, gapMatch ? gapMatch[1] : void 0);
|
|
851
|
+
el.loc = {
|
|
852
|
+
start: { line: directiveStartLine, column: 1 },
|
|
853
|
+
end: { line: baseLine + i - 1, column: 1 }
|
|
854
|
+
};
|
|
855
|
+
elements.push(el);
|
|
856
|
+
} else if (directiveName === "stack") {
|
|
857
|
+
const dirMatch = directiveArg.match(/\bdirection=["']?(horizontal|vertical)["']?/);
|
|
858
|
+
const direction = dirMatch ? dirMatch[1] : "vertical";
|
|
859
|
+
const gapMatch = directiveArg.match(/\bgap=["']?([^"'\s]+)["']?/);
|
|
860
|
+
const { elements: stackChildren } = this.parseLines(blockLines, blockBaseLine);
|
|
861
|
+
const el = createStack(stackChildren, direction, gapMatch ? gapMatch[1] : void 0);
|
|
862
|
+
el.loc = {
|
|
863
|
+
start: { line: directiveStartLine, column: 1 },
|
|
864
|
+
end: { line: baseLine + i - 1, column: 1 }
|
|
865
|
+
};
|
|
866
|
+
elements.push(el);
|
|
623
867
|
}
|
|
624
868
|
continue;
|
|
625
869
|
}
|
|
@@ -837,6 +1081,7 @@ var DefaultYumiaParser = class {
|
|
|
837
1081
|
series.push({ name: title || "Data", values });
|
|
838
1082
|
}
|
|
839
1083
|
}
|
|
1084
|
+
const singleSeriesValues = [];
|
|
840
1085
|
for (const line of blockLines) {
|
|
841
1086
|
const trimmed = line.trim();
|
|
842
1087
|
if (!trimmed || trimmed.startsWith("#"))
|
|
@@ -858,13 +1103,28 @@ var DefaultYumiaParser = class {
|
|
|
858
1103
|
if (l && valStr) {
|
|
859
1104
|
labels.push(l);
|
|
860
1105
|
const val = parseFloat(valStr) || 0;
|
|
861
|
-
|
|
862
|
-
series.push({ name: "Data", values: [] });
|
|
863
|
-
series[0]?.values.push(val);
|
|
1106
|
+
singleSeriesValues.push(val);
|
|
864
1107
|
}
|
|
865
1108
|
}
|
|
1109
|
+
} else {
|
|
1110
|
+
const kvMatch = trimmed.match(/^[-*]?\s*(.*?)\s*[:=]\s*([+-]?\d+(?:\.\d+)?%?)$/);
|
|
1111
|
+
if (kvMatch && kvMatch[1] && kvMatch[2]) {
|
|
1112
|
+
labels.push(kvMatch[1].trim());
|
|
1113
|
+
const val = parseFloat(kvMatch[2].replace("%", "")) || 0;
|
|
1114
|
+
singleSeriesValues.push(val);
|
|
1115
|
+
}
|
|
866
1116
|
}
|
|
867
1117
|
}
|
|
1118
|
+
if (singleSeriesValues.length > 0) {
|
|
1119
|
+
if (series.length === 0) {
|
|
1120
|
+
series.push({ name: title || "Data", values: singleSeriesValues });
|
|
1121
|
+
} else if (series[0]) {
|
|
1122
|
+
series[0].values.push(...singleSeriesValues);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
if (series.length === 0) {
|
|
1126
|
+
series.push({ name: title || "Data", values: [] });
|
|
1127
|
+
}
|
|
868
1128
|
if (labels.length === 0) {
|
|
869
1129
|
const maxLen = Math.max(0, ...series.map((s) => s.values.length));
|
|
870
1130
|
labels = Array.from({ length: maxLen }, (_, i) => `Item ${i + 1}`);
|
|
@@ -910,6 +1170,13 @@ var DefaultYumiaParser = class {
|
|
|
910
1170
|
const rightMatch = headerArg.match(/right=['"](.*?)['"]/);
|
|
911
1171
|
const leftTitle = leftMatch ? leftMatch[1] : void 0;
|
|
912
1172
|
const rightTitle = rightMatch ? rightMatch[1] : void 0;
|
|
1173
|
+
const hasColumns = blockLines.some((l) => l.trim().startsWith(":::column"));
|
|
1174
|
+
if (hasColumns) {
|
|
1175
|
+
const cols = this.parseColumnsBlock(blockLines, baseLine);
|
|
1176
|
+
const leftElements2 = cols[0]?.elements || [];
|
|
1177
|
+
const rightElements2 = cols[1]?.elements || [];
|
|
1178
|
+
return createCompare(leftElements2, rightElements2, leftTitle, rightTitle);
|
|
1179
|
+
}
|
|
913
1180
|
let leftLines = [];
|
|
914
1181
|
let rightLines = [];
|
|
915
1182
|
let currentSide = "left";
|
|
@@ -944,6 +1211,449 @@ function parseYumia(source, options) {
|
|
|
944
1211
|
return parser.parse(source, options);
|
|
945
1212
|
}
|
|
946
1213
|
|
|
1214
|
+
// ../parser/dist/native-parser.js
|
|
1215
|
+
var NativeYumiaParser = class {
|
|
1216
|
+
parse(source) {
|
|
1217
|
+
const lines = source.split(/\r?\n/);
|
|
1218
|
+
const tokens = [];
|
|
1219
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1220
|
+
const raw = lines[i];
|
|
1221
|
+
const matchIndent = raw.match(/^(\s*)/);
|
|
1222
|
+
const indent = matchIndent ? matchIndent[1].length : 0;
|
|
1223
|
+
const text = raw.trim();
|
|
1224
|
+
if (!text || text.startsWith("//") || text.startsWith("#"))
|
|
1225
|
+
continue;
|
|
1226
|
+
const spaceIdx = text.indexOf(" ");
|
|
1227
|
+
const command = spaceIdx === -1 ? text : text.slice(0, spaceIdx);
|
|
1228
|
+
const args = spaceIdx === -1 ? "" : text.slice(spaceIdx + 1).trim();
|
|
1229
|
+
tokens.push({
|
|
1230
|
+
indent,
|
|
1231
|
+
lineNum: i + 1,
|
|
1232
|
+
text,
|
|
1233
|
+
command: command.toLowerCase(),
|
|
1234
|
+
args
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
const metadata = {};
|
|
1238
|
+
const slides = [];
|
|
1239
|
+
let currentSlideElements = [];
|
|
1240
|
+
let currentSlide = null;
|
|
1241
|
+
const flushSlide = () => {
|
|
1242
|
+
if (currentSlide) {
|
|
1243
|
+
currentSlide.elements = [...currentSlideElements];
|
|
1244
|
+
slides.push(currentSlide);
|
|
1245
|
+
currentSlideElements = [];
|
|
1246
|
+
currentSlide = null;
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
let idx = 0;
|
|
1250
|
+
while (idx < tokens.length) {
|
|
1251
|
+
const tok = tokens[idx];
|
|
1252
|
+
const cmdLower = tok.command.toLowerCase();
|
|
1253
|
+
if (cmdLower === "document" || cmdLower === "title") {
|
|
1254
|
+
metadata.title = this.stripQuotes(tok.args);
|
|
1255
|
+
idx++;
|
|
1256
|
+
continue;
|
|
1257
|
+
}
|
|
1258
|
+
if (cmdLower === "theme") {
|
|
1259
|
+
metadata.theme = this.stripQuotes(tok.args);
|
|
1260
|
+
idx++;
|
|
1261
|
+
continue;
|
|
1262
|
+
}
|
|
1263
|
+
if (cmdLower === "aspectratio" || cmdLower === "ratio") {
|
|
1264
|
+
metadata.aspectRatio = this.stripQuotes(tok.args);
|
|
1265
|
+
idx++;
|
|
1266
|
+
continue;
|
|
1267
|
+
}
|
|
1268
|
+
if (cmdLower === "transition") {
|
|
1269
|
+
metadata.transition = this.stripQuotes(tok.args);
|
|
1270
|
+
idx++;
|
|
1271
|
+
continue;
|
|
1272
|
+
}
|
|
1273
|
+
if (cmdLower === "watermark") {
|
|
1274
|
+
metadata.watermark = this.stripQuotes(tok.args);
|
|
1275
|
+
idx++;
|
|
1276
|
+
continue;
|
|
1277
|
+
}
|
|
1278
|
+
if (cmdLower === "author") {
|
|
1279
|
+
metadata.author = this.stripQuotes(tok.args);
|
|
1280
|
+
idx++;
|
|
1281
|
+
continue;
|
|
1282
|
+
}
|
|
1283
|
+
if (tok.command === "slide" || tok.command === "---") {
|
|
1284
|
+
flushSlide();
|
|
1285
|
+
const slideTitle = tok.command === "slide" ? this.stripQuotes(tok.args) : void 0;
|
|
1286
|
+
currentSlide = createSlide([], {
|
|
1287
|
+
loc: {
|
|
1288
|
+
start: { line: tok.lineNum, column: 1 },
|
|
1289
|
+
end: { line: tok.lineNum, column: tok.text.length }
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
if (slideTitle) {
|
|
1293
|
+
currentSlideElements.push(createHeading(slideTitle, 1));
|
|
1294
|
+
}
|
|
1295
|
+
idx++;
|
|
1296
|
+
continue;
|
|
1297
|
+
}
|
|
1298
|
+
if (!currentSlide) {
|
|
1299
|
+
currentSlide = createSlide([], {
|
|
1300
|
+
loc: {
|
|
1301
|
+
start: { line: tok.lineNum, column: 1 },
|
|
1302
|
+
end: { line: tok.lineNum, column: tok.text.length }
|
|
1303
|
+
}
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
if (tok.command === "notes") {
|
|
1307
|
+
const noteLines = [];
|
|
1308
|
+
idx++;
|
|
1309
|
+
while (idx < tokens.length && tokens[idx].indent > tok.indent) {
|
|
1310
|
+
noteLines.push(tokens[idx].text);
|
|
1311
|
+
idx++;
|
|
1312
|
+
}
|
|
1313
|
+
currentSlide.notes = (currentSlide.notes ? currentSlide.notes + "\n" : "") + noteLines.join("\n");
|
|
1314
|
+
continue;
|
|
1315
|
+
}
|
|
1316
|
+
const parsedEl = this.parseElement(tokens, idx);
|
|
1317
|
+
if (parsedEl) {
|
|
1318
|
+
currentSlideElements.push(parsedEl.element);
|
|
1319
|
+
idx = parsedEl.nextIdx;
|
|
1320
|
+
} else {
|
|
1321
|
+
idx++;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
flushSlide();
|
|
1325
|
+
if (slides.length === 0) {
|
|
1326
|
+
slides.push(createSlide([createHeading(metadata.title || "Untitled Presentation", 1)]));
|
|
1327
|
+
}
|
|
1328
|
+
return createPresentation(metadata, slides);
|
|
1329
|
+
}
|
|
1330
|
+
parseElement(tokens, idx) {
|
|
1331
|
+
const tok = tokens[idx];
|
|
1332
|
+
const baseIndent = tok.indent;
|
|
1333
|
+
switch (tok.command) {
|
|
1334
|
+
case "heading":
|
|
1335
|
+
case "h1":
|
|
1336
|
+
case "h2":
|
|
1337
|
+
case "h3": {
|
|
1338
|
+
const level = tok.command === "h1" ? 1 : tok.command === "h2" ? 2 : tok.command === "h3" ? 3 : 1;
|
|
1339
|
+
const text = this.stripQuotes(tok.args);
|
|
1340
|
+
return { element: createHeading(text, level), nextIdx: idx + 1 };
|
|
1341
|
+
}
|
|
1342
|
+
case "paragraph":
|
|
1343
|
+
case "text":
|
|
1344
|
+
case "p": {
|
|
1345
|
+
let text = this.stripQuotes(tok.args);
|
|
1346
|
+
let nextIdx = idx + 1;
|
|
1347
|
+
if (!text) {
|
|
1348
|
+
const pLines = [];
|
|
1349
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1350
|
+
pLines.push(tokens[nextIdx].text);
|
|
1351
|
+
nextIdx++;
|
|
1352
|
+
}
|
|
1353
|
+
text = pLines.join(" ");
|
|
1354
|
+
}
|
|
1355
|
+
return { element: createParagraph(text), nextIdx };
|
|
1356
|
+
}
|
|
1357
|
+
case "icon": {
|
|
1358
|
+
const nameMatch = tok.args.match(/^(?:name=)?["']?([^"'\s]+)["']?/);
|
|
1359
|
+
const name = nameMatch ? nameMatch[1] : tok.args.trim();
|
|
1360
|
+
const sizeMatch = tok.args.match(/\bsize=["']?([^"'\s]+)["']?/);
|
|
1361
|
+
const colorMatch = tok.args.match(/\bcolor=["']?([^"'\s]+)["']?/);
|
|
1362
|
+
return {
|
|
1363
|
+
element: createIcon(name, void 0, sizeMatch ? sizeMatch[1] : void 0, colorMatch ? colorMatch[1] : void 0),
|
|
1364
|
+
nextIdx: idx + 1
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
case "card": {
|
|
1368
|
+
const titleMatch = tok.args.match(/title=["']([^"']+)["']/);
|
|
1369
|
+
const variantMatch = tok.args.match(/variant=["']?([^"'\s]+)["']?/);
|
|
1370
|
+
const title = titleMatch ? titleMatch[1] : this.stripQuotes(tok.args) || void 0;
|
|
1371
|
+
const variant = variantMatch ? variantMatch[1] : "default";
|
|
1372
|
+
const children = [];
|
|
1373
|
+
let nextIdx = idx + 1;
|
|
1374
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1375
|
+
const childRes = this.parseElement(tokens, nextIdx);
|
|
1376
|
+
if (childRes) {
|
|
1377
|
+
children.push(childRes.element);
|
|
1378
|
+
nextIdx = childRes.nextIdx;
|
|
1379
|
+
} else {
|
|
1380
|
+
nextIdx++;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
return { element: createCard(children, title, variant), nextIdx };
|
|
1384
|
+
}
|
|
1385
|
+
case "columns": {
|
|
1386
|
+
const ratios = tok.args || "50:50";
|
|
1387
|
+
const cols = [];
|
|
1388
|
+
let nextIdx = idx + 1;
|
|
1389
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1390
|
+
const childRes = this.parseElement(tokens, nextIdx);
|
|
1391
|
+
if (childRes) {
|
|
1392
|
+
cols.push(childRes.element);
|
|
1393
|
+
nextIdx = childRes.nextIdx;
|
|
1394
|
+
} else {
|
|
1395
|
+
nextIdx++;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
const colElements = cols.map((c) => c.type === "column" ? c : createColumn([c]));
|
|
1399
|
+
return { element: createColumns(colElements, ratios), nextIdx };
|
|
1400
|
+
}
|
|
1401
|
+
case "grid": {
|
|
1402
|
+
const colsMatch = tok.args.match(/columns=["']?([^"'\s]+)["']?/);
|
|
1403
|
+
const gapMatch = tok.args.match(/gap=["']?([^"'\s]+)["']?/);
|
|
1404
|
+
const columns = colsMatch ? parseInt(colsMatch[1], 10) || colsMatch[1] : 2;
|
|
1405
|
+
const gap = gapMatch ? gapMatch[1] : void 0;
|
|
1406
|
+
const children = [];
|
|
1407
|
+
let nextIdx = idx + 1;
|
|
1408
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1409
|
+
const childRes = this.parseElement(tokens, nextIdx);
|
|
1410
|
+
if (childRes) {
|
|
1411
|
+
children.push(childRes.element);
|
|
1412
|
+
nextIdx = childRes.nextIdx;
|
|
1413
|
+
} else {
|
|
1414
|
+
nextIdx++;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
return { element: createGrid(children, columns, gap), nextIdx };
|
|
1418
|
+
}
|
|
1419
|
+
case "stack": {
|
|
1420
|
+
const dirMatch = tok.args.match(/direction=["']?(horizontal|vertical)["']?/);
|
|
1421
|
+
const direction = dirMatch ? dirMatch[1] : "vertical";
|
|
1422
|
+
const gapMatch = tok.args.match(/gap=["']?([^"'\s]+)["']?/);
|
|
1423
|
+
const children = [];
|
|
1424
|
+
let nextIdx = idx + 1;
|
|
1425
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1426
|
+
const childRes = this.parseElement(tokens, nextIdx);
|
|
1427
|
+
if (childRes) {
|
|
1428
|
+
children.push(childRes.element);
|
|
1429
|
+
nextIdx = childRes.nextIdx;
|
|
1430
|
+
} else {
|
|
1431
|
+
nextIdx++;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
return {
|
|
1435
|
+
element: createStack(children, direction, gapMatch ? gapMatch[1] : void 0),
|
|
1436
|
+
nextIdx
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
case "metric": {
|
|
1440
|
+
const valMatch = tok.args.match(/^(?:value=)?["']([^"']+)["']/);
|
|
1441
|
+
const labelMatch = tok.args.match(/\blabel=["']([^"']+)["']/);
|
|
1442
|
+
const diffMatch = tok.args.match(/\bdiff=["']([^"']+)["']/);
|
|
1443
|
+
const variantMatch = tok.args.match(/\bvariant=["']?([^"'\s]+)["']?/);
|
|
1444
|
+
const value = valMatch ? valMatch[1] : "0";
|
|
1445
|
+
const label = labelMatch ? labelMatch[1] : "Metric";
|
|
1446
|
+
return {
|
|
1447
|
+
element: createMetric(value, label, variantMatch ? variantMatch[1] : "primary", void 0, void 0, diffMatch ? diffMatch[1] : void 0),
|
|
1448
|
+
nextIdx: idx + 1
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
case "code": {
|
|
1452
|
+
const langMatch = tok.args.match(/\blang(?:uage)?=["']?([^"'\s]+)["']?/);
|
|
1453
|
+
const hlMatch = tok.args.match(/\bhighlight=["']([^"']+)["']/);
|
|
1454
|
+
const codeLines = [];
|
|
1455
|
+
let nextIdx = idx + 1;
|
|
1456
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1457
|
+
codeLines.push(tokens[nextIdx].text);
|
|
1458
|
+
nextIdx++;
|
|
1459
|
+
}
|
|
1460
|
+
const el = createCode(codeLines.join("\n"), langMatch ? langMatch[1] : void 0);
|
|
1461
|
+
if (hlMatch && hlMatch[1]) {
|
|
1462
|
+
el.highlight = hlMatch[1];
|
|
1463
|
+
el.highlightLines = parseHighlightLines(hlMatch[1]);
|
|
1464
|
+
}
|
|
1465
|
+
return { element: el, nextIdx };
|
|
1466
|
+
}
|
|
1467
|
+
case "section": {
|
|
1468
|
+
const titleMatch = tok.args.match(/^(?:title=)?["']([^"']+)["']/);
|
|
1469
|
+
const subtitleMatch = tok.args.match(/\bsubtitle=["']([^"']+)["']/);
|
|
1470
|
+
const numMatch = tok.args.match(/\bnumber=["']?([^"'\s]+)["']?/);
|
|
1471
|
+
const title = titleMatch ? titleMatch[1] : this.stripQuotes(tok.args) || "Section";
|
|
1472
|
+
return {
|
|
1473
|
+
element: createSection(title, subtitleMatch ? subtitleMatch[1] : void 0, numMatch ? numMatch[1] : void 0),
|
|
1474
|
+
nextIdx: idx + 1
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
case "toc": {
|
|
1478
|
+
const title = this.stripQuotes(tok.args) || "Table of Contents";
|
|
1479
|
+
return { element: createToc(title), nextIdx: idx + 1 };
|
|
1480
|
+
}
|
|
1481
|
+
case "badge": {
|
|
1482
|
+
const textMatch = tok.args.match(/^(?:text=)?["']([^"']+)["']/);
|
|
1483
|
+
const variantMatch = tok.args.match(/\bvariant=["']?([^"'\s]+)["']?/);
|
|
1484
|
+
const text = textMatch ? textMatch[1] : this.stripQuotes(tok.args);
|
|
1485
|
+
return {
|
|
1486
|
+
element: createBadge(text, variantMatch ? variantMatch[1] : "default"),
|
|
1487
|
+
nextIdx: idx + 1
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
case "list": {
|
|
1491
|
+
const items = [];
|
|
1492
|
+
let nextIdx = idx + 1;
|
|
1493
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1494
|
+
const sub = tokens[nextIdx];
|
|
1495
|
+
if (sub.command === "item" || sub.command === "-") {
|
|
1496
|
+
items.push({ text: this.stripQuotes(sub.args) });
|
|
1497
|
+
} else {
|
|
1498
|
+
items.push({ text: sub.text.replace(/^[-*]\s*/, "") });
|
|
1499
|
+
}
|
|
1500
|
+
nextIdx++;
|
|
1501
|
+
}
|
|
1502
|
+
return { element: createList(items, false), nextIdx };
|
|
1503
|
+
}
|
|
1504
|
+
case "quote": {
|
|
1505
|
+
const authorMatch = tok.args.match(/\bauthor=["']([^"']+)["']/);
|
|
1506
|
+
const textLines = [];
|
|
1507
|
+
let nextIdx = idx + 1;
|
|
1508
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1509
|
+
textLines.push(tokens[nextIdx].text);
|
|
1510
|
+
nextIdx++;
|
|
1511
|
+
}
|
|
1512
|
+
return {
|
|
1513
|
+
element: createQuote(textLines.join(" "), authorMatch ? authorMatch[1] : void 0),
|
|
1514
|
+
nextIdx
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
default:
|
|
1518
|
+
return { element: createParagraph(tok.text), nextIdx: idx + 1 };
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
stripQuotes(str) {
|
|
1522
|
+
if (!str)
|
|
1523
|
+
return "";
|
|
1524
|
+
const trimmed = str.trim();
|
|
1525
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
1526
|
+
return trimmed.slice(1, -1);
|
|
1527
|
+
}
|
|
1528
|
+
return trimmed;
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
function parseNativeYumia(source) {
|
|
1532
|
+
const parser = new NativeYumiaParser();
|
|
1533
|
+
return parser.parse(source);
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
// ../parser/dist/migrator.js
|
|
1537
|
+
function migrateMarkdownToNative(source) {
|
|
1538
|
+
const presentation = parseYumia(source);
|
|
1539
|
+
const out = [];
|
|
1540
|
+
if (presentation.metadata.title) {
|
|
1541
|
+
out.push(`document "${presentation.metadata.title}"`);
|
|
1542
|
+
}
|
|
1543
|
+
if (presentation.metadata.theme) {
|
|
1544
|
+
const themeName = typeof presentation.metadata.theme === "string" ? presentation.metadata.theme : presentation.metadata.theme.name;
|
|
1545
|
+
out.push(` theme "${themeName}"`);
|
|
1546
|
+
}
|
|
1547
|
+
if (presentation.metadata.author) {
|
|
1548
|
+
out.push(` author "${presentation.metadata.author}"`);
|
|
1549
|
+
}
|
|
1550
|
+
if (presentation.metadata.aspectRatio) {
|
|
1551
|
+
out.push(` aspectRatio "${presentation.metadata.aspectRatio}"`);
|
|
1552
|
+
}
|
|
1553
|
+
if (presentation.metadata.transition) {
|
|
1554
|
+
const trans = typeof presentation.metadata.transition === "string" ? presentation.metadata.transition : presentation.metadata.transition.type;
|
|
1555
|
+
out.push(` transition "${trans}"`);
|
|
1556
|
+
}
|
|
1557
|
+
if (presentation.metadata.watermark) {
|
|
1558
|
+
out.push(` watermark "${presentation.metadata.watermark}"`);
|
|
1559
|
+
}
|
|
1560
|
+
out.push("");
|
|
1561
|
+
for (const slide of presentation.slides) {
|
|
1562
|
+
const firstHeading = slide.elements.find((el) => el.type === "heading");
|
|
1563
|
+
const slideTitle = firstHeading && firstHeading.level === 1 ? firstHeading.text : "";
|
|
1564
|
+
if (slideTitle) {
|
|
1565
|
+
out.push(`slide "${slideTitle}"`);
|
|
1566
|
+
} else {
|
|
1567
|
+
out.push("slide");
|
|
1568
|
+
}
|
|
1569
|
+
if (slide.transition) {
|
|
1570
|
+
const trans = typeof slide.transition === "string" ? slide.transition : slide.transition.type;
|
|
1571
|
+
out.push(` transition "${trans}"`);
|
|
1572
|
+
}
|
|
1573
|
+
for (const el of slide.elements) {
|
|
1574
|
+
if (el === firstHeading && firstHeading.level === 1)
|
|
1575
|
+
continue;
|
|
1576
|
+
out.push(serializeElement(el, 2));
|
|
1577
|
+
}
|
|
1578
|
+
if (slide.notes) {
|
|
1579
|
+
out.push(" notes");
|
|
1580
|
+
for (const nl of slide.notes.split("\n")) {
|
|
1581
|
+
out.push(` ${nl}`);
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
out.push("");
|
|
1585
|
+
}
|
|
1586
|
+
return out.join("\n").trim() + "\n";
|
|
1587
|
+
}
|
|
1588
|
+
function serializeElement(el, indent) {
|
|
1589
|
+
const pad = " ".repeat(indent);
|
|
1590
|
+
switch (el.type) {
|
|
1591
|
+
case "heading":
|
|
1592
|
+
return `${pad}heading "${el.text}"`;
|
|
1593
|
+
case "paragraph":
|
|
1594
|
+
return `${pad}text "${el.text}"`;
|
|
1595
|
+
case "icon":
|
|
1596
|
+
return `${pad}icon "${el.name}"`;
|
|
1597
|
+
case "badge":
|
|
1598
|
+
return `${pad}badge "${el.text}" variant="${el.variant || "default"}"`;
|
|
1599
|
+
case "metric":
|
|
1600
|
+
return `${pad}metric "${el.value}" label="${el.label}"${el.change ? ` diff="${el.change}"` : ""}`;
|
|
1601
|
+
case "code": {
|
|
1602
|
+
const hl = el.highlight ? ` highlight="${el.highlight}"` : "";
|
|
1603
|
+
const lang = el.language ? ` lang="${el.language}"` : "";
|
|
1604
|
+
const codeLines = el.code.split("\n").map((l) => `${pad} ${l}`).join("\n");
|
|
1605
|
+
return `${pad}code${lang}${hl}
|
|
1606
|
+
${codeLines}`;
|
|
1607
|
+
}
|
|
1608
|
+
case "section": {
|
|
1609
|
+
const sub = el.subtitle ? ` subtitle="${el.subtitle}"` : "";
|
|
1610
|
+
const num = el.number !== void 0 ? ` number="${el.number}"` : "";
|
|
1611
|
+
return `${pad}section "${el.title}"${sub}${num}`;
|
|
1612
|
+
}
|
|
1613
|
+
case "toc":
|
|
1614
|
+
return `${pad}toc "${el.title || "Table of Contents"}"`;
|
|
1615
|
+
case "card": {
|
|
1616
|
+
const cleanTitle = (el.title || "").replace(/^[Tt]itle=['"]?/, "").replace(/['"]$/, "");
|
|
1617
|
+
const title = cleanTitle ? ` title="${cleanTitle}"` : "";
|
|
1618
|
+
const v = el.variant ? ` variant="${el.variant}"` : "";
|
|
1619
|
+
const cardChildren = (el.elements || []).map((c) => serializeElement(c, indent + 2)).join("\n");
|
|
1620
|
+
return `${pad}card${title}${v}
|
|
1621
|
+
${cardChildren}`;
|
|
1622
|
+
}
|
|
1623
|
+
case "grid": {
|
|
1624
|
+
const gridChildren = el.elements.map((c) => serializeElement(c, indent + 2)).join("\n");
|
|
1625
|
+
return `${pad}grid columns=${el.columns}
|
|
1626
|
+
${gridChildren}`;
|
|
1627
|
+
}
|
|
1628
|
+
case "stack": {
|
|
1629
|
+
const stackChildren = el.elements.map((c) => serializeElement(c, indent + 2)).join("\n");
|
|
1630
|
+
return `${pad}stack direction="${el.direction}"
|
|
1631
|
+
${stackChildren}`;
|
|
1632
|
+
}
|
|
1633
|
+
case "columns": {
|
|
1634
|
+
const colChildren = el.columns.map((col) => {
|
|
1635
|
+
const inner = col.elements.map((c) => serializeElement(c, indent + 4)).join("\n");
|
|
1636
|
+
return `${pad} column
|
|
1637
|
+
${inner}`;
|
|
1638
|
+
}).join("\n");
|
|
1639
|
+
return `${pad}columns ${el.ratios || "50:50"}
|
|
1640
|
+
${colChildren}`;
|
|
1641
|
+
}
|
|
1642
|
+
case "list": {
|
|
1643
|
+
const listItems = el.items.map((it) => `${pad} item "${it.text}"`).join("\n");
|
|
1644
|
+
return `${pad}list
|
|
1645
|
+
${listItems}`;
|
|
1646
|
+
}
|
|
1647
|
+
case "quote": {
|
|
1648
|
+
const qAuthor = el.author ? ` author="${el.author}"` : "";
|
|
1649
|
+
return `${pad}quote${qAuthor}
|
|
1650
|
+
${pad} ${el.text}`;
|
|
1651
|
+
}
|
|
1652
|
+
default:
|
|
1653
|
+
return `${pad}// [${el.type}]`;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
|
|
947
1657
|
// ../layout/dist/engine.js
|
|
948
1658
|
var DEFAULT_VIEWPORT = {
|
|
949
1659
|
width: 1920,
|
|
@@ -1036,6 +1746,14 @@ var DefaultLayoutEngine = class {
|
|
|
1036
1746
|
const height = 90;
|
|
1037
1747
|
return { element, bounds: { x, y, width, height } };
|
|
1038
1748
|
}
|
|
1749
|
+
case "section": {
|
|
1750
|
+
const height = 280;
|
|
1751
|
+
return { element, bounds: { x, y, width, height } };
|
|
1752
|
+
}
|
|
1753
|
+
case "toc": {
|
|
1754
|
+
const height = 320;
|
|
1755
|
+
return { element, bounds: { x, y, width, height } };
|
|
1756
|
+
}
|
|
1039
1757
|
case "card": {
|
|
1040
1758
|
return this.layoutCard(element, x, y, width, gap);
|
|
1041
1759
|
}
|
|
@@ -1753,50 +2471,559 @@ var academicTheme = {
|
|
|
1753
2471
|
}
|
|
1754
2472
|
}
|
|
1755
2473
|
};
|
|
1756
|
-
var
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
},
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
2474
|
+
var nordTheme = {
|
|
2475
|
+
name: "nord",
|
|
2476
|
+
description: "Arctic, north-bluish clean dark palette for elegant developer decks",
|
|
2477
|
+
colors: {
|
|
2478
|
+
primary: "#88C0D0",
|
|
2479
|
+
secondary: "#81A1C1",
|
|
2480
|
+
background: "#2E3440",
|
|
2481
|
+
surface: "#3B4252",
|
|
2482
|
+
elevatedSurface: "#434C5E",
|
|
2483
|
+
text: "#ECEFF4",
|
|
2484
|
+
muted: "#D8DEE9",
|
|
2485
|
+
accent: "#5E81AC",
|
|
2486
|
+
border: "#4C566A",
|
|
2487
|
+
divider: "#434C5E",
|
|
2488
|
+
success: "#A3BE8C",
|
|
2489
|
+
warning: "#EBCB8B",
|
|
2490
|
+
danger: "#BF616A",
|
|
2491
|
+
info: "#88C0D0"
|
|
2492
|
+
},
|
|
2493
|
+
typography: {
|
|
2494
|
+
headingFont: "Inter, system-ui, sans-serif",
|
|
2495
|
+
bodyFont: "Inter, system-ui, sans-serif",
|
|
2496
|
+
codeFont: "JetBrains Mono, Fira Code, monospace",
|
|
2497
|
+
sizes: {
|
|
2498
|
+
display: 56,
|
|
2499
|
+
h1: 44,
|
|
2500
|
+
h2: 36,
|
|
2501
|
+
h3: 28,
|
|
2502
|
+
h4: 22,
|
|
2503
|
+
body: 18,
|
|
2504
|
+
small: 14,
|
|
2505
|
+
caption: 12,
|
|
2506
|
+
code: 16,
|
|
2507
|
+
quote: 20,
|
|
2508
|
+
metadata: 12
|
|
2509
|
+
},
|
|
2510
|
+
weights: {
|
|
2511
|
+
normal: 400,
|
|
2512
|
+
medium: 500,
|
|
2513
|
+
bold: 700
|
|
2514
|
+
},
|
|
2515
|
+
lineHeights: {
|
|
2516
|
+
tight: 1.15,
|
|
2517
|
+
snug: 1.3,
|
|
2518
|
+
normal: 1.55,
|
|
2519
|
+
relaxed: 1.7
|
|
2520
|
+
},
|
|
2521
|
+
letterSpacing: {
|
|
2522
|
+
tight: "-0.02em",
|
|
2523
|
+
normal: "0em",
|
|
2524
|
+
wide: "0.03em"
|
|
2525
|
+
}
|
|
2526
|
+
},
|
|
2527
|
+
spacing: {
|
|
2528
|
+
unit: 8,
|
|
2529
|
+
scale: [0, 4, 8, 12, 16, 24, 32, 48, 64, 96],
|
|
2530
|
+
slidePadding: 48,
|
|
2531
|
+
elementGap: 24,
|
|
2532
|
+
safeArea: { top: 48, bottom: 48, left: 48, right: 48 }
|
|
2533
|
+
},
|
|
2534
|
+
radius: {
|
|
2535
|
+
none: 0,
|
|
2536
|
+
sm: 4,
|
|
2537
|
+
md: 8,
|
|
2538
|
+
lg: 14,
|
|
2539
|
+
xl: 20,
|
|
2540
|
+
full: 9999,
|
|
2541
|
+
default: 8
|
|
2542
|
+
},
|
|
2543
|
+
shadows: {
|
|
2544
|
+
none: "none",
|
|
2545
|
+
sm: "0 2px 4px rgba(0, 0, 0, 0.25)",
|
|
2546
|
+
md: "0 6px 12px rgba(0, 0, 0, 0.35)",
|
|
2547
|
+
lg: "0 12px 24px rgba(0, 0, 0, 0.45)",
|
|
2548
|
+
glow: "0 0 16px rgba(136, 192, 208, 0.35)"
|
|
2549
|
+
},
|
|
2550
|
+
components: {
|
|
2551
|
+
card: {
|
|
2552
|
+
background: "#3B4252",
|
|
2553
|
+
borderColor: "#88C0D0",
|
|
2554
|
+
borderRadius: 10,
|
|
2555
|
+
padding: 24
|
|
2556
|
+
},
|
|
2557
|
+
metric: {
|
|
2558
|
+
valueColor: "#88C0D0",
|
|
2559
|
+
labelColor: "#D8DEE9",
|
|
2560
|
+
borderRadius: 10
|
|
2561
|
+
},
|
|
2562
|
+
code: {
|
|
2563
|
+
background: "#242933",
|
|
2564
|
+
textColor: "#ECEFF4",
|
|
2565
|
+
borderRadius: 8
|
|
2566
|
+
},
|
|
2567
|
+
table: {
|
|
2568
|
+
headerBackground: "#434C5E",
|
|
2569
|
+
rowAlternateBackground: "#3B4252",
|
|
2570
|
+
borderColor: "#4C566A"
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
var draculaTheme = {
|
|
2575
|
+
name: "dracula",
|
|
2576
|
+
description: "Famous dark theme with rich purples, vibrant pinks and pastel highlights",
|
|
2577
|
+
colors: {
|
|
2578
|
+
primary: "#BD93F9",
|
|
2579
|
+
secondary: "#FF79C6",
|
|
2580
|
+
background: "#282A36",
|
|
2581
|
+
surface: "#343746",
|
|
2582
|
+
elevatedSurface: "#44475A",
|
|
2583
|
+
text: "#F8F8F2",
|
|
2584
|
+
muted: "#6272A4",
|
|
2585
|
+
accent: "#8BE9FD",
|
|
2586
|
+
border: "#44475A",
|
|
2587
|
+
divider: "#6272A4",
|
|
2588
|
+
success: "#50FA7B",
|
|
2589
|
+
warning: "#F1FA8C",
|
|
2590
|
+
danger: "#FF5555",
|
|
2591
|
+
info: "#8BE9FD"
|
|
2592
|
+
},
|
|
2593
|
+
typography: {
|
|
2594
|
+
headingFont: "Outfit, Inter, sans-serif",
|
|
2595
|
+
bodyFont: "Inter, sans-serif",
|
|
2596
|
+
codeFont: "Fira Code, JetBrains Mono, monospace",
|
|
2597
|
+
sizes: {
|
|
2598
|
+
display: 56,
|
|
2599
|
+
h1: 44,
|
|
2600
|
+
h2: 36,
|
|
2601
|
+
h3: 28,
|
|
2602
|
+
h4: 22,
|
|
2603
|
+
body: 18,
|
|
2604
|
+
small: 14,
|
|
2605
|
+
caption: 12,
|
|
2606
|
+
code: 16,
|
|
2607
|
+
quote: 20,
|
|
2608
|
+
metadata: 12
|
|
2609
|
+
},
|
|
2610
|
+
weights: {
|
|
2611
|
+
normal: 400,
|
|
2612
|
+
medium: 500,
|
|
2613
|
+
bold: 700
|
|
2614
|
+
},
|
|
2615
|
+
lineHeights: {
|
|
2616
|
+
tight: 1.15,
|
|
2617
|
+
snug: 1.3,
|
|
2618
|
+
normal: 1.55,
|
|
2619
|
+
relaxed: 1.7
|
|
2620
|
+
},
|
|
2621
|
+
letterSpacing: {
|
|
2622
|
+
tight: "-0.02em",
|
|
2623
|
+
normal: "0em",
|
|
2624
|
+
wide: "0.03em"
|
|
2625
|
+
}
|
|
2626
|
+
},
|
|
2627
|
+
spacing: {
|
|
2628
|
+
unit: 8,
|
|
2629
|
+
scale: [0, 4, 8, 12, 16, 24, 32, 48, 64, 96],
|
|
2630
|
+
slidePadding: 48,
|
|
2631
|
+
elementGap: 24,
|
|
2632
|
+
safeArea: { top: 48, bottom: 48, left: 48, right: 48 }
|
|
2633
|
+
},
|
|
2634
|
+
radius: {
|
|
2635
|
+
none: 0,
|
|
2636
|
+
sm: 4,
|
|
2637
|
+
md: 10,
|
|
2638
|
+
lg: 16,
|
|
2639
|
+
xl: 24,
|
|
2640
|
+
full: 9999,
|
|
2641
|
+
default: 10
|
|
2642
|
+
},
|
|
2643
|
+
shadows: {
|
|
2644
|
+
none: "none",
|
|
2645
|
+
sm: "0 2px 5px rgba(0, 0, 0, 0.3)",
|
|
2646
|
+
md: "0 8px 16px rgba(0, 0, 0, 0.45)",
|
|
2647
|
+
lg: "0 16px 32px rgba(0, 0, 0, 0.6)",
|
|
2648
|
+
glow: "0 0 20px rgba(189, 147, 249, 0.4)"
|
|
2649
|
+
},
|
|
2650
|
+
components: {
|
|
2651
|
+
card: {
|
|
2652
|
+
background: "#343746",
|
|
2653
|
+
borderColor: "#BD93F9",
|
|
2654
|
+
borderRadius: 12,
|
|
2655
|
+
padding: 24
|
|
2656
|
+
},
|
|
2657
|
+
metric: {
|
|
2658
|
+
valueColor: "#FF79C6",
|
|
2659
|
+
labelColor: "#6272A4",
|
|
2660
|
+
borderRadius: 12
|
|
2661
|
+
},
|
|
2662
|
+
code: {
|
|
2663
|
+
background: "#1E1F29",
|
|
2664
|
+
textColor: "#F8F8F2",
|
|
2665
|
+
borderRadius: 8
|
|
2666
|
+
},
|
|
2667
|
+
table: {
|
|
2668
|
+
headerBackground: "#44475A",
|
|
2669
|
+
rowAlternateBackground: "#343746",
|
|
2670
|
+
borderColor: "#6272A4"
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
};
|
|
2674
|
+
var tokyoNightTheme = {
|
|
2675
|
+
name: "tokyo-night",
|
|
2676
|
+
description: "Sleek Tokyo Night neon indigo theme with cyan, violet and magenta tones",
|
|
2677
|
+
colors: {
|
|
2678
|
+
primary: "#7AA2F7",
|
|
2679
|
+
secondary: "#BB9AF7",
|
|
2680
|
+
background: "#1A1B26",
|
|
2681
|
+
surface: "#24283B",
|
|
2682
|
+
elevatedSurface: "#2F354A",
|
|
2683
|
+
text: "#C0CAF5",
|
|
2684
|
+
muted: "#565F89",
|
|
2685
|
+
accent: "#7DCFFF",
|
|
2686
|
+
border: "#2F354A",
|
|
2687
|
+
divider: "#414868",
|
|
2688
|
+
success: "#9ECE6A",
|
|
2689
|
+
warning: "#E0AF68",
|
|
2690
|
+
danger: "#F7768E",
|
|
2691
|
+
info: "#7DCFFF"
|
|
2692
|
+
},
|
|
2693
|
+
typography: {
|
|
2694
|
+
headingFont: "Outfit, Inter, sans-serif",
|
|
2695
|
+
bodyFont: "Inter, sans-serif",
|
|
2696
|
+
codeFont: "JetBrains Mono, monospace",
|
|
2697
|
+
sizes: {
|
|
2698
|
+
display: 58,
|
|
2699
|
+
h1: 46,
|
|
2700
|
+
h2: 36,
|
|
2701
|
+
h3: 28,
|
|
2702
|
+
h4: 22,
|
|
2703
|
+
body: 18,
|
|
2704
|
+
small: 14,
|
|
2705
|
+
caption: 12,
|
|
2706
|
+
code: 16,
|
|
2707
|
+
quote: 20,
|
|
2708
|
+
metadata: 12
|
|
2709
|
+
},
|
|
2710
|
+
weights: {
|
|
2711
|
+
normal: 400,
|
|
2712
|
+
medium: 500,
|
|
2713
|
+
bold: 700
|
|
2714
|
+
},
|
|
2715
|
+
lineHeights: {
|
|
2716
|
+
tight: 1.15,
|
|
2717
|
+
snug: 1.3,
|
|
2718
|
+
normal: 1.55,
|
|
2719
|
+
relaxed: 1.7
|
|
2720
|
+
},
|
|
2721
|
+
letterSpacing: {
|
|
2722
|
+
tight: "-0.02em",
|
|
2723
|
+
normal: "0em",
|
|
2724
|
+
wide: "0.03em"
|
|
2725
|
+
}
|
|
2726
|
+
},
|
|
2727
|
+
spacing: {
|
|
2728
|
+
unit: 8,
|
|
2729
|
+
scale: [0, 4, 8, 12, 16, 24, 32, 48, 64, 96],
|
|
2730
|
+
slidePadding: 48,
|
|
2731
|
+
elementGap: 24,
|
|
2732
|
+
safeArea: { top: 48, bottom: 48, left: 48, right: 48 }
|
|
2733
|
+
},
|
|
2734
|
+
radius: {
|
|
2735
|
+
none: 0,
|
|
2736
|
+
sm: 6,
|
|
2737
|
+
md: 10,
|
|
2738
|
+
lg: 16,
|
|
2739
|
+
xl: 24,
|
|
2740
|
+
full: 9999,
|
|
2741
|
+
default: 10
|
|
2742
|
+
},
|
|
2743
|
+
shadows: {
|
|
2744
|
+
none: "none",
|
|
2745
|
+
sm: "0 2px 4px rgba(0, 0, 0, 0.3)",
|
|
2746
|
+
md: "0 6px 14px rgba(0, 0, 0, 0.45)",
|
|
2747
|
+
lg: "0 14px 28px rgba(0, 0, 0, 0.6)",
|
|
2748
|
+
glow: "0 0 18px rgba(122, 162, 247, 0.4)"
|
|
2749
|
+
},
|
|
2750
|
+
components: {
|
|
2751
|
+
card: {
|
|
2752
|
+
background: "#24283B",
|
|
2753
|
+
borderColor: "#7AA2F7",
|
|
2754
|
+
borderRadius: 12,
|
|
2755
|
+
padding: 24
|
|
2756
|
+
},
|
|
2757
|
+
metric: {
|
|
2758
|
+
valueColor: "#7AA2F7",
|
|
2759
|
+
labelColor: "#565F89",
|
|
2760
|
+
borderRadius: 12
|
|
2761
|
+
},
|
|
2762
|
+
code: {
|
|
2763
|
+
background: "#16161E",
|
|
2764
|
+
textColor: "#C0CAF5",
|
|
2765
|
+
borderRadius: 8
|
|
2766
|
+
},
|
|
2767
|
+
table: {
|
|
2768
|
+
headerBackground: "#2F354A",
|
|
2769
|
+
rowAlternateBackground: "#24283B",
|
|
2770
|
+
borderColor: "#414868"
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
};
|
|
2774
|
+
var emeraldTheme = {
|
|
2775
|
+
name: "emerald",
|
|
2776
|
+
description: "Deep forest luxury green with mint and emerald highlights",
|
|
2777
|
+
colors: {
|
|
2778
|
+
primary: "#10B981",
|
|
2779
|
+
secondary: "#34D399",
|
|
2780
|
+
background: "#022C22",
|
|
2781
|
+
surface: "#064E3B",
|
|
2782
|
+
elevatedSurface: "#065F46",
|
|
2783
|
+
text: "#ECFDF5",
|
|
2784
|
+
muted: "#6EE7B7",
|
|
2785
|
+
accent: "#A7F3D0",
|
|
2786
|
+
border: "#047857",
|
|
2787
|
+
divider: "#065F46",
|
|
2788
|
+
success: "#34D399",
|
|
2789
|
+
warning: "#FBBF24",
|
|
2790
|
+
danger: "#F87171",
|
|
2791
|
+
info: "#38BDF8"
|
|
2792
|
+
},
|
|
2793
|
+
typography: {
|
|
2794
|
+
headingFont: "Outfit, Inter, sans-serif",
|
|
2795
|
+
bodyFont: "Inter, sans-serif",
|
|
2796
|
+
codeFont: "JetBrains Mono, monospace",
|
|
2797
|
+
sizes: {
|
|
2798
|
+
display: 56,
|
|
2799
|
+
h1: 44,
|
|
2800
|
+
h2: 36,
|
|
2801
|
+
h3: 28,
|
|
2802
|
+
h4: 22,
|
|
2803
|
+
body: 18,
|
|
2804
|
+
small: 14,
|
|
2805
|
+
caption: 12,
|
|
2806
|
+
code: 16,
|
|
2807
|
+
quote: 20,
|
|
2808
|
+
metadata: 12
|
|
2809
|
+
},
|
|
2810
|
+
weights: {
|
|
2811
|
+
normal: 400,
|
|
2812
|
+
medium: 500,
|
|
2813
|
+
bold: 700
|
|
2814
|
+
},
|
|
2815
|
+
lineHeights: {
|
|
2816
|
+
tight: 1.15,
|
|
2817
|
+
snug: 1.3,
|
|
2818
|
+
normal: 1.55,
|
|
2819
|
+
relaxed: 1.7
|
|
2820
|
+
},
|
|
2821
|
+
letterSpacing: {
|
|
2822
|
+
tight: "-0.02em",
|
|
2823
|
+
normal: "0em",
|
|
2824
|
+
wide: "0.03em"
|
|
2825
|
+
}
|
|
2826
|
+
},
|
|
2827
|
+
spacing: {
|
|
2828
|
+
unit: 8,
|
|
2829
|
+
scale: [0, 4, 8, 12, 16, 24, 32, 48, 64, 96],
|
|
2830
|
+
slidePadding: 48,
|
|
2831
|
+
elementGap: 24,
|
|
2832
|
+
safeArea: { top: 48, bottom: 48, left: 48, right: 48 }
|
|
2833
|
+
},
|
|
2834
|
+
radius: {
|
|
2835
|
+
none: 0,
|
|
2836
|
+
sm: 4,
|
|
2837
|
+
md: 8,
|
|
2838
|
+
lg: 16,
|
|
2839
|
+
xl: 24,
|
|
2840
|
+
full: 9999,
|
|
2841
|
+
default: 8
|
|
2842
|
+
},
|
|
2843
|
+
shadows: {
|
|
2844
|
+
none: "none",
|
|
2845
|
+
sm: "0 2px 4px rgba(0, 0, 0, 0.3)",
|
|
2846
|
+
md: "0 6px 14px rgba(0, 0, 0, 0.45)",
|
|
2847
|
+
lg: "0 14px 28px rgba(0, 0, 0, 0.6)",
|
|
2848
|
+
glow: "0 0 18px rgba(16, 185, 129, 0.4)"
|
|
2849
|
+
},
|
|
2850
|
+
components: {
|
|
2851
|
+
card: {
|
|
2852
|
+
background: "#064E3B",
|
|
2853
|
+
borderColor: "#10B981",
|
|
2854
|
+
borderRadius: 12,
|
|
2855
|
+
padding: 24
|
|
2856
|
+
},
|
|
2857
|
+
metric: {
|
|
2858
|
+
valueColor: "#10B981",
|
|
2859
|
+
labelColor: "#6EE7B7",
|
|
2860
|
+
borderRadius: 12
|
|
2861
|
+
},
|
|
2862
|
+
code: {
|
|
2863
|
+
background: "#011A14",
|
|
2864
|
+
textColor: "#ECFDF5",
|
|
2865
|
+
borderRadius: 8
|
|
2866
|
+
},
|
|
2867
|
+
table: {
|
|
2868
|
+
headerBackground: "#065F46",
|
|
2869
|
+
rowAlternateBackground: "#064E3B",
|
|
2870
|
+
borderColor: "#047857"
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
};
|
|
2874
|
+
var synthwaveTheme = {
|
|
2875
|
+
name: "synthwave",
|
|
2876
|
+
description: "80s retro neon sunset with hot pink, glowing cyan and electric violet",
|
|
2877
|
+
colors: {
|
|
2878
|
+
primary: "#FF71CE",
|
|
2879
|
+
secondary: "#01CDFE",
|
|
2880
|
+
background: "#1A0E2E",
|
|
2881
|
+
surface: "#261447",
|
|
2882
|
+
elevatedSurface: "#351B63",
|
|
2883
|
+
text: "#FFFFFF",
|
|
2884
|
+
muted: "#B967FF",
|
|
2885
|
+
accent: "#05FFA1",
|
|
2886
|
+
border: "#4D288C",
|
|
2887
|
+
divider: "#6432B8",
|
|
2888
|
+
success: "#05FFA1",
|
|
2889
|
+
warning: "#FFFB96",
|
|
2890
|
+
danger: "#FF2A6D",
|
|
2891
|
+
info: "#01CDFE"
|
|
2892
|
+
},
|
|
2893
|
+
typography: {
|
|
2894
|
+
headingFont: "Outfit, Inter, sans-serif",
|
|
2895
|
+
bodyFont: "Inter, sans-serif",
|
|
2896
|
+
codeFont: "Fira Code, monospace",
|
|
2897
|
+
sizes: {
|
|
2898
|
+
display: 58,
|
|
2899
|
+
h1: 46,
|
|
2900
|
+
h2: 38,
|
|
2901
|
+
h3: 28,
|
|
2902
|
+
h4: 22,
|
|
2903
|
+
body: 18,
|
|
2904
|
+
small: 14,
|
|
2905
|
+
caption: 12,
|
|
2906
|
+
code: 16,
|
|
2907
|
+
quote: 20,
|
|
2908
|
+
metadata: 12
|
|
2909
|
+
},
|
|
2910
|
+
weights: {
|
|
2911
|
+
normal: 400,
|
|
2912
|
+
medium: 500,
|
|
2913
|
+
bold: 700
|
|
2914
|
+
},
|
|
2915
|
+
lineHeights: {
|
|
2916
|
+
tight: 1.15,
|
|
2917
|
+
snug: 1.3,
|
|
2918
|
+
normal: 1.55,
|
|
2919
|
+
relaxed: 1.7
|
|
2920
|
+
},
|
|
2921
|
+
letterSpacing: {
|
|
2922
|
+
tight: "-0.02em",
|
|
2923
|
+
normal: "0em",
|
|
2924
|
+
wide: "0.04em"
|
|
2925
|
+
}
|
|
2926
|
+
},
|
|
2927
|
+
spacing: {
|
|
2928
|
+
unit: 8,
|
|
2929
|
+
scale: [0, 4, 8, 12, 16, 24, 32, 48, 64, 96],
|
|
2930
|
+
slidePadding: 48,
|
|
2931
|
+
elementGap: 24,
|
|
2932
|
+
safeArea: { top: 48, bottom: 48, left: 48, right: 48 }
|
|
2933
|
+
},
|
|
2934
|
+
radius: {
|
|
2935
|
+
none: 0,
|
|
2936
|
+
sm: 6,
|
|
2937
|
+
md: 12,
|
|
2938
|
+
lg: 18,
|
|
2939
|
+
xl: 26,
|
|
2940
|
+
full: 9999,
|
|
2941
|
+
default: 12
|
|
2942
|
+
},
|
|
2943
|
+
shadows: {
|
|
2944
|
+
none: "none",
|
|
2945
|
+
sm: "0 2px 6px rgba(0, 0, 0, 0.4)",
|
|
2946
|
+
md: "0 8px 18px rgba(0, 0, 0, 0.6)",
|
|
2947
|
+
lg: "0 16px 36px rgba(0, 0, 0, 0.75)",
|
|
2948
|
+
glow: "0 0 22px rgba(255, 113, 206, 0.5)"
|
|
2949
|
+
},
|
|
2950
|
+
components: {
|
|
2951
|
+
card: {
|
|
2952
|
+
background: "#261447",
|
|
2953
|
+
borderColor: "#FF71CE",
|
|
2954
|
+
borderRadius: 14,
|
|
2955
|
+
padding: 24
|
|
2956
|
+
},
|
|
2957
|
+
metric: {
|
|
2958
|
+
valueColor: "#FF71CE",
|
|
2959
|
+
labelColor: "#B967FF",
|
|
2960
|
+
borderRadius: 14
|
|
2961
|
+
},
|
|
2962
|
+
code: {
|
|
2963
|
+
background: "#11091F",
|
|
2964
|
+
textColor: "#05FFA1",
|
|
2965
|
+
borderRadius: 8
|
|
2966
|
+
},
|
|
2967
|
+
table: {
|
|
2968
|
+
headerBackground: "#351B63",
|
|
2969
|
+
rowAlternateBackground: "#261447",
|
|
2970
|
+
borderColor: "#4D288C"
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
};
|
|
2974
|
+
var THEME_REGISTRY = {
|
|
2975
|
+
default: defaultTheme,
|
|
2976
|
+
cyberpunk: cyberpunkTheme,
|
|
2977
|
+
minimal: minimalTheme,
|
|
2978
|
+
corporate: corporateTheme,
|
|
2979
|
+
terminal: terminalTheme,
|
|
2980
|
+
academic: academicTheme,
|
|
2981
|
+
nord: nordTheme,
|
|
2982
|
+
dracula: draculaTheme,
|
|
2983
|
+
"tokyo-night": tokyoNightTheme,
|
|
2984
|
+
tokyonight: tokyoNightTheme,
|
|
2985
|
+
midnight: tokyoNightTheme,
|
|
2986
|
+
emerald: emeraldTheme,
|
|
2987
|
+
forest: emeraldTheme,
|
|
2988
|
+
synthwave: synthwaveTheme,
|
|
2989
|
+
sunset: synthwaveTheme
|
|
2990
|
+
};
|
|
2991
|
+
function resolveTheme(themeNameOrRef, explicitOverrides) {
|
|
2992
|
+
const name = typeof themeNameOrRef === "string" ? themeNameOrRef : themeNameOrRef?.name || "default";
|
|
2993
|
+
const baseTheme = THEME_REGISTRY[name.toLowerCase()] || defaultTheme;
|
|
2994
|
+
const refOverrides = typeof themeNameOrRef === "object" ? themeNameOrRef.overrides : void 0;
|
|
2995
|
+
const mergedOverrides = {
|
|
2996
|
+
...refOverrides,
|
|
2997
|
+
...explicitOverrides,
|
|
2998
|
+
colors: { ...baseTheme.colors, ...refOverrides?.colors, ...explicitOverrides?.colors },
|
|
2999
|
+
typography: {
|
|
3000
|
+
...baseTheme.typography,
|
|
3001
|
+
...refOverrides?.typography,
|
|
3002
|
+
...explicitOverrides?.typography,
|
|
3003
|
+
sizes: {
|
|
3004
|
+
...baseTheme.typography.sizes,
|
|
3005
|
+
...refOverrides?.typography?.sizes,
|
|
3006
|
+
...explicitOverrides?.typography?.sizes
|
|
3007
|
+
},
|
|
3008
|
+
weights: {
|
|
3009
|
+
...baseTheme.typography.weights,
|
|
3010
|
+
...refOverrides?.typography?.weights,
|
|
3011
|
+
...explicitOverrides?.typography?.weights
|
|
3012
|
+
},
|
|
3013
|
+
lineHeights: {
|
|
3014
|
+
...baseTheme.typography.lineHeights,
|
|
3015
|
+
...refOverrides?.typography?.lineHeights,
|
|
3016
|
+
...explicitOverrides?.typography?.lineHeights
|
|
3017
|
+
}
|
|
3018
|
+
},
|
|
3019
|
+
spacing: {
|
|
3020
|
+
...baseTheme.spacing,
|
|
3021
|
+
...refOverrides?.spacing,
|
|
3022
|
+
...explicitOverrides?.spacing,
|
|
3023
|
+
safeArea: {
|
|
3024
|
+
...baseTheme.spacing.safeArea,
|
|
3025
|
+
...refOverrides?.spacing?.safeArea,
|
|
3026
|
+
...explicitOverrides?.spacing?.safeArea
|
|
1800
3027
|
}
|
|
1801
3028
|
},
|
|
1802
3029
|
radius: {
|
|
@@ -2248,6 +3475,174 @@ function lint(sourceOrPresentation, options) {
|
|
|
2248
3475
|
return defaultCompiler.lint(sourceOrPresentation, options);
|
|
2249
3476
|
}
|
|
2250
3477
|
|
|
3478
|
+
// ../renderer/dist/icons.js
|
|
3479
|
+
var BUILTIN_ICONS = {
|
|
3480
|
+
// Lucide & General
|
|
3481
|
+
rocket: {
|
|
3482
|
+
name: "rocket",
|
|
3483
|
+
provider: "lucide",
|
|
3484
|
+
viewBox: "0 0 24 24",
|
|
3485
|
+
path: '<path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/>'
|
|
3486
|
+
},
|
|
3487
|
+
code: {
|
|
3488
|
+
name: "code",
|
|
3489
|
+
provider: "lucide",
|
|
3490
|
+
viewBox: "0 0 24 24",
|
|
3491
|
+
path: '<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>'
|
|
3492
|
+
},
|
|
3493
|
+
terminal: {
|
|
3494
|
+
name: "terminal",
|
|
3495
|
+
provider: "lucide",
|
|
3496
|
+
viewBox: "0 0 24 24",
|
|
3497
|
+
path: '<polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/>'
|
|
3498
|
+
},
|
|
3499
|
+
cpu: {
|
|
3500
|
+
name: "cpu",
|
|
3501
|
+
provider: "lucide",
|
|
3502
|
+
viewBox: "0 0 24 24",
|
|
3503
|
+
path: '<rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><line x1="9" y1="1" x2="9" y2="4"/><line x1="15" y1="1" x2="15" y2="4"/><line x1="9" y1="20" x2="9" y2="23"/><line x1="15" y1="20" x2="15" y2="23"/><line x1="20" y1="9" x2="23" y2="9"/><line x1="20" y1="14" x2="23" y2="14"/><line x1="1" y1="9" x2="4" y2="9"/><line x1="1" y1="14" x2="4" y2="14"/>'
|
|
3504
|
+
},
|
|
3505
|
+
database: {
|
|
3506
|
+
name: "database",
|
|
3507
|
+
provider: "lucide",
|
|
3508
|
+
viewBox: "0 0 24 24",
|
|
3509
|
+
path: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/>'
|
|
3510
|
+
},
|
|
3511
|
+
zap: {
|
|
3512
|
+
name: "zap",
|
|
3513
|
+
provider: "lucide",
|
|
3514
|
+
viewBox: "0 0 24 24",
|
|
3515
|
+
path: '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>'
|
|
3516
|
+
},
|
|
3517
|
+
shield: {
|
|
3518
|
+
name: "shield",
|
|
3519
|
+
provider: "lucide",
|
|
3520
|
+
viewBox: "0 0 24 24",
|
|
3521
|
+
path: '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>'
|
|
3522
|
+
},
|
|
3523
|
+
activity: {
|
|
3524
|
+
name: "activity",
|
|
3525
|
+
provider: "lucide",
|
|
3526
|
+
viewBox: "0 0 24 24",
|
|
3527
|
+
path: '<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>'
|
|
3528
|
+
},
|
|
3529
|
+
palette: {
|
|
3530
|
+
name: "palette",
|
|
3531
|
+
provider: "lucide",
|
|
3532
|
+
viewBox: "0 0 24 24",
|
|
3533
|
+
path: '<circle cx="13.5" cy="6.5" r=".5"/><circle cx="17.5" cy="10.5" r=".5"/><circle cx="8.5" cy="7.5" r=".5"/><circle cx="6.5" cy="12.5" r=".5"/><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z"/>'
|
|
3534
|
+
},
|
|
3535
|
+
chart: {
|
|
3536
|
+
name: "chart",
|
|
3537
|
+
provider: "lucide",
|
|
3538
|
+
viewBox: "0 0 24 24",
|
|
3539
|
+
path: '<line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/>'
|
|
3540
|
+
},
|
|
3541
|
+
layers: {
|
|
3542
|
+
name: "layers",
|
|
3543
|
+
provider: "lucide",
|
|
3544
|
+
viewBox: "0 0 24 24",
|
|
3545
|
+
path: '<polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/>'
|
|
3546
|
+
},
|
|
3547
|
+
users: {
|
|
3548
|
+
name: "users",
|
|
3549
|
+
provider: "lucide",
|
|
3550
|
+
viewBox: "0 0 24 24",
|
|
3551
|
+
path: '<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>'
|
|
3552
|
+
},
|
|
3553
|
+
check: {
|
|
3554
|
+
name: "check",
|
|
3555
|
+
provider: "lucide",
|
|
3556
|
+
viewBox: "0 0 24 24",
|
|
3557
|
+
path: '<polyline points="20 6 9 17 4 12"/>'
|
|
3558
|
+
},
|
|
3559
|
+
"git-branch": {
|
|
3560
|
+
name: "git-branch",
|
|
3561
|
+
provider: "lucide",
|
|
3562
|
+
viewBox: "0 0 24 24",
|
|
3563
|
+
path: '<line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/>'
|
|
3564
|
+
},
|
|
3565
|
+
globe: {
|
|
3566
|
+
name: "globe",
|
|
3567
|
+
provider: "lucide",
|
|
3568
|
+
viewBox: "0 0 24 24",
|
|
3569
|
+
path: '<circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>'
|
|
3570
|
+
},
|
|
3571
|
+
sparkles: {
|
|
3572
|
+
name: "sparkles",
|
|
3573
|
+
provider: "lucide",
|
|
3574
|
+
viewBox: "0 0 24 24",
|
|
3575
|
+
path: '<path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/>'
|
|
3576
|
+
}
|
|
3577
|
+
};
|
|
3578
|
+
var IconResolver = class {
|
|
3579
|
+
cache = /* @__PURE__ */ new Map();
|
|
3580
|
+
customProviders = /* @__PURE__ */ new Map();
|
|
3581
|
+
constructor() {
|
|
3582
|
+
for (const [key, def] of Object.entries(BUILTIN_ICONS)) {
|
|
3583
|
+
this.cache.set(key, def);
|
|
3584
|
+
this.cache.set(`lucide:${key}`, def);
|
|
3585
|
+
this.cache.set(`material:${key}`, { ...def, provider: "material" });
|
|
3586
|
+
this.cache.set(`fa:${key}`, { ...def, provider: "fa" });
|
|
3587
|
+
this.cache.set(`tabler:${key}`, { ...def, provider: "tabler" });
|
|
3588
|
+
this.cache.set(`heroicons:${key}`, { ...def, provider: "heroicons" });
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
registerProvider(name, resolver) {
|
|
3592
|
+
this.customProviders.set(name.toLowerCase(), resolver);
|
|
3593
|
+
}
|
|
3594
|
+
resolve(rawName, options = {}) {
|
|
3595
|
+
const trimmed = rawName.trim();
|
|
3596
|
+
if (!trimmed) {
|
|
3597
|
+
return this.getFallback("unknown");
|
|
3598
|
+
}
|
|
3599
|
+
if (this.cache.has(trimmed.toLowerCase())) {
|
|
3600
|
+
return this.cache.get(trimmed.toLowerCase());
|
|
3601
|
+
}
|
|
3602
|
+
let provider = options.defaultProvider || "lucide";
|
|
3603
|
+
let iconName = trimmed;
|
|
3604
|
+
if (trimmed.includes(":")) {
|
|
3605
|
+
const parts = trimmed.split(":");
|
|
3606
|
+
provider = parts[0].toLowerCase();
|
|
3607
|
+
iconName = parts.slice(1).join(":").toLowerCase();
|
|
3608
|
+
}
|
|
3609
|
+
if (this.customProviders.has(provider)) {
|
|
3610
|
+
const customDef = this.customProviders.get(provider)(iconName);
|
|
3611
|
+
if (customDef) {
|
|
3612
|
+
this.cache.set(trimmed.toLowerCase(), customDef);
|
|
3613
|
+
return customDef;
|
|
3614
|
+
}
|
|
3615
|
+
}
|
|
3616
|
+
if (this.cache.has(iconName)) {
|
|
3617
|
+
const def = { ...this.cache.get(iconName), provider };
|
|
3618
|
+
this.cache.set(trimmed.toLowerCase(), def);
|
|
3619
|
+
return def;
|
|
3620
|
+
}
|
|
3621
|
+
if (options.strict) {
|
|
3622
|
+
throw new Error(`Icon '${trimmed}' not found in registry (provider: ${provider})`);
|
|
3623
|
+
}
|
|
3624
|
+
const fallback = this.getFallback(iconName, provider);
|
|
3625
|
+
this.cache.set(trimmed.toLowerCase(), fallback);
|
|
3626
|
+
return fallback;
|
|
3627
|
+
}
|
|
3628
|
+
getFallback(iconName, provider = "lucide") {
|
|
3629
|
+
const initial = iconName.charAt(0).toUpperCase() || "\u2605";
|
|
3630
|
+
return {
|
|
3631
|
+
name: iconName,
|
|
3632
|
+
provider,
|
|
3633
|
+
viewBox: "0 0 24 24",
|
|
3634
|
+
path: `<circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="2"/><text x="12" y="16" text-anchor="middle" font-size="11" font-weight="bold" fill="currentColor" font-family="sans-serif">${initial}</text>`
|
|
3635
|
+
};
|
|
3636
|
+
}
|
|
3637
|
+
toSvg(rawName, size = 24, color, className = "yumia-icon") {
|
|
3638
|
+
const icon = this.resolve(rawName);
|
|
3639
|
+
const fill = color ? `color="${color}"` : "";
|
|
3640
|
+
const style = color ? `style="color:${color}; fill:none; stroke:currentColor;"` : 'style="fill:none; stroke:currentColor;"';
|
|
3641
|
+
return `<svg class="${className}" width="${size}" height="${size}" viewBox="${icon.viewBox}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ${fill} ${style}>${icon.path}</svg>`;
|
|
3642
|
+
}
|
|
3643
|
+
};
|
|
3644
|
+
var defaultIconResolver = new IconResolver();
|
|
3645
|
+
|
|
2251
3646
|
// ../renderer-pptx/dist/renderer.js
|
|
2252
3647
|
import pptxgen from "pptxgenjs";
|
|
2253
3648
|
var CSS_NAMED_COLORS = {
|
|
@@ -2294,6 +3689,8 @@ function cleanFontFace(fontString) {
|
|
|
2294
3689
|
return "Segoe UI";
|
|
2295
3690
|
}
|
|
2296
3691
|
function parseInlineMarkdown(rawText, baseOptions) {
|
|
3692
|
+
if (!rawText)
|
|
3693
|
+
return [];
|
|
2297
3694
|
const chunks = [];
|
|
2298
3695
|
const regex = /(\*\*.*?\*\*|\*.*?\*|`.*?`)/g;
|
|
2299
3696
|
const parts = rawText.split(regex);
|
|
@@ -2356,7 +3753,7 @@ var PptxRenderer = class {
|
|
|
2356
3753
|
pptxSlide.background = { color: bgColor };
|
|
2357
3754
|
const slideLayout = this.layoutEngine.computeSlide(slide, pixelViewport);
|
|
2358
3755
|
for (const node of slideLayout.nodes) {
|
|
2359
|
-
this.renderNode(pptxSlide, pptx, node, scaleX, scaleY, theme);
|
|
3756
|
+
this.renderNode(pptxSlide, pptx, node, scaleX, scaleY, theme, presentation);
|
|
2360
3757
|
}
|
|
2361
3758
|
if (slide.notes) {
|
|
2362
3759
|
pptxSlide.addNotes(slide.notes);
|
|
@@ -2371,7 +3768,7 @@ var PptxRenderer = class {
|
|
|
2371
3768
|
fileName: `${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}.pptx`
|
|
2372
3769
|
};
|
|
2373
3770
|
}
|
|
2374
|
-
renderNode(pptxSlide, pptx, node, scaleX, scaleY, theme) {
|
|
3771
|
+
renderNode(pptxSlide, pptx, node, scaleX, scaleY, theme, presentation) {
|
|
2375
3772
|
const { element, bounds } = node;
|
|
2376
3773
|
const rect = this.toInches(bounds, scaleX, scaleY);
|
|
2377
3774
|
switch (element.type) {
|
|
@@ -2400,10 +3797,10 @@ var PptxRenderer = class {
|
|
|
2400
3797
|
this.renderMetric(pptxSlide, pptx, node, scaleX, scaleY, theme);
|
|
2401
3798
|
break;
|
|
2402
3799
|
case "card":
|
|
2403
|
-
this.renderCard(pptxSlide, pptx, node, scaleX, scaleY, theme);
|
|
3800
|
+
this.renderCard(pptxSlide, pptx, node, scaleX, scaleY, theme, presentation);
|
|
2404
3801
|
break;
|
|
2405
3802
|
case "columns":
|
|
2406
|
-
this.renderColumns(pptxSlide, pptx, node, scaleX, scaleY, theme);
|
|
3803
|
+
this.renderColumns(pptxSlide, pptx, node, scaleX, scaleY, theme, presentation);
|
|
2407
3804
|
break;
|
|
2408
3805
|
case "badge":
|
|
2409
3806
|
this.renderBadge(pptxSlide, pptx, element, rect, theme);
|
|
@@ -2417,12 +3814,42 @@ var PptxRenderer = class {
|
|
|
2417
3814
|
case "compare":
|
|
2418
3815
|
this.renderCompare(pptxSlide, pptx, node, scaleX, scaleY, theme);
|
|
2419
3816
|
break;
|
|
3817
|
+
case "section":
|
|
3818
|
+
this.renderSection(pptxSlide, pptx, element, rect, theme);
|
|
3819
|
+
break;
|
|
3820
|
+
case "toc":
|
|
3821
|
+
this.renderToc(pptxSlide, pptx, element, rect, theme, presentation);
|
|
3822
|
+
break;
|
|
2420
3823
|
case "mermaid":
|
|
2421
3824
|
this.renderMermaid(pptxSlide, pptx, element, rect, theme);
|
|
2422
3825
|
break;
|
|
2423
3826
|
case "math":
|
|
2424
3827
|
this.renderMath(pptxSlide, pptx, element, rect, theme);
|
|
2425
3828
|
break;
|
|
3829
|
+
case "icon": {
|
|
3830
|
+
const ic = element;
|
|
3831
|
+
const iconName = ic.name.replace(/^[^:]+:/, "").toUpperCase();
|
|
3832
|
+
pptxSlide.addText(`\u2605 ${iconName}`, {
|
|
3833
|
+
x: rect.x,
|
|
3834
|
+
y: rect.y,
|
|
3835
|
+
w: Math.max(rect.w, 1.5),
|
|
3836
|
+
h: Math.max(rect.h, 0.4),
|
|
3837
|
+
fontSize: 14,
|
|
3838
|
+
bold: true,
|
|
3839
|
+
color: this.cleanHexColor(theme.colors.primary),
|
|
3840
|
+
valign: "middle"
|
|
3841
|
+
});
|
|
3842
|
+
break;
|
|
3843
|
+
}
|
|
3844
|
+
case "grid":
|
|
3845
|
+
case "stack": {
|
|
3846
|
+
if (node.children) {
|
|
3847
|
+
for (const childNode of node.children) {
|
|
3848
|
+
this.renderNode(pptxSlide, pptx, childNode, scaleX, scaleY, theme, presentation);
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
break;
|
|
3852
|
+
}
|
|
2426
3853
|
default:
|
|
2427
3854
|
break;
|
|
2428
3855
|
}
|
|
@@ -2636,7 +4063,7 @@ var PptxRenderer = class {
|
|
|
2636
4063
|
});
|
|
2637
4064
|
}
|
|
2638
4065
|
}
|
|
2639
|
-
renderCard(pptxSlide, pptx, node, scaleX, scaleY, theme) {
|
|
4066
|
+
renderCard(pptxSlide, pptx, node, scaleX, scaleY, theme, presentation) {
|
|
2640
4067
|
const card = node.element;
|
|
2641
4068
|
const rect = this.toInches(node.bounds, scaleX, scaleY);
|
|
2642
4069
|
const cardTheme = theme.components?.card;
|
|
@@ -2657,6 +4084,14 @@ var PptxRenderer = class {
|
|
|
2657
4084
|
line: { color: borderColor, width: 1.5 },
|
|
2658
4085
|
rectRadius: 0.08
|
|
2659
4086
|
});
|
|
4087
|
+
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
4088
|
+
x: rect.x + 0.02,
|
|
4089
|
+
y: rect.y + 0.04,
|
|
4090
|
+
w: 0.06,
|
|
4091
|
+
h: rect.h - 0.08,
|
|
4092
|
+
fill: { color: borderColor },
|
|
4093
|
+
rectRadius: 0.03
|
|
4094
|
+
});
|
|
2660
4095
|
if (card.title) {
|
|
2661
4096
|
pptxSlide.addText(card.title, {
|
|
2662
4097
|
x: rect.x + 0.25,
|
|
@@ -2671,16 +4106,16 @@ var PptxRenderer = class {
|
|
|
2671
4106
|
}
|
|
2672
4107
|
if (node.children) {
|
|
2673
4108
|
for (const childNode of node.children) {
|
|
2674
|
-
this.renderNode(pptxSlide, pptx, childNode, scaleX, scaleY, theme);
|
|
4109
|
+
this.renderNode(pptxSlide, pptx, childNode, scaleX, scaleY, theme, presentation);
|
|
2675
4110
|
}
|
|
2676
4111
|
}
|
|
2677
4112
|
}
|
|
2678
|
-
renderColumns(pptxSlide, pptx, node, scaleX, scaleY, theme) {
|
|
4113
|
+
renderColumns(pptxSlide, pptx, node, scaleX, scaleY, theme, presentation) {
|
|
2679
4114
|
if (node.children) {
|
|
2680
4115
|
for (const colNode of node.children) {
|
|
2681
4116
|
if (colNode.children) {
|
|
2682
4117
|
for (const itemNode of colNode.children) {
|
|
2683
|
-
this.renderNode(pptxSlide, pptx, itemNode, scaleX, scaleY, theme);
|
|
4118
|
+
this.renderNode(pptxSlide, pptx, itemNode, scaleX, scaleY, theme, presentation);
|
|
2684
4119
|
}
|
|
2685
4120
|
}
|
|
2686
4121
|
}
|
|
@@ -2688,26 +4123,88 @@ var PptxRenderer = class {
|
|
|
2688
4123
|
}
|
|
2689
4124
|
renderCode(pptxSlide, pptx, code, rect, theme) {
|
|
2690
4125
|
const codeTheme = theme.components?.code;
|
|
2691
|
-
const bgColor = this.cleanHexColor(codeTheme?.background || "#
|
|
4126
|
+
const bgColor = this.cleanHexColor(codeTheme?.background || "#0a0f1d");
|
|
2692
4127
|
const textColor = this.cleanHexColor(codeTheme?.textColor || "#f8fafc");
|
|
4128
|
+
const primaryColor = this.cleanHexColor(theme.colors.primary || "#00F0FF");
|
|
4129
|
+
const mutedColor = this.cleanHexColor(theme.colors.muted || "#64748b");
|
|
2693
4130
|
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
2694
4131
|
x: rect.x,
|
|
2695
4132
|
y: rect.y,
|
|
2696
4133
|
w: rect.w,
|
|
2697
4134
|
h: rect.h,
|
|
2698
4135
|
fill: { color: bgColor },
|
|
4136
|
+
line: { color: this.cleanHexColor(theme.colors.border || "#1e293b"), width: 1 },
|
|
2699
4137
|
rectRadius: 0.05
|
|
2700
4138
|
});
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
4139
|
+
const lines = code.code.split("\n");
|
|
4140
|
+
if (code.highlight) {
|
|
4141
|
+
const highlightSet = /* @__PURE__ */ new Set();
|
|
4142
|
+
const parts = code.highlight.split(",");
|
|
4143
|
+
for (const part of parts) {
|
|
4144
|
+
const trimmed = part.trim();
|
|
4145
|
+
if (!trimmed)
|
|
4146
|
+
continue;
|
|
4147
|
+
if (trimmed.includes("-")) {
|
|
4148
|
+
const [startStr, endStr] = trimmed.split("-");
|
|
4149
|
+
const start = parseInt(startStr || "0", 10);
|
|
4150
|
+
const end = parseInt(endStr || "0", 10);
|
|
4151
|
+
if (!isNaN(start) && !isNaN(end) && start <= end) {
|
|
4152
|
+
for (let n = start; n <= end; n++)
|
|
4153
|
+
highlightSet.add(n);
|
|
4154
|
+
}
|
|
4155
|
+
} else {
|
|
4156
|
+
const num = parseInt(trimmed, 10);
|
|
4157
|
+
if (!isNaN(num))
|
|
4158
|
+
highlightSet.add(num);
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
const chunks = [];
|
|
4162
|
+
lines.forEach((line, idx) => {
|
|
4163
|
+
const lineNum = idx + 1;
|
|
4164
|
+
const isHl = highlightSet.has(lineNum);
|
|
4165
|
+
const lineNumPad = String(lineNum).padStart(2, "0");
|
|
4166
|
+
const numColor = isHl ? primaryColor : mutedColor;
|
|
4167
|
+
const contentColor = isHl ? primaryColor : mutedColor;
|
|
4168
|
+
chunks.push({
|
|
4169
|
+
text: `${lineNumPad} `,
|
|
4170
|
+
options: {
|
|
4171
|
+
fontSize: 12,
|
|
4172
|
+
fontFace: "Consolas",
|
|
4173
|
+
color: numColor,
|
|
4174
|
+
bold: isHl
|
|
4175
|
+
}
|
|
4176
|
+
});
|
|
4177
|
+
chunks.push({
|
|
4178
|
+
text: line || " ",
|
|
4179
|
+
options: {
|
|
4180
|
+
fontSize: 12,
|
|
4181
|
+
fontFace: "Consolas",
|
|
4182
|
+
color: contentColor,
|
|
4183
|
+
bold: isHl,
|
|
4184
|
+
breakLine: idx < lines.length - 1
|
|
4185
|
+
}
|
|
4186
|
+
});
|
|
4187
|
+
});
|
|
4188
|
+
pptxSlide.addText(chunks, {
|
|
4189
|
+
x: rect.x + 0.2,
|
|
4190
|
+
y: rect.y + 0.15,
|
|
4191
|
+
w: rect.w - 0.4,
|
|
4192
|
+
h: rect.h - 0.3,
|
|
4193
|
+
valign: "top",
|
|
4194
|
+
margin: 0
|
|
4195
|
+
});
|
|
4196
|
+
} else {
|
|
4197
|
+
pptxSlide.addText(code.code, {
|
|
4198
|
+
x: rect.x + 0.2,
|
|
4199
|
+
y: rect.y + 0.15,
|
|
4200
|
+
w: rect.w - 0.4,
|
|
4201
|
+
h: rect.h - 0.3,
|
|
4202
|
+
fontSize: 13,
|
|
4203
|
+
fontFace: "Consolas",
|
|
4204
|
+
color: textColor,
|
|
4205
|
+
valign: "top"
|
|
4206
|
+
});
|
|
4207
|
+
}
|
|
2711
4208
|
}
|
|
2712
4209
|
renderQuote(pptxSlide, pptx, quote, rect, theme) {
|
|
2713
4210
|
const accentColor = this.cleanHexColor(theme.colors.accent || theme.colors.primary);
|
|
@@ -2734,7 +4231,8 @@ var PptxRenderer = class {
|
|
|
2734
4231
|
renderBadge(pptxSlide, pptx, badge, rect, theme) {
|
|
2735
4232
|
const colorKey = badge.variant || "primary";
|
|
2736
4233
|
const badgeColor = this.cleanHexColor(theme.colors[colorKey] || theme.colors.primary);
|
|
2737
|
-
const
|
|
4234
|
+
const badgeText = badge.text;
|
|
4235
|
+
const badgeW = Math.min(2.5, Math.max(1, badgeText.length * 0.12 + 0.4));
|
|
2738
4236
|
const badgeH = Math.min(0.38, rect.h);
|
|
2739
4237
|
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
2740
4238
|
x: rect.x,
|
|
@@ -2745,7 +4243,7 @@ var PptxRenderer = class {
|
|
|
2745
4243
|
line: { color: badgeColor, width: 1.5 },
|
|
2746
4244
|
rectRadius: 0.15
|
|
2747
4245
|
});
|
|
2748
|
-
pptxSlide.addText(
|
|
4246
|
+
pptxSlide.addText(badgeText.toUpperCase(), {
|
|
2749
4247
|
x: rect.x,
|
|
2750
4248
|
y: rect.y,
|
|
2751
4249
|
w: badgeW,
|
|
@@ -2853,9 +4351,10 @@ var PptxRenderer = class {
|
|
|
2853
4351
|
align: "center"
|
|
2854
4352
|
});
|
|
2855
4353
|
}
|
|
4354
|
+
const cleanTitle = item.title;
|
|
2856
4355
|
const descText = item.description ? `
|
|
2857
4356
|
${item.description}` : "";
|
|
2858
|
-
pptxSlide.addText(`${
|
|
4357
|
+
pptxSlide.addText(`${cleanTitle}${descText}`, {
|
|
2859
4358
|
x: itemX + 0.05,
|
|
2860
4359
|
y: lineY + 0.45,
|
|
2861
4360
|
w: itemW - 0.1,
|
|
@@ -2879,7 +4378,7 @@ ${item.description}` : "";
|
|
|
2879
4378
|
w: colW,
|
|
2880
4379
|
h: rect.h,
|
|
2881
4380
|
fill: { color: this.cleanHexColor(theme.colors.surface) },
|
|
2882
|
-
line: { color: this.cleanHexColor(theme.colors.border), width: 1 },
|
|
4381
|
+
line: { color: this.cleanHexColor(theme.colors.border), width: 1.5 },
|
|
2883
4382
|
rectRadius: 0.1
|
|
2884
4383
|
});
|
|
2885
4384
|
if (compare.leftTitle) {
|
|
@@ -2888,7 +4387,7 @@ ${item.description}` : "";
|
|
|
2888
4387
|
y: rect.y + 0.15,
|
|
2889
4388
|
w: colW - 0.3,
|
|
2890
4389
|
h: 0.4,
|
|
2891
|
-
fontSize:
|
|
4390
|
+
fontSize: 15,
|
|
2892
4391
|
bold: true,
|
|
2893
4392
|
color: this.cleanHexColor(theme.colors.primary),
|
|
2894
4393
|
fontFace: cleanFontFace(theme.typography.headingFont)
|
|
@@ -2901,7 +4400,7 @@ ${item.description}` : "";
|
|
|
2901
4400
|
w: colW,
|
|
2902
4401
|
h: rect.h,
|
|
2903
4402
|
fill: { color: this.cleanHexColor(theme.colors.surface) },
|
|
2904
|
-
line: { color: this.cleanHexColor(theme.colors.border), width: 1 },
|
|
4403
|
+
line: { color: this.cleanHexColor(theme.colors.border), width: 1.5 },
|
|
2905
4404
|
rectRadius: 0.1
|
|
2906
4405
|
});
|
|
2907
4406
|
if (compare.rightTitle) {
|
|
@@ -2910,12 +4409,222 @@ ${item.description}` : "";
|
|
|
2910
4409
|
y: rect.y + 0.15,
|
|
2911
4410
|
w: colW - 0.3,
|
|
2912
4411
|
h: 0.4,
|
|
2913
|
-
fontSize:
|
|
4412
|
+
fontSize: 15,
|
|
2914
4413
|
bold: true,
|
|
2915
4414
|
color: this.cleanHexColor(theme.colors.primary),
|
|
2916
4415
|
fontFace: cleanFontFace(theme.typography.headingFont)
|
|
2917
4416
|
});
|
|
2918
4417
|
}
|
|
4418
|
+
const vsX = rect.x + colW + 0.05;
|
|
4419
|
+
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
4420
|
+
x: vsX,
|
|
4421
|
+
y: rect.y + rect.h / 2 - 0.18,
|
|
4422
|
+
w: 0.3,
|
|
4423
|
+
h: 0.3,
|
|
4424
|
+
fill: { color: this.cleanHexColor(theme.colors.border || "#334155") },
|
|
4425
|
+
rectRadius: 0.15
|
|
4426
|
+
});
|
|
4427
|
+
pptxSlide.addText("VS", {
|
|
4428
|
+
x: vsX,
|
|
4429
|
+
y: rect.y + rect.h / 2 - 0.18,
|
|
4430
|
+
w: 0.3,
|
|
4431
|
+
h: 0.3,
|
|
4432
|
+
fontSize: 10,
|
|
4433
|
+
bold: true,
|
|
4434
|
+
color: this.cleanHexColor(theme.colors.muted || "#94a3b8"),
|
|
4435
|
+
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
4436
|
+
align: "center",
|
|
4437
|
+
valign: "middle"
|
|
4438
|
+
});
|
|
4439
|
+
}
|
|
4440
|
+
renderSection(pptxSlide, pptx, section, rect, theme) {
|
|
4441
|
+
const cardBg = this.cleanHexColor(theme.colors.surface || "#0f172a");
|
|
4442
|
+
const primaryHex = this.cleanHexColor(theme.colors.primary || "#00F0FF");
|
|
4443
|
+
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
4444
|
+
x: rect.x,
|
|
4445
|
+
y: rect.y,
|
|
4446
|
+
w: rect.w,
|
|
4447
|
+
h: rect.h,
|
|
4448
|
+
fill: { color: cardBg },
|
|
4449
|
+
line: { color: primaryHex, width: 2 },
|
|
4450
|
+
rectRadius: 0.1
|
|
4451
|
+
});
|
|
4452
|
+
if (section.number !== void 0) {
|
|
4453
|
+
const numStr = String(section.number);
|
|
4454
|
+
const pillW = Math.min(2.4, Math.max(1.4, numStr.length * 0.15 + 0.8));
|
|
4455
|
+
const pillX = rect.x + (rect.w - pillW) / 2;
|
|
4456
|
+
const pillY = rect.y + 0.35;
|
|
4457
|
+
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
4458
|
+
x: pillX,
|
|
4459
|
+
y: pillY,
|
|
4460
|
+
w: pillW,
|
|
4461
|
+
h: 0.36,
|
|
4462
|
+
fill: { color: primaryHex },
|
|
4463
|
+
rectRadius: 0.18
|
|
4464
|
+
});
|
|
4465
|
+
pptxSlide.addText(`SECTION ${numStr}`.toUpperCase(), {
|
|
4466
|
+
x: pillX,
|
|
4467
|
+
y: pillY,
|
|
4468
|
+
w: pillW,
|
|
4469
|
+
h: 0.36,
|
|
4470
|
+
fontSize: 11,
|
|
4471
|
+
bold: true,
|
|
4472
|
+
color: "000000",
|
|
4473
|
+
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
4474
|
+
align: "center",
|
|
4475
|
+
valign: "middle"
|
|
4476
|
+
});
|
|
4477
|
+
}
|
|
4478
|
+
const titleY = section.number !== void 0 ? rect.y + 0.85 : rect.y + 0.45;
|
|
4479
|
+
pptxSlide.addText(section.title, {
|
|
4480
|
+
x: rect.x + 0.3,
|
|
4481
|
+
y: titleY,
|
|
4482
|
+
w: rect.w - 0.6,
|
|
4483
|
+
h: 0.85,
|
|
4484
|
+
fontSize: 28,
|
|
4485
|
+
bold: true,
|
|
4486
|
+
color: this.cleanHexColor(theme.colors.text || "#ffffff"),
|
|
4487
|
+
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
4488
|
+
align: "center",
|
|
4489
|
+
valign: "middle"
|
|
4490
|
+
});
|
|
4491
|
+
if (section.subtitle) {
|
|
4492
|
+
pptxSlide.addText(section.subtitle, {
|
|
4493
|
+
x: rect.x + 0.4,
|
|
4494
|
+
y: titleY + 0.85,
|
|
4495
|
+
w: rect.w - 0.8,
|
|
4496
|
+
h: 0.55,
|
|
4497
|
+
fontSize: 15,
|
|
4498
|
+
color: this.cleanHexColor(theme.colors.muted || "#94a3b8"),
|
|
4499
|
+
fontFace: cleanFontFace(theme.typography.bodyFont),
|
|
4500
|
+
align: "center",
|
|
4501
|
+
valign: "top"
|
|
4502
|
+
});
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4505
|
+
renderToc(pptxSlide, pptx, toc, rect, theme, presentation) {
|
|
4506
|
+
const items = toc.items ? [...toc.items] : [];
|
|
4507
|
+
if (items.length === 0 && presentation) {
|
|
4508
|
+
let autoIdx = 1;
|
|
4509
|
+
for (const s of presentation.slides) {
|
|
4510
|
+
for (const el of s.elements) {
|
|
4511
|
+
if (el.type === "section") {
|
|
4512
|
+
const sec = el;
|
|
4513
|
+
items.push({
|
|
4514
|
+
number: sec.number !== void 0 ? String(sec.number) : String(autoIdx++),
|
|
4515
|
+
title: sec.title,
|
|
4516
|
+
description: sec.subtitle
|
|
4517
|
+
});
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4520
|
+
}
|
|
4521
|
+
if (items.length === 0) {
|
|
4522
|
+
presentation.slides.forEach((s, idx) => {
|
|
4523
|
+
const heading = s.elements.find((el) => el.type === "heading");
|
|
4524
|
+
if (heading) {
|
|
4525
|
+
items.push({
|
|
4526
|
+
number: String(idx + 1),
|
|
4527
|
+
title: heading.text
|
|
4528
|
+
});
|
|
4529
|
+
}
|
|
4530
|
+
});
|
|
4531
|
+
}
|
|
4532
|
+
}
|
|
4533
|
+
if (items.length === 0)
|
|
4534
|
+
return;
|
|
4535
|
+
const primaryHex = this.cleanHexColor(theme.colors.primary || "#00F0FF");
|
|
4536
|
+
const surfaceHex = this.cleanHexColor(theme.colors.surface || "#0f172a");
|
|
4537
|
+
const borderHex = this.cleanHexColor(theme.colors.border || "#334155");
|
|
4538
|
+
const textHex = this.cleanHexColor(theme.colors.text || "#ffffff");
|
|
4539
|
+
const mutedHex = this.cleanHexColor(theme.colors.muted || "#94a3b8");
|
|
4540
|
+
let currentY = rect.y;
|
|
4541
|
+
if (toc.title) {
|
|
4542
|
+
pptxSlide.addText(toc.title, {
|
|
4543
|
+
x: rect.x,
|
|
4544
|
+
y: currentY,
|
|
4545
|
+
w: rect.w,
|
|
4546
|
+
h: 0.5,
|
|
4547
|
+
fontSize: 22,
|
|
4548
|
+
bold: true,
|
|
4549
|
+
color: primaryHex,
|
|
4550
|
+
fontFace: cleanFontFace(theme.typography.headingFont)
|
|
4551
|
+
});
|
|
4552
|
+
currentY += 0.65;
|
|
4553
|
+
}
|
|
4554
|
+
const availableH = rect.h - (currentY - rect.y);
|
|
4555
|
+
const cols = items.length > 4 ? 2 : 1;
|
|
4556
|
+
const rows = Math.ceil(items.length / cols);
|
|
4557
|
+
const colW = (rect.w - (cols - 1) * 0.3) / cols;
|
|
4558
|
+
const itemH = Math.min(0.85, (availableH - (rows - 1) * 0.12) / rows);
|
|
4559
|
+
items.forEach((item, idx) => {
|
|
4560
|
+
const c = idx % cols;
|
|
4561
|
+
const r = Math.floor(idx / cols);
|
|
4562
|
+
const itemX = rect.x + c * (colW + 0.3);
|
|
4563
|
+
const itemY = currentY + r * (itemH + 0.12);
|
|
4564
|
+
const num = item.number !== void 0 ? String(item.number) : String(idx + 1);
|
|
4565
|
+
const descText = item.description || item.subtitle;
|
|
4566
|
+
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
4567
|
+
x: itemX,
|
|
4568
|
+
y: itemY,
|
|
4569
|
+
w: colW,
|
|
4570
|
+
h: itemH,
|
|
4571
|
+
fill: { color: surfaceHex },
|
|
4572
|
+
line: { color: borderHex, width: 1 },
|
|
4573
|
+
rectRadius: 0.08
|
|
4574
|
+
});
|
|
4575
|
+
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
4576
|
+
x: itemX + 0.12,
|
|
4577
|
+
y: itemY + (itemH - 0.36) / 2,
|
|
4578
|
+
w: 0.36,
|
|
4579
|
+
h: 0.36,
|
|
4580
|
+
fill: { color: primaryHex },
|
|
4581
|
+
rectRadius: 0.08
|
|
4582
|
+
});
|
|
4583
|
+
pptxSlide.addText(num, {
|
|
4584
|
+
x: itemX + 0.12,
|
|
4585
|
+
y: itemY + (itemH - 0.36) / 2,
|
|
4586
|
+
w: 0.36,
|
|
4587
|
+
h: 0.36,
|
|
4588
|
+
fontSize: 11,
|
|
4589
|
+
bold: true,
|
|
4590
|
+
color: "000000",
|
|
4591
|
+
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
4592
|
+
align: "center",
|
|
4593
|
+
valign: "middle"
|
|
4594
|
+
});
|
|
4595
|
+
const textX = itemX + 0.55;
|
|
4596
|
+
const textW = colW - 0.65;
|
|
4597
|
+
const titleChunks = [
|
|
4598
|
+
{
|
|
4599
|
+
text: item.title,
|
|
4600
|
+
options: {
|
|
4601
|
+
fontSize: 13,
|
|
4602
|
+
bold: true,
|
|
4603
|
+
color: textHex,
|
|
4604
|
+
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
4605
|
+
breakLine: Boolean(descText)
|
|
4606
|
+
}
|
|
4607
|
+
}
|
|
4608
|
+
];
|
|
4609
|
+
if (descText) {
|
|
4610
|
+
titleChunks.push({
|
|
4611
|
+
text: descText,
|
|
4612
|
+
options: {
|
|
4613
|
+
fontSize: 10,
|
|
4614
|
+
color: mutedHex,
|
|
4615
|
+
fontFace: cleanFontFace(theme.typography.bodyFont)
|
|
4616
|
+
}
|
|
4617
|
+
});
|
|
4618
|
+
}
|
|
4619
|
+
pptxSlide.addText(titleChunks, {
|
|
4620
|
+
x: textX,
|
|
4621
|
+
y: itemY + 0.06,
|
|
4622
|
+
w: textW,
|
|
4623
|
+
h: itemH - 0.12,
|
|
4624
|
+
valign: "middle",
|
|
4625
|
+
margin: 0
|
|
4626
|
+
});
|
|
4627
|
+
});
|
|
2919
4628
|
}
|
|
2920
4629
|
renderMermaid(pptxSlide, pptx, mermaid, rect, theme) {
|
|
2921
4630
|
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
@@ -3076,7 +4785,9 @@ var HtmlRenderer = class {
|
|
|
3076
4785
|
})();
|
|
3077
4786
|
</script>
|
|
3078
4787
|
` : "";
|
|
3079
|
-
const slidesHtml = presentation.slides.map((slide, idx) => this.renderSlide(slide, idx + 1, presentation.slides.length, theme)).join("\n");
|
|
4788
|
+
const slidesHtml = presentation.slides.map((slide, idx) => this.renderSlide(slide, idx + 1, presentation.slides.length, theme, presentation.metadata.watermark, presentation)).join("\n");
|
|
4789
|
+
const customStyles = presentation.metadata.styles ? (Array.isArray(presentation.metadata.styles) ? presentation.metadata.styles : [presentation.metadata.styles]).map((url) => `<link rel="stylesheet" href="${url}">`).join("\n ") : "";
|
|
4790
|
+
const customScripts = presentation.metadata.scripts ? (Array.isArray(presentation.metadata.scripts) ? presentation.metadata.scripts : [presentation.metadata.scripts]).map((url) => `<script src="${url}"></script>`).join("\n ") : "";
|
|
3080
4791
|
const html = `<!DOCTYPE html>
|
|
3081
4792
|
<html lang="en">
|
|
3082
4793
|
<head>
|
|
@@ -3085,6 +4796,11 @@ var HtmlRenderer = class {
|
|
|
3085
4796
|
<title>${this.escapeHtml(title)}</title>
|
|
3086
4797
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
3087
4798
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
4799
|
+
${customStyles}
|
|
4800
|
+
${customScripts}
|
|
4801
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" crossorigin="anonymous">
|
|
4802
|
+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" crossorigin="anonymous"></script>
|
|
4803
|
+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" crossorigin="anonymous"></script>
|
|
3088
4804
|
<script type="module">
|
|
3089
4805
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
|
3090
4806
|
try {
|
|
@@ -3246,9 +4962,6 @@ var HtmlRenderer = class {
|
|
|
3246
4962
|
margin-bottom: 0.8em;
|
|
3247
4963
|
overflow-wrap: break-word;
|
|
3248
4964
|
}
|
|
3249
|
-
color: var(--yumia-text);
|
|
3250
|
-
margin-bottom: 0.8em;
|
|
3251
|
-
}
|
|
3252
4965
|
|
|
3253
4966
|
p strong, li strong {
|
|
3254
4967
|
color: var(--yumia-primary);
|
|
@@ -3685,20 +5398,40 @@ var HtmlRenderer = class {
|
|
|
3685
5398
|
border: 1.5px solid var(--yumia-border);
|
|
3686
5399
|
border-left: 4px solid var(--yumia-primary);
|
|
3687
5400
|
border-radius: var(--yumia-radius-card);
|
|
3688
|
-
padding: 1.
|
|
3689
|
-
margin:
|
|
5401
|
+
padding: 0.75rem 1.4rem;
|
|
5402
|
+
margin: 0.7rem 0;
|
|
3690
5403
|
display: flex;
|
|
3691
5404
|
align-items: center;
|
|
3692
5405
|
justify-content: center;
|
|
3693
5406
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.25);
|
|
5407
|
+
overflow-x: auto;
|
|
5408
|
+
max-width: 100%;
|
|
3694
5409
|
}
|
|
3695
5410
|
|
|
3696
5411
|
.yumia-math-equation {
|
|
3697
|
-
font-
|
|
3698
|
-
font-size: clamp(1.2rem, 2.2vw, 1.8rem);
|
|
3699
|
-
font-style: italic;
|
|
5412
|
+
font-size: clamp(1.1rem, 1.8vw, 1.45rem);
|
|
3700
5413
|
color: var(--yumia-text);
|
|
3701
|
-
letter-spacing: 0.
|
|
5414
|
+
letter-spacing: 0.03em;
|
|
5415
|
+
}
|
|
5416
|
+
|
|
5417
|
+
/* Watermark Branding */
|
|
5418
|
+
.yumia-watermark {
|
|
5419
|
+
position: absolute;
|
|
5420
|
+
bottom: 12px;
|
|
5421
|
+
left: 20px;
|
|
5422
|
+
font-size: 11px;
|
|
5423
|
+
font-weight: 600;
|
|
5424
|
+
letter-spacing: 0.08em;
|
|
5425
|
+
text-transform: uppercase;
|
|
5426
|
+
color: var(--yumia-muted);
|
|
5427
|
+
opacity: 0.35;
|
|
5428
|
+
pointer-events: none;
|
|
5429
|
+
user-select: none;
|
|
5430
|
+
z-index: 10;
|
|
5431
|
+
transition: opacity 0.2s ease;
|
|
5432
|
+
}
|
|
5433
|
+
.yumia-slide-wrapper:hover .yumia-watermark {
|
|
5434
|
+
opacity: 0.65;
|
|
3702
5435
|
}
|
|
3703
5436
|
|
|
3704
5437
|
/* Slide Transitions */
|
|
@@ -3728,17 +5461,177 @@ var HtmlRenderer = class {
|
|
|
3728
5461
|
to { opacity: 1; transform: scale(1); }
|
|
3729
5462
|
}
|
|
3730
5463
|
|
|
3731
|
-
/*
|
|
3732
|
-
.yumia-
|
|
3733
|
-
|
|
5464
|
+
/* Code Block Line Highlighting & Numbers */
|
|
5465
|
+
.yumia-code-block {
|
|
5466
|
+
display: block;
|
|
5467
|
+
padding: 0.75rem 0;
|
|
5468
|
+
font-family: var(--yumia-font-code);
|
|
5469
|
+
font-size: 0.95rem;
|
|
5470
|
+
line-height: 1.6;
|
|
5471
|
+
overflow-x: auto;
|
|
5472
|
+
border-radius: var(--yumia-radius-card);
|
|
5473
|
+
background: rgba(10, 15, 30, 0.88);
|
|
5474
|
+
border: 1.5px solid var(--yumia-border);
|
|
5475
|
+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.35);
|
|
5476
|
+
margin: 0.8rem 0;
|
|
5477
|
+
}
|
|
5478
|
+
.yumia-code-block code {
|
|
5479
|
+
display: block;
|
|
5480
|
+
padding: 0;
|
|
5481
|
+
background: transparent;
|
|
5482
|
+
border: none;
|
|
5483
|
+
}
|
|
5484
|
+
.yumia-code-line {
|
|
5485
|
+
display: flex;
|
|
5486
|
+
align-items: center;
|
|
5487
|
+
min-height: 1.6em;
|
|
5488
|
+
padding: 0 1rem;
|
|
5489
|
+
transition: background 0.15s ease, opacity 0.15s ease;
|
|
3734
5490
|
}
|
|
3735
|
-
.yumia-
|
|
3736
|
-
opacity: 0.
|
|
3737
|
-
transform: translateY(4px);
|
|
5491
|
+
.yumia-code-line.dimmed {
|
|
5492
|
+
opacity: 0.35;
|
|
3738
5493
|
}
|
|
3739
|
-
.yumia-
|
|
5494
|
+
.yumia-code-line.highlighted {
|
|
5495
|
+
background: rgba(0, 240, 255, 0.16);
|
|
5496
|
+
border-left: 3.5px solid var(--yumia-primary);
|
|
3740
5497
|
opacity: 1;
|
|
3741
|
-
|
|
5498
|
+
font-weight: 600;
|
|
5499
|
+
}
|
|
5500
|
+
.yumia-code-line .line-num {
|
|
5501
|
+
user-select: none;
|
|
5502
|
+
width: 28px;
|
|
5503
|
+
margin-right: 14px;
|
|
5504
|
+
color: rgba(255, 255, 255, 0.3);
|
|
5505
|
+
font-size: 0.8rem;
|
|
5506
|
+
text-align: right;
|
|
5507
|
+
}
|
|
5508
|
+
.yumia-code-line .line-text {
|
|
5509
|
+
flex: 1;
|
|
5510
|
+
}
|
|
5511
|
+
|
|
5512
|
+
/* Section Divider Card */
|
|
5513
|
+
.yumia-section-card {
|
|
5514
|
+
display: flex;
|
|
5515
|
+
flex-direction: column;
|
|
5516
|
+
align-items: center;
|
|
5517
|
+
justify-content: center;
|
|
5518
|
+
text-align: center;
|
|
5519
|
+
padding: 3rem 2rem;
|
|
5520
|
+
margin: auto 0;
|
|
5521
|
+
background: radial-gradient(circle at center, rgba(0, 240, 255, 0.12) 0%, rgba(15, 23, 42, 0.6) 100%);
|
|
5522
|
+
border: 1.5px solid var(--yumia-primary);
|
|
5523
|
+
border-radius: var(--yumia-radius-card);
|
|
5524
|
+
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.5), 0 0 20px rgba(0, 240, 255, 0.2);
|
|
5525
|
+
width: 100%;
|
|
5526
|
+
}
|
|
5527
|
+
.yumia-section-pill {
|
|
5528
|
+
display: inline-flex;
|
|
5529
|
+
align-items: center;
|
|
5530
|
+
padding: 4px 14px;
|
|
5531
|
+
border-radius: 999px;
|
|
5532
|
+
background: var(--yumia-primary);
|
|
5533
|
+
color: #000;
|
|
5534
|
+
font-weight: 800;
|
|
5535
|
+
font-size: 0.85rem;
|
|
5536
|
+
letter-spacing: 0.08em;
|
|
5537
|
+
text-transform: uppercase;
|
|
5538
|
+
margin-bottom: 1.2rem;
|
|
5539
|
+
}
|
|
5540
|
+
.yumia-section-title {
|
|
5541
|
+
font-size: clamp(2rem, 3.5vw, 3rem);
|
|
5542
|
+
font-weight: 800;
|
|
5543
|
+
color: var(--yumia-text);
|
|
5544
|
+
margin-bottom: 0.8rem;
|
|
5545
|
+
line-height: 1.2;
|
|
5546
|
+
}
|
|
5547
|
+
.yumia-section-subtitle {
|
|
5548
|
+
font-size: 1.15rem;
|
|
5549
|
+
color: var(--yumia-muted);
|
|
5550
|
+
max-width: 650px;
|
|
5551
|
+
}
|
|
5552
|
+
|
|
5553
|
+
/* Table of Contents Grid */
|
|
5554
|
+
.yumia-toc-grid {
|
|
5555
|
+
display: grid;
|
|
5556
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
5557
|
+
gap: 16px;
|
|
5558
|
+
width: 100%;
|
|
5559
|
+
margin: 1.2rem 0;
|
|
5560
|
+
}
|
|
5561
|
+
.yumia-toc-item {
|
|
5562
|
+
display: flex;
|
|
5563
|
+
align-items: center;
|
|
5564
|
+
gap: 14px;
|
|
5565
|
+
background: var(--yumia-surface);
|
|
5566
|
+
border: 1.5px solid var(--yumia-border);
|
|
5567
|
+
border-radius: 10px;
|
|
5568
|
+
padding: 14px 18px;
|
|
5569
|
+
transition: transform 0.2s ease, border-color 0.2s ease;
|
|
5570
|
+
}
|
|
5571
|
+
.yumia-toc-item:hover {
|
|
5572
|
+
transform: translateX(4px);
|
|
5573
|
+
border-color: var(--yumia-primary);
|
|
5574
|
+
}
|
|
5575
|
+
.yumia-toc-num {
|
|
5576
|
+
display: flex;
|
|
5577
|
+
align-items: center;
|
|
5578
|
+
justify-content: center;
|
|
5579
|
+
width: 34px;
|
|
5580
|
+
height: 34px;
|
|
5581
|
+
border-radius: 8px;
|
|
5582
|
+
background: rgba(0, 240, 255, 0.15);
|
|
5583
|
+
color: var(--yumia-primary);
|
|
5584
|
+
font-weight: 800;
|
|
5585
|
+
font-size: 0.95rem;
|
|
5586
|
+
}
|
|
5587
|
+
.yumia-toc-title {
|
|
5588
|
+
font-weight: 600;
|
|
5589
|
+
font-size: 1.05rem;
|
|
5590
|
+
color: var(--yumia-text);
|
|
5591
|
+
}
|
|
5592
|
+
|
|
5593
|
+
/* Print & Export Media Styles */
|
|
5594
|
+
@media print {
|
|
5595
|
+
@page {
|
|
5596
|
+
size: landscape;
|
|
5597
|
+
margin: 0;
|
|
5598
|
+
}
|
|
5599
|
+
body {
|
|
5600
|
+
background: #0f172a !important;
|
|
5601
|
+
color: #f8fafc !important;
|
|
5602
|
+
overflow: visible !important;
|
|
5603
|
+
-webkit-print-color-adjust: exact !important;
|
|
5604
|
+
print-color-adjust: exact !important;
|
|
5605
|
+
}
|
|
5606
|
+
#deck-container {
|
|
5607
|
+
display: block !important;
|
|
5608
|
+
width: 100% !important;
|
|
5609
|
+
height: auto !important;
|
|
5610
|
+
}
|
|
5611
|
+
#yumia-deck {
|
|
5612
|
+
display: block !important;
|
|
5613
|
+
position: static !important;
|
|
5614
|
+
width: 100% !important;
|
|
5615
|
+
height: auto !important;
|
|
5616
|
+
}
|
|
5617
|
+
.yumia-slide-wrapper {
|
|
5618
|
+
display: flex !important;
|
|
5619
|
+
page-break-after: always !important;
|
|
5620
|
+
break-after: page !important;
|
|
5621
|
+
page-break-inside: avoid !important;
|
|
5622
|
+
position: relative !important;
|
|
5623
|
+
width: 100vw !important;
|
|
5624
|
+
height: 100vh !important;
|
|
5625
|
+
min-height: 100vh !important;
|
|
5626
|
+
margin: 0 !important;
|
|
5627
|
+
box-shadow: none !important;
|
|
5628
|
+
opacity: 1 !important;
|
|
5629
|
+
visibility: visible !important;
|
|
5630
|
+
transform: none !important;
|
|
5631
|
+
}
|
|
5632
|
+
.yumia-controls, .yumia-notes-drawer, .yumia-overview-modal, .yumia-progress-bar {
|
|
5633
|
+
display: none !important;
|
|
5634
|
+
}
|
|
3742
5635
|
}
|
|
3743
5636
|
|
|
3744
5637
|
/* Notes Drawer */
|
|
@@ -3968,6 +5861,7 @@ var HtmlRenderer = class {
|
|
|
3968
5861
|
<button class="yumia-btn" id="btn-next" title="Next Slide (\u2192)">\u25B6</button>
|
|
3969
5862
|
<button class="yumia-btn" id="btn-overview" title="Slide Overview (ESC / O)">\u25A6</button>
|
|
3970
5863
|
<button class="yumia-btn" id="btn-speaker" title="Speaker View (S)">\u{1F3A4}</button>
|
|
5864
|
+
<button class="yumia-btn" id="btn-print" title="Stampa / Salva PDF (Ctrl+P)">\u{1F5A8}\uFE0F</button>
|
|
3971
5865
|
<button class="yumia-btn" id="btn-notes" title="Toggle Notes (N)">\u{1F4DD}</button>
|
|
3972
5866
|
<button class="yumia-btn" id="btn-fs" title="Fullscreen (F)">\u26F6</button>
|
|
3973
5867
|
</div>
|
|
@@ -4080,9 +5974,40 @@ var HtmlRenderer = class {
|
|
|
4080
5974
|
if (window.renderMermaidInSlide && slides[currentIdx]) {
|
|
4081
5975
|
window.renderMermaidInSlide(slides[currentIdx]);
|
|
4082
5976
|
}
|
|
5977
|
+
if (slides[currentIdx]) {
|
|
5978
|
+
renderMathInSlide(slides[currentIdx]);
|
|
5979
|
+
}
|
|
4083
5980
|
}, 50);
|
|
4084
5981
|
}
|
|
4085
5982
|
|
|
5983
|
+
function renderMathInSlide(slideEl) {
|
|
5984
|
+
if (!slideEl) return;
|
|
5985
|
+
if (window.renderMathInElement) {
|
|
5986
|
+
try {
|
|
5987
|
+
window.renderMathInElement(slideEl, {
|
|
5988
|
+
delimiters: [
|
|
5989
|
+
{ left: '$$', right: '$$', display: true }
|
|
5990
|
+
],
|
|
5991
|
+
throwOnError: false
|
|
5992
|
+
});
|
|
5993
|
+
} catch (e) {
|
|
5994
|
+
console.warn('KaTeX auto-render notice:', e);
|
|
5995
|
+
}
|
|
5996
|
+
}
|
|
5997
|
+
if (window.katex) {
|
|
5998
|
+
slideEl.querySelectorAll('.yumia-math-equation:not([data-katex="true"])').forEach(function(el) {
|
|
5999
|
+
try {
|
|
6000
|
+
const rawExpr =
|
|
6001
|
+
el.getAttribute('data-expr') || el.textContent.replace(/^[$]{2}|[$]{2}$/g, '').trim();
|
|
6002
|
+
window.katex.render(rawExpr, el, { displayMode: true, throwOnError: false });
|
|
6003
|
+
el.setAttribute('data-katex', 'true');
|
|
6004
|
+
} catch (err) {
|
|
6005
|
+
console.warn('KaTeX equation render notice:', err);
|
|
6006
|
+
}
|
|
6007
|
+
});
|
|
6008
|
+
}
|
|
6009
|
+
}
|
|
6010
|
+
|
|
4086
6011
|
function openSpeakerWindow() {
|
|
4087
6012
|
const url = new URL(window.location.href);
|
|
4088
6013
|
url.searchParams.set('speaker', 'true');
|
|
@@ -4231,8 +6156,15 @@ var HtmlRenderer = class {
|
|
|
4231
6156
|
const hash = window.location.hash.replace('#', '');
|
|
4232
6157
|
const initialIdx = parseInt(hash, 10) - 1;
|
|
4233
6158
|
goToSlide(isNaN(initialIdx) ? 0 : initialIdx, false);
|
|
6159
|
+
setTimeout(() => {
|
|
6160
|
+
slides.forEach(renderMathInSlide);
|
|
6161
|
+
}, 100);
|
|
4234
6162
|
}
|
|
4235
6163
|
|
|
6164
|
+
window.addEventListener('load', () => {
|
|
6165
|
+
slides.forEach(renderMathInSlide);
|
|
6166
|
+
});
|
|
6167
|
+
|
|
4236
6168
|
window.deckController = {
|
|
4237
6169
|
init: init,
|
|
4238
6170
|
next: function() { goToSlide(currentIdx + 1); },
|
|
@@ -4240,6 +6172,7 @@ var HtmlRenderer = class {
|
|
|
4240
6172
|
toggleNotes: function() { notesDrawer?.classList.toggle('open'); },
|
|
4241
6173
|
toggleOverview: function() { toggleOverview(); },
|
|
4242
6174
|
openSpeaker: openSpeakerWindow,
|
|
6175
|
+
print: function() { window.print(); },
|
|
4243
6176
|
toggleFs: function() {
|
|
4244
6177
|
if (!document.fullscreenElement) {
|
|
4245
6178
|
document.documentElement.requestFullscreen().catch(() => {});
|
|
@@ -4258,6 +6191,7 @@ var HtmlRenderer = class {
|
|
|
4258
6191
|
document.getElementById('btn-overview')?.addEventListener('click', window.deckController.toggleOverview);
|
|
4259
6192
|
document.getElementById('btn-close-overview')?.addEventListener('click', () => toggleOverview(false));
|
|
4260
6193
|
document.getElementById('btn-speaker')?.addEventListener('click', window.deckController.openSpeaker);
|
|
6194
|
+
document.getElementById('btn-print')?.addEventListener('click', window.deckController.print);
|
|
4261
6195
|
document.getElementById('btn-fs')?.addEventListener('click', window.deckController.toggleFs);
|
|
4262
6196
|
|
|
4263
6197
|
window.addEventListener('keydown', function(e) {
|
|
@@ -4275,6 +6209,11 @@ var HtmlRenderer = class {
|
|
|
4275
6209
|
}
|
|
4276
6210
|
}
|
|
4277
6211
|
|
|
6212
|
+
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'p') {
|
|
6213
|
+
// let default browser print work or call print explicitly
|
|
6214
|
+
return;
|
|
6215
|
+
}
|
|
6216
|
+
|
|
4278
6217
|
if (e.key === 'ArrowRight' || e.key === ' ' || e.key === 'PageDown' || e.key.toLowerCase() === 'l') {
|
|
4279
6218
|
e.preventDefault();
|
|
4280
6219
|
window.deckController.next();
|
|
@@ -4285,6 +6224,8 @@ var HtmlRenderer = class {
|
|
|
4285
6224
|
window.deckController.toggleFs();
|
|
4286
6225
|
} else if (e.key.toLowerCase() === 's') {
|
|
4287
6226
|
window.deckController.openSpeaker();
|
|
6227
|
+
} else if (e.key.toLowerCase() === 'p') {
|
|
6228
|
+
window.deckController.print();
|
|
4288
6229
|
} else if (e.key.toLowerCase() === 'n') {
|
|
4289
6230
|
window.deckController.toggleNotes();
|
|
4290
6231
|
} else if (e.key === 'Escape' || e.key.toLowerCase() === 'o') {
|
|
@@ -4315,21 +6256,25 @@ var HtmlRenderer = class {
|
|
|
4315
6256
|
slideCount: presentation.slides.length
|
|
4316
6257
|
};
|
|
4317
6258
|
}
|
|
4318
|
-
renderSlide(slide, slideNum, totalSlides, theme) {
|
|
6259
|
+
renderSlide(slide, slideNum, totalSlides, theme, watermarkOpt, presentation) {
|
|
4319
6260
|
const activeClass = slideNum === 1 ? "active" : "";
|
|
4320
6261
|
const notesAttr = slide.notes ? this.escapeHtml(slide.notes.replace(/\n/g, "<br>")) : "";
|
|
4321
6262
|
const progressPercent = Math.round(slideNum / totalSlides * 100);
|
|
4322
6263
|
const transition = slide.transition || "fade";
|
|
4323
6264
|
const transType = typeof transition === "string" ? transition : transition.type;
|
|
4324
6265
|
const transClass = `transition-${transType || "fade"}`;
|
|
4325
|
-
const
|
|
6266
|
+
const isWatermarkEnabled = watermarkOpt !== false;
|
|
6267
|
+
const watermarkText = typeof watermarkOpt === "string" && watermarkOpt.trim().length > 0 ? watermarkOpt : "YumiaMD";
|
|
6268
|
+
const watermarkHtml = isWatermarkEnabled ? `<div class="yumia-watermark">${this.escapeHtml(watermarkText)}</div>` : "";
|
|
6269
|
+
const elementsHtml = slide.elements.map((el) => this.renderElement(el, theme, presentation)).join("\n");
|
|
4326
6270
|
return `
|
|
4327
6271
|
<div class="yumia-slide-wrapper ${activeClass} ${transClass}" id="slide-${slideNum}" data-notes="${notesAttr}">
|
|
4328
6272
|
${elementsHtml}
|
|
6273
|
+
${watermarkHtml}
|
|
4329
6274
|
<div class="yumia-progress-bar" style="width: ${progressPercent}%;"></div>
|
|
4330
6275
|
</div>`;
|
|
4331
6276
|
}
|
|
4332
|
-
renderElement(element, theme) {
|
|
6277
|
+
renderElement(element, theme, presentation) {
|
|
4333
6278
|
switch (element.type) {
|
|
4334
6279
|
case "heading": {
|
|
4335
6280
|
const h = element;
|
|
@@ -4349,8 +6294,100 @@ var HtmlRenderer = class {
|
|
|
4349
6294
|
case "code": {
|
|
4350
6295
|
const c = element;
|
|
4351
6296
|
const langClass = c.language ? `class="language-${c.language}"` : "";
|
|
6297
|
+
const lines = c.code.split("\n");
|
|
6298
|
+
if (c.highlight) {
|
|
6299
|
+
const highlightSet = /* @__PURE__ */ new Set();
|
|
6300
|
+
const parts = c.highlight.split(",");
|
|
6301
|
+
for (const part of parts) {
|
|
6302
|
+
const trimmed = part.trim();
|
|
6303
|
+
if (!trimmed)
|
|
6304
|
+
continue;
|
|
6305
|
+
if (trimmed.includes("-")) {
|
|
6306
|
+
const [startStr, endStr] = trimmed.split("-");
|
|
6307
|
+
const start = parseInt(startStr || "0", 10);
|
|
6308
|
+
const end = parseInt(endStr || "0", 10);
|
|
6309
|
+
if (!isNaN(start) && !isNaN(end) && start <= end) {
|
|
6310
|
+
for (let n = start; n <= end; n++)
|
|
6311
|
+
highlightSet.add(n);
|
|
6312
|
+
}
|
|
6313
|
+
} else {
|
|
6314
|
+
const num = parseInt(trimmed, 10);
|
|
6315
|
+
if (!isNaN(num))
|
|
6316
|
+
highlightSet.add(num);
|
|
6317
|
+
}
|
|
6318
|
+
}
|
|
6319
|
+
const linesHtml = lines.map((line, idx) => {
|
|
6320
|
+
const lineNum = idx + 1;
|
|
6321
|
+
const isHl = highlightSet.has(lineNum);
|
|
6322
|
+
const hlClass = isHl ? "highlighted" : "dimmed";
|
|
6323
|
+
return `<div class="yumia-code-line ${hlClass}"><span class="line-num">${lineNum}</span><span class="line-text">${this.escapeHtml(line) || " "}</span></div>`;
|
|
6324
|
+
}).join("");
|
|
6325
|
+
return `<pre class="yumia-code-block"><code ${langClass}>${linesHtml}</code></pre>`;
|
|
6326
|
+
}
|
|
4352
6327
|
return `<pre><code ${langClass}>${this.escapeHtml(c.code)}</code></pre>`;
|
|
4353
6328
|
}
|
|
6329
|
+
case "section": {
|
|
6330
|
+
const s = element;
|
|
6331
|
+
const numStr = s.number !== void 0 ? `<div class="yumia-section-pill">SECTION ${this.escapeHtml(String(s.number))}</div>` : "";
|
|
6332
|
+
const subStr = s.subtitle ? `<div class="yumia-section-subtitle">${this.formatInline(s.subtitle)}</div>` : "";
|
|
6333
|
+
return `
|
|
6334
|
+
<div class="yumia-section-card">
|
|
6335
|
+
${numStr}
|
|
6336
|
+
<div class="yumia-section-title">${this.formatInline(s.title)}</div>
|
|
6337
|
+
${subStr}
|
|
6338
|
+
</div>`;
|
|
6339
|
+
}
|
|
6340
|
+
case "toc": {
|
|
6341
|
+
const t = element;
|
|
6342
|
+
const items = t.items ? [...t.items] : [];
|
|
6343
|
+
if (items.length === 0 && presentation) {
|
|
6344
|
+
let autoSecIdx = 1;
|
|
6345
|
+
for (const s of presentation.slides) {
|
|
6346
|
+
for (const el of s.elements) {
|
|
6347
|
+
if (el.type === "section") {
|
|
6348
|
+
const sec = el;
|
|
6349
|
+
items.push({
|
|
6350
|
+
number: sec.number !== void 0 ? String(sec.number) : String(autoSecIdx++),
|
|
6351
|
+
title: sec.title,
|
|
6352
|
+
description: sec.subtitle
|
|
6353
|
+
});
|
|
6354
|
+
}
|
|
6355
|
+
}
|
|
6356
|
+
}
|
|
6357
|
+
if (items.length === 0) {
|
|
6358
|
+
presentation.slides.forEach((s, idx) => {
|
|
6359
|
+
const heading = s.elements.find((el) => el.type === "heading");
|
|
6360
|
+
if (heading) {
|
|
6361
|
+
items.push({
|
|
6362
|
+
number: String(idx + 1),
|
|
6363
|
+
title: heading.text
|
|
6364
|
+
});
|
|
6365
|
+
}
|
|
6366
|
+
});
|
|
6367
|
+
}
|
|
6368
|
+
}
|
|
6369
|
+
const titleHtml = t.title ? `<h2 style="margin-bottom:1.5rem;">${this.escapeHtml(t.title)}</h2>` : "";
|
|
6370
|
+
const itemsHtml = items.map((it, idx) => {
|
|
6371
|
+
const num = it.number !== void 0 ? String(it.number) : String(idx + 1);
|
|
6372
|
+
const descText = it.description || it.subtitle;
|
|
6373
|
+
const desc = descText ? `<div style="font-size:0.85rem; color:var(--yumia-muted); margin-top:2px;">${this.formatInline(descText)}</div>` : "";
|
|
6374
|
+
return `
|
|
6375
|
+
<div class="yumia-toc-item">
|
|
6376
|
+
<div class="yumia-toc-num">${this.escapeHtml(num)}</div>
|
|
6377
|
+
<div>
|
|
6378
|
+
<div class="yumia-toc-title">${this.formatInline(it.title)}</div>
|
|
6379
|
+
${desc}
|
|
6380
|
+
</div>
|
|
6381
|
+
</div>`;
|
|
6382
|
+
}).join("\n");
|
|
6383
|
+
return `
|
|
6384
|
+
<div class="yumia-toc-container">
|
|
6385
|
+
${titleHtml}
|
|
6386
|
+
<div class="yumia-toc-grid">
|
|
6387
|
+
${itemsHtml}
|
|
6388
|
+
</div>
|
|
6389
|
+
</div>`;
|
|
6390
|
+
}
|
|
4354
6391
|
case "quote": {
|
|
4355
6392
|
const q = element;
|
|
4356
6393
|
const author = q.author ? `<br><small>\u2014 ${this.escapeHtml(q.author)}</small>` : "";
|
|
@@ -4426,9 +6463,10 @@ var HtmlRenderer = class {
|
|
|
4426
6463
|
}
|
|
4427
6464
|
case "math": {
|
|
4428
6465
|
const mathEl = element;
|
|
6466
|
+
const expr = mathEl.expression;
|
|
4429
6467
|
return `
|
|
4430
6468
|
<div class="yumia-math-container">
|
|
4431
|
-
<div class="yumia-math-equation"
|
|
6469
|
+
<div class="yumia-math-equation" data-expr="${this.escapeHtml(expr)}">$$${this.escapeHtml(expr)}$$</div>
|
|
4432
6470
|
</div>`;
|
|
4433
6471
|
}
|
|
4434
6472
|
case "chart": {
|
|
@@ -4437,6 +6475,27 @@ var HtmlRenderer = class {
|
|
|
4437
6475
|
case "timeline": {
|
|
4438
6476
|
return this.renderTimeline(element);
|
|
4439
6477
|
}
|
|
6478
|
+
case "icon": {
|
|
6479
|
+
const ic = element;
|
|
6480
|
+
const iconSvg = defaultIconResolver.toSvg(ic.name, ic.size || 24, ic.color || "currentColor", "yumia-icon");
|
|
6481
|
+
return `<span class="yumia-icon-wrapper" style="display:inline-flex; align-items:center; vertical-align:middle;">${iconSvg}</span>`;
|
|
6482
|
+
}
|
|
6483
|
+
case "grid": {
|
|
6484
|
+
const g = element;
|
|
6485
|
+
const cols = typeof g.columns === "number" ? `repeat(${g.columns}, 1fr)` : g.columns;
|
|
6486
|
+
const gap = g.gap !== void 0 ? typeof g.gap === "number" ? `${g.gap}px` : g.gap : "1.5rem";
|
|
6487
|
+
const inner = g.elements.map((child) => this.renderElement(child, theme, presentation)).join("\n");
|
|
6488
|
+
return `<div class="yumia-grid" style="display:grid; grid-template-columns:${cols}; gap:${gap}; width:100%;">${inner}</div>`;
|
|
6489
|
+
}
|
|
6490
|
+
case "stack": {
|
|
6491
|
+
const st = element;
|
|
6492
|
+
const dir = st.direction === "horizontal" ? "row" : "column";
|
|
6493
|
+
const gap = st.gap !== void 0 ? typeof st.gap === "number" ? `${st.gap}px` : st.gap : "1rem";
|
|
6494
|
+
const align = st.align ? `align-items:${st.align};` : "";
|
|
6495
|
+
const justify = st.justify ? `justify-content:${st.justify};` : "";
|
|
6496
|
+
const inner = st.elements.map((child) => this.renderElement(child, theme, presentation)).join("\n");
|
|
6497
|
+
return `<div class="yumia-stack" style="display:flex; flex-direction:${dir}; gap:${gap}; ${align} ${justify} width:100%;">${inner}</div>`;
|
|
6498
|
+
}
|
|
4440
6499
|
case "compare": {
|
|
4441
6500
|
return this.renderCompare(element, theme);
|
|
4442
6501
|
}
|
|
@@ -4590,8 +6649,7 @@ var HtmlRenderer = class {
|
|
|
4590
6649
|
</div>`;
|
|
4591
6650
|
}
|
|
4592
6651
|
formatInline(text) {
|
|
4593
|
-
|
|
4594
|
-
return escaped.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>").replace(/\*(.*?)\*/g, "<em>$1</em>").replace(/`(.*?)`/g, "<code>$1</code>");
|
|
6652
|
+
return this.escapeHtml(text).replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>").replace(/\*(.*?)\*/g, "<em>$1</em>").replace(/`(.*?)`/g, "<code>$1</code>");
|
|
4595
6653
|
}
|
|
4596
6654
|
escapeHtml(str) {
|
|
4597
6655
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -4636,7 +6694,7 @@ var PdfRenderer = class {
|
|
|
4636
6694
|
const totalSlides = presentation.slides.length;
|
|
4637
6695
|
for (let i = 0; i < totalSlides; i++) {
|
|
4638
6696
|
const slide = presentation.slides[i];
|
|
4639
|
-
this.renderSlide(doc, slide, i + 1, totalSlides, pageWidth, pageHeight, theme);
|
|
6697
|
+
this.renderSlide(doc, slide, i + 1, totalSlides, pageWidth, pageHeight, theme, presentation);
|
|
4640
6698
|
}
|
|
4641
6699
|
doc.end();
|
|
4642
6700
|
} catch (err) {
|
|
@@ -4644,7 +6702,7 @@ var PdfRenderer = class {
|
|
|
4644
6702
|
}
|
|
4645
6703
|
});
|
|
4646
6704
|
}
|
|
4647
|
-
renderSlide(doc, slide, slideNum, totalSlides, pageWidth, pageHeight, theme) {
|
|
6705
|
+
renderSlide(doc, slide, slideNum, totalSlides, pageWidth, pageHeight, theme, presentation) {
|
|
4648
6706
|
doc.addPage({
|
|
4649
6707
|
size: [pageWidth, pageHeight],
|
|
4650
6708
|
margins: { top: 0, bottom: 0, left: 0, right: 0 }
|
|
@@ -4655,7 +6713,7 @@ var PdfRenderer = class {
|
|
|
4655
6713
|
const contentWidth = pageWidth - padX * 2;
|
|
4656
6714
|
let cursorY = padY;
|
|
4657
6715
|
for (const element of slide.elements) {
|
|
4658
|
-
cursorY = this.renderElement(doc, element, padX, cursorY, contentWidth, theme);
|
|
6716
|
+
cursorY = this.renderElement(doc, element, padX, cursorY, contentWidth, theme, presentation);
|
|
4659
6717
|
cursorY += 12;
|
|
4660
6718
|
}
|
|
4661
6719
|
const progressWidth = slideNum / totalSlides * pageWidth;
|
|
@@ -4665,7 +6723,7 @@ var PdfRenderer = class {
|
|
|
4665
6723
|
align: "right"
|
|
4666
6724
|
});
|
|
4667
6725
|
}
|
|
4668
|
-
renderElement(doc, element, x, y, width, theme) {
|
|
6726
|
+
renderElement(doc, element, x, y, width, theme, presentation) {
|
|
4669
6727
|
switch (element.type) {
|
|
4670
6728
|
case "heading": {
|
|
4671
6729
|
const h = element;
|
|
@@ -4717,12 +6775,42 @@ var PdfRenderer = class {
|
|
|
4717
6775
|
}
|
|
4718
6776
|
case "code": {
|
|
4719
6777
|
const c = element;
|
|
4720
|
-
const
|
|
4721
|
-
doc.font("Courier").fontSize(
|
|
4722
|
-
const
|
|
4723
|
-
const boxHeight =
|
|
6778
|
+
const lines = c.code.split("\n");
|
|
6779
|
+
doc.font("Courier").fontSize(10);
|
|
6780
|
+
const lineHeight = 14;
|
|
6781
|
+
const boxHeight = lines.length * lineHeight + 20;
|
|
4724
6782
|
doc.roundedRect(x, y, width, boxHeight, 6).fill("#0a0a10").strokeColor(theme.colors.border || "rgba(255,255,255,0.1)").stroke();
|
|
4725
|
-
|
|
6783
|
+
const highlightSet = /* @__PURE__ */ new Set();
|
|
6784
|
+
if (c.highlight) {
|
|
6785
|
+
const parts = c.highlight.split(",");
|
|
6786
|
+
for (const part of parts) {
|
|
6787
|
+
const trimmed = part.trim();
|
|
6788
|
+
if (!trimmed)
|
|
6789
|
+
continue;
|
|
6790
|
+
if (trimmed.includes("-")) {
|
|
6791
|
+
const [startStr, endStr] = trimmed.split("-");
|
|
6792
|
+
const start = parseInt(startStr || "0", 10);
|
|
6793
|
+
const end = parseInt(endStr || "0", 10);
|
|
6794
|
+
if (!isNaN(start) && !isNaN(end) && start <= end) {
|
|
6795
|
+
for (let n = start; n <= end; n++)
|
|
6796
|
+
highlightSet.add(n);
|
|
6797
|
+
}
|
|
6798
|
+
} else {
|
|
6799
|
+
const num = parseInt(trimmed, 10);
|
|
6800
|
+
if (!isNaN(num))
|
|
6801
|
+
highlightSet.add(num);
|
|
6802
|
+
}
|
|
6803
|
+
}
|
|
6804
|
+
}
|
|
6805
|
+
lines.forEach((line, idx) => {
|
|
6806
|
+
const lineNum = idx + 1;
|
|
6807
|
+
const lineY = y + 10 + idx * lineHeight;
|
|
6808
|
+
const isHl = highlightSet.has(lineNum);
|
|
6809
|
+
const numColor = isHl ? theme.colors.primary : theme.colors.muted || "#555566";
|
|
6810
|
+
const textColor = c.highlight ? isHl ? theme.colors.primary || "#00f0ff" : theme.colors.muted || "#666677" : theme.colors.accent || "#38bdf8";
|
|
6811
|
+
doc.font("Courier").fontSize(9).fillColor(numColor).text(String(lineNum).padStart(2, " "), x + 10, lineY, { width: 22 });
|
|
6812
|
+
doc.font("Courier").fontSize(10).fillColor(textColor).text(line || " ", x + 36, lineY, { width: width - 48 });
|
|
6813
|
+
});
|
|
4726
6814
|
return y + boxHeight;
|
|
4727
6815
|
}
|
|
4728
6816
|
case "card": {
|
|
@@ -4930,7 +7018,7 @@ var PdfRenderer = class {
|
|
|
4930
7018
|
const barY = topY + plotH - h;
|
|
4931
7019
|
doc.rect(barX, barY, barW, h).fill(theme.colors.primary);
|
|
4932
7020
|
doc.font("Helvetica").fontSize(9).fillColor(theme.colors.text).text(String(val), barX, barY - 12, { width: barW, align: "center" });
|
|
4933
|
-
if (ch.labels[idx]) {
|
|
7021
|
+
if (ch.labels?.[idx]) {
|
|
4934
7022
|
doc.font("Helvetica").fontSize(9).fillColor(theme.colors.muted || "#888888").text(this.stripFormatting(ch.labels[idx]), barX - 10, topY + plotH + 4, {
|
|
4935
7023
|
width: barW + 20,
|
|
4936
7024
|
align: "center"
|
|
@@ -4959,6 +7047,116 @@ var PdfRenderer = class {
|
|
|
4959
7047
|
});
|
|
4960
7048
|
return y + boxH + 8;
|
|
4961
7049
|
}
|
|
7050
|
+
case "section": {
|
|
7051
|
+
const s = element;
|
|
7052
|
+
const boxH = 130;
|
|
7053
|
+
doc.roundedRect(x, y, width, boxH, 8).fill(theme.colors.surface || "rgba(255,255,255,0.06)");
|
|
7054
|
+
doc.roundedRect(x, y, width, boxH, 8).lineWidth(2).strokeColor(theme.colors.primary).stroke();
|
|
7055
|
+
let curY = y + 18;
|
|
7056
|
+
if (s.number !== void 0) {
|
|
7057
|
+
const numStr = String(s.number);
|
|
7058
|
+
doc.roundedRect(x + width / 2 - 40, curY, 80, 18, 9).fill(theme.colors.primary);
|
|
7059
|
+
doc.font("Helvetica-Bold").fontSize(9).fillColor("#000000").text(`SECTION ${numStr}`.toUpperCase(), x, curY + 4, { width, align: "center" });
|
|
7060
|
+
curY += 28;
|
|
7061
|
+
}
|
|
7062
|
+
doc.font("Helvetica-Bold").fontSize(22).fillColor(theme.colors.text).text(this.stripFormatting(s.title), x + 20, curY, {
|
|
7063
|
+
width: width - 40,
|
|
7064
|
+
align: "center"
|
|
7065
|
+
});
|
|
7066
|
+
curY += 28;
|
|
7067
|
+
if (s.subtitle) {
|
|
7068
|
+
doc.font("Helvetica").fontSize(12).fillColor(theme.colors.muted || "#999999").text(this.stripFormatting(s.subtitle), x + 30, curY, {
|
|
7069
|
+
width: width - 60,
|
|
7070
|
+
align: "center"
|
|
7071
|
+
});
|
|
7072
|
+
}
|
|
7073
|
+
return y + boxH + 8;
|
|
7074
|
+
}
|
|
7075
|
+
case "toc": {
|
|
7076
|
+
const t = element;
|
|
7077
|
+
const items = t.items ? [...t.items] : [];
|
|
7078
|
+
if (items.length === 0 && presentation) {
|
|
7079
|
+
let autoIdx = 1;
|
|
7080
|
+
for (const s of presentation.slides) {
|
|
7081
|
+
for (const el of s.elements) {
|
|
7082
|
+
if (el.type === "section") {
|
|
7083
|
+
const sec = el;
|
|
7084
|
+
items.push({
|
|
7085
|
+
number: sec.number !== void 0 ? String(sec.number) : String(autoIdx++),
|
|
7086
|
+
title: sec.title,
|
|
7087
|
+
description: sec.subtitle
|
|
7088
|
+
});
|
|
7089
|
+
}
|
|
7090
|
+
}
|
|
7091
|
+
}
|
|
7092
|
+
if (items.length === 0) {
|
|
7093
|
+
presentation.slides.forEach((s, idx) => {
|
|
7094
|
+
const heading = s.elements.find((el) => el.type === "heading");
|
|
7095
|
+
if (heading) {
|
|
7096
|
+
items.push({
|
|
7097
|
+
number: String(idx + 1),
|
|
7098
|
+
title: heading.text
|
|
7099
|
+
});
|
|
7100
|
+
}
|
|
7101
|
+
});
|
|
7102
|
+
}
|
|
7103
|
+
}
|
|
7104
|
+
let curY = y;
|
|
7105
|
+
if (t.title) {
|
|
7106
|
+
doc.font("Helvetica-Bold").fontSize(18).fillColor(theme.colors.primary).text(this.stripFormatting(t.title), x, curY, { width });
|
|
7107
|
+
curY += 26;
|
|
7108
|
+
}
|
|
7109
|
+
const itemH = 34;
|
|
7110
|
+
items.forEach((item, idx) => {
|
|
7111
|
+
const num = item.number !== void 0 ? String(item.number) : String(idx + 1);
|
|
7112
|
+
const descText = item.description || item.subtitle;
|
|
7113
|
+
const itemY = curY + idx * (itemH + 8);
|
|
7114
|
+
doc.roundedRect(x, itemY, width, itemH, 6).fill(theme.colors.surface || "rgba(255,255,255,0.04)");
|
|
7115
|
+
doc.roundedRect(x, itemY, width, itemH, 6).strokeColor(theme.colors.border || "rgba(255,255,255,0.1)").stroke();
|
|
7116
|
+
doc.roundedRect(x + 10, itemY + 6, 22, 22, 4).fill(theme.colors.primary);
|
|
7117
|
+
doc.font("Helvetica-Bold").fontSize(10).fillColor("#000000").text(num, x + 10, itemY + 11, { width: 22, align: "center" });
|
|
7118
|
+
doc.font("Helvetica-Bold").fontSize(12).fillColor(theme.colors.text).text(this.stripFormatting(item.title), x + 40, itemY + (descText ? 5 : 10), {
|
|
7119
|
+
width: width - 50
|
|
7120
|
+
});
|
|
7121
|
+
if (descText) {
|
|
7122
|
+
doc.font("Helvetica").fontSize(9).fillColor(theme.colors.muted || "#888888").text(this.stripFormatting(descText), x + 40, itemY + 19, {
|
|
7123
|
+
width: width - 50
|
|
7124
|
+
});
|
|
7125
|
+
}
|
|
7126
|
+
});
|
|
7127
|
+
return curY + items.length * (itemH + 8) + 8;
|
|
7128
|
+
}
|
|
7129
|
+
case "icon": {
|
|
7130
|
+
const ic = element;
|
|
7131
|
+
const iconText = `\u2605 ${ic.name.replace(/^[^:]+:/, "").toUpperCase()}`;
|
|
7132
|
+
doc.font("Helvetica-Bold").fontSize(11).fillColor(theme.colors.primary);
|
|
7133
|
+
doc.text(iconText, x, y, { width: 120 });
|
|
7134
|
+
return y + 20;
|
|
7135
|
+
}
|
|
7136
|
+
case "grid": {
|
|
7137
|
+
const g = element;
|
|
7138
|
+
const colCount = typeof g.columns === "number" ? g.columns : parseInt(String(g.columns), 10) || 2;
|
|
7139
|
+
const gap = 16;
|
|
7140
|
+
const availableWidth = width - gap * (colCount - 1);
|
|
7141
|
+
const colWidth = availableWidth / colCount;
|
|
7142
|
+
let maxY = y;
|
|
7143
|
+
for (let i = 0; i < g.elements.length; i++) {
|
|
7144
|
+
const colIdx = i % colCount;
|
|
7145
|
+
const colX = x + colIdx * (colWidth + gap);
|
|
7146
|
+
const childY = this.renderElement(doc, g.elements[i], colX, y, colWidth, theme, presentation);
|
|
7147
|
+
if (childY > maxY)
|
|
7148
|
+
maxY = childY;
|
|
7149
|
+
}
|
|
7150
|
+
return maxY + 8;
|
|
7151
|
+
}
|
|
7152
|
+
case "stack": {
|
|
7153
|
+
const st = element;
|
|
7154
|
+
let curY = y;
|
|
7155
|
+
for (const child of st.elements) {
|
|
7156
|
+
curY = this.renderElement(doc, child, x, curY, width, theme, presentation) + 8;
|
|
7157
|
+
}
|
|
7158
|
+
return curY;
|
|
7159
|
+
}
|
|
4962
7160
|
default:
|
|
4963
7161
|
return y;
|
|
4964
7162
|
}
|
|
@@ -5097,7 +7295,7 @@ function startDevServer(filePath, options = {}) {
|
|
|
5097
7295
|
// src/cli.ts
|
|
5098
7296
|
import { mkdirSync, readFileSync as readFileSync2, watch as fsWatch, writeFileSync } from "fs";
|
|
5099
7297
|
import { basename, dirname, extname, join, resolve as resolve2 } from "path";
|
|
5100
|
-
var VERSION = "0.1.
|
|
7298
|
+
var VERSION = "0.1.21";
|
|
5101
7299
|
function printHelp() {
|
|
5102
7300
|
return `
|
|
5103
7301
|
YumiaMD \u2014 Markdown-based presentation compiler (v${VERSION})
|
|
@@ -5636,10 +7834,21 @@ export {
|
|
|
5636
7834
|
createGroup,
|
|
5637
7835
|
createColumn,
|
|
5638
7836
|
createColumns,
|
|
7837
|
+
createSection,
|
|
7838
|
+
createToc,
|
|
5639
7839
|
createMath,
|
|
5640
7840
|
createLayoutDirective,
|
|
7841
|
+
createIcon,
|
|
7842
|
+
createGrid,
|
|
7843
|
+
createStack,
|
|
7844
|
+
createComponent,
|
|
7845
|
+
createSlot,
|
|
7846
|
+
NativeYumiaParser,
|
|
7847
|
+
parseNativeYumia,
|
|
7848
|
+
parseHighlightLines,
|
|
5641
7849
|
DefaultYumiaParser,
|
|
5642
7850
|
parseYumia,
|
|
7851
|
+
migrateMarkdownToNative,
|
|
5643
7852
|
DEFAULT_VIEWPORT,
|
|
5644
7853
|
VIEWPORT_PRESETS,
|
|
5645
7854
|
DefaultLayoutEngine,
|
|
@@ -5649,6 +7858,11 @@ export {
|
|
|
5649
7858
|
corporateTheme,
|
|
5650
7859
|
terminalTheme,
|
|
5651
7860
|
academicTheme,
|
|
7861
|
+
nordTheme,
|
|
7862
|
+
draculaTheme,
|
|
7863
|
+
tokyoNightTheme,
|
|
7864
|
+
emeraldTheme,
|
|
7865
|
+
synthwaveTheme,
|
|
5652
7866
|
THEME_REGISTRY,
|
|
5653
7867
|
resolveTheme,
|
|
5654
7868
|
createTheme,
|
|
@@ -5657,6 +7871,8 @@ export {
|
|
|
5657
7871
|
parse,
|
|
5658
7872
|
validate,
|
|
5659
7873
|
lint,
|
|
7874
|
+
IconResolver,
|
|
7875
|
+
defaultIconResolver,
|
|
5660
7876
|
cleanFontFace,
|
|
5661
7877
|
parseInlineMarkdown,
|
|
5662
7878
|
PptxRenderer,
|