73 lines
3.8 KiB
Markdown
73 lines
3.8 KiB
Markdown
# Hugo 增加mermaid支持
|
||
|
||
### 增加 shortcode 模板
|
||
|
||
如果用 mermaid 官方的集成方法,会带来一个问题: 官方集成方法会导致我们的每个文章页面都会加载 mermaid.js ,但是 我们写博客的时候,并不是每个页面都需要加载 mermaid 这个 js, 只在文章里面包含 mermaid 代码时我们才需要加载。因此这里我们用 js 动态加载 mermaid.
|
||
|
||
首先,这个 js 我们也懒得放在主题里了,直接用 CDN 的:
|
||
|
||
去 <https://www.jsdelivr.com/package/npm/mermaid> 我们点开 dist 目录,然后找到完整版的js文件(注意不要看错了,选了 core 那个):
|
||
|
||
`https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js`
|
||
|
||
新增加 shortcode, 目前我用的主题是 terminal, 因此在 themes/terminal 下新建:
|
||
|
||
`layouts/shortcodes/mermaid.html` 文件,内容如下:
|
||
|
||
```go-html-template
|
||
<!-- https://github.com/matcornic/hugo-theme-learn/blob/master/layouts/shortcodes/mermaid.html -->
|
||
<pre class="mermaid" align="{{ if .Get "align" }}{{ .Get "align" }}{{ else }}center{{ end }}">{{ safeHTML .Inner }}</pre>
|
||
```
|
||
|
||
这个 shortcode 代码基本上取自[这里](https://github.com/matcornic/hugo-theme-learn/blob/master/layouts/shortcodes/mermaid.html), 但是老灯这里把外层的 `div` 改成了 `pre`
|
||
|
||
关于 `.Inner` 是啥, 可以参考[这个文档](https://gohugo.io/templates/shortcode-templates/#inner)
|
||
|
||
``{{ $_hugo_config := `{ "version": 1 }` }}`` 我也一并移除了,这个是 shortcodes-with-markdown 才需要的,而我们这里面的内容都是直接给 js 处理的,并不需要 markdown 处理。 参考[这里](https://gohugo.io/content-management/shortcodes/#shortcodes-with-markdown)
|
||
|
||
|
||
### 加载 mermaid js
|
||
|
||
网上大部分的模板都不够自动, 很多是需要在配置里选择是否加载 mermaid 的, 这里老灯写了个根据文章内容动态加载的 js .
|
||
|
||
修改模板的 footer.html 文件,增加 js:
|
||
|
||
```javascript
|
||
const loadScript = (url, onloadFunction) => {
|
||
var newScript = document.createElement("script");
|
||
newScript.onerror = (oError) => {
|
||
throw new URIError("The script " + oError.target.src + " didn't load correctly.");
|
||
};
|
||
if (onloadFunction) { newScript.onload = onloadFunction; }
|
||
document.head.insertAdjacentElement('beforeend', newScript);
|
||
newScript.src = url;
|
||
}
|
||
|
||
// mermaid loader by ttys3.dev
|
||
const loadMermaidOnNeed = () => {
|
||
if (document.querySelectorAll('.mermaid').length > 0) {
|
||
loadScript('https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js', () => {
|
||
document.head.insertAdjacentHTML("beforeend", `<style>.mermaid svg { background-color: #dadcd8 !important; }</style>`);
|
||
// default, dark, neutral, forest
|
||
mermaid.initialize({ startOnLoad: false, securityLevel: "strict", theme: "neutral" });
|
||
// https://github.com/mermaid-js/mermaid/blob/e6e94ad57ea06ef8627bf91ddfbd88f5082952bf/src/mermaid.js#L153
|
||
// mermaid.contentLoaded();
|
||
mermaid.init();
|
||
console.log("mermaid init done");
|
||
})
|
||
}
|
||
}
|
||
|
||
window.addEventListener('load', function(event) {
|
||
// load mermaid
|
||
loadMermaidOnNeed();
|
||
});
|
||
```
|
||
|
||
如果要调试问题,可以在配置里增加 `logLevel: 1,`
|
||
|
||
`theme: "neutral"` 是指定主题,可以从 `default, dark, neutral, forest` 四个里面选。 如果不太满意默认的,也可以自行 DIY, 参考 <https://mermaid-js.github.io/mermaid/#/theming>
|
||
|
||
`startOnLoad` 选项其实在我们这里并没有什么用。 如果调用 `mermaid.contentLoaded()` 渲染的话,需要设置 `startOnLoad` 为 `true`. 但是其实 `contentLoaded` 就是判断了一下 `startOnLoad` 然后调用了 `mermaid.init()`, 因此这里老灯直接调用 `mermaid.init()` 渲染了。
|
||
|
||
最后,偷懒的可以直接用老灯这个修改版的`terminal`主题 <https://github.com/ttys3/hugo-theme-terminal/tree/ttys3> |