Home
Tuyen Pham's Blog
Math Typesetting in Zola With KaTeX and Optional MathJax
Math Typesetting in Zola With KaTeX and Optional MathJax
Add the math macro to your base template once, then enable equations globally, for a section, or for one page. KaTeX stays the default, with MathJax as the fallback option.
You do not need to scatter script tags across every template to get this working. In this repo, math support lives in a reusable Tera macro, so the main job is wiring that macro into the base layout and then opting content in where you need it.
Wire it into the base template
This example uses KaTeX by default.
Create or review templates/macros/math.html so it exposes style() and script() macros.
Import that macro in templates/base.html and call it from the math_style and math_script blocks.
{%- import ' macros/math.html ' as macros_math -%}
{%- block math_style %}
{{- macros_math : : style ( ) }}
{%- endblock math_style %}
{%- block math_script %}
{{- macros_math : : script ( ) }}
{%- endblock math_script %}
Enable math where you need it
If most of the site uses equations, turn math on globally in config.toml .
If only part of the site needs it, add the same flag to a page or section frontmatter block instead.
Set config.extra.library = "mathjax" if you want MathJax instead of the default KaTeX bundle.
The KaTeX Supported Functions reference is the quickest way to check whether a command will render.
The MathJax basic tutorial and quick reference is still a handy cheat sheet when you need MathJax-specific syntax.
Examples
Once the flag is on, inline expressions and fenced tex injected blocks render without extra template work. The rest of this page is basically a math smoke test, which sounds stricter than it is.
Inline math
Use inline math for short expressions inside a sentence, for example
\(\varphi = \dfrac{1+\sqrt5}{2} = 1.6180339887…\)
.
Find
\(\{ x, y, z \} \in \N\)
where:
$$::tex
\begin{cases}
x^2 + 7xy + y^2 = z^2 \\
3x^2 - xyz - y^2 = z^2
\end{cases}
::$$
Block math
Use a block when the expression needs room to breathe. Here is a simple example, followed by a wider set of formulas that exercise a few different features.
$$::tex
\text{Find}\quad \{ x, y, z \} \in \N \quad\text{where}\quad
\begin{cases}
x^2 + 7xy + y^2 = z^2 \\
3x^2 - xyz - y^2 = z^2
\end{cases}
::$$
$$::tex
\def\arraystretch{1.5}
\begin{array}{c:c:c}
a & b & c \\ \hline
d & e & f \\
\hdashline
g & h & i
\end{array}
::$$
$$::tex
\mathcal L_{\mathcal T}(\vec{\lambda})
= \sum_{(\mathbf{x},\mathbf{s})\in \mathcal T}
\log P(\mathbf{s}\mid\mathbf{x}) - \sum_{i=1}^m
\frac{\lambda_i^2}{2\sigma^2}
::$$
$$::tex
\displaystyle \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
::$$
$$::tex
\ce{x Na(NH4)HPO4 ->[\Delta] (NaPO3)_x + x NH3 ^ + x H2O}
::$$
$$::tex
\ce{Zn^2+ <=>[+ 2OH-][+ 2H+] $\underset{\text{amphoteres Hydroxid}}{\ce{Zn(OH)2 v}}$ <=>[+ 2OH-][+ 2H+] $\underset{\text{Hydroxozikat}}{\ce{[Zn(OH)4]^2-}}$}
::$$
$$::tex
\ce{Hg^2+ ->[I-] $\underset{\mathrm{red}}{\ce{HgI2}}$ ->[I-] $\underset{\mathrm{red}}{\ce{[Hg^{II}I4]^2-}}$}
::$$
$$::tex
% \f is defined as #1f(#2) using the macro
\f\relax{x} = \int_{-\infty}^\infty
\f\hat\xi\,e^{2 \pi i \xi x}
\,d\xi
::$$
$$::tex
\begin{align}
\sqrt{37} & = \sqrt{\frac{73^2-1}{12^2}} \\
& = \sqrt{\frac{73^2}{12^2}\cdot\frac{73^2-1}{73^2}} \\
& = \sqrt{\frac{73^2}{12^2}}\sqrt{\frac{73^2-1}{73^2}} \\
& = \frac{73}{12}\sqrt{1 - \frac{1}{73^2}} \\
& \approx \frac{73}{12}\left(1 - \frac{1}{2\cdot73^2}\right)
\end{align}
::$$
$$::tex
f(n) =
\begin{cases}
n/2, & \text{if $n$ is even} \\
3n+1, & \text{if $n$ is odd}
\end{cases}
::$$
$$::tex
\begin{array}{c|lcr}
n & \text{Left} & \text{Center} & \text{Right} \\
\hline
1 & 0.24 & 1 & 125 \\
2 & -1 & 189 & -8 \\
3 & -20 & 2000 & 1+10i
\end{array}
::$$
$$::tex
f\left(
\left[
\frac{
1+\left\{x,y\right\}
}{
\left(
\frac{x}{y}+\frac{y}{x}
\right)
\left(u+1\right)
}+a
\right]^{3/2}
\right)
::$$
$$::tex
% \require{extpfeil} % produce extensible horizontal arrows
\begin{array}{ccc} % arrange LPPs
% first row
% first LPP
\begin{array}{ll}
\max & z = c^T x \\
\text{s.t.} & A x \le b \\
& x \ge 0
\end{array}
& \xtofrom{\text{duality}} &
% second LPP
\begin{array}{ll}
\min & v = b^T y \\
\text{s.t.} & A^T y \ge c \\
& y \ge 0
\end{array} \\
({\cal PC}) & & ({\cal DC}) \\
\text{add } {\Large \downharpoonleft} \text{slack var} & & \text{minus } {\Large \downharpoonright} \text{surplus var}\\ % Change to your favorite arrow style
%
% second row
% third LPP
\begin{array}{ll}
\max & z = c^T x \\
\text{s.t.} & A x + s = b \\
& x,s \ge 0
\end{array}
& \xtofrom[\text{some steps skipped}]{\text{duality}} &
% fourth LPP
\begin{array}{ll}
\min & v = b^T y \\
\text{s.t.} & A^T y - t = c \\
& y,t \ge 0
\end{array} \\
({\cal PS}) & & ({\cal DS})
%
\end{array}
::$$
$$::tex
\begin{array}{rrrrrrr|r}
& x_1 & x_2 & x_3 & s_1 & s_2 & s_3 & \\ \hline
s_1 & -2 & 0 & -2 & 1 & 0 & 0 & -60 \\
s_2 & -2 & -4^* & -5 & 0 & 1 & 0 & -70 \\
s_3 & 0 & -3 & -1 & 0 & 0 & 1 & -27 \\ \hdashline
& 8 & 10 & 25 & 0 & 0 & 0 & 0 \\
\text{ratio} & -4 & -5/2 & -5 & & & & \\ \hline
s_1 & -2^* & 0 & -2 & 1 & 0 & 0 & -60 \\
x_2 & 1/2 & 1 & 5/4 & 0 & -1/4 & 0 & 35/2 \\
s_3 & 3/2 & 0 & 11/4 & 0 & -3/4 & 1 & 51/2 \\ \hdashline
& 3 & 0 & 25/2 & 0 & 5/2 & 0 & -175 \\
\text{ratio} & -3/2 & & 25/4 & & & & \\ \hline
x_1 & 1 & 0 & 1 & -1/2 & 0 & 0 & 30 \\
x_2 & 0 & 1 & 3/4 & 1/4 & -1/4 & 0 & 5/2 \\
s_3 & 0 & 0 & 5/4 & 3/4 & -3/4^* & 1 & -39/2 \\ \hdashline
& 0 & 0 & 19/2 & 3/2 & 5/2 & 0 & -265 \\
\text{ratio} & & & & & \dots & & \\ \hline
x_1 & 1 & 0 & 1 & -1/2 & 0 & 0 & 30 \\
x_2 & 0 & 1 & 1/3 & 0 & 0 & -1/3 & 9 \\
s_2 & 0 & 0 & -5/3 & -1 & 1 & -4/3 & 26 \\ \hdashline
& 0 & 0 & 41/3 & 4 & 0 & 10/3 & -330
\end{array}
::$$
$$::tex
\begin{pmatrix}
1 & a_1 & a_1^2 & \cdots & a_1^n \\
1 & a_2 & a_2^2 & \cdots & a_2^n \\
\vdots & \vdots& \vdots & \ddots & \vdots \\
1 & a_m & a_m^2 & \cdots & a_m^n
\end{pmatrix}
::$$
$$::tex
% \require{enclose}
\begin{array}{ccccccccc}
\Large{{A}} & \xrightarrow{0.1} & \Large{{B}} & \xrightarrow{0.2} & \Large{{C}} & \xleftarrow{0.3} & \Large{{D}} & \xleftarrow{0.4} & \Large{{E}}\\
\scriptsize{0.5}\large{\downarrow} & \scriptsize{0.6}\large{\searrow} & \scriptsize{0.7}\large{\downarrow} & \scriptsize{0.8}\large{\nearrow} & \scriptsize{0.9}\large{\downarrow} & \scriptsize{0.1}\large{\swarrow} & \scriptsize{0.2}\large{\downarrow} & \scriptsize{0.3}\large{\nwarrow} & \scriptsize{0.4}\large{\downarrow}\\
\Large{{F}} & \xrightarrow[0.5]{} & \Large{{G}} & \xrightarrow[0.6]{} & \Large{{H}} & \xleftarrow[0.7]{} & \Large{{I}} & \xleftarrow[0.8]{} & \Large{{J}}\\
\circlearrowright\tfrac12\\
\end{array}
::$$
$$::tex
\left. \left(3x\left(\frac{\left(\log(\frac{3x^2}{6}\right)^{\frac{-x^2}{8}}}{3x^{1/2}} \right) \right) \right|_{\;x=2}^{\;x=8}
::$$
$$::tex
\begin{align*}
V_{ijk}& = \begin{cases}
\dfrac{y_u+y_l}2 - \dfrac{x_u+x_l}2,& \text{if }x_u < y_l\\[15pt]
\dfrac1C \bigg[\dfrac{x_u^3-y_l^3}{6}+\dfrac{y_l^2+x_u^2}{2}x_l + (x_u-y_l)\dfrac{x_l^2}{2}+ \dfrac{y_u^2-x_u^2}{2}(x_u-x_l)& - (y_u-x_u)\dfrac{x_u^2-x_l^2}{2} \bigg],
\\[12pt]& \text{if }x_u\in\left[y_l,y_u\right]\\[15pt]
\dfrac1{x_u-x_l}\bigg[\dfrac{(y_u+y_l)^2}6 - \dfrac{y_u+y_l}2 x_l + \dfrac{x_l^2}2\bigg],& \text{otherwise}
\end{cases}
\end{align*}
::$$
$$::tex
E_z = k\lambda z \int_{-a}^b \frac{dx}{(z^2 + x^2)^{3/2}}
= \frac{k\lambda}{z}\left(\frac{x}{\sqrt{z^2 + x^2}}\right)\Big|_{-a}^b
= \frac{k\lambda}{z}\left(\frac{b}{\sqrt{z^2 + b^2}} + \frac{a}{\sqrt{z^2 + a^2}}\right)
::$$
$$::tex
\dfrac{\left\vert\dfrac{12\sqrt{3+211}}{a}\right|}{1}
::$$
Related articles
Markdown Coding Convention for Calm, Consistent Docs
A practical Markdown convention using rumdl to keep docs predictable across editors, pull requests, and formatting pipelines.
72 Must-Have Features for Ecommerce Website
An infographic checklist of 72 ecommerce website features covering navigation, trust, checkout, content, and conversion.
Okta integration for Optimizely CMS
Step-by-step Okta integration for Optimizely CMS, covering package setup, configuration, authentication, and authorization.
Implement theme using SCSS
Build a light and dark theme switcher with CSS variables, persistent user preference, and synchronisation across browser tabs.