goHugo Mermaid

I did some tinkering with Mermaid and settled on a shortcode that I’m happy with for my Hugo blog.

I’ve switched from the Mainroad theme to the Binario theme initally as a (failed) workaround. I found that the syntax highlighing for Binario theme worked better so I’ve kept it.


via Pandoc? (Nope!)

sequenceDiagram
    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!

I’d had bad experiences with Mermaid and Hugo solutions previously. I’ve had good general expeirences with Pandoc. So, my first idea was to use Pandoc to translate embedded Mermaid diagrams into … whatever Pandoc did. Turns out that it embeds a .png image into the .md as base64, which is adorable!

I tried installing a Mermaid filter for Pandoc globally …

> npm install --global mermaid-filter

… then invoking it from the shell …

> pandoc -t html -F mermaid-filter.cmd -o something.html trymermaid.md

… but that didn’t work because …

λ typedoc.bat
module.js:540
    throw err;
    ^

Error: Cannot find module 'C:\Users\Peter\Desktop\portfolio\portfolio-pxmlam\fud07-types.tex\node_modules\mermaid-filter\index.js'
    at Function.Module._resolveFilename (module.js:538:15)
    at Function.Module._load (module.js:468:25)
    at Function.Module.runMain (module.js:684:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3
Error running filter mermaid-filter.cmd:
Filter returned error status 1

… i.e; it wasn’t being picked up?

Erhmm … what?

I’d rather run it from a local project anyway, so my next idea was to install it “locally” in the project/folder. (This makes my folder into a Node.JS project …)

> npm install mermaid-filter
> pandoc -t markdown -f markdown -F mermaid-filter.cmd -o target/something.md trymermaid.md

… and that works. Hilariously; it worked by embedding the generated image data into the markdown.

I want to try a more-sane approach … which looks nicer with CSS.

Shortcodes (Yass!)

I tried copying the Learn theme’s shortcodes but that scrambled my CSS. I (for no reason) switched to the Binario theme and decided to try and “roll my own” shortcode for Mermaid. The home made shortcode worked out pretty well; I knew which file to put it in and another user’s blog post showed the .js and .html needed to kick it all off. The result, below, needs to be in a theme’s layouts/shortcodes/mermaid.html and then allows {{<mermaid>}}...{{</mermaid>}} shortcodes to embed diagrams in your/my blog posts.

{{ $_hugo_config := `{ "version": 1 }` }}
<!--
    file name and path from; https://github.com/matcornic/hugo-theme-learn/blob/master/layouts/shortcodes/mermaid.html
    shortcode js/html from; https://liveaverage.com/projects/integration-mermaid/
-->
<script src="https://unpkg.com/mermaid@8.1.0/dist/mermaid.min.js" type="text/javascript"></script>
<script type="text/javascript">
    mermaid.initialize({ 
        theme: 'dark',
        themeCSS: '',
        cloneCssStyles: false,
        useMaxWidth: true,
        htmlLabels: false,
        flowchart: { 
                curve: 'basis' 
        }
    });
</script>
<pre class="mermaid" align="{{ if .Get "align" }}{{ .Get "align" }}{{ else }}center{{ end }}">{{ safeHTML .Inner }}</pre>

Examples

Here are some example diagrams from the Learn theme.

graph LR

graph LR;
    A[Hard edge] -->|Link text| B(Round edge)
    B --> C{Decision}
    C -->|One| D[Result one]
    C -->|Two| E[Result two]
graph LR;
	A[Hard edge] -->|Link text| B(Round edge)
	B --> C{Decision}
	C -->|One| D[Result one]
	C -->|Two| E[Result two]

sequenceDiagram

The [ Healthcheck ] loop text can’t be (easily) seen 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 <br/>prevail...
    John-->Alice: Great!
    John->Bob: How about you?
    Bob-->John: Jolly good!
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!

gantt

gantt
    dateFormat  YYYY-MM-DD
    title Adding GANTT diagram functionality to mermaid
    section A section
    Completed task            :done,    des1, 2014-01-06,2014-01-08
    Active task               :active,  des2, 2014-01-09, 3d
    Future task               :         des3, after des2, 5d
    Future task2               :         des4, after des3, 5d
    section Critical tasks
    Completed task in the critical line :crit, done, 2014-01-06,24h
    Implement parser and jison          :crit, done, after des1, 2d
    Create tests for parser             :crit, active, 3d
    Future task in critical line        :crit, 5d
    Create tests for renderer           :2d
    Add to mermaid                      :1d
gantt
	dateFormat  YYYY-MM-DD
	title Adding GANTT diagram functionality to mermaid
	section A section
	Completed task            :done,    des1, 2014-01-06,2014-01-08
	Active task               :active,  des2, 2014-01-09, 3d
	Future task               :         des3, after des2, 5d
	Future task2               :         des4, after des3, 5d
	section Critical tasks
	Completed task in the critical line :crit, done, 2014-01-06,24h
	Implement parser and jison          :crit, done, after des1, 2d
	Create tests for parser             :crit, active, 3d
	Future task in critical line        :crit, 5d
	Create tests for renderer           :2d
	Add to mermaid                      :1d

classDiagram

classDiagram
    Class01 <|-- AveryLongClass : Cool
    Class03 *-- Class04
    Class05 o-- Class06
    Class07 .. Class08
    Class09 --> C2 : Where am i?
    Class09 --* C3
    Class09 --|> Class07
    Class07 : equals()
    Class07 : Object[] elementData
    Class01 : size()
    Class01 : int chimp
    Class01 : int gorilla
    Class08 <--> C2: Cool label
classDiagram
	Class01 <|-- AveryLongClass : Cool
	Class03 *-- Class04
	Class05 o-- Class06
	Class07 .. Class08
	Class09 --> C2 : Where am i?
	Class09 --* C3
	Class09 --|> Class07
	Class07 : equals()
	Class07 : Object[] elementData
	Class01 : size()
	Class01 : int chimp
	Class01 : int gorilla
	Class08 <--> C2: Cool label

This git one doesn’t look quite right to me.

gitGraph

gitGraph:
options
{
    "nodeSpacing": 64,
    "nodeRadius": 8
}
end
    commit
    branch newbranch
    checkout newbranch
    commit
    commit
    checkout master
    commit
    commit
    merge newbranch
gitGraph:
options
{
	"nodeSpacing": 64,
	"nodeRadius": 8
}
end
	commit
	branch newbranch
	checkout newbranch
	commit
	commit
	checkout master
	commit
	commit
	merge newbranch

Conclusion

I (finally) have a good way to drop charts into my blog posts. I was surprised how easy it was to develop the Shortcodes. At some point, it would seem polite to submit pull requests to the theme … if/when the snags noted above can be resolved.

comments powered by Disqus
Peter LaValle avatar
Peter LaValle
Any links probably include affiliate ids for that sweet sweet kickback - and some programs require that I tell you. The contents of this blog are likely unrelated - as they include games, paints, and build tools.