@ktrysmt/beautiful-mermaid 1.4.0 → 1.4.2

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.js CHANGED
@@ -416,7 +416,7 @@ function parseFlowchart(lines) {
416
416
  const subgraphMatch = line.match(/^subgraph\s+(.+)$/);
417
417
  if (subgraphMatch) {
418
418
  const rest = subgraphMatch[1].trim();
419
- const bracketMatch = rest.match(/^([\w-]+)\s*\[(.+)\]$/);
419
+ const bracketMatch = rest.match(/^([\w\p{L}-]+)\s*\[(.+)\]$/u);
420
420
  let id;
421
421
  let label;
422
422
  if (bracketMatch) {
@@ -424,7 +424,7 @@ function parseFlowchart(lines) {
424
424
  label = normalizeBrTags(bracketMatch[2]);
425
425
  } else {
426
426
  label = normalizeBrTags(rest);
427
- id = rest.replace(/\s+/g, "_").replace(/[^\w]/g, "");
427
+ id = rest.replace(/\s+/g, "_").replace(/[^\p{L}\p{N}\w]/gu, "");
428
428
  }
429
429
  const sg = { id, label, nodeIds: [], children: [] };
430
430
  subgraphStack.push(sg);
@@ -1606,6 +1606,18 @@ function buildSgMap(mSgs, aSgs, result) {
1606
1606
  }
1607
1607
  }
1608
1608
 
1609
+ // src/ascii/multiline-utils.ts
1610
+ function splitLines(label) {
1611
+ return label.split("\n");
1612
+ }
1613
+ function maxLineWidth(label) {
1614
+ const lines = splitLines(label);
1615
+ return Math.max(...lines.map((l) => displayWidth(l)), 0);
1616
+ }
1617
+ function lineCount(label) {
1618
+ return splitLines(label).length;
1619
+ }
1620
+
1609
1621
  // src/ascii/pathfinder.ts
1610
1622
  var MinHeap = class {
1611
1623
  items = [];
@@ -1894,7 +1906,7 @@ function determinePath(graph, edge) {
1894
1906
  }
1895
1907
  function determineLabelLine(graph, edge) {
1896
1908
  if (edge.text.length === 0) return;
1897
- const lenLabel = displayWidth(edge.text);
1909
+ const lenLabel = maxLineWidth(edge.text);
1898
1910
  const pathLen = edge.path.length;
1899
1911
  const isVerticalFlow = graph.config.graphDirection === "TD";
1900
1912
  const segments = [];
@@ -2095,18 +2107,6 @@ function processBundles(graph) {
2095
2107
  }
2096
2108
  }
2097
2109
 
2098
- // src/ascii/multiline-utils.ts
2099
- function splitLines(label) {
2100
- return label.split("\n");
2101
- }
2102
- function maxLineWidth(label) {
2103
- const lines = splitLines(label);
2104
- return Math.max(...lines.map((l) => displayWidth(l)), 0);
2105
- }
2106
- function lineCount(label) {
2107
- return splitLines(label).length;
2108
- }
2109
-
2110
2110
  // src/ascii/shapes/corners.ts
2111
2111
  var SHAPE_CORNERS = {
2112
2112
  // Standard rectangular shapes
@@ -3652,18 +3652,37 @@ function ensureSubgraphSpacing(graph) {
3652
3652
  for (let j = i + 1; j < rootSubgraphs.length; j++) {
3653
3653
  const sg1 = rootSubgraphs[i];
3654
3654
  const sg2 = rootSubgraphs[j];
3655
- if (sg1.minX < sg2.maxX && sg1.maxX > sg2.minX) {
3656
- if (sg1.maxY >= sg2.minY - minSpacing && sg1.minY < sg2.minY) {
3657
- sg2.minY = sg1.maxY + minSpacing + 1;
3658
- } else if (sg2.maxY >= sg1.minY - minSpacing && sg2.minY < sg1.minY) {
3659
- sg1.minY = sg2.maxY + minSpacing + 1;
3655
+ const hOverlap = sg1.minX <= sg2.maxX && sg1.maxX >= sg2.minX;
3656
+ const vOverlap = sg1.minY <= sg2.maxY && sg1.maxY >= sg2.minY;
3657
+ if (!hOverlap || !vOverlap) continue;
3658
+ if (hOverlap) {
3659
+ if (sg1.maxY >= sg2.minY - minSpacing && sg1.minY <= sg2.minY) {
3660
+ const newMinY = sg1.maxY + minSpacing + 1;
3661
+ if (newMinY > sg2.maxY) {
3662
+ sg2.maxY = newMinY + (sg2.maxY - sg2.minY);
3663
+ }
3664
+ sg2.minY = newMinY;
3665
+ } else if (sg2.maxY >= sg1.minY - minSpacing && sg2.minY <= sg1.minY) {
3666
+ const newMinY = sg2.maxY + minSpacing + 1;
3667
+ if (newMinY > sg1.maxY) {
3668
+ sg1.maxY = newMinY + (sg1.maxY - sg1.minY);
3669
+ }
3670
+ sg1.minY = newMinY;
3660
3671
  }
3661
3672
  }
3662
- if (sg1.minY < sg2.maxY && sg1.maxY > sg2.minY) {
3663
- if (sg1.maxX >= sg2.minX - minSpacing && sg1.minX < sg2.minX) {
3664
- sg2.minX = sg1.maxX + minSpacing + 1;
3665
- } else if (sg2.maxX >= sg1.minX - minSpacing && sg2.minX < sg1.minX) {
3666
- sg1.minX = sg2.maxX + minSpacing + 1;
3673
+ if (sg1.minY <= sg2.maxY && sg1.maxY >= sg2.minY) {
3674
+ if (sg1.maxX >= sg2.minX - minSpacing && sg1.minX <= sg2.minX) {
3675
+ const newMinX = sg1.maxX + minSpacing + 1;
3676
+ if (newMinX > sg2.maxX) {
3677
+ sg2.maxX = newMinX + (sg2.maxX - sg2.minX);
3678
+ }
3679
+ sg2.minX = newMinX;
3680
+ } else if (sg2.maxX >= sg1.minX - minSpacing && sg2.minX <= sg1.minX) {
3681
+ const newMinX = sg2.maxX + minSpacing + 1;
3682
+ if (newMinX > sg1.maxX) {
3683
+ sg1.maxX = newMinX + (sg1.maxX - sg1.minX);
3684
+ }
3685
+ sg1.minX = newMinX;
3667
3686
  }
3668
3687
  }
3669
3688
  }
@@ -3732,6 +3751,14 @@ function createMapping(graph) {
3732
3751
  }
3733
3752
  }
3734
3753
  const shouldSeparate = dir === "LR" && hasExternalRoots && hasSubgraphRootsWithEdges;
3754
+ const downstreamSgs = /* @__PURE__ */ new Set();
3755
+ for (const edge of graph.edges) {
3756
+ const fromSg = getNodeSubgraph(graph, edge.from);
3757
+ const toSg = getNodeSubgraph(graph, edge.to);
3758
+ if (fromSg && toSg && fromSg !== toSg && !fromSg.parent && !toSg.parent) {
3759
+ downstreamSgs.add(toSg);
3760
+ }
3761
+ }
3735
3762
  let externalRootNodes;
3736
3763
  let subgraphRootNodes = [];
3737
3764
  if (shouldSeparate) {
@@ -3740,8 +3767,18 @@ function createMapping(graph) {
3740
3767
  } else {
3741
3768
  externalRootNodes = rootNodes;
3742
3769
  }
3743
- const rootsByTarget = /* @__PURE__ */ new Map();
3770
+ const deferredRoots = /* @__PURE__ */ new Set();
3771
+ const primaryRoots = [];
3744
3772
  for (const root of externalRootNodes) {
3773
+ const sg = getNodeSubgraph(graph, root);
3774
+ if (sg && downstreamSgs.has(sg)) {
3775
+ deferredRoots.add(root);
3776
+ } else {
3777
+ primaryRoots.push(root);
3778
+ }
3779
+ }
3780
+ const rootsByTarget = /* @__PURE__ */ new Map();
3781
+ for (const root of primaryRoots) {
3745
3782
  const children = getChildren(graph, root);
3746
3783
  const targetName = children.length > 0 ? children[0].name : "__ungrouped__";
3747
3784
  const group = rootsByTarget.get(targetName) ?? [];
@@ -3767,7 +3804,7 @@ function createMapping(graph) {
3767
3804
  for (const edge of graph.edges) {
3768
3805
  inDegree.set(edge.to.name, (inDegree.get(edge.to.name) ?? 0) + 1);
3769
3806
  }
3770
- let placedCount = externalRootNodes.length + subgraphRootNodes.length;
3807
+ let placedCount = primaryRoots.length + subgraphRootNodes.length;
3771
3808
  while (placedCount < graph.nodes.length) {
3772
3809
  const prevCount = placedCount;
3773
3810
  for (const node of graph.nodes) {
@@ -3778,7 +3815,25 @@ function createMapping(graph) {
3778
3815
  const parentSg = getNodeSubgraph(graph, node);
3779
3816
  const childSg = getNodeSubgraph(graph, child);
3780
3817
  const edgeDir = parentSg && parentSg === childSg && parentSg.direction ? parentSg.direction : graph.config.graphDirection;
3781
- const childLevel = edgeDir === "LR" ? gc.x + 4 : gc.y + 4;
3818
+ let childLevel = edgeDir === "LR" ? gc.x + 4 : gc.y + 4;
3819
+ if (childSg && parentSg !== childSg && deferredRoots.size > 0) {
3820
+ let placedDeferred = false;
3821
+ for (const dr of [...deferredRoots]) {
3822
+ if (dr.gridCoord !== null) continue;
3823
+ const drSg = getNodeSubgraph(graph, dr);
3824
+ if (drSg !== childSg) continue;
3825
+ const drPerp = highestPositionPerLevel[childLevel] ?? 0;
3826
+ const drRequested = edgeDir === "LR" ? { x: childLevel, y: drPerp } : { x: drPerp, y: childLevel };
3827
+ reserveSpotInGrid(graph, graph.nodes[dr.index], drRequested, edgeDir);
3828
+ highestPositionPerLevel[childLevel] = drPerp + 4;
3829
+ deferredRoots.delete(dr);
3830
+ placedCount++;
3831
+ placedDeferred = true;
3832
+ }
3833
+ if (placedDeferred) {
3834
+ childLevel += 4;
3835
+ }
3836
+ }
3782
3837
  let highestPosition;
3783
3838
  if (edgeDir !== graph.config.graphDirection) {
3784
3839
  highestPosition = edgeDir === "LR" ? gc.y : gc.x;
@@ -3788,6 +3843,30 @@ function createMapping(graph) {
3788
3843
  } else {
3789
3844
  highestPosition = highestPositionPerLevel[childLevel];
3790
3845
  }
3846
+ if (childSg) {
3847
+ const existingSgNodes = childSg.nodes.filter((n) => n !== child && n.gridCoord !== null);
3848
+ if (existingSgNodes.length > 0) {
3849
+ const perpPositions = existingSgNodes.map(
3850
+ (n) => graph.config.graphDirection === "TD" ? n.gridCoord.x : n.gridCoord.y
3851
+ );
3852
+ const sgMinPerp = Math.min(...perpPositions);
3853
+ highestPosition = Math.max(highestPosition, sgMinPerp);
3854
+ } else if (parentSg && parentSg !== childSg) {
3855
+ const parentSgNodes = parentSg.nodes.filter((n) => n.gridCoord !== null);
3856
+ if (parentSgNodes.length > 0) {
3857
+ const parentLevels = parentSgNodes.map(
3858
+ (n) => graph.config.graphDirection === "TD" ? n.gridCoord.y : n.gridCoord.x
3859
+ );
3860
+ const parentMaxLevel = Math.max(...parentLevels) + 2;
3861
+ if (childLevel <= parentMaxLevel) {
3862
+ const maxPerp = Math.max(...parentSgNodes.map(
3863
+ (n) => graph.config.graphDirection === "TD" ? n.gridCoord.x : n.gridCoord.y
3864
+ ));
3865
+ highestPosition = Math.max(highestPosition, maxPerp + 4);
3866
+ }
3867
+ }
3868
+ }
3869
+ }
3791
3870
  const requested = edgeDir === "LR" ? { x: childLevel, y: highestPosition } : { x: highestPosition, y: childLevel };
3792
3871
  reserveSpotInGrid(graph, graph.nodes[child.index], requested, edgeDir);
3793
3872
  if (edgeDir === graph.config.graphDirection) {