index.js 1.50 KiB
import mermaid from "mermaid/dist/mermaid";
class MermaidPlugin {
  init() {
    Reveal.addEventListener("slidechanged", (event) =>
      this.onSlideChanged(event)
    );
    this.serial = 0;
    mermaid.initialize({ startOnLoad: false, theme: "neutral" });
    this.processSlide(Reveal.getCurrentSlide());
  /**
   * @param {{ currentSlide: HTMLElement }} param0
  onSlideChanged({ currentSlide }) {
    this.processSlide(currentSlide);
  /**
   * @param {HTMLElement} slide
  async processSlide(slide) {
    const graphs = [];
    for (const graph of slide.querySelectorAll("pre.mermaid")) {
      const prom = this.renderGraph(graph);
      if (prom) {
        graphs.push(prom);
    await Promise.all(graphs);
    Reveal.layout();
  /**
   * @param {HTMLElement} element
   * @return {Promise<boolean>|null}
  renderGraph(element) {
    if (element.hasAttribute("data-processed")) {
      return null;
    return new Promise((resolve, reject) => {
      try {
        mermaid.render(
          `__mermaid${+this.serial}`,
          element.textContent,
          (svgCode) => {
            element.innerHTML = svgCode;
            element.setAttribute("data-processed", true);
            resolve(true);
      } catch (error) {
        element.textContent += `\n\nMermaid ${error}`;
        element.setAttribute("data-processed", true);
        reject(error);
    });
Reveal.registerPlugin("mermaid", new MermaidPlugin());