pukiwiki/数式プラグイン/KaTeX

(87d) 更新


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

MathJax よりもずっと早いらしいです

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

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

pukiwiki に組み込む

ソースファイル:

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}\\)";
    }
}

?>

使い方

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

#katex

と書けば、そのページの

$y=ax^2+bx+c$

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

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

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

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

注意点

pukiwiki の場合、

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

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

$$

 y=ax^2+bx+c

$$

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

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

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

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

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

\hbar が太い

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

katex-hbar.png


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

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

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

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

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

\ne がズレる

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

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

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

braket.sty 対応

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

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

ベクトル解析の各種演算

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

数式の左寄せ

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

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

フォントサイズ

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

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

\big\{ \big\} のサイズがおかしい

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

というコードで、

katex-failure1.png

katex-failure1-src.png

となってしまっていた。

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

wrap

katex-failure1b-src.png

となってうまくいく。

他で定義した css とバッティングしていた

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

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

これ、かなり良い感じ

テクニックアドレスhtmlサイズ描画時間
サーバーサイドでSVGに変換量子力学Ⅰ/球座標を用いた変数分離494kB2.4秒
KaTex量子力学Ⅰ/球座標を用いた変数分離/KaTeX74kB2.7秒
MathJax量子力学Ⅰ/球座標を用いた変数分離/MathJax74kB7.7秒

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

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

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

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

コメント・質問





Counter: 2590 (from 2010/06/03), today: 4, yesterday: 0