使用Mermaid在hugo的Markdown中绘制UML

简介

Mermaid是一个提供绘图功能的JavaScript项目。 它目前(8.6.4)支持:

使用

在Markdown中,使用Mermaid十分简单。


```mermaid
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
```

写出以上代码块,就可以在网页渲染时,自动变成以下的svg图。

graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;

本文不对如何用它表达思想,做过多描述,详见官网文档。 此外,还可在其在线编辑器直接试用:mermaid-live-editor

以下介绍如何配置使用。

配置

GitLab等平台中,内置了Mermaid,只是版本不是最新。 想要使用,直接写就好。

在自己的hugo网站中,则需要在head.html这类的模板中,配置一番。 确保在最后的网页中,在恰当的位置包含以下要素。

<head>
    ...
    <script async src="https://cdn.staticfile.org/mermaid/8.6.4/mermaid.min.js"></script>
</head>
<body>
    ...
<script>
    // Replace mermaid pre.code to div
    Array.from(document.getElementsByClassName('language-mermaid')).forEach(el => {
        el.parentElement.outerHTML = `<div class="mermaid">${el.innerText}</div>`
    })
</script>
<style>
/* Set svg to center */
.mermaid svg {
    display: block;
    margin: auto;
}
</style>
</body>

其中,<head>部分是引入mermaid.js。 这里使用的是staticfile.org作为CDN,可按需替换。

<body>的最后,需要加上<script>这段,用处是替换mermaid代码块为<div>,确保mermaid.js开始工作。 如果没有这段<script>,把```mermaid写成<div class="mermaid">也是能用的,但不够优雅。

最后的<style>则是让svg居中显示。

另一种配置

以下是本站一次更新后的配置。 除了CDN使用jsdelivr、版本更新为8.8.2以外,主要改动是在Hugo模板中添加了if

{{ if .Params.mermaid }}
<script
  src="https://cdn.jsdelivr.net/npm/mermaid@8.8.2/dist/mermaid.min.js"
  integrity="sha256-KqisLh8jVMBRjpNkOhH5W9VWs+F6x6vQksLqxs7+x9A="
  crossorigin="anonymous"
></script>
<script>
  // Replace mermaid pre.code to div
  Array.from(document.getElementsByClassName("language-mermaid")).forEach(
    (el) => {
      el.parentElement.outerHTML = `<div class="mermaid">${el.innerText}</div>`;
    }
  );
</script>
<style>
  /* Set svg to center */
  .mermaid svg {
    display: block;
    margin: auto;
  }
</style>
{{ end }}

以上内容,都放到新增的layouts/partials/mermaid.html中。 把它完整地放在目标模板的<body>中,即可具备Mermaid功能。 这个片段需要放在<body>最底部,避免影响主要内容的加载, 并且可保自动替换div时,能够完整获取目标元素。

在第一行,额外加上了.Params.mermaid的检查,避免所有页面都需要加载它。 在需要使用的Hugo页面,可以在Front Matter中添加一个配置,显式指定使用Mermaid。 以下为TOML形式的示例:

+++
...
mermaid = true
+++

结语

用好Mermaid,可以让Markdown的表现力增色不少。 以后,本站也会更多地使用它来做更好的表达。


相关笔记