Test/node_modules/@excalidraw/mermaid-to-excalidraw/dist/parseMermaid.js
2026-04-09 22:54:00 +07:00

71 lines
2.7 KiB
JavaScript

import mermaid from "mermaid";
import { MERMAID_CONFIG } from "./constants.js";
import { encodeEntities } from "./utils.js";
import { parseMermaidFlowChartDiagram } from "./parser/flowchart.js";
import { parseMermaidSequenceDiagram } from "./parser/sequence.js";
import { parseMermaidClassDiagram } from "./parser/class.js";
// Fallback to Svg
const convertSvgToGraphImage = (svgContainer) => {
// Extract SVG width and height
// TODO: make width and height change dynamically based on user's screen dimension
const svgEl = svgContainer.querySelector("svg");
if (!svgEl) {
throw new Error("SVG element not found");
}
const rect = svgEl.getBoundingClientRect();
const width = rect.width;
const height = rect.height;
// Set width and height explictly since in firefox it gets set to 0
// if the width and height are not expilcitly set
// eg in some cases like er Diagram, gnatt, width and height is set as 100%
// which sets the dimensions as 0 in firefox and thus the diagram isn't rendered
svgEl.setAttribute("width", `${width}`);
svgEl.setAttribute("height", `${height}`);
// Convert SVG to image
const mimeType = "image/svg+xml";
const decoded = unescape(encodeURIComponent(svgEl.outerHTML));
const base64 = btoa(decoded);
const dataURL = `data:image/svg+xml;base64,${base64}`;
const graphImage = {
type: "graphImage",
mimeType,
dataURL,
width,
height,
};
return graphImage;
};
export const parseMermaid = async (definition, config = MERMAID_CONFIG) => {
mermaid.initialize({ ...MERMAID_CONFIG, ...config });
// Parse the diagram
const diagram = await mermaid.mermaidAPI.getDiagramFromText(encodeEntities(definition));
// Render the SVG diagram
const { svg } = await mermaid.render("mermaid-to-excalidraw", definition);
// Append Svg to DOM
const svgContainer = document.createElement("div");
svgContainer.setAttribute("style", `opacity: 0; position: relative; z-index: -1;`);
svgContainer.innerHTML = svg;
svgContainer.id = "mermaid-diagram";
document.body.appendChild(svgContainer);
let data;
switch (diagram.type) {
case "flowchart-v2": {
data = parseMermaidFlowChartDiagram(diagram, svgContainer);
break;
}
case "sequence": {
data = parseMermaidSequenceDiagram(diagram, svgContainer);
break;
}
case "classDiagram": {
data = parseMermaidClassDiagram(diagram, svgContainer);
break;
}
// fallback to image if diagram type not-supported
default: {
data = convertSvgToGraphImage(svgContainer);
}
}
svgContainer.remove();
return data;
};