Hugo 是一款搭建个人博客的框架,支持使用 Markdown 格式的文件生成 HTML 文件。hugo-theme-even 则是 Hugo 的一个主题。Mermaid 则是一个支持在 Markdown 下生成图表的工具。

因为 Hugo 并不原生支持 Mermaid ,所以本文的目的是,基于 hugo-theme-even 主题,通过修改 Hugo 的配置文件,引用 Mermaid 文件,使得 Hugo 生成的博客也能使用 Mermaid 生成的图表。

首先在根目录的 \layouts\partials 下新建文件 mermaid.html,没有 partials 目录的话,需要新建。

<!-- mermaid.html -->

{{ if .Params.mermaid }}  <!-- 判断是否开启 -->
<script type="module">  
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs'; 
    mermaid.initialize({ startOnLoad: true });  
</script>  
<script>  
    // Replace mermaid pre.code to div  
    Array.from(document.getElementsByClassName("language-mermaid")).forEach(  
        (el) => {  
            el.parentElement.outerHTML = `<div class="mermaid">${el.innerHTML}</div>`;  
        }  
    );  
</script>  
<style>  
    /* Set svg to center */  
    .mermaid svg {  
        display: block;  
        margin: auto;  
    }  
</style>  
{{ end }}

el.innerHTML 用于获取元素的 HTML 标记, el.innerText 用户获取元素渲染的文本内容。使用 el.innerHTML 提取 Mermaid 代码,而不是 el.innerText,是因为如果代码中存在 <<interface>>(类图中会存在),el.innerText 会将其忽略掉,会导致 Mermaid 渲染失败。

然后在主题的 layouts\post\single.html 文件中引入 mermaid.html 文件:

<!-- mermaid -->  
{{- partial "mermaid.html" . -}}

在文章中使用的话,需要先在 Front-matter 中使用以下方式开启。

---
mermaid: true
---

Mermaid 渲染的例子是:

	```mermaid
	classDiagram
	class A{
		<<interface>>
	}
	
	class B{
		<<interface>>
	}
	
	A --> B
	```

渲染的结果为:

classDiagram
class A{
	<<interface>>
}

class B{
	<<interface>>
}

A --> B

参考:1. 使用Mermaid在hugo的Markdown中绘制UML · 零壹軒·笔记

  1. A Mermaid User-Guide for Beginners | Calling the JavaScript API

  2. mermaid CDN by jsDelivr - A CDN for npm and GitHub