Fixing this at theme level is possible with a Tera2 component, although I think the better solution would be to handle math at the Markdown-parser level.
The underlying problem is that, unless math parsing is enabled, pulldown-cmark does not know that $...$ or $$...$$ contains TeX.
The contents are therefore parsed as ordinary Markdown before KaTeX ever sees them.
The relevant rendering pipeline in Zola 0.23.x is roughly:
.md
→ Tera2 component
→ generated text
→ CommonMark parser (pulldown-cmark)
→ HTML
→ KaTeX (JS in the Browser)
This explains the problems with characters such as \, _, and *.
For example, CommonMark treats a backslash followed by ASCII punctuation as a Markdown escape.
Commands such as \frac, \alpha, or \sqrt generally don’t have this particular problem because the character following the backslash is a letter rather than ASCII punctuation.
Likewise, _ and * can participate in Markdown’s emphasis parsing, backticks can form code spans, a backslash immediately before a line ending produces a hard line break, and enabled Markdown extensions introduce some additional syntax.
With Zola 0.23’s Tera2 components, one workaround is to explicitly mark math and encode Markdown-sensitive characters as HTML character references before the result reaches pulldown-cmark.
For example:
{% component katex(inline: bool = false, class = "") -%}
{%- set content = body
| trim
| escape_html
| replace(from=`\\`, to=`\` )
| replace(from=`_`, to=`_` )
| replace(from=`*`, to=`*` )
| replace(from="`", to=``` )
| replace(from=`~`, to=`~`)
| replace(from=`[`, to=`[` )
| replace(from=`]`, to=`]` )
| replace(from=`|`, to=`|`)
-%}
{%- if inline -%}
<span class="math math-inline{% if class %} {{ class | escape_html }}{% endif %}" role="math">\({{ content | safe }}\)</span>
{%- else -%}
<div class="math math-display{% if class %} {{ class | escape_html }}{% endif %}" role="math">\[{{ content | safe }}\]</div>
{%- endif %}
{%- endcomponent katex %}
This works, but it is still a workaround: authors have to explicitly wrap their math in a component.
BUT: I think the cleaner solution would be for Zola to expose pulldown-cmark’s native math support.
pulldown-cmark has Options::ENABLE_MATH.
With that option enabled, it recognizes $...$ and $$...$$ as math and produces Event::InlineMath and Event::DisplayMath rather than treating their contents as ordinary Markdown.
That addresses the problem at the correct level: instead of trying to make individual TeX characters survive Markdown parsing, the Markdown parser knows that the region is math in the first place.
Zola could potentially expose this as something like:
[markdown]
math = true
and then enable opts.insert(Options::ENABLE_MATH); in its Markdown options.
I haven’t tested a patched Zola build yet, so there is one important part still to verify: enabling ENABLE_MATH solves the parsing problem, but the resulting InlineMath/DisplayMath events and their HTML representation also need to integrate correctly with Zola’s rendering pipeline and KaTeX auto-render.
If that integration works and is added to Zola, it would be preferable to the component workaround - IMHO.