Mermaid graphs in Obsidian and Hugo
By Andreas Røssland
In the note-taking software Obsidian you can create Mermaid plots by simply setting the language for your fenced code block to mermaid
.
```mermaid
graph LR
A-->B
```
graph LR
A-->B
Since I write my blog in Obsidian and then render it using Hugo, I needed a method for adding Mermaid plots that would render fine in both Obsidian and Hugo.
Solution: Add Mermaid.js to your template’s footer. I added it to my header since the Ananke template doesn’t have an existing partial
for putting things in the footer.
$ cat layouts/partials/head-additions.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.13.4/mermaid.min.js" integrity="sha512-JERecFUBbsm75UpkVheAuDOE8NdHjQBrPACfEQYPwvPG+fjgCpHAz1Jw2ci9EXmd3DdfiWth3O3CQvcfEg8gsA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
window.addEventListener('DOMContentLoaded', function() {
mermaid.init(undefined, ".language-mermaid");
}, false)
</script>
This partially works, but using the Ananke template the chart is rendered inside a <pre>
element with a black background, which looks horrible. Parent selectors aren’t a thing in CSS yet, so I just hacked away the parent element with some JavaScript.
window.addEventListener('DOMContentLoaded', function() {
let codes = document.getElementsByClassName("language-mermaid");
for (let code of codes) {
let pre = code.parentElement;
pre.before(code);
pre.remove();
}
mermaid.init(undefined, ".language-mermaid");
})
A small visualization of what happens here:
Initial state:. <code>
is inside a <pre>
which is inside some container.
graph LR;
Container --> Pre --> Code
Code -->|parent| Pre
Put <code>
element into parent element along with <pre>
with pre.before(code);
.
graph LR;
Container --> Pre
Container --> Code
Then delete the <pre>
element.
graph LR;
Container --> Code
This solution was inspired by the post Use mermaid with code fences found in the Hugo forums.