One of the changes that version .117 of Hugo that has been allowed onto Micro.blog is the ability to use diagrams in your markdown. The documentation on diagrams highlights two different kinds of diagrams that you can include; GoAT and Mermaid.
When you make a diagram using GoAT, Hugo translates this into a SVG on the server side and then delivers it with the HTML for that particular post. You can find some really complicated examples of them on the GitHub page for GoAT and I’ve included one below to demonstrate.
Mermaid is a diagramming and charting tool that uses javascript and will load different libraries as needed to create the final product. I believe that it can be used to make static deliverables that you could save, but -according to my understanding- that’s a separate module and outside what Micro.blog and most installations require.
In addition, Hugo does not include the connections to Mermaid, and it’s up to the theme developers to make sure this works.
When you get it working, you can have diagrams like the one below.
sequenceDiagram participant Alice participant Bob Alice->>John: Hello John, how are you? loop Healthcheck John->>John: Fight against hypochondria end Note right of John: Rational thoughts
prevail! John-->>Alice: Great! John->>Bob: How about you? Bob-->>John: Jolly good!
The Mystery of the Mermaid
I had to ask myself why am I putting the time into getting this feature working in my theme. At first glance, the goals of accessibility and speed do not seem to align with adding diagrams built with third party JavaScript framework. I’ve run this site for years and have used tools to create static images that I serve with alt text to illustrate my point.
Ultimately, it’s because I love DIAGRAMS!
I like being able to have a picture that goes with my posts. I don’t feel that I will be using a lot of these, but I want to help those who do.
And with all of my labarum posts, feel free to take what you want to make your themes better.
Splashing around with the Mermaid
I want to start off this section by stating that a lot of what I’m going to write about is duplication of the documentation found online. This is me documenting my process of applying it and my thought process at the time.
My first stop on implementing this is to open up a browser window to duckduckgo and then opening the first 3-5 search results of Hugo mermaid diagram
from DuckDuckGo before reading the Hugo Mermaid documentation. I do this to get a feel of what developer roadblocks and experiences that I can note before reading the documentation. It’s similar to where I would read the discussion questions the teacher gives for assigned reading back in school.
The step of creating the layouts/_default/_markup/render-codeblock-mermaid.html
is straight forward1.
<pre class="mermaid">
{{ .Inner | safeHTML }}
</pre>
{{ .Page.Store.Set "hasMermaid" true }}
The first line will go to the resultant HTML, and mermaid will look for items that have the mermaid class to get instructions on what kind of image needs to create.
The second line passes whatever was in the code block. This is typically the definition of the diagram but if you are more familiar or more adventurous you can pass mermaid directives or configurations as well.
The next step is to add something similar to the template.
{{ if .Page.Store.Get "hasMermaid" }}
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
{{ end }}
I wasn’t sure why this needed to go on the actual page versus on the footer that would be used on every single page of the website. Most of the examples that I looked at had it on the single.html
and this worked for individual pages but not for the index.html
.
I placed it in article_footer.html
until I get a deeper understanding of how Hugo wants to manage a flag that would toggle the loading of JavaScript.
Luckily, the browsers that I tested with only load the JavaScript once. I’m not a JavaScript expert, but I think multiple loads of the 7k line file might be frowned upon.
Colors of the Mermaid
After I got it working for the index and standalone pages, I tested the diagram with the dark mode of the theme. Unfortunately, the default text color does not work in all situations.
I checked the documentation on theming the diagrams and saw that I can change the theme by giving it as a parameter during the initialization of mermaid.
mermaid.initialize( { startOnLoad: true, theme: 'dark' });
This allows for the diagrams to look good in dark mode.
This looked good in dark mode but not light mode.
I then experimented with changing the background for div.mermaid
and then having the diagrams render using the default theme for both light and dark mode.
Good but not ultimately it just didn’t look good enough. I showed it to my wife and some people in a discord and they agreed as well.
I needed to find a way to make it toggle from default
and dark
.
Searching for the Key
Luckily, when I did my first third group of searches, I came across a Hugo forum thread on the “Correct way to embed Mermaid.JS”2. And it had a link to this article to add Mermaid to Hugo with Dark Mode which is very informative.
|
|
On line 4, we set a property based on the weather the browser is in dark mode.
Line 5 is a ternary statement that chooses between the dark or default themes.
Line 6 is the beginning of a JavaScript Object. I feel that the way it’s in the theme will make it easier to maintain and extend in the future.
It’s all about that base
Mermaid does have a base
theme that allows for you to define the colors for the diagram. Yes, I could have taken the time to learn how to pull colors from the theme or use the toggle from light and dark mode to set the diagram colors. But, that could be a long process to customize something that I may not use.
If you want to take this theme and approach, please do, and please have no hesitation to send me a link of your endeavors.
Limitations
Although this implementation does consider if the user is in light or dark mode, it does not switch dynamically. If you are on a system that changes the theme depending on time, you will have to reload to get the different theme. There are themes and walk throughs that show how to do this, but I feel that this iteration and my skill level are not at the appropriate level to implement it now.
Another limitation is that the diagram definition might find it’s way into the .Summary
for the individual post.
Mermaid Treasure
Thank you for getting this far into my post. Here are some resources if you want to know more about Mermaid.js.
- Accessibility Options
- If you took the time to make the diagram, take a little more time to allow other people to get something from it.
- Tutorials
- Lots of examples on how to make diagrams
- Live Editor
- A quick way to make and test your diagrams before putting them in your posts.
What’s next for Labarum?
I need to do an accessibility and validation audit of the theme. I’ve been making some adjustments and haven’t been testing to make sure that the site is as accessible as I had originally intended.