note
This article was last updated on April 22, 2023, 2 years ago. The content may be out of date.
Mermaid is a javascript library that can render text definitions as diagrams. It’s not supported by PaperMod. There are two major problems that I encountered when adding mermaid support.
Mermaid Diagrams not Showing
I tried the method described in this comment. It only worked in my local development environment. And when I put mermaid related snippets in extend_footer.html
like the author suggested, it won’t even work.
Cause
The head and the footer of the theme is handled by baseof.html
and they’re both partials. However, when rendering, head
is not cached but footer
is not. hasMermaid
variable is only be set when hugo finishes processing the content of the post. The content is based on commit 575cc0c.
|
|
When in my local development environment, hugo is running in fast render mode. By using store, this variable is not reset. When hugo rebuilds the site, the variable is picked up in extend_head.html
so mermaid diagrams display properly.
But when deploying the site, hugo doesn’t rebuild the site. This variable is not set until hugo is done with the content of the post.
Because footer is a cached partial, hugo reuse the same footer across the site. Some pages don’t have mermaid, and they’re usually built first. extend_footer.html
doesn’t work either.
Solution
Modify baseof.html
and add a new partial mermaid.html
that renders mermaid diagrams when hasMermaid
variable is set.
Dark Mode Toggle
When using the dark mode toggle, mermaid diagrams doesn’t update their themes. This is expected since the code used to initialize mermaid diagrams doesn’t take dark mode into consideration.
Solution
By inspecting the source code of the PaperMod theme, when in dark mode document.body.classList.contains('dark')
will return true
, whether dark mode is set auto or manual. That’s the first step. Now we can choose the correct theme when the page is loaded.
But when dark mode is toggled, dark
class on document.body
will be added or removed, and we’ll watch this as well. Javascript has provided MutationObserver
for use to watch any change that might happen to an html element.
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
const theme = document.body.classList.contains('dark')? 'dark': 'default';
if (oldTheme !== theme) {
oldTheme = theme;
// rerender mermaid diagrams
}
});
});
observer.observe(document.body, {
attributes: true,
attributeFilter: ['class']
});
To rerender mermaid diagrams, I have looked up the mermaid documentation and based on this comment.
- Restore the innerhtml of the mermaid diagram elements to their original text (requires saving them before they’re rendered)
- Remove the
data-processed
attribute from these elements - Reinitialize mermaid
- Rerender
warning
mermaid.init
is deprecated according to the mermaid documentation.