@markdy/core 0.8.19 → 0.8.20

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/README.md CHANGED
@@ -68,7 +68,7 @@ try {
68
68
  | `ParseError` | class | Error with `.line` number for diagnostics |
69
69
  | `DiagramAST` | type | Parsed scene: meta, nodes, edges, groups, patterns, beats |
70
70
  | `RenderPlan` | type | Positioned nodes, routed edges, group zones, sequence messages, timed cues, beat ranges |
71
- | `SceneMeta` | type | Scene configuration (width, height, fps, theme, direction) |
71
+ | `SceneMeta` | type | Scene configuration (width, height, fps, theme, direction, controls, interactive, progressColor, playbackRate, loop, autoplay, copyright) |
72
72
  | `NodeDecl` | type | Node declaration (kind, id, label, style) |
73
73
  | `EdgeDecl` | type | Edge declaration (kind, from, to, label) |
74
74
  | `BeatDecl` | type | Named beat with cues |
package/dist/index.d.ts CHANGED
@@ -16,6 +16,20 @@ type SceneMeta = {
16
16
  duration?: number;
17
17
  /** Opt-in diagram mode; defaults to architecture. */
18
18
  type?: DiagramType;
19
+ /** Optional custom progress bar color or gradient. Defaults to rainbow. */
20
+ progressColor?: string;
21
+ /** Enable playback and view reset controls toolbar. */
22
+ controls?: boolean;
23
+ /** Enable wheel zoom and drag pan. */
24
+ interactiveViewport?: boolean;
25
+ /** Autoplay timeline on load. */
26
+ autoplay?: boolean;
27
+ /** Loop playback when reaching the end. */
28
+ loop?: boolean;
29
+ /** Show copyright badge. */
30
+ copyright?: boolean;
31
+ /** Default playback speed multiplier. */
32
+ playbackRate?: number;
19
33
  };
20
34
  type NodeDecl = {
21
35
  kind: string;
package/dist/index.js CHANGED
@@ -400,7 +400,24 @@ var SCENE_KEYS = /* @__PURE__ */ new Set([
400
400
  "duration",
401
401
  "direction",
402
402
  "layout",
403
- "type"
403
+ "type",
404
+ "progressColor",
405
+ "progressBarColor",
406
+ "progress_color",
407
+ "progress_bar_color",
408
+ "progress",
409
+ "progressBar",
410
+ "sceneBoundaryProgress",
411
+ "controls",
412
+ "interactive",
413
+ "interactiveViewport",
414
+ "interactive_viewport",
415
+ "autoplay",
416
+ "loop",
417
+ "copyright",
418
+ "playbackRate",
419
+ "playback_rate",
420
+ "speed"
404
421
  ]);
405
422
  function nodeRole(kind) {
406
423
  const canonical = canonicalNodeKind(kind);
@@ -1571,7 +1588,14 @@ function readIndentedBody(blocks, startIdx, parentIndent) {
1571
1588
  }
1572
1589
  return { body, nextIdx: i };
1573
1590
  }
1574
- var TOP_LEVEL_KEYWORDS_RE = /^(scene|layout|pattern|group|annotation|edge|beat|var|style)\b/;
1591
+ function parseBooleanToken(raw) {
1592
+ if (typeof raw === "boolean") return raw;
1593
+ const s = String(raw).trim().toLowerCase();
1594
+ if (["true", "on", "yes", "1"].includes(s)) return true;
1595
+ if (["false", "off", "no", "0"].includes(s)) return false;
1596
+ return void 0;
1597
+ }
1598
+ var TOP_LEVEL_KEYWORDS_RE = /^(scene|layout|pattern|group|annotation|edge|beat|var|style|controls|interactive|interactiveViewport|interactive_viewport|autoplay|loop|copyright|playbackRate|playback_rate|speed|progressColor|progressBarColor|progress_color|progress_bar_color|progress|progressBar)\b/;
1575
1599
  function isTopLevelStatement(line) {
1576
1600
  if (line === "}") return true;
1577
1601
  if (TOP_LEVEL_KEYWORDS_RE.test(line)) return true;
@@ -1849,7 +1873,29 @@ function parse(source, opts = {}) {
1849
1873
  else if (k === "duration") meta.duration = Number(v);
1850
1874
  else if (k === "theme") meta.theme = String(v);
1851
1875
  else if (k === "direction" || k === "layout") meta.direction = String(v).toUpperCase();
1852
- else if (k === "type") {
1876
+ else if (k === "progressColor" || k === "progressBarColor" || k === "progress_color" || k === "progress_bar_color" || k === "progress") {
1877
+ meta.progressColor = String(v);
1878
+ } else if (k === "progressBar" || k === "sceneBoundaryProgress") {
1879
+ const bool = parseBooleanToken(v);
1880
+ if (bool !== void 0) {
1881
+ if (!bool) meta.progressColor = "none";
1882
+ } else {
1883
+ meta.progressColor = String(v);
1884
+ }
1885
+ } else if (k === "controls") {
1886
+ meta.controls = parseBooleanToken(v) ?? true;
1887
+ } else if (k === "interactive" || k === "interactiveViewport" || k === "interactive_viewport") {
1888
+ meta.interactiveViewport = parseBooleanToken(v) ?? true;
1889
+ } else if (k === "autoplay") {
1890
+ meta.autoplay = parseBooleanToken(v) ?? true;
1891
+ } else if (k === "loop") {
1892
+ meta.loop = parseBooleanToken(v) ?? true;
1893
+ } else if (k === "copyright") {
1894
+ meta.copyright = parseBooleanToken(v) ?? true;
1895
+ } else if (k === "playbackRate" || k === "playback_rate" || k === "speed") {
1896
+ const r = Number(v);
1897
+ if (!Number.isNaN(r) && r > 0) meta.playbackRate = r;
1898
+ } else if (k === "type") {
1853
1899
  const t = String(v).toLowerCase();
1854
1900
  if (!DIAGRAM_TYPES.has(t)) {
1855
1901
  diagnostics.push({ severity: "warning", message: `unknown diagram type '${v}'`, line: lineNo });
@@ -1861,6 +1907,36 @@ function parse(source, opts = {}) {
1861
1907
  i++;
1862
1908
  continue;
1863
1909
  }
1910
+ const directiveMatch = line.match(
1911
+ /^(controls|interactive|interactiveViewport|interactive_viewport|autoplay|loop|copyright|playbackRate|playback_rate|speed|progressColor|progressBarColor|progress_color|progress_bar_color|progress|progressBar)\b(?:\s*[:=]?\s*(.+))?$/
1912
+ );
1913
+ if (directiveMatch) {
1914
+ const keyword = directiveMatch[1];
1915
+ const rawVal = (directiveMatch[2] ?? "").trim();
1916
+ const val = rawVal.startsWith('"') && rawVal.endsWith('"') || rawVal.startsWith("'") && rawVal.endsWith("'") ? rawVal.slice(1, -1) : rawVal;
1917
+ if (keyword === "controls") {
1918
+ meta.controls = val ? parseBooleanToken(val) ?? true : true;
1919
+ } else if (keyword === "interactive" || keyword === "interactiveViewport" || keyword === "interactive_viewport") {
1920
+ meta.interactiveViewport = val ? parseBooleanToken(val) ?? true : true;
1921
+ } else if (keyword === "autoplay") {
1922
+ meta.autoplay = val ? parseBooleanToken(val) ?? true : true;
1923
+ } else if (keyword === "loop") {
1924
+ meta.loop = val ? parseBooleanToken(val) ?? true : true;
1925
+ } else if (keyword === "copyright") {
1926
+ meta.copyright = val ? parseBooleanToken(val) ?? true : true;
1927
+ } else if (keyword === "playbackRate" || keyword === "playback_rate" || keyword === "speed") {
1928
+ const r = Number(val);
1929
+ if (!Number.isNaN(r) && r > 0) meta.playbackRate = r;
1930
+ } else if (keyword === "progressColor" || keyword === "progressBarColor" || keyword === "progress_color" || keyword === "progress_bar_color" || keyword === "progress") {
1931
+ if (val) meta.progressColor = val;
1932
+ } else if (keyword === "progressBar") {
1933
+ const bool = parseBooleanToken(val);
1934
+ if (bool === false) meta.progressColor = "none";
1935
+ else if (val) meta.progressColor = val;
1936
+ }
1937
+ i++;
1938
+ continue;
1939
+ }
1864
1940
  if (/^layout\s+(LR|RL|TB|BT)\b/i.test(line)) {
1865
1941
  meta.direction = line.split(/\s+/)[1].toUpperCase();
1866
1942
  i++;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markdy/core",
3
- "version": "0.8.19",
3
+ "version": "0.8.20",
4
4
  "description": "Diagram-native MarkdyScript parser and compiler (auto-layout, edge routing, cue scheduling) — zero runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "type": "module",