HUGO

  • News
  • Docs
  • Themes
  • Showcase
  • Community
  • GitHub
gohugoio Star
  • About Hugo
    • Overview
    • What is Hugo
    • Hugo features
    • Static site generators
    • Hugo's security model
    • Hugo and the GDPR
    • License
  • Installation
    • Overview
    • macOS
    • Linux
    • Windows
    • BSD
  • Getting started
    • Overview
    • Quick start
    • Basic usage
    • Directory structure
    • Configuration
    • Configure markup
    • Glossary of terms
    • External learning resources
  • Quick reference
    • Overview
    • Emojis
    • Functions
    • Methods
    • Page collections
  • Content management
    • Overview
    • Organization
    • Page bundles
    • Content formats
    • Front matter
    • Build options
    • Page resources
    • Image processing
    • Shortcodes
    • Related content
    • Sections
    • Content types
    • Archetypes
    • Taxonomies
    • Summaries
    • Links and cross references
    • URL management
    • Menus
    • Static files
    • Table of contents
    • Comments
    • Multilingual
    • Markdown attributes
    • Syntax highlighting
    • Diagrams
    • Mathematics
  • Templates
    • Overview
    • Templating
    • Template lookup order
    • Base templates and blocks
    • Single page templates
    • List templates
    • Homepage template
    • Section templates
    • Taxonomy templates
    • Pagination
    • Content view templates
    • Partial templates
    • Shortcode templates
    • Menu templates
    • Data templates
    • RSS templates
    • Sitemap templates
    • Internal templates
    • Custom output formats
    • 404 page
    • Robots.txt
  • Functions
    • Overview
    • cast
    • collections
    • compare
    • crypto
    • data
    • debug
    • diagrams
    • encoding
    • fmt
    • global
    • go template
    • hugo
    • images
    • inflect
    • js
    • lang
    • math
    • openapi3
    • os
    • partials
    • path
    • reflect
    • resources
    • safe
    • strings
    • templates
    • time
    • transform
    • urls
  • Methods
    • Overview
    • Duration
    • Menu
    • Menu entry
    • Page
    • Pages
    • Resource
    • Shortcode
    • Site
    • Taxonomy
    • Time
  • Render hooks
    • Overview
    • Introduction
    • Code blocks
    • Headings
    • Images
    • Links
  • Hugo Modules
    • Overview
    • Configure Hugo modules
    • Use Hugo Modules
    • Theme components
  • Hugo Pipes
    • Overview
    • Introduction
    • Transpile Sass to CSS
    • PostCSS
    • PostProcess
    • JavaScript building
    • Babel
    • Asset minification
    • Concatenating assets
    • Fingerprinting and SRI hashing
    • Resource from string
    • Resource from template
  • CLI
  • Troubleshooting
    • Overview
    • Audit
    • Logging
    • Inspection
    • Deprecation
    • Performance
    • FAQs
  • Developer tools
    • Overview
    • Editor plugins
    • Front-ends
    • Search
    • Migrations
    • Other projects
  • Hosting and deployment
    • Overview
    • Hugo Deploy
    • Deploy with Rclone
    • Deploy with Rsync
    • Host on 21YunBox
    • Host on AWS Amplify
    • Host on Azure Static Web Apps
    • Host on Cloudflare Pages
    • Host on Firebase
    • Host on GitHub Pages
    • Host on GitLab Pages
    • Host on KeyCDN
    • Host on Netlify
    • Host on Render
  • Contribute
    • Overview
    • Development
    • Documentation
    • Themes
  • Maintenance
CONTENT MANAGEMENT

Mathematics in Markdown

Include mathematical equations and expressions in your Markdown using LaTeX or TeX typesetting syntax.
\[ \begin{aligned} KL(\hat{y} || y) &= \sum_{c=1}^{M}\hat{y}_c \log{\frac{\hat{y}_c}{y_c}} \\ JS(\hat{y} || y) &= \frac{1}{2}(KL(y||\frac{y+\hat{y}}{2}) + KL(\hat{y}||\frac{y+\hat{y}}{2})) \end{aligned} \]

Overview

Mathematical equations and expressions authored in LaTeX or TeX are common in academic and scientific publications. Your browser typically renders this mathematical markup using an open-source JavaScript display engine such as MathJax or KaTeX.

For example, this is the mathematical markup for the equations displayed at the top of this page:

\[
\begin{aligned}
KL(\hat{y} || y) &= \sum_{c=1}^{M}\hat{y}_c \log{\frac{\hat{y}_c}{y_c}} \\
JS(\hat{y} || y) &= \frac{1}{2}(KL(y||\frac{y+\hat{y}}{2}) + KL(\hat{y}||\frac{y+\hat{y}}{2}))
\end{aligned}
\]

Equations and expressions can be displayed inline with other text, or as standalone blocks. Block presentation is also known as “display” mode.

Whether an equation or expression appears inline, or as a block, depends on the delimiters that surround the mathematical markup. Delimiters are defined in pairs, where each pair consists of an opening and closing delimiter. The opening and closing delimiters may be the same, or different. Common delimiter pairs are shown in Step 1.

The approach described below avoids reliance on platform-specific features like shortcodes or code block render hooks. Instead, it utilizes a standardized markup format for mathematical equations and expressions, compatible with the rendering engines used by GitHub, GitLab, Microsoft VS Code, Obsidian, Typora, and others.

Setup

Follow these instructions to include mathematical equations and expressions in your Markdown using LaTeX or TeX typesetting syntax.

Step 1

Enable and configure the Goldmark passthrough extension in your site configuration. The passthrough extension preserves raw Markdown within delimited snippets of text, including the delimiters themselves.

hugo.
     
markup:
  goldmark:
    extensions:
      passthrough:
        delimiters:
          block:
          - - \[
            - \]
          - - $$
            - $$
          inline:
          - - \(
            - \)
        enable: true
params:
  math: true
[markup]
  [markup.goldmark]
    [markup.goldmark.extensions]
      [markup.goldmark.extensions.passthrough]
        enable = true
        [markup.goldmark.extensions.passthrough.delimiters]
          block = [['\[', '\]'], ['$$', '$$']]
          inline = [['\(', '\)']]
[params]
  math = true
{
   "markup": {
      "goldmark": {
         "extensions": {
            "passthrough": {
               "delimiters": {
                  "block": [
                     [
                        "\\[",
                        "\\]"
                     ],
                     [
                        "$$",
                        "$$"
                     ]
                  ],
                  "inline": [
                     [
                        "\\(",
                        "\\)"
                     ]
                  ]
               },
               "enable": true
            }
         }
      }
   },
   "params": {
      "math": true
   }
}

The configuration above enables mathematical rendering on every page unless you set the math parameter to false in front matter. To enable mathematical rendering as needed, set the math parameter to false in your site configuration, and set the math parameter to true in front matter. Use this parameter in your base template as shown in Step 3.

The configuration above precludes the use of the $...$ delimiter pair for inline equations. Although you can add this delimiter pair to the configuration and JavaScript, you will need to double-escape the $ symbol when used outside of math contexts to avoid unintended formatting.

See the inline delimiters section for details.

To disable passthrough of inline snippets, omit the inline key from the configuration:

hugo.
     
markup:
  goldmark:
    extensions:
      passthrough:
        delimiters:
          block:
          - - \[
            - \]
          - - $$
            - $$
[markup]
  [markup.goldmark]
    [markup.goldmark.extensions]
      [markup.goldmark.extensions.passthrough]
        [markup.goldmark.extensions.passthrough.delimiters]
          block = [['\[', '\]'], ['$$', '$$']]
{
   "markup": {
      "goldmark": {
         "extensions": {
            "passthrough": {
               "delimiters": {
                  "block": [
                     [
                        "\\[",
                        "\\]"
                     ],
                     [
                        "$$",
                        "$$"
                     ]
                  ]
               }
            }
         }
      }
   }
}

You can define your own opening and closing delimiters, provided they match the delimiters that you set in Step 2.

hugo.
     
markup:
  goldmark:
    extensions:
      passthrough:
        delimiters:
          block:
          - - '@@'
            - '@@'
          inline:
          - - '@'
            - '@'
[markup]
  [markup.goldmark]
    [markup.goldmark.extensions]
      [markup.goldmark.extensions.passthrough]
        [markup.goldmark.extensions.passthrough.delimiters]
          block = [['@@', '@@']]
          inline = [['@', '@']]
{
   "markup": {
      "goldmark": {
         "extensions": {
            "passthrough": {
               "delimiters": {
                  "block": [
                     [
                        "@@",
                        "@@"
                     ]
                  ],
                  "inline": [
                     [
                        "@",
                        "@"
                     ]
                  ]
               }
            }
         }
      }
   }
}
Step 2

Create a partial template to load MathJax or KaTeX. The example below loads MathJax, or you can use KaTeX as described in the engines section.

layouts/partials/math.html
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
<script>
  MathJax = {
    tex: {
      displayMath: [['\\[', '\\]'], ['$$', '$$']],  // block
      inlineMath: [['\\(', '\\)']]                  // inline
    }
  };
</script>

The delimiters above must match the delimiters in your site configuration.

Step 3

Conditionally call the partial template from the base template.

layouts/_default/baseof.html
<head>
  ...
  {{ if .Param "math" }}
    {{ partialCached "math.html" . }}
  {{ end }}
  ...
</head>

The example above loads the partial template if you have set the math parameter in front matter to true. If you have not set the math parameter in front matter, the conditional statement falls back to the math parameter in your site configuration.

Step 4

Include mathematical equations and expressions in your Markdown using LaTeX or TeX typesetting syntax.

content/math-examples.md
This is an inline \(a^*=x-b^*\) equation.

These are block equations:

\[a^*=x-b^*\]

\[ a^*=x-b^* \]

\[
a^*=x-b^*
\]

These are block equations using alternate delimiters:

$$a^*=x-b^*$$

$$ a^*=x-b^* $$

$$
a^*=x-b^*
$$

If you set the math parameter to false in your site configuration, you must set the math parameter to true in front matter. For example:

content/math-examples.md
     
---
date: 2024-01-24T18:09:49-08:00
params:
  math: true
title: Math examples
---
+++
date = 2024-01-24T18:09:49-08:00
title = 'Math examples'
[params]
  math = true
+++
{
   "date": "2024-01-24T18:09:49-08:00",
   "params": {
      "math": true
   },
   "title": "Math examples"
}

Inline delimiters

The configuration, JavaScript, and examples above use the \(...\) delimiter pair for inline equations. The $...$ delimiter pair is a common alternative, but using it may result in unintended formatting if you use the $ symbol outside of math contexts.

If you add the $...$ delimiter pair to your configuration and JavaScript, you must double-escape the $ when outside of math contexts, regardless of whether mathematical rendering is enabled on the page. For example:

A \\$5 bill _saved_ is a \\$5 bill _earned_.

If you use the $...$ delimiter pair for inline equations, and occasionally use the $ symbol outside of math contexts, you must use MathJax instead of KaTeX to avoid unintended formatting caused by this KaTeX limitation.

Engines

MathJax and KaTeX are open-source JavaScript display engines. Both engines are fast, but at the time of this writing MathJax v3.2.2 is slightly faster than KaTeX v0.16.9.

If you use the $...$ delimiter pair for inline equations, and occasionally use the $ symbol outside of math contexts, you must use MathJax instead of KaTeX to avoid unintended formatting caused by this KaTeX limitation.

See the inline delimiters section for details.

To use KaTeX instead of MathJax, replace the partial template from Step 2 with this:

layouts/partials/math.html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" integrity="sha384-XjKyOOlGwcjNTAIQHIpgOno0Hl1YQqzUOEleOLALmuqehneUG+vnGctmUb0ZY0l8" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script>
<script>
  document.addEventListener("DOMContentLoaded", function() {
    renderMathInElement(document.body, {
      delimiters: [
        {left: '\\[', right: '\\]', display: true},   // block
        {left: '$$', right: '$$', display: true},     // block
        {left: '\\(', right: '\\)', display: false},  // inline
      ],
      throwOnError : false
    });
  });
</script>

The delimiters above must match the delimiters in your site configuration.

Chemistry

Both MathJax and KaTeX provide support for chemical equations. For example:

$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$

As shown in Step 2 above, MathJax supports chemical equations without additional configuration. To add chemistry support to KaTeX, enable the mhchem extension as described in the KaTeX documentation.

See also

  • Archetypes
  • Front matter
  • Host on 21YunBox
  • Markdown attributes
  • Menu templates

On this page

  • Overview
  • Setup
  • Inline delimiters
  • Engines
  • Chemistry
Last updated: February 11, 2024: Capitalize the word Markdown throughout the documentation (c36d20d3)
Improve this page
By the Hugo Authors
Hugo Logo
  • File an Issue
  • Get Help
  • @GoHugoIO
  • @spf13
  • @bepsays

Netlify badge

 

Hugo Sponsors

 

The Hugo logos are copyright © Steve Francia 2013–2024.

The Hugo Gopher is based on an original work by Renée French.

  • News
  • Docs
  • Themes
  • Showcase
  • Community
  • GitHub
  • About Hugo
  • Installation
  • Getting started
  • Quick reference
  • Content management
  • Templates
  • Functions
  • Methods
  • Render hooks
  • Hugo Modules
  • Hugo Pipes
  • CLI
  • Troubleshooting
  • Developer tools
  • Hosting and deployment
  • Contribute
  • Maintenance