How to use markdown syntax to write math in Hugo?

Viewed 2549

I am new to Hugo, or any web development. I want to build a personal site to share my math notes, which are written in markdown. Precisely, I use the template hugo-book. But I find it does not support the math mode in markdown, i.e. it does not work if I write equations between $$. I do find some ways to write math equations, for example, I can use {{< katex >}}, but this is not convenient to change this for my markdown notes every time. So, is there a way that I can use $$ to write math equations in this template?

Thanks!

2 Answers

For Mathjax 3, put this in the page source somewhere. I put it in layouts/partials/head-additions.html, but perhaps that is specific to the ananke theme:

<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

Now you can put this on your page and have it rendered:

Raw Mathjax block:
 

$$a_4 \ne b_4$$

like you'd expect.

Keep in mind though that according to the commonmark spec (which Hugo follows since it uses goldmark internally), you need to add two backslashes before punctuation characters such as ( and [. So:

This shows as Mathjax \\(a \ne b\\), but this doesn't \(a \ne b\)

Likewise, this shows as Mathjax

\\[a \ne b\\]

but this doesn't:

\[a \ne b\]

Of course you can avoid that by using $$ TeX Source $$.

You can stop here.

But I went a step further, because I didn't like how Mathjax gives you a flash of unstyled content (FOUC) as described in issue 131. I modified the approach suggested in that issue. Put this in the page source instead of the two simple <script> tags above:

{{- if or (.HasShortcode "mathjax/block") (.HasShortcode "mathjax/inline") -}}
<style>
.has-mathjax {
    visibility: hidden;
}
</style>

<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

<script>
window.MathJax = {
  startup: {
    pageReady: () => {
      return MathJax.startup.defaultPageReady().then(() => {
        for (let element of document.getElementsByClassName("has-mathjax")) {
            element.style.visibility = "visible"
        }
      });
    }
  }
};
</script>
{{- end -}}

Put this in layouts/shortcodes/mathjax/block.html:

<div class="has-mathjax">
{{ .Inner }}
</div>

And this in layouts/shortcodes/mathjax/inline.html:

<span class="has-mathjax">{{ .Inner }}</span>

Now you can put this in your page source:

Mathjax block:
  
{{< mathjax/block >}}
\[a \ne 0\]
{{< /mathjax/block >}}

Inline shortcode {{< mathjax/inline >}}\(a \ne 0\){{< /mathjax/inline >}} with
Mathjax.

As you can see, using shortcodes also works around the issue of needing to add two backslashes before punctuation characters such as ( and [.

(Full disclosure: This approach also appears on an article on my blog)

The toha theme has the following layout file:

toha/layouts/partials/math.html:

<link rel="stylesheet" href="{{ "/katex/katex.min.css" | relURL }}">
<script type="text/javascript" defer src="{{ "/katex/katex.min.js" | relURL }}"></script>
<script type="text/javascript" defer src="{{ "/katex/auto-render.min.js" | relURL }}" onload="renderMathInElement(document.body);">
    renderMathInElement(
        document.body,
        {
            delimiters: [
                {left: "$$", right: "$$", display: true},
                {left: "\\[", right: "\\]", display: true},
                {left: "$", right: "$", display: false},
                {left: "\\(", right: "\\)", display: false}
            ]
        }
    );
</script>

This allows you to use the same syntax as in @PeterVMorch's answer:

Inline mathjax \\(a \ne b\\) or display style $$a \ne b$$
Related