記事を書いた日: 2019-08-12 (更新履歴)
要約: Hugo で構築したブログで [KaTeX](https://katex.org/) を使った数式組版を行いたいが、よく使われている auto-render extension を使う方式だとエスケープの問題がある。そこで、Hugo の shortcode を経由することでエスケープの問題を回避する。
!!! 注意: このブログは以前 Hugo でビルドしていたが、現在は zola に移行済みのため、この記事の数式レンダリングの一部は動かない。!!!
Auto-render extension という機能で、$$
などで挟んだ LaTeX コードをレンダリングすることができるが、エスケープ周りにちょっと問題がある。
例えば、$[a](b)$
の $ で挟まれた中身は通常の KaTeX でも有効な LaTeX コードだが、一旦 Markdown パーサーを通してしまうと $<a href="b">a</a>$
と解釈されてしまい、意図しない表示になってしまう。
これは極端な例なのでは?という気もするが、Markdown パーサーに意図せず変換されてしまう例は、他にも下記のようにいくつか考えられる。
$a _{b_ c}$
$a *b* c$
$<a>$
長めの式を書いていて気づかないうちにこの手のエラーに引っかかると、原因の特定だけでかなり時間を消費してしまうので、なんとかして防ぎたい。
Hugo の shortcodes で独自のマークアップを作ることで、エスケープの問題を回避することができる。
インラインの数式と別行立ての数式用の shortcode はそれぞれ以下の通り。
layouts/shortcodes/eq.html:
<span class="tex" data-expr="{{ .Get 0 }}"></span>
layouts/shortcodes/eq-display.html:
<div class="tex displaystyle" data-expr="\displaystyle {{ trim .Inner "\n\r" }}"></div>
後から CSS で参照する都合上、displaystyle をクラスに追加しておいたが、別に必須ではない。
数式を入れたページで通常通り KaTeX のファイルをロードしつつ、下記のような JS を実行すれば数式が表示される。
(function() {
var tex = document.getElementsByClassName("tex");
Array.prototype.forEach.call(tex, function(el) {
katex.render(el.getAttribute("data-expr"), el);
});
})();
例えば下記のような感じで使う1。 1: 例は https://katex.org/ より
See how it renders with {{<eq "\KaTeX">}}:
{{< eq-display >}}
f(x) = \int_{-\infty}^\infty
\hat f(\xi)\,e^{2 \pi i \xi x}
\,d\xi
{{< /eq-display >}}
するとこんな感じでレンダリングされる。
See how it renders with {{<eq "\KaTeX">}}:
{{< eq-display >}} f(x) = \int_{-\infty}^\infty \hat f(\xi),e^{2 \pi i \xi x} ,d\xi {{< /eq-display >}}
ただし、auto-render extension 方式に比べると明らかに記法が煩雑なので、こちらの方式が必ずしも良いとは言い切れない。 簡潔だが時にエスケープが面倒な記法と、煩雑だが問題の少ない記法のどちらを選ぶかは好みによると思う。