KaTeX で HTML 内の TeX 形式の数式を記述し、ブラウザでレンダリングできるので極めて便利である。さらに推し進めて、SVG 内の TeX 形式の数式をプラウザがレンダリングしてくれたら有り難いと思い、SVG 内の text
にて '\(o_o\)'
などと書いてみたところ、どうも SVG なのに HTML と等しく処理してしまっているため、返って悪さをしていることに気づいてしまった。
解決策の一つは、意図しないレンダリングを抑止することである。それには、KaTeX のレンダーオプションの ignoredTags
キーに以下のように text
タグを加えればよい。
ignoredTags: [ "script", "noscript", "style", "textarea", "pre", "code", "text", // ← これを追加 ],XML の名前空間が異なるものを追加するので些か気持ち悪いが、これで意図しないレンダリングは抑止される。もっとも、そもそも SVG には
foreignObject
タグなるものが用意されていて、
以上のように SVG 内で text
タグではなく、foreignObject
タグで数式を記述したものなら (上は SVG ファイルの img
タグなので、そのまま表示) 以下のように無事 KaTeX によりレンダリングされる(MathJax でも同様)。
ちなみに、HTML に直に埋め込みたくなければ、以下のように XMLHttpRequest
で埋め込むことも可能。
(クリックで外部ファイルの埋め込みと数式のレンダリング)
しかし、foreignObject
タグによる数式の欠点は、レンダリング結果のサイズが分からないので、テキストの中央揃えや右揃えが試行錯誤に成らざるを得ないことである。
さて、もう一つの解決策は、Javascript で数式が記述された text
タグをサイズを取得して foreignObject
タグに載せ替えてしまう事である。これなら、テキストの中央揃えや右揃えも text-anchor
属性でなんとかなりそうだ。例えば、
以上のような SVG (上は SVG ファイルの img
タグなので、そのまま表示) を KaTeX の自動レンダリングされた HTML に直に置くと、通常は数式の部分には何も表示されないが、ここでの施し convertKatexTextToForeignObjectInSVGsOfElement(element)
を受ければ以下のように数式が表示されるようになる。
ひとまず、これで問題は解決である。
ちなみに、HTML に直に埋め込みたくなければ、以下のように XMLHttpRequest
で埋め込むことも可能。
(クリックで外部ファイルの埋め込みと数式のレンダリング)
但し、注意事項として、'\(\)'
ではなく、'\[\]'
で数式を書いた場合は、display モードの数式の周りの余白のせいで、
テキストの中央揃えや右揃えが試行錯誤に成らざるを得なくなることは foreignObject
タグによる数式と同様である。試しに、以下に text
タグにて display モードによる数式を含んだ SVG を直に置いておく。
これは SVG のエリアの中心から下に、以下のように数式が display モードでレンダリングされているはずである。Firefox と Chrome では display モードの表示が若干異なる。ちなみに、Safari では元々の KaTeX の表示が些か怪しい(\(\ne\)
(\(\ne\)) と書いてみればわかる)。
ちなみに、SVG 形式のファイルの作成について、例えば Method-Draw などは foreignObject
タグに対応しているので、さらに Method-Draw+KaTeX で数式に対応しておいた。
ここでの静的な SVG+TeX in HTML+TeX については、以上で解決したのであるが、動的な SVG+TeX について、少々手こずると思い、以下にまとめる。
質量を無視できる長さ \(l [\mathrm{m}]\) の棒の両端に質点 \(m_1, m_2 [\mathrm{kg}]\) で、\(m_1\) のある左端から \(r [\mathrm{m}]\) を通り棒に垂直な回転軸まわりの質点の慣性モーメント \(I [\mathrm{kg}\cdot\mathrm{m}^2]\): \[ I = m_1r^2 + m_2(l - r)^2 \]
スライダを動かすと動的に SVG が表示される。軸の名前は text
タグであるが、検証のために、グラフの名前は foreignObject
タグで数式を記述している。