All files / public/docs mermaid.js

0% Statements 0/35
0% Branches 0/6
0% Functions 0/5
0% Lines 0/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103                                                                                                                                                                                                             
import mermaid from "mermaid";
 
// We don't get the "mermaid" code block id through
// so be really hacky about it
const START_SYNTAX = [
  "flowchart",
  "sequenceDiagram",
  "gantt",
  "classDiagram",
  "stateDiagram",
  "stateDiagram-v2",
  "erDiagram",
  "journey",
  "pie",
  "requirementDiagram",
  "gitGraph",
  "C4Context",
  "C4Container",
  "C4Component",
  "mindmap",
  "timeline",
  "pie",
  "graph",
];
 
// Render each SVG and add events for the dropdown
async function renderSVG(block, index) {
  const codeSnippet = document.createElement("div");
  codeSnippet.className = "p-code-snippet";
 
  const content = block.innerText;
  const { svg } = await mermaid.render(`diagram-${index}`, content);
 
  codeSnippet.innerHTML = `
    <div class="p-code-snippet__header">
      <h5 class="p-code-snippet__title">Mermaid Diagram</h5>
      <div class="p-code-snippet__dropdowns">
        <select class="p-code-snippet__dropdown">
          <option value="rendered">Rendered</option>
          <option value="markup">Markup</option>
        </select>
      </div>
    </div>
  `;
 
  const renderedDiv = document.createElement("div");
  renderedDiv.className = "rendered";
  renderedDiv.style.marginTop = "1rem";
  renderedDiv.innerHTML = svg;
 
  const markupDiv = document.createElement("div");
  markupDiv.className = "markup";
  markupDiv.textContent = block.parentNode.outerHTML;
 
  codeSnippet.appendChild(renderedDiv);
  codeSnippet.appendChild(markupDiv);
 
  block.parentNode.parentNode.replaceChild(codeSnippet, block.parentNode);
 
  const rendered = codeSnippet.querySelector(".rendered");
  const markup = codeSnippet.querySelector(".markup");
 
  // immediately hide the original markup block
  markup.style.display = "none";
 
  codeSnippet
    .querySelector(".p-code-snippet__dropdown")
    .addEventListener("change", (e) => {
      // Simple switch
      if (e.target.value === "rendered") {
        markup.style.display = "none";
        rendered.style.display = "block";
      } else {
        markup.style.display = "block";
        rendered.style.display = "none";
      }
    });
}
 
async function initMermaid() {
  // Get all code blocks that are in the main content of the site
  const codeBlocks = document.querySelectorAll("#main-content pre code");
  const mermaidBlocks = Array.from(codeBlocks).filter((block) => {
    // Get the first line of the inner code
    const firstLine = block.innerText.split("\n")[0];
    // Get the first word and match it against the predefined list
    if (START_SYNTAX.includes(firstLine.split(" ")[0].trim())) {
      return true;
    }
    return false;
  });
 
  // Only if we have some blocks should we do anything
  if (mermaidBlocks) {
    mermaid.initialize({ startOnLoad: false, securityLevel: "antiscript" });
    await Promise.all(
      mermaidBlocks.map((block, index) => renderSVG(block, index))
    );
  }
}
 
export { initMermaid };