pukiwiki/数式プラグイン/KaTeX の変更点

更新


[[ソフトウェア/pukiwiki/数式プラグイン]]

* MathJax よりもずっと早いらしいです [#dd8c7909]

MathJax と同様に、html 中に書かれた TeX ソースを javascript 
でレンダリングしてくれるライブラリなのですが、
いろいろ制限はあるもののずっと軽く動作するとの評判です。

https://khan.github.io/KaTeX/

* pukiwiki に組み込む [#a64e23dc]

ソースファイル:
 LANG:php
 <?php
 //
 // pukiwiki用 数式プラグイン (katex.inc.php)
 //   Copywrite 2018 Osamu Takeuchi <osamu@big.jp>
 //
 // [履歴]
 //   2018.07.02 初期リリース
 //
 // [インストール]
 //   ソースファイルを (pukiwiki)/plugin/katex.inc.php として保存
 //
 // [使い方]
 //   #katex; として一回呼んでおくと、その後の TeX ソース内に
 //   記述された katex 形式の tex ソースを katex で処理する
 //   ようになる
 //
 
 function plugin_katex_header()
 {
     return <<<'EOS'
 <link href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha256-tkzDFSl16wERzhCWg0ge2tON2+D6Qe9iEaJqM4ZGd4E=" crossorigin="anonymous" type="text/css" rel="stylesheet" />
 <script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js" integrity="sha256-gNVpJCw01Tg4rruvtWJp9vS0rRchXP2YF+U+b2lp8Po=" crossorigin="anonymous" type="text/javascript"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/contrib/auto-render.min.js" integrity="sha256-ExtbCSBuYA7kq1Pz362ibde9nnsHYPt6JxuxYeZbU+c=" crossorigin="anonymous" type="text/javascript"></script>
 <script>
   document.addEventListener("DOMContentLoaded", function(){
     renderMathInElement(
       document.body,
       {
         delimiters: [
           {left: "$$", right: "$$", display: true},
           {left: "$", right: "$", display: false}
         ],
         ignoredTags: [
           "script",
           "noscript",
           "style",
           "textarea",
           "pre",
           "code"
         ]
       }
     );
   });
 </script>
 EOS;
 }
 
 function plugin_katex_convert()
 {
     return plugin_katex_inline();
 }
 
 function plugin_katex_inline()
 {
     $header = "";
     if (!defined("PLUGIN_KATEX_LOADED")) {
         define("PLUGIN_KATEX_LOADED", "LOADED");
         $header = plugin_katex_header();
     }
 
     $aryargs = func_get_args();
     $math = join(",", $aryargs);
     $math = rtrim($math, ",");  //remove extra comma at the end.
     $math = htmlspecialchars($math);
 
     if($math===""){
         return $header;
     }else{
         return $header . "\\(\\displaystyle\\begin{split}" . $math . "\\end{split}\\)";
     }
 }
 
 ?>

* 使い方 [#rfbf7c80]

pukiwiki の個別ページのソースファイルに

 #katex

と書けば、そのページの

 $y=ax^2+bx+c$

や

 $$
 y=ax^2+bx+c
 $$

を、$y=ax^2+bx+c$ や

$$
y=ax^2+bx+c
$$

のように表示してくれます。

#katex

** 注意点 [#of927482]
pukiwiki の場合、

 $$
   y=ax^2+bx+c
 $$

と書いてしまうと、空白文字から始まる行が pre に変換されてしまい、

$$
  y=ax^2+bx+c
$$

となってしまうため、そこだけ注意が必要です。

* 使えない記法や、おかしな動作がまだ残っている [#a410c3fe]

徐々に改善されてきてますが、たまに動作のおかしなところを踏んでしまうことがあるようです?

気づいたらここにメモろうと思います。

とはいえ、ずいぶん使えるようになってきているので、
新しく書くページから徐々に KaTeX に移行しようかと思います。

** \hbar が太い [#se2e9fc5]

\hbar と書くと h に比べて太くなって、ベクトルと見分けづらい。

#ref(katex-hbar.png,wrap,33%);

~

h に ダッシュ を重ね打ちするマクロを定義すれば同じ太さで書けそう。

 LANG:javascript
        macros: {
          "\\hbar": "h\\mathllap{\\raisebox{3pt}{--\\hspace{0.2pt}}}"
        }

あら、これだとフォントサイズが変わるとずれちゃうみたい。

 LANG:javascript
        macros: {
          "\\hbar": "h\\mathllap{{}^-}"
        }

だと何とかそれらしい感じだ。

** \ne がズレる [#t7bb773d]

1行が広いとき、\ne の = と / が上下にずれてしまっていた。

 LANG:javascript
        macros: {
         "\\ne": "\\,\\mathrlap{\\,/}{=}\\,"
        }

のようにマクロ定義を変えたところ、ズレなくなった。

** braket.sty 対応 [#gc38a656]

 LANG:javascript
        macros: {
          "\\set": "\\left\\{#1\\right\\}",
          "\\setm": "\\left\\{#1\\ \\middle\\vert\\ #2\\right\\}",
          "\\bra":"\\left\\langle#1\\right|",
          "\\ket":"\\left|#1\\right\\rangle",
          "\\braket":"\\left\\langle#1\\middle|#2\\right\\rangle",
          "\\braketm":"\\left\\langle#1\\middle|#2\\middle|#3\\right\\rangle"
        }

とすることで、

|\set{x_i}|$\set{x_i}$|
|\setm{x\ne 0}{x\in R}|$\setm{x\ne 0}{x\in R}$|
|\bra{\varphi}|$\bra{\varphi}$|
|\ket{\varphi}|$\ket{\varphi}$|
|\braket{\varphi'}{\varphi}|$\braket{\varphi'}{\varphi}$|
|\braketm{\varphi'}{\hat H}{\varphi}|$\braketm{\varphi'}{\hat H}{\varphi}$|

などが書けるようになる。

手抜きをしているので、\set{a|b} のようには書けず、\setm{a}{b} のようにしなきゃならないことに注意。

\braketm も同様。

** \mathrm [#b5616b95]

 LANG:javascript
        macros: {
          "\\mathrm": "\\text{#1}"
        }

** ベクトル解析の各種演算 [#ndcb0caf]

 LANG:javascript
        macros: {
         "\\DIV": "\\,\\text{div}\\,",
         "\\grad": "\\,\\text{grad}\\,",
         "\\rot": "\\,\\text{rot}\\,",
         "\\curl": "\\,\\text{curl}\\,",
        }

** 数式の左寄せ [#cc91eb2f]

latex で言うところの fleqn 的な表示は css で対応可能

 LANG:css
 .katex-display > .katex {
   text-align: left !important;
   padding-left: 14px;
 }

** フォントサイズ [#g1509db2]

html にスタイルシートを指定した

 LANG:css
 .katex {
   font-size: 1.1em;
 }

** \big\{ \big\} のサイズがおかしい [#r737f483]

 $$
 \int_0^\infty \bigl\{rR_n{}^l(r)\bigr\}^*\bigl\{rR_{n'}{}^l(r)\bigr\}\,dr=\delta_{nn'}
 $$

というコードで、

&ref(katex-failure1.png,wrap,33%);

&ref(katex-failure1-src.png);

となってしまっていた。

不思議なことに、https://khan.github.io/KaTeX/ に同じコードを入れてみると、

&ref(katex-failure1b.png,,wrap,33%);

&ref(katex-failure1b-src.png);

となってうまくいく。

*** 他で定義した css とバッティングしていた [#q6658647]

別途 span.size1 というのが定義されていて、
そちらの font-size: xx-small が適用されていた。

バッティングしそうなルールに ::not(.katex) を付けて対処する。

* これ、かなり良い感じ [#te2b6a97]

|テクニック|アドレス|htmlサイズ|描画時間|
|サーバーサイドでSVGに変換|[[量子力学Ⅰ/球座標を用いた変数分離]]| 494kB|2.4秒|
|KaTex|[[量子力学Ⅰ/球座標を用いた変数分離/KaTeX]]| 74kB|2.7秒|
|MathJax|[[量子力学Ⅰ/球座標を用いた変数分離/MathJax]]| 74kB|7.7秒|

これらを比べると、KaTex で表示にかかる時間はサーバーサイド変換と比べてほとんど遜色なく、
ダウンロード時間を考えるとむしろ早い。仕上がりもほぼ問題ないレベル。

ただ別途、フォントや js, css をダウンロードしなければならないので、
初回アクセスでは時間がかかるかも。

MathJax が数式を多く含むページを表示するのに 8 秒とかかかるのはさすがに実用性に乏しい。
PCでこれだとモバイル端末では酷いことになりそう。


追記:[[量子力学Ⅰ/球座標を用いた変数分離]] のページ自体、KaTeX で書き直してしまったので、上記の比較は以前の版に対するものとなっています。
* コメント・質問 [#efc17ea1]

#article_kcaptcha

Counter: 2668 (from 2010/06/03), today: 3, yesterday: 0