@ktrysmt/beautiful-mermaid 1.5.0 → 1.5.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 +95 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/parser.test.ts +37 -0
- package/src/ascii/grid.ts +93 -3
- package/src/parser.ts +62 -0
package/dist/index.js
CHANGED
|
@@ -481,8 +481,43 @@ function parseFlowchart(lines) {
|
|
|
481
481
|
}
|
|
482
482
|
parseEdgeLine(line, graph, subgraphStack);
|
|
483
483
|
}
|
|
484
|
+
resolveSubgraphEdgeEndpoints(graph);
|
|
484
485
|
return graph;
|
|
485
486
|
}
|
|
487
|
+
function resolveSubgraphEdgeEndpoints(graph) {
|
|
488
|
+
const representatives = /* @__PURE__ */ new Map();
|
|
489
|
+
function pickRepresentative(sg) {
|
|
490
|
+
for (const id of sg.nodeIds) {
|
|
491
|
+
if (graph.nodes.has(id)) return id;
|
|
492
|
+
}
|
|
493
|
+
for (const child of sg.children) {
|
|
494
|
+
const childRep = representatives.get(child.id) ?? pickRepresentative(child);
|
|
495
|
+
if (childRep) return childRep;
|
|
496
|
+
}
|
|
497
|
+
return void 0;
|
|
498
|
+
}
|
|
499
|
+
function visit(sg) {
|
|
500
|
+
for (const child of sg.children) visit(child);
|
|
501
|
+
const rep = pickRepresentative(sg);
|
|
502
|
+
if (rep) representatives.set(sg.id, rep);
|
|
503
|
+
}
|
|
504
|
+
for (const sg of graph.subgraphs) visit(sg);
|
|
505
|
+
if (representatives.size === 0) return;
|
|
506
|
+
for (const edge of graph.edges) {
|
|
507
|
+
const newSource = representatives.get(edge.source);
|
|
508
|
+
if (newSource) edge.source = newSource;
|
|
509
|
+
const newTarget = representatives.get(edge.target);
|
|
510
|
+
if (newTarget) edge.target = newTarget;
|
|
511
|
+
}
|
|
512
|
+
for (const sgId of representatives.keys()) {
|
|
513
|
+
graph.nodes.delete(sgId);
|
|
514
|
+
}
|
|
515
|
+
function scrubMembership(sg) {
|
|
516
|
+
sg.nodeIds = sg.nodeIds.filter((id) => !representatives.has(id));
|
|
517
|
+
for (const child of sg.children) scrubMembership(child);
|
|
518
|
+
}
|
|
519
|
+
for (const sg of graph.subgraphs) scrubMembership(sg);
|
|
520
|
+
}
|
|
486
521
|
function parseStateDiagram(lines) {
|
|
487
522
|
const graph = {
|
|
488
523
|
direction: "TD",
|
|
@@ -3912,6 +3947,7 @@ function createMapping(graph) {
|
|
|
3912
3947
|
primaryRoots.push(root);
|
|
3913
3948
|
}
|
|
3914
3949
|
}
|
|
3950
|
+
const sourceStartLevel = computeSourceStartLevels(graph, primaryRoots);
|
|
3915
3951
|
const rootsByTarget = /* @__PURE__ */ new Map();
|
|
3916
3952
|
for (const root of primaryRoots) {
|
|
3917
3953
|
const children = getChildren(graph, root);
|
|
@@ -3922,9 +3958,10 @@ function createMapping(graph) {
|
|
|
3922
3958
|
}
|
|
3923
3959
|
for (const [, roots] of rootsByTarget) {
|
|
3924
3960
|
for (const node of roots) {
|
|
3925
|
-
const
|
|
3961
|
+
const startLevel = sourceStartLevel.get(node.name) ?? 0;
|
|
3962
|
+
const requested = dir === "LR" ? { x: startLevel, y: highestPositionPerLevel[startLevel] } : { x: highestPositionPerLevel[startLevel], y: startLevel };
|
|
3926
3963
|
reserveSpotInGrid(graph, graph.nodes[node.index], requested);
|
|
3927
|
-
highestPositionPerLevel[
|
|
3964
|
+
highestPositionPerLevel[startLevel] = highestPositionPerLevel[startLevel] + 4;
|
|
3928
3965
|
}
|
|
3929
3966
|
}
|
|
3930
3967
|
if (shouldSeparate && subgraphRootNodes.length > 0) {
|
|
@@ -4073,6 +4110,62 @@ function createMapping(graph) {
|
|
|
4073
4110
|
function getEdgesFromNode(graph, node) {
|
|
4074
4111
|
return graph.edges.filter((e) => e.from.name === node.name);
|
|
4075
4112
|
}
|
|
4113
|
+
function computeSourceStartLevels(graph, sources) {
|
|
4114
|
+
const childrenByName = /* @__PURE__ */ new Map();
|
|
4115
|
+
const parentsByName = /* @__PURE__ */ new Map();
|
|
4116
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
4117
|
+
for (const n of graph.nodes) {
|
|
4118
|
+
childrenByName.set(n.name, []);
|
|
4119
|
+
parentsByName.set(n.name, []);
|
|
4120
|
+
inDegree.set(n.name, 0);
|
|
4121
|
+
}
|
|
4122
|
+
for (const e of graph.edges) {
|
|
4123
|
+
if (e.from.name === e.to.name) continue;
|
|
4124
|
+
childrenByName.get(e.from.name).push(e.to);
|
|
4125
|
+
parentsByName.get(e.to.name).push(e.from);
|
|
4126
|
+
inDegree.set(e.to.name, (inDegree.get(e.to.name) ?? 0) + 1);
|
|
4127
|
+
}
|
|
4128
|
+
const queue = [];
|
|
4129
|
+
for (const n of graph.nodes) {
|
|
4130
|
+
if ((inDegree.get(n.name) ?? 0) === 0) queue.push(n);
|
|
4131
|
+
}
|
|
4132
|
+
const topoOrder = [];
|
|
4133
|
+
while (queue.length > 0) {
|
|
4134
|
+
const n = queue.shift();
|
|
4135
|
+
topoOrder.push(n);
|
|
4136
|
+
for (const c of childrenByName.get(n.name) ?? []) {
|
|
4137
|
+
const d = (inDegree.get(c.name) ?? 0) - 1;
|
|
4138
|
+
inDegree.set(c.name, d);
|
|
4139
|
+
if (d === 0) queue.push(c);
|
|
4140
|
+
}
|
|
4141
|
+
}
|
|
4142
|
+
const result = /* @__PURE__ */ new Map();
|
|
4143
|
+
if (topoOrder.length < graph.nodes.length) return result;
|
|
4144
|
+
const forwardLevel = /* @__PURE__ */ new Map();
|
|
4145
|
+
for (const n of topoOrder) {
|
|
4146
|
+
let best = 0;
|
|
4147
|
+
for (const p of parentsByName.get(n.name) ?? []) {
|
|
4148
|
+
const pl = (forwardLevel.get(p.name) ?? 0) + 1;
|
|
4149
|
+
if (pl > best) best = pl;
|
|
4150
|
+
}
|
|
4151
|
+
forwardLevel.set(n.name, best);
|
|
4152
|
+
}
|
|
4153
|
+
for (const src of sources) {
|
|
4154
|
+
const children = getChildren(graph, src).filter((c) => c.name !== src.name);
|
|
4155
|
+
if (children.length === 0) {
|
|
4156
|
+
result.set(src.name, 0);
|
|
4157
|
+
continue;
|
|
4158
|
+
}
|
|
4159
|
+
let minChild = Infinity;
|
|
4160
|
+
for (const c of children) {
|
|
4161
|
+
const cl = forwardLevel.get(c.name) ?? 0;
|
|
4162
|
+
if (cl < minChild) minChild = cl;
|
|
4163
|
+
}
|
|
4164
|
+
const logical = Number.isFinite(minChild) ? Math.max(0, minChild - 1) : 0;
|
|
4165
|
+
result.set(src.name, logical * 4);
|
|
4166
|
+
}
|
|
4167
|
+
return result;
|
|
4168
|
+
}
|
|
4076
4169
|
function getChildren(graph, node) {
|
|
4077
4170
|
return getEdgesFromNode(graph, node).map((e) => e.to);
|
|
4078
4171
|
}
|