yumiamd 0.1.18 → 0.1.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "./chunk-SP4B4UF7.js";
4
+ } from "./chunk-YEQHWFYS.js";
5
5
 
6
6
  // src/bin.ts
7
7
  var result = await runCli(process.argv);
@@ -143,6 +143,13 @@ function createColumns(columns, ratios, gap) {
143
143
  ...gap !== void 0 ? { gap } : {}
144
144
  };
145
145
  }
146
+ function createMath(expression, displayMode = true) {
147
+ return {
148
+ type: "math",
149
+ expression,
150
+ displayMode
151
+ };
152
+ }
146
153
  function createLayoutDirective(mode, attributes) {
147
154
  return {
148
155
  type: "layout-directive",
@@ -252,6 +259,15 @@ var DefaultYumiaParser = class {
252
259
  result.theme = metadata["theme"];
253
260
  if (typeof metadata["aspectRatio"] === "string")
254
261
  result.aspectRatio = metadata["aspectRatio"];
262
+ if (typeof metadata["transition"] === "string")
263
+ result.transition = metadata["transition"];
264
+ if (typeof metadata["template"] === "string")
265
+ result.template = metadata["template"];
266
+ if (typeof metadata["embedFonts"] === "string") {
267
+ result.embedFonts = metadata["embedFonts"] === "true" || metadata["embedFonts"] === "yes";
268
+ } else if (typeof metadata["embedFonts"] === "boolean") {
269
+ result.embedFonts = metadata["embedFonts"];
270
+ }
255
271
  const colors = {};
256
272
  if (typeof metadata["background"] === "string")
257
273
  colors.background = metadata["background"];
@@ -304,12 +320,14 @@ var DefaultYumiaParser = class {
304
320
  }
305
321
  parseSlide(slideContent, startLine) {
306
322
  const lines = slideContent.split("\n");
307
- const { elements, notes, layout } = this.parseLines(lines, startLine);
323
+ const { elements, notes, layout, transition } = this.parseLines(lines, startLine);
308
324
  const slideOptions = {};
309
325
  if (notes)
310
326
  slideOptions.notes = notes;
311
327
  if (layout)
312
328
  slideOptions.layout = layout;
329
+ if (transition)
330
+ slideOptions.transition = transition;
313
331
  slideOptions.loc = {
314
332
  start: { line: startLine, column: 1 },
315
333
  end: {
@@ -323,6 +341,7 @@ var DefaultYumiaParser = class {
323
341
  const elements = [];
324
342
  let notes;
325
343
  let layout;
344
+ let transition;
326
345
  let i = 0;
327
346
  let currentParagraph = [];
328
347
  let paragraphStartLine = baseLine;
@@ -405,6 +424,24 @@ var DefaultYumiaParser = class {
405
424
  flushAll();
406
425
  const directiveHeader = line.slice(3).trim();
407
426
  const directiveStartLine = currentLineNum;
427
+ if (directiveHeader.startsWith("transition")) {
428
+ const transArg = directiveHeader.slice(10).trim();
429
+ const typeMatch = transArg.match(/type=['"](.*?)['"]/);
430
+ const durationMatch = transArg.match(/duration=['"](.*?)['"]/);
431
+ const dirMatch = transArg.match(/direction=['"](.*?)['"]/);
432
+ const rawType = typeMatch ? typeMatch[1] : transArg.replace(/duration=['"].*?['"]|direction=['"].*?['"]/, "").trim() || "fade";
433
+ const cleanType = (rawType || "fade").replace(/^['"](.*)['"]$/, "$1");
434
+ const transObj = {
435
+ type: cleanType
436
+ };
437
+ if (durationMatch && durationMatch[1])
438
+ transObj.duration = durationMatch[1];
439
+ if (dirMatch && dirMatch[1])
440
+ transObj.direction = dirMatch[1];
441
+ transition = transObj;
442
+ i++;
443
+ continue;
444
+ }
408
445
  if (directiveHeader.startsWith("layout")) {
409
446
  const layoutMatch = directiveHeader.match(/^layout\s*(.*)$/);
410
447
  const rawArg = layoutMatch && layoutMatch[1] ? layoutMatch[1].trim() : "default";
@@ -477,7 +514,7 @@ var DefaultYumiaParser = class {
477
514
  const innerLine = lines[i]?.trim() ?? "";
478
515
  const isInlineClosed = innerLine.startsWith(":::") && innerLine.endsWith(":::") && innerLine.length > 5;
479
516
  const isSeparator = innerLine === ":::vs" || innerLine.startsWith(":::vs ");
480
- const isSingleLine = isInlineClosed || isSeparator || innerLine.startsWith(":::metric") || innerLine.startsWith(":::layout") || innerLine.startsWith(":::badge") && (innerLine.includes("text=") || innerLine.includes("variant=")) || innerLine.startsWith(":::chart") && innerLine.includes("data=");
517
+ const isSingleLine = isInlineClosed || isSeparator || innerLine.startsWith(":::transition") || innerLine.startsWith(":::metric") || innerLine.startsWith(":::layout") || innerLine.startsWith(":::badge") && (innerLine.includes("text=") || innerLine.includes("variant=")) || innerLine.startsWith(":::chart") && innerLine.includes("data=");
481
518
  if (innerLine.startsWith(":::") && innerLine.length > 3 && !isSingleLine) {
482
519
  nestedCount++;
483
520
  } else if (innerLine === ":::") {
@@ -575,9 +612,50 @@ var DefaultYumiaParser = class {
575
612
  sEl.step = 1;
576
613
  elements.push(sEl);
577
614
  }
615
+ } else if (directiveName === "math") {
616
+ const expr = blockLines.join("\n").trim();
617
+ const el = createMath(expr, true);
618
+ el.loc = {
619
+ start: { line: directiveStartLine, column: 1 },
620
+ end: { line: baseLine + i - 1, column: 1 }
621
+ };
622
+ elements.push(el);
578
623
  }
579
624
  continue;
580
625
  }
626
+ if (line.startsWith("$$")) {
627
+ flushAll();
628
+ const mathStartLine = currentLineNum;
629
+ if (line.length > 2 && line.endsWith("$$") && line.length > 4) {
630
+ const expr = line.slice(2, -2).trim();
631
+ const el2 = createMath(expr, true);
632
+ el2.loc = {
633
+ start: { line: currentLineNum, column: 1 },
634
+ end: { line: currentLineNum, column: rawLine.length + 1 }
635
+ };
636
+ elements.push(el2);
637
+ i++;
638
+ continue;
639
+ }
640
+ const mathLines = [];
641
+ i++;
642
+ while (i < lines.length) {
643
+ const mLine = lines[i] ?? "";
644
+ if (mLine.trim() === "$$") {
645
+ i++;
646
+ break;
647
+ }
648
+ mathLines.push(mLine);
649
+ i++;
650
+ }
651
+ const el = createMath(mathLines.join("\n").trim(), true);
652
+ el.loc = {
653
+ start: { line: mathStartLine, column: 1 },
654
+ end: { line: baseLine + i - 1, column: 1 }
655
+ };
656
+ elements.push(el);
657
+ continue;
658
+ }
581
659
  if (line.startsWith("|") && line.endsWith("|")) {
582
660
  const nextLine = lines[i + 1]?.trim() ?? "";
583
661
  if (nextLine.startsWith("|") && nextLine.includes("---")) {
@@ -678,7 +756,8 @@ var DefaultYumiaParser = class {
678
756
  return {
679
757
  elements,
680
758
  ...notes ? { notes } : {},
681
- ...layout ? { layout } : {}
759
+ ...layout ? { layout } : {},
760
+ ...transition ? { transition } : {}
682
761
  };
683
762
  }
684
763
  parseColumnsBlock(lines, baseLine) {
@@ -699,7 +778,7 @@ var DefaultYumiaParser = class {
699
778
  const innerLine = lines[i]?.trim() ?? "";
700
779
  const isInlineClosed = innerLine.startsWith(":::") && innerLine.endsWith(":::") && innerLine.length > 5;
701
780
  const isSeparator = innerLine === ":::vs" || innerLine.startsWith(":::vs ");
702
- const isSingleLine = isInlineClosed || isSeparator || innerLine.startsWith(":::metric") || innerLine.startsWith(":::layout") || innerLine.startsWith(":::badge") && (innerLine.includes("text=") || innerLine.includes("variant=")) || innerLine.startsWith(":::chart") && innerLine.includes("data=");
781
+ const isSingleLine = isInlineClosed || isSeparator || innerLine.startsWith(":::transition") || innerLine.startsWith(":::metric") || innerLine.startsWith(":::layout") || innerLine.startsWith(":::badge") && (innerLine.includes("text=") || innerLine.includes("variant=")) || innerLine.startsWith(":::chart") && innerLine.includes("data=");
703
782
  if (innerLine.startsWith(":::") && innerLine.length > 3 && !isSingleLine) {
704
783
  nestedCount++;
705
784
  } else if (innerLine === ":::") {
@@ -953,6 +1032,10 @@ var DefaultLayoutEngine = class {
953
1032
  const height = this.estimateMetricHeight(element);
954
1033
  return { element, bounds: { x, y, width, height } };
955
1034
  }
1035
+ case "math": {
1036
+ const height = 90;
1037
+ return { element, bounds: { x, y, width, height } };
1038
+ }
956
1039
  case "card": {
957
1040
  return this.layoutCard(element, x, y, width, gap);
958
1041
  }
@@ -2337,6 +2420,9 @@ var PptxRenderer = class {
2337
2420
  case "mermaid":
2338
2421
  this.renderMermaid(pptxSlide, pptx, element, rect, theme);
2339
2422
  break;
2423
+ case "math":
2424
+ this.renderMath(pptxSlide, pptx, element, rect, theme);
2425
+ break;
2340
2426
  default:
2341
2427
  break;
2342
2428
  }
@@ -2878,6 +2964,48 @@ ${mermaid.code}`, {
2878
2964
  return 18;
2879
2965
  }
2880
2966
  }
2967
+ renderMath(pptxSlide, pptx, math, rect, theme) {
2968
+ const surfaceColor = this.cleanHexColor(theme.colors.surface || "11111b");
2969
+ const borderColor = this.cleanHexColor(theme.colors.border || theme.colors.primary);
2970
+ const accentColor = this.cleanHexColor(theme.colors.primary);
2971
+ const textColor = this.cleanHexColor(theme.colors.text || "ffffff");
2972
+ pptxSlide.addShape(pptx.ShapeType.roundRect, {
2973
+ x: rect.x,
2974
+ y: rect.y,
2975
+ w: rect.w,
2976
+ h: rect.h,
2977
+ rectRadius: 0.08,
2978
+ fill: { color: surfaceColor },
2979
+ line: { color: borderColor, width: 1.2 }
2980
+ });
2981
+ pptxSlide.addShape(pptx.ShapeType.rect, {
2982
+ x: rect.x,
2983
+ y: rect.y,
2984
+ w: 0.06,
2985
+ h: rect.h,
2986
+ fill: { color: accentColor },
2987
+ line: { color: accentColor, width: 0 }
2988
+ });
2989
+ pptxSlide.addText([
2990
+ {
2991
+ text: math.expression,
2992
+ options: {
2993
+ fontFace: "Cambria Math",
2994
+ fontSize: 20,
2995
+ color: textColor,
2996
+ italic: true,
2997
+ align: "center",
2998
+ valign: "middle"
2999
+ }
3000
+ }
3001
+ ], {
3002
+ x: rect.x + 0.15,
3003
+ y: rect.y,
3004
+ w: Math.max(0.1, rect.w - 0.3),
3005
+ h: rect.h,
3006
+ margin: 0.08
3007
+ });
3008
+ }
2881
3009
  isDarkColor(rawHex) {
2882
3010
  const hex = this.cleanHexColor(rawHex);
2883
3011
  const r = parseInt(hex.substring(0, 2), 16) || 0;
@@ -3551,6 +3679,55 @@ var HtmlRenderer = class {
3551
3679
  max-height: 420px;
3552
3680
  }
3553
3681
 
3682
+ /* Math Equation Container */
3683
+ .yumia-math-container {
3684
+ background: var(--yumia-surface);
3685
+ border: 1.5px solid var(--yumia-border);
3686
+ border-left: 4px solid var(--yumia-primary);
3687
+ border-radius: var(--yumia-radius-card);
3688
+ padding: 1.25rem 2rem;
3689
+ margin: 1.2rem 0;
3690
+ display: flex;
3691
+ align-items: center;
3692
+ justify-content: center;
3693
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.25);
3694
+ }
3695
+
3696
+ .yumia-math-equation {
3697
+ font-family: 'Cambria Math', 'JetBrains Mono', monospace;
3698
+ font-size: clamp(1.2rem, 2.2vw, 1.8rem);
3699
+ font-style: italic;
3700
+ color: var(--yumia-text);
3701
+ letter-spacing: 0.05em;
3702
+ }
3703
+
3704
+ /* Slide Transitions */
3705
+ .yumia-slide-wrapper.transition-fade.active {
3706
+ animation: fadeIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
3707
+ }
3708
+ .yumia-slide-wrapper.transition-push.active {
3709
+ animation: pushIn 0.35s cubic-bezier(0.16, 1, 0.3, 1);
3710
+ }
3711
+ .yumia-slide-wrapper.transition-wipe.active {
3712
+ animation: wipeIn 0.4s cubic-bezier(0.16, 1, 0.3, 1);
3713
+ }
3714
+ .yumia-slide-wrapper.transition-zoom.active {
3715
+ animation: zoomIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
3716
+ }
3717
+
3718
+ @keyframes pushIn {
3719
+ from { opacity: 0; transform: translateX(40px); }
3720
+ to { opacity: 1; transform: translateX(0); }
3721
+ }
3722
+ @keyframes wipeIn {
3723
+ from { clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%); }
3724
+ to { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
3725
+ }
3726
+ @keyframes zoomIn {
3727
+ from { opacity: 0; transform: scale(0.92); }
3728
+ to { opacity: 1; transform: scale(1); }
3729
+ }
3730
+
3554
3731
  /* Progressive Reveal (Step Builds) */
3555
3732
  .yumia-slide-wrapper [data-step] {
3556
3733
  transition: opacity 0.25s ease, transform 0.25s ease;
@@ -4109,9 +4286,12 @@ var HtmlRenderer = class {
4109
4286
  const activeClass = slideNum === 1 ? "active" : "";
4110
4287
  const notesAttr = slide.notes ? this.escapeHtml(slide.notes.replace(/\n/g, "<br>")) : "";
4111
4288
  const progressPercent = Math.round(slideNum / totalSlides * 100);
4289
+ const transition = slide.transition || "fade";
4290
+ const transType = typeof transition === "string" ? transition : transition.type;
4291
+ const transClass = `transition-${transType || "fade"}`;
4112
4292
  const elementsHtml = slide.elements.map((el) => this.renderElement(el, theme)).join("\n");
4113
4293
  return `
4114
- <div class="yumia-slide-wrapper ${activeClass}" id="slide-${slideNum}" data-notes="${notesAttr}">
4294
+ <div class="yumia-slide-wrapper ${activeClass} ${transClass}" id="slide-${slideNum}" data-notes="${notesAttr}">
4115
4295
  ${elementsHtml}
4116
4296
  <div class="yumia-progress-bar" style="width: ${progressPercent}%;"></div>
4117
4297
  </div>`;
@@ -4211,6 +4391,13 @@ var HtmlRenderer = class {
4211
4391
  <pre class="mermaid">${this.escapeHtml(m.code)}</pre>
4212
4392
  </div>`;
4213
4393
  }
4394
+ case "math": {
4395
+ const mathEl = element;
4396
+ return `
4397
+ <div class="yumia-math-container">
4398
+ <div class="yumia-math-equation">${this.escapeHtml(mathEl.expression)}</div>
4399
+ </div>`;
4400
+ }
4214
4401
  case "chart": {
4215
4402
  return this.renderChart(element, theme);
4216
4403
  }
@@ -4727,6 +4914,18 @@ var PdfRenderer = class {
4727
4914
  doc.font("Courier").fontSize(11).fillColor(theme.colors.text).text(this.stripFormatting(m.code), x + 12, y + 12, { width: width - 24 });
4728
4915
  return y + boxH + 8;
4729
4916
  }
4917
+ case "math": {
4918
+ const mathEl = element;
4919
+ const boxH = 50;
4920
+ doc.roundedRect(x, y, width, boxH, 6).fill(theme.colors.surface || "rgba(255,255,255,0.06)");
4921
+ doc.roundedRect(x, y, width, boxH, 6).lineWidth(1).strokeColor(theme.colors.border || theme.colors.primary).stroke();
4922
+ doc.rect(x, y, 4, boxH).fill(theme.colors.primary);
4923
+ doc.font("Helvetica-Oblique").fontSize(14).fillColor(theme.colors.text).text(this.stripFormatting(mathEl.expression), x + 16, y + 18, {
4924
+ width: width - 32,
4925
+ align: "center"
4926
+ });
4927
+ return y + boxH + 8;
4928
+ }
4730
4929
  default:
4731
4930
  return y;
4732
4931
  }
@@ -4858,7 +5057,7 @@ function startDevServer(filePath, options = {}) {
4858
5057
  // src/cli.ts
4859
5058
  import { mkdirSync, readFileSync as readFileSync2, watch as fsWatch, writeFileSync } from "fs";
4860
5059
  import { basename, dirname, extname, join, resolve as resolve2 } from "path";
4861
- var VERSION = "0.1.18";
5060
+ var VERSION = "0.1.19";
4862
5061
  function printHelp() {
4863
5062
  return `
4864
5063
  YumiaMD \u2014 Markdown-based presentation compiler (v${VERSION})
@@ -4884,6 +5083,9 @@ Theming & Color Options:
4884
5083
  --secondary Hex secondary color (e.g. "#00F0FF")
4885
5084
  --text Hex text color (e.g. "#FFFFFF" or "#0F172A")
4886
5085
  --accent Hex accent bar & highlight color
5086
+ --transition Default transition: push | fade | wipe | zoom
5087
+ --template, -T Master template file (.potx) or custom layout
5088
+ --embed-fonts Embed custom TrueType fonts in presentation package
4887
5089
 
4888
5090
  Server & Compiler Options:
4889
5091
  --port <num> Port for live dev server (default: 3000)
@@ -5394,6 +5596,7 @@ export {
5394
5596
  createGroup,
5395
5597
  createColumn,
5396
5598
  createColumns,
5599
+ createMath,
5397
5600
  createLayoutDirective,
5398
5601
  DefaultYumiaParser,
5399
5602
  parseYumia,
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ export * from '@yumiamd/renderer-pptx';
9
9
  export * from '@yumiamd/renderer-html';
10
10
  export * from '@yumiamd/renderer-pdf';
11
11
 
12
- declare const VERSION = "0.1.18";
12
+ declare const VERSION = "0.1.19";
13
13
  declare function printHelp(): string;
14
14
  declare function runCli(argv: string[]): Promise<{
15
15
  exitCode: number;
package/dist/index.js CHANGED
@@ -25,6 +25,7 @@ import {
25
25
  createImage,
26
26
  createLayoutDirective,
27
27
  createList,
28
+ createMath,
28
29
  createMermaid,
29
30
  createMetric,
30
31
  createParagraph,
@@ -47,7 +48,7 @@ import {
47
48
  startDevServer,
48
49
  terminalTheme,
49
50
  validate
50
- } from "./chunk-SP4B4UF7.js";
51
+ } from "./chunk-YEQHWFYS.js";
51
52
  export {
52
53
  DEFAULT_VIEWPORT,
53
54
  DefaultLayoutEngine,
@@ -75,6 +76,7 @@ export {
75
76
  createImage,
76
77
  createLayoutDirective,
77
78
  createList,
79
+ createMath,
78
80
  createMermaid,
79
81
  createMetric,
80
82
  createParagraph,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yumiamd",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Command line interface and compiler for YumiaMD presentations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,15 +21,15 @@
21
21
  },
22
22
  "devDependencies": {
23
23
  "tsup": "^8.5.1",
24
- "@yumiamd/ast": "0.1.18",
25
- "@yumiamd/renderer": "0.1.18",
26
- "@yumiamd/layout": "0.1.18",
27
- "@yumiamd/core": "0.1.18",
28
- "@yumiamd/theme": "0.1.18",
29
- "@yumiamd/renderer-html": "0.1.18",
30
- "@yumiamd/parser": "0.1.18",
31
- "@yumiamd/renderer-pptx": "0.1.18",
32
- "@yumiamd/renderer-pdf": "0.1.18"
24
+ "@yumiamd/ast": "0.1.19",
25
+ "@yumiamd/layout": "0.1.19",
26
+ "@yumiamd/parser": "0.1.19",
27
+ "@yumiamd/renderer-pdf": "0.1.19",
28
+ "@yumiamd/renderer": "0.1.19",
29
+ "@yumiamd/renderer-html": "0.1.19",
30
+ "@yumiamd/core": "0.1.19",
31
+ "@yumiamd/theme": "0.1.19",
32
+ "@yumiamd/renderer-pptx": "0.1.19"
33
33
  },
34
34
  "keywords": [
35
35
  "yumia",