transform.ToMath
- Syntax
- transform.ToMath INPUT [OPTIONS]
- Returns
- template.HTML
Usage
The transform.ToMath function returns the given mathematical markup, written in the LaTeX language, rendered to HTML. Hugo uses an embedded instance of the KaTeX display engine to render the markup. You do not need to install the KaTeX display engine.
Call this function from a passthrough render hook to render mathematical markup when you build the site, instead of on the client side with MathJax or KaTeX.
Hugo caches the result to disk in the misc file cache, so calling the function multiple times with the same arguments incurs no additional overhead.
Error handling
There are three ways to handle errors:
- Let KaTeX throw an error and fail the build. This is the default behavior.
- Set the
throwOnErroroption tofalseto make KaTeX render the expression as an error instead of throwing an error. - Handle the error in your template, as shown in the render hook example under examples.
Chemistry
New in v0.144.0You can also use the transform.ToMath function to render chemical equations, using the \ce and \pu functions from the mhchem package.
$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$Options
The transform.ToMath function accepts an options map. These options are a subset of the KaTeX rendering options.
displayMode- (
bool) Whether to render in display mode instead of inline mode. Default isfalse. errorColor- (
string) The color of the error messages expressed as an RGB hexadecimal color. Default is#cc0000. fleqn- (
bool) Whether to render flush left with a 2em left margin. Default isfalse. macros- (
map) A map of macros to be used in the math expression. Default is{}.{{ $macros := dict "\\addBar" "\\bar{#1}" "\\bold" "\\mathbf{#1}" }} {{ $opts := dict "macros" $macros }} {{ transform.ToMath "\\addBar{y} + \\bold{H}" $opts }} minRuleThickness- (
float) The minimum thickness of the fraction lines inem. Default is0.04. output- (
string) Determines the markup language of the output, one ofhtml,mathml, orhtmlAndMathml. Default ismathml.With
htmlandhtmlAndMathmlyou must include the KaTeX stylesheet within theheadelement of your base template.<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.18.4/dist/katex.min.css" integrity="sha384-u1zONI5gPXUx0UKI62c75/zww972y0v2rSK5ZYlVdS6xEuWDeZWUI66v6t1gvlXJ" crossorigin="anonymous"> strict- New in v0.147.6
- (
string) Controls how KaTeX handles LaTeX features that offer convenience but aren’t officially supported, one oferror,ignore, orwarn. Default iserror.error: Throws an error when convenient, unsupported LaTeX features are encountered.ignore: Allows convenient, unsupported LaTeX features without any feedback.warn: New in v0.147.7 Emits a warning when convenient, unsupported LaTeX features are encountered.
The
newLineInDisplayModeerror code, which flags the use of\\or\newlinein display mode outside an array or tabular environment, is intentionally designed not to throw an error, despite this behavior being questionable. throwOnError- (
bool) Whether to throw aParseErrorwhen KaTeX encounters an unsupported command or invalid LaTeX. Default istrue.
Examples
{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" }}Rendering to HTML and MathML:
{{ $opts := dict "output" "htmlAndMathml" }}
{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" $opts }}In a passthrough render hook, handling errors within the template:
- Step 1
- Enable and configure the Goldmark passthrough extension in your project configuration. The passthrough extension preserves raw Markdown within delimited snippets of text, including the delimiters themselves.
markup: goldmark: extensions: passthrough: delimiters: block: - - '\[' - '\]' - - $$ - $$ inline: - - '\(' - '\)' enable: true[markup] [markup.goldmark] [markup.goldmark.extensions] [markup.goldmark.extensions.passthrough] enable = true [markup.goldmark.extensions.passthrough.delimiters] block = [['\[', '\]'], ['$$', '$$']] inline = [['\(', '\)']]{ "markup": { "goldmark": { "extensions": { "passthrough": { "delimiters": { "block": [ [ "\\[", "\\]" ], [ "$$", "$$" ] ], "inline": [ [ "\\(", "\\)" ] ] }, "enable": true } } } } }The configuration above precludes the use of the
$...$delimiter pair for inline equations. Although you can add this delimiter pair to the configuration, you must double-escape the$symbol when used outside of math contexts to avoid unintended formatting. - Step 2
- Create a passthrough render hook to capture and render the LaTeX markup.layouts/_markup/render-passthrough.html
{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }} {{- with try (transform.ToMath .Inner $opts) }} {{- with .Err }} {{- errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }} {{- else }} {{- .Value }} {{- $.Page.Store.Set "hasMath" true }} {{- end }} {{- end -}} - Step 3
- In your base template, conditionally include the KaTeX CSS within the
headelement.layouts/baseof.html<head> {{ $noop := .WordCount }} {{ if .Page.Store.Get "hasMath" }} <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.18.4/dist/katex.min.css" integrity="sha384-u1zONI5gPXUx0UKI62c75/zww972y0v2rSK5ZYlVdS6xEuWDeZWUI66v6t1gvlXJ" crossorigin="anonymous"> {{ end }} </head>The noop statement forces content rendering before the template checks the value of
hasMathwith theStore.Getmethod.This conditional approach only identifies math on the current page. Mathematical expressions do not display correctly when one page’s content is embedded within another. For example, if a list page calls the
ContentorSummarymethods while ranging through its page collection, the list page does not load the KaTeX CSS.If this affects your site, use this conditional logic instead:
layouts/baseof.html{{ $noop := .WordCount }} {{ if or (.Page.Store.Get "hasMath") .IsNode }} <link rel="stylesheet" href="..."> {{ end }} - Step 4
- Add some mathematical markup to your content, then test.content/example.md
This is an inline \(a^*=x-b^*\) equation. These are block equations: \[a^*=x-b^*\] $$a^*=x-b^*$$
