Next.js, Contentful, markedの環境における数式表示
はじめに
ブログに数式の表示機能を実装した。そのうち統計学や機械学習の数理も勉強して記事にできればなと漠然と思っているのでその下準備的な意味も込めて。自分は以前 MathJax
を使ったことがあったけれど、今回改めて調べてみると以下のような情報があった。
mathjax というやつは世の中に現存するJSの中でも最も行儀が悪い振る舞いをするものの一つです。気軽に導入していいものではない。というか積極的に避けねばならない。あいつはXML的木構造を破壊しながら自身の特殊構文に継ぎ直してる。
— mizchi (@mizchi) April 25, 2017
一度mathjaxを当てた箇所は真っ当なフレームワークのDOMレンダリングに回復することは不可能です
— mizchi (@mizchi) April 25, 2017
ということで今回は KaTeX
を使うことにした。前に記事にしたように、このブログはContentfulにmarkdownの形で記事データを持っており、クライアントでそれをHTMLにマークアップしている。KaTeXはmarkedの renderer
の中で使うことになる。
記事作成時の環境について
marked
: 2.0.5katex
: 0.13.11next
: 10.2.2 (今回 Next.js は全く関係ないが一応記載)
実装について
参考にした情報
実装は次のリンク先のコメントで共有されている方法にまるまる乗っかっているので、コードは省略する。
この方法に乗っかると以下のような書き味になる。
- インラインの数式を使いたい時はインラインコードの中で対象を
$
で囲う - ブロックの数式を使いたい時はコードブロックの中で対象を
$$
で囲う
注意点
CSSを読み込んでおく
そもそもの話だけど、KaTeXを使う場合KaTeXのCSSを読み込む必要があるので、以下のスクリプトタグを書いておく。Next.jsなら _document.tsx
の <Head>
内に書くことになる。
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.css"
integrity="sha384-knaESGLxlQRSHWSJ+ZbTX6/L1bJZWBsBYGb2O+g64XHFuO7CbIj9Pkf1aaVXzIZJ"
crossOrigin="anonymous"
/>
サニタイズに気をつける
KaTeXで生成したHTMLには <span>
タグの中に、class
や style
などのAttributeが存在している。このブログではmarkedでマークアップしたHTMLを自前でサニタイズをしているので、設定によってはここで上記のAttributeが落ちる。サニタイズを行っていない場合は全く気にすることはないけど、サニタイズをしていて表示が崩れている場合はサニタイザーの設定を疑うと良い。
結果のサンプル
量子力学では状態の時間発展はSchrödinger方程式に従う。
iℏ∂∂t∣ψ,t⟩=H^∣ψ,t⟩i\hbar\frac{\partial}{\partial t}|\psi, t\rangle=\hat{H}|\psi, t\rangleiℏ∂t∂∣ψ,t⟩=H^∣ψ,t⟩ここで H^\hat{H}H^ はハミルトニアン演算子で全体のエネルギーを表す。スピンのない非相対論的で外力の働いていない粒子の運動を考えると、ハミルトニアンは次式で書ける。
H^=12mp^2\hat{H} = \frac{1}{2m}\hat{\bm{p}}^2H^=2m1p^2ここで mmm は粒子の質量であり、p^\hat{\bm{p}}p^ は運動量演算子である。位置基底で考えるとSchrödinger方程式は次式になる。
iℏ∂∂tψ(x,t)=−ℏ22m∇2ψ(x,t)i\hbar\frac{\partial}{\partial t}\psi(\bm{x}, t)=-\frac{\hbar^2}{2m}\nabla^2\psi(\bm{x}, t)iℏ∂t∂ψ(x,t)=−2mℏ2∇2ψ(x,t)ψ(x,t)=⟨x∣ψ,t⟩\psi(\bm{x}, t)=\langle\bm{x}|\psi, t\rangleψ(x,t)=⟨x∣ψ,t⟩ は位置空間での波動関数である。
ということで、良い感じになった。