@tldraw/mermaid 5.4.2 → 5.5.0-canary.0241f11f2e99
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-cjs/colors.js +15 -14
- package/dist-cjs/colors.js.map +2 -2
- package/dist-cjs/createMermaidDiagram.js +6 -4
- package/dist-cjs/createMermaidDiagram.js.map +2 -2
- package/dist-cjs/defaultMermaidNodeRenderSpec.js +13 -40
- package/dist-cjs/defaultMermaidNodeRenderSpec.js.map +2 -2
- package/dist-cjs/flowchartDiagram.js +22 -63
- package/dist-cjs/flowchartDiagram.js.map +2 -2
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/mermaidNodeCreateShape.js +9 -25
- package/dist-cjs/mermaidNodeCreateShape.js.map +2 -2
- package/dist-cjs/mindmapDiagram.js +42 -66
- package/dist-cjs/mindmapDiagram.js.map +2 -2
- package/dist-cjs/renderBlueprint.js +108 -169
- package/dist-cjs/renderBlueprint.js.map +2 -2
- package/dist-cjs/sequenceDiagram.js +117 -163
- package/dist-cjs/sequenceDiagram.js.map +3 -3
- package/dist-cjs/stateDiagram.js +80 -157
- package/dist-cjs/stateDiagram.js.map +3 -3
- package/dist-cjs/svgParsing.js +50 -26
- package/dist-cjs/svgParsing.js.map +2 -2
- package/dist-cjs/utils.js +5 -0
- package/dist-cjs/utils.js.map +2 -2
- package/dist-esm/colors.mjs +15 -14
- package/dist-esm/colors.mjs.map +2 -2
- package/dist-esm/createMermaidDiagram.mjs +7 -5
- package/dist-esm/createMermaidDiagram.mjs.map +2 -2
- package/dist-esm/defaultMermaidNodeRenderSpec.mjs +13 -40
- package/dist-esm/defaultMermaidNodeRenderSpec.mjs.map +2 -2
- package/dist-esm/flowchartDiagram.mjs +33 -66
- package/dist-esm/flowchartDiagram.mjs.map +2 -2
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/mermaidNodeCreateShape.mjs +9 -25
- package/dist-esm/mermaidNodeCreateShape.mjs.map +2 -2
- package/dist-esm/mindmapDiagram.mjs +44 -68
- package/dist-esm/mindmapDiagram.mjs.map +2 -2
- package/dist-esm/renderBlueprint.mjs +108 -169
- package/dist-esm/renderBlueprint.mjs.map +2 -2
- package/dist-esm/sequenceDiagram.mjs +117 -163
- package/dist-esm/sequenceDiagram.mjs.map +3 -3
- package/dist-esm/stateDiagram.mjs +84 -159
- package/dist-esm/stateDiagram.mjs.map +3 -3
- package/dist-esm/svgParsing.mjs +50 -26
- package/dist-esm/svgParsing.mjs.map +2 -2
- package/dist-esm/utils.mjs +5 -0
- package/dist-esm/utils.mjs.map +2 -2
- package/package.json +4 -4
- package/src/colors.ts +18 -17
- package/src/createMermaidDiagram.test.ts +0 -18
- package/src/createMermaidDiagram.ts +8 -6
- package/src/defaultMermaidNodeRenderSpec.ts +14 -40
- package/src/flowchartDiagram.ts +33 -76
- package/src/mermaidDiagrams.test.ts +113 -111
- package/src/mermaidNodeCreateShape.ts +13 -26
- package/src/mindmapDiagram.ts +48 -89
- package/src/renderBlueprint.ts +128 -189
- package/src/sequenceDiagram.ts +133 -182
- package/src/stateDiagram.ts +106 -198
- package/src/svgParsing.test.ts +33 -13
- package/src/svgParsing.ts +90 -47
- package/src/utils.ts +10 -0
- package/src/layoutParsing.test.ts +0 -71
package/dist-cjs/colors.js
CHANGED
|
@@ -21,7 +21,8 @@ __export(colors_exports, {
|
|
|
21
21
|
buildClassDefColorMap: () => buildClassDefColorMap,
|
|
22
22
|
parseCssStyles: () => parseCssStyles,
|
|
23
23
|
parseNodeInlineColor: () => parseNodeInlineColor,
|
|
24
|
-
parseRgbToTldrawColor: () => parseRgbToTldrawColor
|
|
24
|
+
parseRgbToTldrawColor: () => parseRgbToTldrawColor,
|
|
25
|
+
toNodeColorProps: () => toNodeColorProps
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(colors_exports);
|
|
27
28
|
var import_tldraw = require("tldraw");
|
|
@@ -29,23 +30,23 @@ function buildClassDefColorMap(classDefs, items) {
|
|
|
29
30
|
const result = /* @__PURE__ */ new Map();
|
|
30
31
|
if (classDefs.size === 0) return result;
|
|
31
32
|
for (const [nodeId, item] of items) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const stroke = toColor(props.get("stroke"));
|
|
39
|
-
if (!fill && !stroke) continue;
|
|
40
|
-
const colors = {};
|
|
41
|
-
if (fill) colors.fillColor = nearestTldrawColor(fill);
|
|
42
|
-
if (stroke) colors.strokeColor = nearestTldrawColor(stroke);
|
|
43
|
-
result.set(nodeId, colors);
|
|
44
|
-
break;
|
|
33
|
+
for (const className of item.classes ?? []) {
|
|
34
|
+
const colors = parseNodeInlineColor(classDefs.get(className)?.styles);
|
|
35
|
+
if (colors) {
|
|
36
|
+
result.set(nodeId, colors);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
45
39
|
}
|
|
46
40
|
}
|
|
47
41
|
return result;
|
|
48
42
|
}
|
|
43
|
+
function toNodeColorProps(colors) {
|
|
44
|
+
if (!colors) return {};
|
|
45
|
+
return {
|
|
46
|
+
...colors.fillColor && { fill: "solid" },
|
|
47
|
+
color: colors.strokeColor ?? colors.fillColor
|
|
48
|
+
};
|
|
49
|
+
}
|
|
49
50
|
function parseRgbToTldrawColor(text) {
|
|
50
51
|
const color = toColor(text);
|
|
51
52
|
if (!color) return null;
|
package/dist-cjs/colors.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/colors.ts"],
|
|
4
|
-
"sourcesContent": ["import { DEFAULT_THEME, TLDefaultColorStyle, TLDefaultDashStyle, TLDefaultSizeStyle } from 'tldraw'\n\ntype Color = [number, number, number, number]\n\nexport interface ParsedNodeColors {\n\tfillColor?: TLDefaultColorStyle\n\tstrokeColor?: TLDefaultColorStyle\n}\n\n/**\n * Build a map of node id \u2192 parsed fill/stroke colors from Mermaid's classDef definitions.\n *\n * Uses the structured data from `db.getClasses()` and each node's `classes`\n * array. For each node, looks up its applied classDef styles and maps fill and\n * stroke independently to the nearest tldraw palette color.\n */\nexport function buildClassDefColorMap(\n\tclassDefs: Map<string, { styles: string[] }>,\n\titems: Iterable<[string, { classes?: string[] }]>\n): Map<string, ParsedNodeColors> {\n\tconst result = new Map<string, ParsedNodeColors>()\n\tif (classDefs.size === 0) return result\n\n\tfor (const [nodeId, item] of items) {\n\t\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA2F;
|
|
4
|
+
"sourcesContent": ["import { DEFAULT_THEME, TLDefaultColorStyle, TLDefaultDashStyle, TLDefaultSizeStyle } from 'tldraw'\nimport type { MermaidBlueprintNode } from './blueprint'\n\ntype Color = [number, number, number, number]\n\nexport interface ParsedNodeColors {\n\tfillColor?: TLDefaultColorStyle\n\tstrokeColor?: TLDefaultColorStyle\n}\n\n/**\n * Build a map of node id \u2192 parsed fill/stroke colors from Mermaid's classDef definitions.\n *\n * Uses the structured data from `db.getClasses()` and each node's `classes`\n * array. For each node, looks up its applied classDef styles and maps fill and\n * stroke independently to the nearest tldraw palette color.\n */\nexport function buildClassDefColorMap(\n\tclassDefs: Map<string, { styles: string[] }>,\n\titems: Iterable<[string, { classes?: string[] }]>\n): Map<string, ParsedNodeColors> {\n\tconst result = new Map<string, ParsedNodeColors>()\n\tif (classDefs.size === 0) return result\n\n\tfor (const [nodeId, item] of items) {\n\t\tfor (const className of item.classes ?? []) {\n\t\t\tconst colors = parseNodeInlineColor(classDefs.get(className)?.styles)\n\t\t\tif (colors) {\n\t\t\t\tresult.set(nodeId, colors)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\n/** Blueprint node style props for parsed fill/stroke colors: solid fill when a fill was set, stroke color preferred. */\nexport function toNodeColorProps(\n\tcolors: ParsedNodeColors | undefined\n): Pick<MermaidBlueprintNode, 'fill' | 'color'> {\n\tif (!colors) return {}\n\treturn {\n\t\t...(colors.fillColor && { fill: 'solid' as const }),\n\t\tcolor: colors.strokeColor ?? colors.fillColor,\n\t}\n}\n\nexport function parseRgbToTldrawColor(\n\ttext: string\n): { color: TLDefaultColorStyle; hasAlpha: boolean } | null {\n\tconst color = toColor(text)\n\tif (!color) return null\n\treturn { color: nearestTldrawColor(color), hasAlpha: color[3] < 255 }\n}\n\ninterface ParsedCssOverrides {\n\tcolor?: TLDefaultColorStyle\n\tdashOverride?: TLDefaultDashStyle\n\tsizeOverride?: TLDefaultSizeStyle\n}\n\nfunction parseCssProps(styles: string[]): Map<string, string> {\n\tconst props = new Map<string, string>()\n\tfor (const entry of styles) {\n\t\tfor (const part of entry.split(';')) {\n\t\t\tconst colon = part.indexOf(':')\n\t\t\tif (colon < 0) continue\n\t\t\tconst key = part.slice(0, colon).trim().toLowerCase()\n\t\t\tconst value = part.slice(colon + 1).trim()\n\t\t\tif (key && value) props.set(key, value)\n\t\t}\n\t}\n\treturn props\n}\n\n/**\n * Parse a Mermaid CSS style array from an edge (FlowEdge.style / linkStyle)\n * and return tldraw-compatible overrides.\n */\nexport function parseCssStyles(styles: string[] | undefined): ParsedCssOverrides {\n\tif (!styles || styles.length === 0) return {}\n\n\tconst props = parseCssProps(styles)\n\tconst result: ParsedCssOverrides = {}\n\n\tconst stroke = toColor(props.get('stroke'))\n\tif (stroke) {\n\t\tresult.color = nearestTldrawColor(stroke)\n\t}\n\n\tif (props.has('stroke-dasharray')) {\n\t\tresult.dashOverride = 'dashed'\n\t}\n\n\tconst strokeWidth = props.get('stroke-width')\n\tif (strokeWidth) {\n\t\tconst pixels = parseFloat(strokeWidth)\n\t\tif (Number.isFinite(pixels)) {\n\t\t\tif (pixels <= 1) result.sizeOverride = 's'\n\t\t\telse if (pixels <= 2) result.sizeOverride = 'm'\n\t\t\telse result.sizeOverride = 'l'\n\t\t}\n\t}\n\n\treturn result\n}\n\n/**\n * Parse inline `style nodeId fill:\u2026,stroke:\u2026` directives from a FlowVertex.styles\n * array and return fill and stroke as independent tldraw colors.\n */\nexport function parseNodeInlineColor(styles: string[] | undefined): ParsedNodeColors | undefined {\n\tif (!styles || styles.length === 0) return undefined\n\n\tconst props = parseCssProps(styles)\n\tconst fill = toColor(props.get('fill'))\n\tconst stroke = toColor(props.get('stroke'))\n\n\tif (!fill && !stroke) return undefined\n\n\tconst colors: ParsedNodeColors = {}\n\tif (fill) colors.fillColor = nearestTldrawColor(fill)\n\tif (stroke) colors.strokeColor = nearestTldrawColor(stroke)\n\treturn colors\n}\n\nfunction parseHexToRgb(hex: string): [number, number, number] | null {\n\tconst stripped = hex.replace(/^#/, '')\n\tif (stripped.length === 3 || stripped.length === 4) {\n\t\treturn [\n\t\t\tparseInt(stripped[0] + stripped[0], 16),\n\t\t\tparseInt(stripped[1] + stripped[1], 16),\n\t\t\tparseInt(stripped[2] + stripped[2], 16),\n\t\t]\n\t}\n\tif (stripped.length === 6 || stripped.length === 8) {\n\t\treturn [\n\t\t\tparseInt(stripped.slice(0, 2), 16),\n\t\t\tparseInt(stripped.slice(2, 4), 16),\n\t\t\tparseInt(stripped.slice(4, 6), 16),\n\t\t]\n\t}\n\treturn null\n}\n\nconst defaultColorNames: TLDefaultColorStyle[] = [\n\t'black',\n\t'grey',\n\t'light-violet',\n\t'violet',\n\t'blue',\n\t'light-blue',\n\t'yellow',\n\t'orange',\n\t'green',\n\t'light-green',\n\t'light-red',\n\t'red',\n\t'white',\n]\n\nconst TLDRAW_PALETTE: [TLDefaultColorStyle, number, number, number][] = defaultColorNames.map(\n\t(name) => {\n\t\tconst { solid } = DEFAULT_THEME.colors.light[name]!\n\t\tconst rgb = parseHexToRgb(solid)!\n\t\treturn [name, rgb[0], rgb[1], rgb[2]]\n\t}\n)\n\n/** Map an arbitrary Color tuple to the nearest tldraw named color (best-effort). */\nfunction nearestTldrawColor(rgb: Color): TLDefaultColorStyle {\n\tlet [r, g, b] = rgb\n\n\tconst max = Math.max(r, g, b)\n\tconst min = Math.min(r, g, b)\n\tconst lightness = (max + min) / 2 / 255\n\tconst chroma = max - min\n\n\t// For very light pastels, strip the white base and amplify the\n\t// chromatic signal so the distance metric can see the hue.\n\tif (lightness > 0.75 && chroma > 5) {\n\t\tconst target = 200\n\t\tr = Math.round(((r - min) / chroma) * target)\n\t\tg = Math.round(((g - min) / chroma) * target)\n\t\tb = Math.round(((b - min) / chroma) * target)\n\t}\n\n\tlet best: TLDefaultColorStyle = 'black'\n\tlet bestDistance = Infinity\n\tfor (const [name, red, green, blue] of TLDRAW_PALETTE) {\n\t\t// \"Redmean\" weighted Euclidean distance (Compuphase approximation).\n\t\t// Weights RGB channels by the average red value of the two colors to\n\t\t// approximate human perception, which is more sensitive to green and\n\t\t// varies in red/blue sensitivity depending on the color's warmth.\n\t\tconst rMean = (r + red) / 2\n\t\tconst dR = r - red\n\t\tconst dG = g - green\n\t\tconst dB = b - blue\n\t\tconst distance = (2 + rMean / 256) * dR * dR + 4 * dG * dG + (2 + (255 - rMean) / 256) * dB * dB\n\t\tif (distance < bestDistance) {\n\t\t\tbestDistance = distance\n\t\t\tbest = name\n\t\t}\n\t}\n\treturn best\n}\n\nfunction toColor(value: string | undefined): Color | undefined {\n\tif (!value) return undefined\n\n\tconst trimmed = value.trim()\n\tif (!trimmed || trimmed === 'none' || trimmed === 'transparent') return undefined\n\n\tif (trimmed.startsWith('rgb')) {\n\t\tconst match = trimmed.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)/)\n\t\tif (!match) return undefined\n\t\treturn [\n\t\t\tparseInt(match[1], 10),\n\t\t\tparseInt(match[2], 10),\n\t\t\tparseInt(match[3], 10),\n\t\t\tmatch[4] !== undefined ? Math.round(parseFloat(match[4]) * 255) : 255,\n\t\t]\n\t}\n\tif (trimmed.startsWith('#')) {\n\t\tconst rgb = parseHexToRgb(trimmed)\n\t\tif (!rgb) return undefined\n\t\treturn [rgb[0], rgb[1], rgb[2], 255]\n\t}\n\treturn undefined\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -73,10 +73,12 @@ async function createMermaidDiagram(editor, text, options = {}) {
|
|
|
73
73
|
throw new MermaidDiagramError("not a mermaid diagram", "parse");
|
|
74
74
|
}
|
|
75
75
|
const offscreen = document.createElement("div");
|
|
76
|
-
offscreen.style
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
Object.assign(offscreen.style, {
|
|
77
|
+
position: "absolute",
|
|
78
|
+
left: "-9999px",
|
|
79
|
+
top: "-9999px",
|
|
80
|
+
overflow: "hidden"
|
|
81
|
+
});
|
|
80
82
|
document.body.appendChild(offscreen);
|
|
81
83
|
try {
|
|
82
84
|
const parsedSvg = (await mermaid.render(`mermaid-${nextMermaidId++}`, text, offscreen)).svg;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/createMermaidDiagram.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import type { FlowDB } from 'mermaid/dist/diagrams/flowchart/flowDb.d.ts'\nimport type { FlowEdge, FlowSubGraph, FlowVertex } from 'mermaid/dist/diagrams/flowchart/types.js'\nimport type { MindmapDB } from 'mermaid/dist/diagrams/mindmap/mindmapDb.d.ts'\nimport type { SequenceDB } from 'mermaid/dist/diagrams/sequence/sequenceDb.d.ts'\nimport type { StateDB } from 'mermaid/dist/diagrams/state/stateDb.d.ts'\nimport { Editor } from 'tldraw'\nimport { flowchartToBlueprint, parseFlowchartLayout } from './flowchartDiagram'\nimport { mindmapToBlueprint, parseMindmapLayout } from './mindmapDiagram'\nimport { BlueprintRenderingOptions, renderBlueprint } from './renderBlueprint'\nimport { countSequenceEvents, parseSequenceLayout, sequenceToBlueprint } from './sequenceDiagram'\nimport { parseStateDiagramLayout, stateToBlueprint } from './stateDiagram'\n\nlet nextMermaidId = 0\n\n/** @public */\nexport class MermaidDiagramError extends Error {\n\tconstructor(\n\t\tpublic diagramType: string,\n\t\tpublic type: 'parse' | 'unsupported'\n\t) {\n\t\tsuper(`mermaid diagram error: ${diagramType}`)\n\t\tthis.name = 'MermaidDiagramError'\n\t}\n}\n\n// Inflate the font size so Mermaid's layout engine allocates larger nodes,\n// compensating for tldraw's hand-drawn font being wider than Mermaid's default.\nconst FONT_INFLATE = 1.4\n\nconst MERMAID_CONFIG = {\n\tstartOnLoad: false,\n\tflowchart: { nodeSpacing: 80, rankSpacing: 80, padding: 20 },\n\tstate: { nodeSpacing: 80, rankSpacing: 80, padding: 20 },\n\tmindmap: { padding: 20 },\n\tsequence: { actorMargin: 50, noteMargin: 20 },\n\tthemeVariables: { fontSize: `${18 * FONT_INFLATE}px` },\n}\n\n/** @public */\nexport interface MermaidDiagramOptions {\n\tmermaidConfig?: Record<string, any>\n\tblueprintRender?: BlueprintRenderingOptions\n\tonUnsupportedDiagram?(svg: string): Promise<void>\n}\n\n/**\n * Parse mermaid text and create tldraw shapes for supported diagram types.\n * Returns the SVG string for supported diagrams, or `null` when the diagram type\n * is unsupported (after calling `onUnsupportedDiagram` if provided).\n * Throws {@link MermaidDiagramError} if parsing fails.\n * @public\n */\nexport async function createMermaidDiagram(\n\teditor: Editor,\n\ttext: string,\n\toptions: MermaidDiagramOptions = {}\n): Promise<void> {\n\t// load mermaid lazily: it's a large, ESM-only dependency only needed when a\n\t// diagram is actually created. a dynamic import() works from CommonJS (unlike\n\t// a static import, which compiles to require(<esm>) and throws\n\t// ERR_REQUIRE_ESM on Node <20.19, Jest, and ts-node) and avoids pulling\n\t// mermaid in when @tldraw/mermaid is merely imported.\n\tconst mermaid = (await import('mermaid')).default\n\n\tmermaid.initialize({\n\t\t...MERMAID_CONFIG,\n\t\t...(options.mermaidConfig ?? {}),\n\t\tflowchart: { ...MERMAID_CONFIG.flowchart, ...options.mermaidConfig?.flowchart },\n\t\tstate: { ...MERMAID_CONFIG.state, ...options.mermaidConfig?.state },\n\t\tmindmap: { ...MERMAID_CONFIG.mindmap, ...options.mermaidConfig?.mindmap },\n\t\tsequence: { ...MERMAID_CONFIG.sequence, ...options.mermaidConfig?.sequence },\n\t\tthemeVariables: { ...MERMAID_CONFIG.themeVariables, ...options.mermaidConfig?.themeVariables },\n\t})\n\n\tconst parsedResult = await mermaid.parse(text, { suppressErrors: true })\n\n\tif (!parsedResult) {\n\t\tthrow new MermaidDiagramError('not a mermaid diagram', 'parse')\n\t}\n\n\tconst offscreen = document.createElement('div')\n\tObject.assign(offscreen.style, {\n\t\tposition: 'absolute',\n\t\tleft: '-9999px',\n\t\ttop: '-9999px',\n\t\toverflow: 'hidden',\n\t})\n\tdocument.body.appendChild(offscreen)\n\n\ttry {\n\t\tconst parsedSvg = (await mermaid.render(`mermaid-${nextMermaidId++}`, text, offscreen)).svg\n\n\t\t// Reuse the live SVG that mermaid.render() already mounted into the\n\t\t// offscreen container. This avoids a second DOM mount and ensures\n\t\t// getBBox() works for every diagram type (state diagrams in particular\n\t\t// lack explicit dimension attributes and rely on live layout).\n\t\tlet liveSvg = offscreen.querySelector('svg')\n\n\t\tif (!liveSvg) {\n\t\t\toffscreen.innerHTML = parsedSvg\n\t\t\tliveSvg = offscreen.querySelector('svg')\n\t\t\tif (!liveSvg) {\n\t\t\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'parse')\n\t\t\t}\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tconst diagramResult = await mermaid.mermaidAPI.getDiagramFromText(text)\n\n\t\tlet blueprint\n\t\tswitch (parsedResult.diagramType) {\n\t\t\tcase 'flowchart-v2': {\n\t\t\t\tconst db = diagramResult.db as FlowDB\n\t\t\t\tconst vertices = db.getVertices() as Map<string, FlowVertex>\n\t\t\t\tconst edges = db.getEdges() as FlowEdge[]\n\t\t\t\tconst subGraphs = db.getSubGraphs() as FlowSubGraph[]\n\t\t\t\tconst classes = db.getClasses()\n\t\t\t\tconst layout = parseFlowchartLayout(liveSvg)\n\t\t\t\tblueprint = flowchartToBlueprint(layout, vertices, edges, subGraphs, classes)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'sequence': {\n\t\t\t\tconst db = diagramResult.db as SequenceDB\n\t\t\t\tconst actors = db.getActors()\n\t\t\t\tconst actorKeys = db.getActorKeys()\n\t\t\t\tconst messages = db.getMessages()\n\t\t\t\tconst layout = parseSequenceLayout(liveSvg, actorKeys.length, countSequenceEvents(messages))\n\t\t\t\tblueprint = sequenceToBlueprint(\n\t\t\t\t\tlayout,\n\t\t\t\t\tactors,\n\t\t\t\t\tactorKeys,\n\t\t\t\t\tmessages,\n\t\t\t\t\tdb.getCreatedActors(),\n\t\t\t\t\tdb.getDestroyedActors()\n\t\t\t\t)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'state':\n\t\t\tcase 'stateDiagram': {\n\t\t\t\tconst db = diagramResult.db as StateDB\n\t\t\t\tconst states = db.getStates()\n\t\t\t\tconst relations = db.getRelations()\n\t\t\t\tconst classes = db.getClasses()\n\t\t\t\tconst layout = parseStateDiagramLayout(liveSvg)\n\t\t\t\tblueprint = stateToBlueprint(layout, states, relations, classes)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'mindmap': {\n\t\t\t\tconst db = diagramResult.db as MindmapDB\n\t\t\t\tconst tree = db.getMindmap()\n\t\t\t\tif (tree) {\n\t\t\t\t\tdb.assignSections(tree)\n\t\t\t\t\tconst layout = parseMindmapLayout(liveSvg)\n\t\t\t\t\tblueprint = mindmapToBlueprint(layout, tree, liveSvg)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif (options.onUnsupportedDiagram) {\n\t\t\t\t\tawait options.onUnsupportedDiagram(parsedSvg)\n\t\t\t\t} else {\n\t\t\t\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'unsupported')\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t}\n\n\t\tif (blueprint) {\n\t\t\trenderBlueprint(editor, blueprint, options.blueprintRender)\n\t\t}\n\t} catch (e) {\n\t\tif (e instanceof MermaidDiagramError) throw e\n\t\tconsole.error(e)\n\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'parse')\n\t} finally {\n\t\toffscreen.remove()\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -22,6 +22,7 @@ __export(defaultMermaidNodeRenderSpec_exports, {
|
|
|
22
22
|
resolveMermaidNodeRender: () => resolveMermaidNodeRender
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(defaultMermaidNodeRenderSpec_exports);
|
|
25
|
+
var import_mindmapDiagram = require("./mindmapDiagram");
|
|
25
26
|
function flowchartKindToGeo(kind) {
|
|
26
27
|
switch (kind) {
|
|
27
28
|
case "diamond":
|
|
@@ -41,11 +42,6 @@ function flowchartKindToGeo(kind) {
|
|
|
41
42
|
return "rhombus";
|
|
42
43
|
case "lean_left":
|
|
43
44
|
return "rhombus-2";
|
|
44
|
-
case "subgraph":
|
|
45
|
-
case "square":
|
|
46
|
-
case "rect":
|
|
47
|
-
case "round":
|
|
48
|
-
case "subroutine":
|
|
49
45
|
default:
|
|
50
46
|
return "rectangle";
|
|
51
47
|
}
|
|
@@ -58,10 +54,6 @@ function stateKindToGeo(kind) {
|
|
|
58
54
|
case "end":
|
|
59
55
|
case "end_inner":
|
|
60
56
|
return "ellipse";
|
|
61
|
-
case "compound":
|
|
62
|
-
case "note":
|
|
63
|
-
case "fork":
|
|
64
|
-
case "join":
|
|
65
57
|
default:
|
|
66
58
|
return "rectangle";
|
|
67
59
|
}
|
|
@@ -72,51 +64,32 @@ function sequenceKindToGeo(kind) {
|
|
|
72
64
|
return "ellipse";
|
|
73
65
|
case "database":
|
|
74
66
|
return "oval";
|
|
75
|
-
case "sequence_activation":
|
|
76
|
-
case "sequence_fragment":
|
|
77
|
-
case "sequence_fragment_section":
|
|
78
|
-
case "sequence_note":
|
|
79
67
|
default:
|
|
80
68
|
return "rectangle";
|
|
81
69
|
}
|
|
82
70
|
}
|
|
83
71
|
function mindmapKindToGeo(kind) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
case 3:
|
|
72
|
+
switch (Number(kind)) {
|
|
73
|
+
case import_mindmapDiagram.MERMAID_MINDMAP_NODE_TYPE.CIRCLE:
|
|
87
74
|
return "ellipse";
|
|
88
|
-
case
|
|
75
|
+
case import_mindmapDiagram.MERMAID_MINDMAP_NODE_TYPE.CLOUD:
|
|
89
76
|
return "cloud";
|
|
90
|
-
case
|
|
77
|
+
case import_mindmapDiagram.MERMAID_MINDMAP_NODE_TYPE.HEXAGON:
|
|
91
78
|
return "hexagon";
|
|
92
|
-
case
|
|
79
|
+
case import_mindmapDiagram.MERMAID_MINDMAP_NODE_TYPE.BANG:
|
|
93
80
|
return "star";
|
|
94
|
-
case 2:
|
|
95
|
-
case 1:
|
|
96
|
-
case 0:
|
|
97
81
|
default:
|
|
98
82
|
return "rectangle";
|
|
99
83
|
}
|
|
100
84
|
}
|
|
85
|
+
const KIND_TO_GEO = {
|
|
86
|
+
flowchart: flowchartKindToGeo,
|
|
87
|
+
state: stateKindToGeo,
|
|
88
|
+
sequence: sequenceKindToGeo,
|
|
89
|
+
mindmap: mindmapKindToGeo
|
|
90
|
+
};
|
|
101
91
|
function defaultMermaidNodeRenderSpec(diagramKind, kind) {
|
|
102
|
-
|
|
103
|
-
switch (diagramKind) {
|
|
104
|
-
case "flowchart":
|
|
105
|
-
geo = flowchartKindToGeo(kind);
|
|
106
|
-
break;
|
|
107
|
-
case "state":
|
|
108
|
-
geo = stateKindToGeo(kind);
|
|
109
|
-
break;
|
|
110
|
-
case "sequence":
|
|
111
|
-
geo = sequenceKindToGeo(kind);
|
|
112
|
-
break;
|
|
113
|
-
case "mindmap":
|
|
114
|
-
geo = mindmapKindToGeo(kind);
|
|
115
|
-
break;
|
|
116
|
-
default:
|
|
117
|
-
geo = "rectangle";
|
|
118
|
-
}
|
|
119
|
-
return { variant: "geo", geo };
|
|
92
|
+
return { variant: "geo", geo: KIND_TO_GEO[diagramKind]?.(kind) ?? "rectangle" };
|
|
120
93
|
}
|
|
121
94
|
function resolveMermaidNodeRender(diagramKind, node, mapper) {
|
|
122
95
|
return mapper?.({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/defaultMermaidNodeRenderSpec.ts"],
|
|
4
|
-
"sourcesContent": ["import type { TLGeoShapeGeoStyle } from 'tldraw'\nimport type {\n\tMermaidBlueprintNode,\n\tMermaidBlueprintNodeRenderSpec,\n\tMermaidDiagramKind,\n\tMermaidNodeRenderMapper,\n} from './blueprint'\n\nfunction flowchartKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'diamond':\n\t\t\treturn 'diamond'\n\t\tcase 'ellipse':\n\t\tcase 'circle':\n\t\tcase 'doublecircle':\n\t\tcase 'stadium':\n\t\tcase 'cylinder':\n\t\t\treturn 'ellipse'\n\t\tcase 'hexagon':\n\t\t\treturn 'hexagon'\n\t\tcase 'trapezoid':\n\t\tcase 'inv_trapezoid':\n\t\t\treturn 'trapezoid'\n\t\tcase 'lean_right':\n\t\t\treturn 'rhombus'\n\t\tcase 'lean_left':\n\t\t\treturn 'rhombus-2'\n\t\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import type { TLGeoShapeGeoStyle } from 'tldraw'\nimport type {\n\tMermaidBlueprintNode,\n\tMermaidBlueprintNodeRenderSpec,\n\tMermaidDiagramKind,\n\tMermaidNodeRenderMapper,\n} from './blueprint'\nimport { MERMAID_MINDMAP_NODE_TYPE } from './mindmapDiagram'\n\nfunction flowchartKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'diamond':\n\t\t\treturn 'diamond'\n\t\tcase 'ellipse':\n\t\tcase 'circle':\n\t\tcase 'doublecircle':\n\t\tcase 'stadium':\n\t\tcase 'cylinder':\n\t\t\treturn 'ellipse'\n\t\tcase 'hexagon':\n\t\t\treturn 'hexagon'\n\t\tcase 'trapezoid':\n\t\tcase 'inv_trapezoid':\n\t\t\treturn 'trapezoid'\n\t\tcase 'lean_right':\n\t\t\treturn 'rhombus'\n\t\tcase 'lean_left':\n\t\t\treturn 'rhombus-2'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction stateKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'choice':\n\t\t\treturn 'diamond'\n\t\tcase 'start':\n\t\tcase 'end':\n\t\tcase 'end_inner':\n\t\t\treturn 'ellipse'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction sequenceKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'actor':\n\t\t\treturn 'ellipse'\n\t\tcase 'database':\n\t\t\treturn 'oval'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction mindmapKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (Number(kind)) {\n\t\tcase MERMAID_MINDMAP_NODE_TYPE.CIRCLE:\n\t\t\treturn 'ellipse'\n\t\tcase MERMAID_MINDMAP_NODE_TYPE.CLOUD:\n\t\t\treturn 'cloud'\n\t\tcase MERMAID_MINDMAP_NODE_TYPE.HEXAGON:\n\t\t\treturn 'hexagon'\n\t\tcase MERMAID_MINDMAP_NODE_TYPE.BANG:\n\t\t\treturn 'star'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nconst KIND_TO_GEO: Record<MermaidDiagramKind, (kind: string) => TLGeoShapeGeoStyle> = {\n\tflowchart: flowchartKindToGeo,\n\tstate: stateKindToGeo,\n\tsequence: sequenceKindToGeo,\n\tmindmap: mindmapKindToGeo,\n}\n\n/**\n * Default built-in mapping from {@link MermaidDiagramKind} + semantic `kind` to a geo {@link MermaidBlueprintNodeRenderSpec}.\n * Used when `mapNodeToRenderSpec` is omitted from `renderBlueprint` options, or when the mapper returns `undefined`.\n * @public\n */\nexport function defaultMermaidNodeRenderSpec(\n\tdiagramKind: MermaidDiagramKind,\n\tkind: string\n): MermaidBlueprintNodeRenderSpec {\n\treturn { variant: 'geo', geo: KIND_TO_GEO[diagramKind]?.(kind) ?? 'rectangle' }\n}\n\n/**\n * Uses the optional mapper when it returns a value; otherwise {@link defaultMermaidNodeRenderSpec}.\n * @public\n */\nexport function resolveMermaidNodeRender(\n\tdiagramKind: MermaidDiagramKind,\n\tnode: MermaidBlueprintNode,\n\tmapper?: MermaidNodeRenderMapper | undefined\n): MermaidBlueprintNodeRenderSpec {\n\treturn (\n\t\tmapper?.({\n\t\t\tdiagramKind,\n\t\t\tnodeId: node.id,\n\t\t\tkind: node.kind,\n\t\t\tnode,\n\t\t}) ?? defaultMermaidNodeRenderSpec(diagramKind, node.kind)\n\t)\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,4BAA0C;AAE1C,SAAS,mBAAmB,MAAkC;AAC7D,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,eAAe,MAAkC;AACzD,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,kBAAkB,MAAkC;AAC5D,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,iBAAiB,MAAkC;AAC3D,UAAQ,OAAO,IAAI,GAAG;AAAA,IACrB,KAAK,gDAA0B;AAC9B,aAAO;AAAA,IACR,KAAK,gDAA0B;AAC9B,aAAO;AAAA,IACR,KAAK,gDAA0B;AAC9B,aAAO;AAAA,IACR,KAAK,gDAA0B;AAC9B,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,MAAM,cAAgF;AAAA,EACrF,WAAW;AAAA,EACX,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AACV;AAOO,SAAS,6BACf,aACA,MACiC;AACjC,SAAO,EAAE,SAAS,OAAO,KAAK,YAAY,WAAW,IAAI,IAAI,KAAK,YAAY;AAC/E;AAMO,SAAS,yBACf,aACA,MACA,QACiC;AACjC,SACC,SAAS;AAAA,IACR;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,IACX;AAAA,EACD,CAAC,KAAK,6BAA6B,aAAa,KAAK,IAAI;AAE3D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -26,19 +26,13 @@ var import_colors = require("./colors");
|
|
|
26
26
|
var import_svgParsing = require("./svgParsing");
|
|
27
27
|
var import_utils = require("./utils");
|
|
28
28
|
function mapEdgeTypeToArrowhead(type) {
|
|
29
|
-
if (
|
|
30
|
-
if (type
|
|
31
|
-
if (type
|
|
32
|
-
if (type.includes("cross")) return "bar";
|
|
33
|
-
if (type.includes("open")) return "none";
|
|
29
|
+
if (type?.includes("circle")) return "dot";
|
|
30
|
+
if (type?.includes("cross")) return "bar";
|
|
31
|
+
if (type?.includes("open")) return "none";
|
|
34
32
|
return "arrow";
|
|
35
33
|
}
|
|
36
|
-
function mapEdgeStrokeToDash(stroke) {
|
|
37
|
-
if (!stroke) return "solid";
|
|
38
|
-
if (stroke === "dotted") return "dotted";
|
|
39
|
-
return "solid";
|
|
40
|
-
}
|
|
41
34
|
const FRAME_TOP_PAD = 14;
|
|
35
|
+
const NODE_ID = /^flowchart-(.+)-\d+$/;
|
|
42
36
|
function buildHierarchy(subGraphs) {
|
|
43
37
|
const subGraphIds = new Set(subGraphs.map((subGraph) => subGraph.id));
|
|
44
38
|
const nodeToSubGraph = /* @__PURE__ */ new Map();
|
|
@@ -55,15 +49,8 @@ function buildHierarchy(subGraphs) {
|
|
|
55
49
|
return { nodeToSubGraph, subGraphParent };
|
|
56
50
|
}
|
|
57
51
|
function parseFlowchartLayout(root) {
|
|
58
|
-
const nodes = (0, import_svgParsing.parseNodesFromSvg)(root, ".node", (domId) =>
|
|
59
|
-
|
|
60
|
-
return match ? match[1] : domId;
|
|
61
|
-
});
|
|
62
|
-
const clusters = (0, import_svgParsing.parseClustersFromSvg)(
|
|
63
|
-
root,
|
|
64
|
-
".cluster",
|
|
65
|
-
(domId) => domId.replace(/^mermaid-\d+-/, "")
|
|
66
|
-
);
|
|
52
|
+
const nodes = (0, import_svgParsing.parseNodesFromSvg)(root, ".node", (domId) => (0, import_svgParsing.parseDomId)(domId, NODE_ID));
|
|
53
|
+
const clusters = (0, import_svgParsing.parseClustersFromSvg)(root, ".cluster", import_svgParsing.stripDiagramIdPrefix);
|
|
67
54
|
const edges = (0, import_svgParsing.parseAllEdgePointsFromSvg)(root, (dataId) => {
|
|
68
55
|
const match = dataId.match(/(?:^|-)L_(.+)_([^_]+)_\d+$/);
|
|
69
56
|
return match ? { start: match[1], end: match[2] } : null;
|
|
@@ -72,7 +59,7 @@ function parseFlowchartLayout(root) {
|
|
|
72
59
|
return { nodes, clusters, edges };
|
|
73
60
|
}
|
|
74
61
|
function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
|
|
75
|
-
const nodeColorMap =
|
|
62
|
+
const nodeColorMap = (0, import_colors.buildClassDefColorMap)(classDefs ?? /* @__PURE__ */ new Map(), vertices);
|
|
76
63
|
const { nodes: svgNodes, clusters: svgClusters, edges: svgEdges } = layout;
|
|
77
64
|
const nodeCenters = (0, import_svgParsing.buildNodeCentersFromSvg)(svgNodes, svgClusters);
|
|
78
65
|
const allSubGraphs = subGraphs || [];
|
|
@@ -86,11 +73,9 @@ function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
|
|
|
86
73
|
)) {
|
|
87
74
|
const cluster = svgClusters.get(subGraph.id);
|
|
88
75
|
if (!cluster) continue;
|
|
89
|
-
const id = subGraph.id;
|
|
90
|
-
const kind = "subgraph";
|
|
91
76
|
nodes.push({
|
|
92
|
-
id,
|
|
93
|
-
kind,
|
|
77
|
+
id: subGraph.id,
|
|
78
|
+
kind: "subgraph",
|
|
94
79
|
x: cluster.topLeft.x,
|
|
95
80
|
y: cluster.topLeft.y - FRAME_TOP_PAD,
|
|
96
81
|
w: cluster.width,
|
|
@@ -108,23 +93,20 @@ function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
|
|
|
108
93
|
for (const [id, vertex] of vertices) {
|
|
109
94
|
const svgNode = svgNodes.get(id);
|
|
110
95
|
if (!svgNode) continue;
|
|
111
|
-
const kind = vertex.type ?? "rect";
|
|
112
|
-
const colors = nodeColorMap.get(id) ?? (0, import_colors.parseNodeInlineColor)(vertex.styles);
|
|
113
96
|
let { width: w, height: h } = svgNode;
|
|
114
97
|
if (vertex.type === "circle" || vertex.type === "doublecircle") {
|
|
115
98
|
w = h = Math.max(w, h);
|
|
116
99
|
}
|
|
117
100
|
nodes.push({
|
|
118
101
|
id,
|
|
119
|
-
kind,
|
|
102
|
+
kind: vertex.type ?? "rect",
|
|
120
103
|
x: svgNode.center.x - w / 2,
|
|
121
104
|
y: svgNode.center.y - h / 2,
|
|
122
105
|
w,
|
|
123
106
|
h,
|
|
124
107
|
parentId: nodeToSubGraph.get(id),
|
|
125
108
|
label: vertex.text || void 0,
|
|
126
|
-
...
|
|
127
|
-
...colors && { color: colors.strokeColor ?? colors.fillColor },
|
|
109
|
+
...(0, import_colors.toNodeColorProps)(nodeColorMap.get(id) ?? (0, import_colors.parseNodeInlineColor)(vertex.styles)),
|
|
128
110
|
align: "middle",
|
|
129
111
|
verticalAlign: "middle",
|
|
130
112
|
size: "m"
|
|
@@ -132,33 +114,14 @@ function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
|
|
|
132
114
|
}
|
|
133
115
|
const claimed = /* @__PURE__ */ new Set();
|
|
134
116
|
for (const edge of edges) {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (claimed.has(i) || svgEdges[i].points.length < 2) continue;
|
|
143
|
-
const points = svgEdges[i].points;
|
|
144
|
-
const distance = Math.hypot(points[0].x - startCenter.x, points[0].y - startCenter.y) + Math.hypot(
|
|
145
|
-
points[points.length - 1].x - endCenter.x,
|
|
146
|
-
points[points.length - 1].y - endCenter.y
|
|
147
|
-
);
|
|
148
|
-
if (distance < bestDist) {
|
|
149
|
-
bestDist = distance;
|
|
150
|
-
bestIndex = i;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
if (bestIndex >= 0) {
|
|
154
|
-
claimed.add(bestIndex);
|
|
155
|
-
bend = (0, import_utils.getArrowBend)(svgEdges[bestIndex]);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
const cssOverrides = edge.style ? (0, import_colors.parseCssStyles)(edge.style) : void 0;
|
|
117
|
+
const bend = (0, import_svgParsing.claimNearestEdgeBend)(
|
|
118
|
+
svgEdges,
|
|
119
|
+
claimed,
|
|
120
|
+
nodeCenters.get(edge.start),
|
|
121
|
+
nodeCenters.get(edge.end)
|
|
122
|
+
);
|
|
123
|
+
const cssOverrides = (0, import_colors.parseCssStyles)(edge.style);
|
|
159
124
|
const arrowheadEnd = mapEdgeTypeToArrowhead(edge.type);
|
|
160
|
-
const dash = cssOverrides?.dashOverride ?? mapEdgeStrokeToDash(edge.stroke);
|
|
161
|
-
const size = cssOverrides?.sizeOverride ?? (edge.stroke === "thick" ? "l" : "s");
|
|
162
125
|
blueprintEdges.push({
|
|
163
126
|
startNodeId: edge.start,
|
|
164
127
|
endNodeId: edge.end,
|
|
@@ -166,15 +129,11 @@ function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
|
|
|
166
129
|
bend,
|
|
167
130
|
arrowheadEnd,
|
|
168
131
|
arrowheadStart: edge.type?.includes("double_arrow") ? arrowheadEnd : void 0,
|
|
169
|
-
dash,
|
|
170
|
-
size,
|
|
171
|
-
color: cssOverrides
|
|
132
|
+
dash: cssOverrides.dashOverride ?? (edge.stroke === "dotted" ? "dotted" : "solid"),
|
|
133
|
+
size: cssOverrides.sizeOverride ?? (edge.stroke === "thick" ? "l" : "s"),
|
|
134
|
+
color: cssOverrides.color
|
|
172
135
|
});
|
|
173
136
|
}
|
|
174
|
-
|
|
175
|
-
const validEdges = blueprintEdges.filter(
|
|
176
|
-
(e) => nodeIds.has(e.startNodeId) && nodeIds.has(e.endNodeId)
|
|
177
|
-
);
|
|
178
|
-
return { diagramKind: "flowchart", nodes, edges: validEdges };
|
|
137
|
+
return { diagramKind: "flowchart", nodes, edges: (0, import_utils.dropDanglingEdges)(nodes, blueprintEdges) };
|
|
179
138
|
}
|
|
180
139
|
//# sourceMappingURL=flowchartDiagram.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/flowchartDiagram.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n\tFlowClass,\n\tFlowEdge,\n\tFlowSubGraph,\n\tFlowVertex,\n} from 'mermaid/dist/diagrams/flowchart/types.js'\nimport { TLArrowShapeArrowheadStyle
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,
|
|
4
|
+
"sourcesContent": ["import type {\n\tFlowClass,\n\tFlowEdge,\n\tFlowSubGraph,\n\tFlowVertex,\n} from 'mermaid/dist/diagrams/flowchart/types.js'\nimport { TLArrowShapeArrowheadStyle } from 'tldraw'\nimport type {\n\tDiagramMermaidBlueprint,\n\tMermaidBlueprintEdge,\n\tMermaidBlueprintNode,\n} from './blueprint'\nimport {\n\tbuildClassDefColorMap,\n\tparseCssStyles,\n\tparseNodeInlineColor,\n\ttoNodeColorProps,\n} from './colors'\nimport {\n\tbuildNodeCentersFromSvg,\n\tclaimNearestEdgeBend,\n\tparseAllEdgePointsFromSvg,\n\tparseClustersFromSvg,\n\tparseDomId,\n\ttype ParsedDiagramLayout,\n\tparseNodesFromSvg,\n\tscaleLayout,\n\tstripDiagramIdPrefix,\n} from './svgParsing'\nimport { dropDanglingEdges, LAYOUT_SCALE, orderTopDown } from './utils'\n\nfunction mapEdgeTypeToArrowhead(type: string | undefined): TLArrowShapeArrowheadStyle {\n\tif (type?.includes('circle')) return 'dot'\n\tif (type?.includes('cross')) return 'bar'\n\tif (type?.includes('open')) return 'none'\n\treturn 'arrow'\n}\n\nconst FRAME_TOP_PAD = 14\nconst NODE_ID = /^flowchart-(.+)-\\d+$/\n\nfunction buildHierarchy(subGraphs: FlowSubGraph[]) {\n\tconst subGraphIds = new Set(subGraphs.map((subGraph) => subGraph.id))\n\tconst nodeToSubGraph = new Map<string, string>()\n\tconst subGraphParent = new Map<string, string>()\n\tfor (const subGraph of subGraphs) {\n\t\tfor (const nodeId of subGraph.nodes) {\n\t\t\tif (subGraphIds.has(nodeId)) {\n\t\t\t\tsubGraphParent.set(nodeId, subGraph.id)\n\t\t\t} else if (!nodeToSubGraph.has(nodeId)) {\n\t\t\t\tnodeToSubGraph.set(nodeId, subGraph.id)\n\t\t\t}\n\t\t}\n\t}\n\treturn { nodeToSubGraph, subGraphParent }\n}\n\n/** Parse flowchart-specific SVG layout data for use by {@link flowchartToBlueprint}. */\nexport function parseFlowchartLayout(root: Element): ParsedDiagramLayout {\n\tconst nodes = parseNodesFromSvg(root, '.node', (domId) => parseDomId(domId, NODE_ID))\n\tconst clusters = parseClustersFromSvg(root, '.cluster', stripDiagramIdPrefix)\n\tconst edges = parseAllEdgePointsFromSvg(root, (dataId) => {\n\t\tconst match = dataId.match(/(?:^|-)L_(.+)_([^_]+)_\\d+$/)\n\t\treturn match ? { start: match[1], end: match[2] } : null\n\t})\n\tscaleLayout(nodes, clusters, edges, LAYOUT_SCALE)\n\treturn { nodes, clusters, edges }\n}\n\n/** Convert a parsed Mermaid flowchart into a tldraw blueprint of nodes and edges. */\nexport function flowchartToBlueprint(\n\tlayout: ParsedDiagramLayout,\n\tvertices: Map<string, FlowVertex>,\n\tedges: FlowEdge[],\n\tsubGraphs?: FlowSubGraph[],\n\tclassDefs?: Map<string, FlowClass>\n): DiagramMermaidBlueprint {\n\tconst nodeColorMap = buildClassDefColorMap(classDefs ?? new Map(), vertices)\n\tconst { nodes: svgNodes, clusters: svgClusters, edges: svgEdges } = layout\n\tconst nodeCenters = buildNodeCentersFromSvg(svgNodes, svgClusters)\n\n\tconst allSubGraphs = subGraphs || []\n\tconst { nodeToSubGraph, subGraphParent } = buildHierarchy(allSubGraphs)\n\n\tconst nodes: MermaidBlueprintNode[] = []\n\tconst blueprintEdges: MermaidBlueprintEdge[] = []\n\n\t// Frames for subgraphs\n\tfor (const subGraph of orderTopDown(\n\t\tallSubGraphs,\n\t\t(subGraph) => subGraph.id,\n\t\t(subGraph) => subGraphParent.get(subGraph.id)\n\t)) {\n\t\tconst cluster = svgClusters.get(subGraph.id)\n\t\tif (!cluster) continue\n\n\t\tnodes.push({\n\t\t\tid: subGraph.id,\n\t\t\tkind: 'subgraph',\n\t\t\tx: cluster.topLeft.x,\n\t\t\ty: cluster.topLeft.y - FRAME_TOP_PAD,\n\t\t\tw: cluster.width,\n\t\t\th: cluster.height + FRAME_TOP_PAD,\n\t\t\tparentId: subGraphParent.get(subGraph.id),\n\t\t\tlabel: subGraph.title || subGraph.id,\n\t\t\tfill: 'semi',\n\t\t\tcolor: 'black',\n\t\t\tdash: 'draw',\n\t\t\tsize: 's',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'start',\n\t\t})\n\t}\n\n\t// Node shapes\n\tfor (const [id, vertex] of vertices) {\n\t\tconst svgNode = svgNodes.get(id)\n\t\tif (!svgNode) continue\n\n\t\tlet { width: w, height: h } = svgNode\n\t\tif (vertex.type === 'circle' || vertex.type === 'doublecircle') {\n\t\t\tw = h = Math.max(w, h)\n\t\t}\n\n\t\tnodes.push({\n\t\t\tid,\n\t\t\tkind: vertex.type ?? 'rect',\n\t\t\tx: svgNode.center.x - w / 2,\n\t\t\ty: svgNode.center.y - h / 2,\n\t\t\tw,\n\t\t\th,\n\t\t\tparentId: nodeToSubGraph.get(id),\n\t\t\tlabel: vertex.text || undefined,\n\t\t\t...toNodeColorProps(nodeColorMap.get(id) ?? parseNodeInlineColor(vertex.styles)),\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\tsize: 'm',\n\t\t})\n\t}\n\n\t// Edges: match DB edges to SVG edges by proximity, compute bends\n\tconst claimed = new Set<number>()\n\tfor (const edge of edges) {\n\t\tconst bend = claimNearestEdgeBend(\n\t\t\tsvgEdges,\n\t\t\tclaimed,\n\t\t\tnodeCenters.get(edge.start),\n\t\t\tnodeCenters.get(edge.end)\n\t\t)\n\t\tconst cssOverrides = parseCssStyles(edge.style)\n\t\tconst arrowheadEnd = mapEdgeTypeToArrowhead(edge.type)\n\n\t\tblueprintEdges.push({\n\t\t\tstartNodeId: edge.start,\n\t\t\tendNodeId: edge.end,\n\t\t\tlabel: edge.text,\n\t\t\tbend,\n\t\t\tarrowheadEnd,\n\t\t\tarrowheadStart: edge.type?.includes('double_arrow') ? arrowheadEnd : undefined,\n\t\t\tdash: cssOverrides.dashOverride ?? (edge.stroke === 'dotted' ? 'dotted' : 'solid'),\n\t\t\tsize: cssOverrides.sizeOverride ?? (edge.stroke === 'thick' ? 'l' : 's'),\n\t\t\tcolor: cssOverrides.color,\n\t\t})\n\t}\n\n\treturn { diagramKind: 'flowchart', nodes, edges: dropDanglingEdges(nodes, blueprintEdges) }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["subGraph"]
|
|
7
7
|
}
|
package/dist-cjs/index.js
CHANGED
|
@@ -35,7 +35,7 @@ var import_mermaidNodeCreateShape = require("./mermaidNodeCreateShape");
|
|
|
35
35
|
var import_renderBlueprint = require("./renderBlueprint");
|
|
36
36
|
(0, import_utils.registerTldrawLibraryVersion)(
|
|
37
37
|
"@tldraw/mermaid",
|
|
38
|
-
"5.
|
|
38
|
+
"5.5.0-canary.0241f11f2e99",
|
|
39
39
|
"cjs"
|
|
40
40
|
);
|
|
41
41
|
//# sourceMappingURL=index.js.map
|
|
@@ -36,31 +36,15 @@ function defaultCreateMermaidNodeFromBlueprint(args) {
|
|
|
36
36
|
...node.align && { align: node.align },
|
|
37
37
|
...node.verticalAlign && { verticalAlign: node.verticalAlign }
|
|
38
38
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
geo: render.geo
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
} else {
|
|
52
|
-
editor.createShape({
|
|
53
|
-
id: shapeId,
|
|
54
|
-
type: render.type,
|
|
55
|
-
x,
|
|
56
|
-
y,
|
|
57
|
-
parentId: parentShapeId,
|
|
58
|
-
props: {
|
|
59
|
-
...baseProps,
|
|
60
|
-
...render.props
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
39
|
+
const { type, props } = render.variant === "geo" ? { type: "geo", props: { geo: render.geo } } : { type: render.type, props: render.props };
|
|
40
|
+
editor.createShape({
|
|
41
|
+
id: shapeId,
|
|
42
|
+
type,
|
|
43
|
+
x,
|
|
44
|
+
y,
|
|
45
|
+
parentId: parentShapeId,
|
|
46
|
+
props: { ...baseProps, ...props }
|
|
47
|
+
});
|
|
64
48
|
return editor.getShape(shapeId);
|
|
65
49
|
}
|
|
66
50
|
//# sourceMappingURL=mermaidNodeCreateShape.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/mermaidNodeCreateShape.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Editor,
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA2B;AAM3B,mBAAoC;AAuB7B,SAAS,sCACf,MACU;AACV,QAAM,EAAE,QAAQ,MAAM,SAAS,GAAG,GAAG,eAAe,OAAO,IAAI;AAC/D,QAAM,YAAY;AAAA,IACjB,GAAG,KAAK;AAAA,IACR,GAAG,KAAK;AAAA,IACR,MAAM,KAAK,QAAQ;AAAA,IACnB,OAAO,KAAK,SAAS;AAAA,IACrB,MAAM,KAAK,QAAQ;AAAA,IACnB,MAAM,KAAK,QAAQ;AAAA,IACnB,GAAI,KAAK,SAAS,EAAE,cAAU,8BAAW,kCAAoB,KAAK,KAAK,CAAC,EAAE;AAAA,IAC1E,GAAI,KAAK,SAAS,EAAE,OAAO,KAAK,MAAM;AAAA,IACtC,GAAI,KAAK,iBAAiB,EAAE,eAAe,KAAK,cAAc;AAAA,EAC/D;AAEA,
|
|
4
|
+
"sourcesContent": ["import type { Editor, TLShape, TLShapeId } from 'tldraw'\nimport { toRichText } from 'tldraw'\nimport type {\n\tMermaidBlueprintNode,\n\tMermaidBlueprintNodeRenderSpec,\n\tMermaidDiagramKind,\n} from './blueprint'\nimport { sanitizeDiagramText } from './utils'\n\n/**\n * Arguments for {@link defaultCreateMermaidNodeFromBlueprint}. `x` / `y` are in shape space (parent-relative when\n * `parentShapeId` is set), matching {@link renderBlueprint}.\n * @public\n */\nexport interface MermaidNodeCreateFunctionArgs {\n\teditor: Editor\n\tnode: MermaidBlueprintNode\n\tshapeId: TLShapeId\n\tx: number\n\ty: number\n\tparentShapeId?: TLShapeId\n\tdiagramKind: MermaidDiagramKind\n\t/** Materialization spec (from {@link resolveMermaidNodeRender} or your mapper). */\n\trender: MermaidBlueprintNodeRenderSpec\n}\n\n/**\n * Creates the tldraw shape for one Mermaid blueprint node using `render` and layout-derived props.\n * @public\n */\nexport function defaultCreateMermaidNodeFromBlueprint(\n\targs: MermaidNodeCreateFunctionArgs\n): TLShape {\n\tconst { editor, node, shapeId, x, y, parentShapeId, render } = args\n\tconst baseProps = {\n\t\tw: node.w,\n\t\th: node.h,\n\t\tfill: node.fill ?? 'none',\n\t\tcolor: node.color ?? 'black',\n\t\tdash: node.dash ?? 'draw',\n\t\tsize: node.size ?? 'm',\n\t\t...(node.label && { richText: toRichText(sanitizeDiagramText(node.label)) }),\n\t\t...(node.align && { align: node.align }),\n\t\t...(node.verticalAlign && { verticalAlign: node.verticalAlign }),\n\t}\n\n\tconst { type, props } =\n\t\trender.variant === 'geo'\n\t\t\t? { type: 'geo', props: { geo: render.geo } }\n\t\t\t: { type: render.type, props: render.props }\n\teditor.createShape({\n\t\tid: shapeId,\n\t\ttype: type as any,\n\t\tx,\n\t\ty,\n\t\tparentId: parentShapeId,\n\t\tprops: { ...baseProps, ...props },\n\t})\n\treturn editor.getShape(shapeId)!\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA2B;AAM3B,mBAAoC;AAuB7B,SAAS,sCACf,MACU;AACV,QAAM,EAAE,QAAQ,MAAM,SAAS,GAAG,GAAG,eAAe,OAAO,IAAI;AAC/D,QAAM,YAAY;AAAA,IACjB,GAAG,KAAK;AAAA,IACR,GAAG,KAAK;AAAA,IACR,MAAM,KAAK,QAAQ;AAAA,IACnB,OAAO,KAAK,SAAS;AAAA,IACrB,MAAM,KAAK,QAAQ;AAAA,IACnB,MAAM,KAAK,QAAQ;AAAA,IACnB,GAAI,KAAK,SAAS,EAAE,cAAU,8BAAW,kCAAoB,KAAK,KAAK,CAAC,EAAE;AAAA,IAC1E,GAAI,KAAK,SAAS,EAAE,OAAO,KAAK,MAAM;AAAA,IACtC,GAAI,KAAK,iBAAiB,EAAE,eAAe,KAAK,cAAc;AAAA,EAC/D;AAEA,QAAM,EAAE,MAAM,MAAM,IACnB,OAAO,YAAY,QAChB,EAAE,MAAM,OAAO,OAAO,EAAE,KAAK,OAAO,IAAI,EAAE,IAC1C,EAAE,MAAM,OAAO,MAAM,OAAO,OAAO,MAAM;AAC7C,SAAO,YAAY;AAAA,IAClB,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,OAAO,EAAE,GAAG,WAAW,GAAG,MAAM;AAAA,EACjC,CAAC;AACD,SAAO,OAAO,SAAS,OAAO;AAC/B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|