background Layer 1 Math in \(o_o\) HTML Math inside SVG by using KaTeX

KaTeX による HTML 内 SVG の問題について

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 でも同様)。

background Layer 1 \(\displaystyle \delta_{ij} = \begin{cases}1&\text{if }i=j\\0&\text{if }i\ne j\end{cases}\), \(I = (\delta_{ij})\),\(\\\)\((e_i, e_j) = \delta_{ij}\) \(\delta_{ij} = [i=j]\). クロネッカーの \(\delta_{ij}\)

ちなみに、HTML に直に埋め込みたくなければ、以下のように XMLHttpRequest で埋め込むことも可能。

(クリックで外部ファイルの埋め込みと数式のレンダリング)

しかし、foreignObject タグによる数式の欠点は、レンダリング結果のサイズが分からないので、テキストの中央揃えや右揃えが試行錯誤に成らざるを得ないことである。

もう一つの解決策

さて、もう一つの解決策は、Javascript で数式が記述された text タグをサイズを取得して foreignObject タグに載せ替えてしまう事である。これなら、テキストの中央揃えや右揃えも text-anchor 属性でなんとかなりそうだ。例えば、

以上のような SVG (上は SVG ファイルの img タグなので、そのまま表示) を KaTeX の自動レンダリングされた HTML に直に置くと、通常は数式の部分には何も表示されないが、ここでの施し convertKatexTextToForeignObjectInSVGsOfElement(element) を受ければ以下のように数式が表示されるようになる。

background Layer 1 \(E=mc^2\) [\(\mathrm{J}\)] \(F=ma\) [\(\mathrm{N}\)] \(\displaystyle \Gamma(z)=\int_0^\infty t^{z-1}e^{-t}\,dt\)

ひとまず、これで問題は解決である。

ちなみに、HTML に直に埋め込みたくなければ、以下のように XMLHttpRequest で埋め込むことも可能。

(クリックで外部ファイルの埋め込みと数式のレンダリング)

但し、注意事項として、'\(\)' ではなく、'\[\]' で数式を書いた場合は、display モードの数式の周りの余白のせいで、 テキストの中央揃えや右揃えが試行錯誤に成らざるを得なくなることは foreignObject タグによる数式と同様である。試しに、以下に text タグにて display モードによる数式を含んだ SVG を直に置いておく。

background Layer 1 \[ \begin{aligned} {\frac{\partial{\mathcal{H}}}{\partial q_{j}}} &= -{\dot{p}}_{j},\\ {\frac{\partial{\mathcal{H}}}{\partial p_{j}}} &= {\dot{q}}_{j},\\ {\frac{\partial{\mathcal{H}}}{\partial t}} &= -{\partial{\mathcal{L}}\over\partial t}.\\ \end{aligned} \]

これは SVG のエリアの中心から下に、以下のように数式が display モードでレンダリングされているはずである。Firefox と Chrome では display モードの表示が若干異なる。ちなみに、Safari では元々の KaTeX の表示が些か怪しい(\(\ne\)(\(\ne\)) と書いてみればわかる)。

\[ \begin{aligned} {\frac{\partial{\mathcal{H}}}{\partial q_{j}}} &= -{\dot{p}}_{j},\\ {\frac{\partial{\mathcal{H}}}{\partial p_{j}}} &= {\dot{q}}_{j},\\ {\frac{\partial{\mathcal{H}}}{\partial t}} &= -{\partial{\mathcal{L}}\over\partial t}.\\ \end{aligned} \]

ちなみに、SVG 形式のファイルの作成について、例えば Method-Draw などは foreignObject タグに対応しているので、さらに Method-Draw+KaTeX で数式に対応しておいた。

動的な SVG と TeX

ここでの静的な 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 \]

変数 \(l\): \(0\)\(100\): \([\mathrm{m}]\)
\(m_1\): \(0\)\(100\): \([\mathrm{kg}]\)
\(m_2\): \(0\)\(100\): \([\mathrm{kg}]\)
結果

スライダを動かすと動的に SVG が表示される。軸の名前は text タグであるが、検証のために、グラフの名前は foreignObject タグで数式を記述している。

HTML+Math Editor

Programmed by Taiji Yamada <taiji@aihara.co.jp> at 2018/7/12.