@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 +107 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ascii/edge-routing.ts +2 -1
- package/src/ascii/grid.ts +125 -14
- package/src/parser.ts +3 -3
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]/
|
|
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 =
|
|
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
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
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
|
|
3663
|
-
if (sg1.maxX >= sg2.minX - minSpacing && sg1.minX
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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) {
|