Overview

  • Jekyllでの数式の記述方法について説明します。
  • 使用環境
    • Jekyll (非 GitHub Pages)
    • Kramdown
    • MathJax

長年放置していたブログをWordpressからJekyllに移行しました。 あまり活用できていない(かつ、大したアクセスもない)にも関わらずレンタルサーバ代がかかるのがもったいなかったのが大きな理由です。 あと、CloudflareにDNSを移行させたのでCloudflareの別の機能を活用してみたかったという理由もあります。

数式を使うことがそこそこあるので、数式の記述がしやすいことは重要です。 できれば数式中のエスケープは避けられるとよいなというのがモチベーションです。

結論

結論から書くと、Jekyll, Kramdown, MathJax の組み合わせにおいては数式を記述する際に、以下のようにすると良さそうでした。

MathJaxのタグの追加

環境によって異なると思いますがJekyllはデフォルトではMathJaxのスクリプトを読み込まないので、適切な追加が必要になります。 おおむねこちらのページJekyll の Bulma Clean Theme に MathJax を組み込むと同じ設定になっています。 参考にしたのは別のページだったのですがどこだったか忘れてしまいました。 MathJax =で始まる設定は今の所実施していません。 _config.ymlは以下のようになっています。 おそらくデフォルトなので必要ないかもしれません。

markdown: kramdown
kramdown:
  input: GFM
  math_engine: mathjax

記述例

特別なエスケープが入らない読みやすい記述が可能です。

インライン表示の場合は $$\LaTeX$$

ディスプレイ表示の場合は以下のように

$$
\begin{aligned}
q &= [w, \boldsymbol{v}] \\
  &= [w, x, y, z]
\end{aligned}
$$

出力例

インライン表示の場合は \(\LaTeX\)

ディスプレイ表示の場合は以下のように

\[\begin{aligned} q &= [w, \boldsymbol{v}] \\ &= [w, x, y, z] \end{aligned}\]

Jekyllにおける数式処理の流れ

最初は仕組みがわからずにエスケープ周りで試行錯誤しました。 MathJaxを使ってブラウザ上で数式が表示されるまでに下図のように大きく2回の変換がかかります。

Markdown上で $$...$$ と記述した箇所は Html に変換される際にコンテキストによってインライン表示\(...\)とディスプレイ表示\[...\]に置換されます。

この挙動はJekyllが使用しているkramdownの Math Blocks の挙動です。 Markdownの Parser としてkramdownを指定していなくても適用されるようです。 Jekyllのデフォルトである GFM (GitHub Flavored Markdown) を使用していても適用されました。

コンテキストの解釈はkramdownのソースコードmath.rbで参照できます。 空白文字を除いて$$$$の前後に余計な文字が入っていなければディスプレイモードとして扱われるようです。 リスト中で期待したモードで表示できないことがあったのでもう少し別の判断が入っているかもしれません。

変換された\(...\)\[...\]はMathJaxのデフォルトの設定で使用されている形式になるのでこれでブラウザ上で表示される、ということになります。

$$だけを使用した場合、kramdownでの解釈がかなり強力に入るため数式中のエスケープはほぼ不要になります。kramdownのドキュメントの中ではパイプ|\vertにするとよいという記述がありましたが誤ってテーブルとして解釈されるときだけ使えば良さそうです。

注意点

エスケープの扱い

kramdownにまかせて$$を使用している場合、エスケープをほとんど意識せずに済みます。

言い換えると、$$ではない場合はエスケープが必要になります。 たとえば$$を使用せずに適当にエスケープしてhtmlに出力してあげれば直接MathJaxに渡せるのでkramdownの処理をバイパスするような形になります。ただし、この場合は数式のエスケープもkramdownに頼ることができないのでエスケープが少しというかかなり面倒になります。改行だけでも\\\\\\になったりするのでかなり煩雑です。

デリミタの変更

気持ちとしてはインラインモードとディスプレモードを$$$で使い分けたかったので、しばらく試行錯誤したのですがkramdownのエスケープ処理に頼るほうがメリットがあると判断して諦めました。

デリミタの変更でややこしいのは、Jekyllの設定でオプションとして数式のデリミタを変更する方法が提供されていたり、使用するテーマやプラグイン(例:jekyll-spaceship)などによってhtmlへの追加の変換が入る場合があるところです。

Jekyllで数式周りのオプションを使用する場合はどのタイミングでの変換に使用されるか、追加のエスケープ処理が入るかなどを意識したほうが良さそうです。

再度結論

上記理由から、一部の例外を除いてkramdownに完全に頼る形で$$に統一しました。 kramdownに頼らずに手作業でエスケープすることも可能なので、必要な場合(ディスプレイとインラインを指定したい場合など)は自分でエスケープする手段を取ることも可能です。