@markdy/core 1.4.4 → 1.4.6

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/index.d.ts CHANGED
@@ -87,6 +87,8 @@ type SceneMeta = {
87
87
  explicitTheme?: boolean;
88
88
  /** Whether layout direction was explicitly specified by the author in the script. */
89
89
  explicitDirection?: boolean;
90
+ /** Layout mode: explicit fixed direction or adaptive auto. */
91
+ layoutMode?: "auto" | "explicit";
90
92
  /** Opt-in diagram mode; defaults to architecture. */
91
93
  type?: DiagramType;
92
94
  /** Playback, controls, interaction, and chrome behavior. Source of truth. */
package/dist/index.js CHANGED
@@ -2237,9 +2237,11 @@ function layoutRadar(ast) {
2237
2237
  }
2238
2238
  function layoutNodes(ast, edges) {
2239
2239
  const dtype = diagramType(ast);
2240
+ const isAutoNarrow = (ast.meta.layoutMode === "auto" || !ast.meta.explicitDirection) && ast.meta.explicitWidth && ast.meta.width < 640;
2241
+ const isVertical = isAutoNarrow || ast.meta.direction === "TB" || ast.meta.direction === "BT";
2240
2242
  switch (dtype) {
2241
2243
  case "flowchart":
2242
- return layoutRanked(ast, edges, { forceVertical: ast.meta.direction === "TB" || ast.meta.direction === "BT" });
2244
+ return layoutRanked(ast, edges, { forceVertical: isVertical });
2243
2245
  case "tree":
2244
2246
  return layoutTree(ast, edges.some((edge) => edge.structural) ? edges.filter((edge) => edge.structural) : edges);
2245
2247
  case "sequence":
@@ -2270,9 +2272,9 @@ function layoutNodes(ast, edges) {
2270
2272
  case "nested":
2271
2273
  return layoutNested(ast);
2272
2274
  case "state":
2273
- return layoutRanked(ast, cycleSafeEdges(Object.keys(ast.nodes), edges), { forceVertical: ast.meta.direction === "TB" || ast.meta.direction === "BT" });
2275
+ return layoutRanked(ast, cycleSafeEdges(Object.keys(ast.nodes), edges), { forceVertical: isVertical });
2274
2276
  default:
2275
- return layoutRanked(ast, edges, { forceVertical: ast.meta.direction === "TB" || ast.meta.direction === "BT" });
2277
+ return layoutRanked(ast, edges, { forceVertical: isVertical });
2276
2278
  }
2277
2279
  }
2278
2280
  function computeGroupBoundaries(ast, nodes) {
@@ -2546,7 +2548,10 @@ function computeAdaptiveDimensions(ast, edges) {
2546
2548
  const nodeIds = Object.keys(ast.nodes);
2547
2549
  const nodeCount = nodeIds.length;
2548
2550
  const dtype = diagramType(ast);
2549
- const direction = ast.meta.direction ?? "LR";
2551
+ let direction = ast.meta.direction ?? "LR";
2552
+ if ((ast.meta.layoutMode === "auto" || !ast.meta.explicitDirection) && ast.meta.explicitWidth && ast.meta.width < 640) {
2553
+ direction = ast.meta.direction === "RL" || ast.meta.direction === "BT" ? "BT" : "TB";
2554
+ }
2550
2555
  const isVertical = direction === "TB" || direction === "BT";
2551
2556
  const groupCount = Object.keys(ast.groups).length;
2552
2557
  const nodeDims = nodeIds.map((id) => computeNodeDimensions(ast.nodes[id]));
@@ -3957,7 +3962,8 @@ function parse(source, opts = {}) {
3957
3962
  theme: "paper",
3958
3963
  explicitTheme: false,
3959
3964
  direction: "LR",
3960
- explicitDirection: false
3965
+ explicitDirection: false,
3966
+ layoutMode: "auto"
3961
3967
  };
3962
3968
  const styles = {};
3963
3969
  const nodes = {};
@@ -4058,11 +4064,19 @@ function parse(source, opts = {}) {
4058
4064
  meta.title = title;
4059
4065
  remainder = str.rest;
4060
4066
  }
4061
- const inlineLayout = remainder.match(/\b(?:layout|direction|rankdir)\s+(LR|RL|TB|BT)\b/i);
4067
+ const inlineLayout = remainder.match(/\b(?:layout|direction|rankdir)\s+(LR|RL|TB|BT|auto)\b/i);
4062
4068
  if (inlineLayout) {
4063
- meta.direction = inlineLayout[1].toUpperCase();
4064
- meta.explicitDirection = true;
4065
- remainder = remainder.replace(/\b(?:layout|direction|rankdir)\s+(LR|RL|TB|BT)\b/i, " ");
4069
+ const val = inlineLayout[1].toUpperCase();
4070
+ if (val === "AUTO") {
4071
+ meta.direction = "LR";
4072
+ meta.explicitDirection = false;
4073
+ meta.layoutMode = "auto";
4074
+ } else {
4075
+ meta.direction = val;
4076
+ meta.explicitDirection = true;
4077
+ meta.layoutMode = "explicit";
4078
+ }
4079
+ remainder = remainder.replace(/\b(?:layout|direction|rankdir)\s+(LR|RL|TB|BT|auto)\b/i, " ");
4066
4080
  }
4067
4081
  const props = parseProps(remainder);
4068
4082
  for (const [k, v] of Object.entries(props)) {
@@ -4084,8 +4098,16 @@ function parse(source, opts = {}) {
4084
4098
  meta.theme = val;
4085
4099
  meta.explicitTheme = val !== "auto";
4086
4100
  } else if (k === "direction" || k === "layout" || k === "rankdir") {
4087
- meta.direction = String(v).toUpperCase();
4088
- meta.explicitDirection = true;
4101
+ const val = String(v).toUpperCase();
4102
+ if (val === "AUTO") {
4103
+ meta.direction = "LR";
4104
+ meta.explicitDirection = false;
4105
+ meta.layoutMode = "auto";
4106
+ } else {
4107
+ meta.direction = val;
4108
+ meta.explicitDirection = true;
4109
+ meta.layoutMode = "explicit";
4110
+ }
4089
4111
  } else if (PLAYER_FLAT_KEY_SET.has(k)) {
4090
4112
  const error = applyPlayerSetting(meta.player ??= {}, "player", k, String(v));
4091
4113
  if (error) diagnostics.push({ severity: "warning", message: error, line: lineNo });
@@ -4122,9 +4144,17 @@ function parse(source, opts = {}) {
4122
4144
  i++;
4123
4145
  continue;
4124
4146
  }
4125
- if (/^layout\s+(LR|RL|TB|BT)\b/i.test(line)) {
4126
- meta.direction = line.split(/\s+/)[1].toUpperCase();
4127
- meta.explicitDirection = true;
4147
+ if (/^layout\s+(LR|RL|TB|BT|auto)\b/i.test(line)) {
4148
+ const val = line.split(/\s+/)[1].toUpperCase();
4149
+ if (val === "AUTO") {
4150
+ meta.direction = "LR";
4151
+ meta.explicitDirection = false;
4152
+ meta.layoutMode = "auto";
4153
+ } else {
4154
+ meta.direction = val;
4155
+ meta.explicitDirection = true;
4156
+ meta.layoutMode = "explicit";
4157
+ }
4128
4158
  i++;
4129
4159
  continue;
4130
4160
  }
@@ -7266,6 +7296,7 @@ function getIntelliCodeCompletions(docText, cursorLine, cursorCol) {
7266
7296
  }
7267
7297
  if (/(layout\s+|direction\s*=\s*)\w*$/i.test(ctx.linePrefix)) {
7268
7298
  items.push(
7299
+ { label: "auto", insertText: "auto", kind: "layout", detail: "Responsive Auto (LR / TB)", documentation: "Automatically adapts layout orientation between horizontal (LR) and vertical (TB) based on container width.", boost: 11 },
7269
7300
  { label: "LR", insertText: "LR", kind: "layout", detail: "Left-to-Right", documentation: "Horizontal left-to-right system flow layout.", boost: 10 },
7270
7301
  { label: "TB", insertText: "TB", kind: "layout", detail: "Top-to-Bottom", documentation: "Vertical top-to-bottom hierarchy layout.", boost: 9 },
7271
7302
  { label: "RL", insertText: "RL", kind: "layout", detail: "Right-to-Left", documentation: "Right-to-left reverse topology layout.", boost: 5 },
@@ -7637,7 +7668,9 @@ function formatScene(ast) {
7637
7668
  if (ast.meta.fps !== 60) sceneParts.push(`fps=${ast.meta.fps}`);
7638
7669
  if (ast.meta.duration !== void 0) sceneParts.push(`duration=${ast.meta.duration}`);
7639
7670
  lines.push(sceneParts.join(" "));
7640
- if (ast.meta.direction !== "LR") {
7671
+ if (ast.meta.layoutMode === "auto") {
7672
+ lines.push("layout auto");
7673
+ } else if (ast.meta.direction !== "LR") {
7641
7674
  lines.push(`layout ${ast.meta.direction}`);
7642
7675
  }
7643
7676
  for (const style of Object.values(ast.styles)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markdy/core",
3
- "version": "1.4.4",
3
+ "version": "1.4.6",
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",