覚え書きのページ。
UTF-8なページになったので、以前¥
と書いてあったものは\
に書き換わっています。
いろいろな方法があるが、
window.MathJax
にJSONを突っ込んでおくと、MathJaxの初期化時にそれを設定として取り込んでくれるので、
.js
ファイルにして
<script>
で読み込んでしまうのが一番楽だと思われる。
積分など、派手に上下に飛び出す数式で起こる。
縦スクロールバーが出てしまう要素にCSSで
padding
を設定する。
いい方法は見つからなかったが、たとえば、
TeX: { Macros: { eol: '\\\\[0.5em]' } }といったマクロを設定し、
\\
の変わりに\eol
と書けばよい。
\hbox{...}
で一時的に数式モードを抜ける。
MathJax側では
mtextFontInherit
を
true
に設定する。
\hbox
で立体にする。
シフトJISでうまくいくかどうかは知らない。
TeX: extensions: ["cancel.js"]
として、
\cancel{...}
とする。
MJXc-display
か
mjx-chtml
に設定すればよい。
Chromeの開発者モードでエレメントを調べると分かる。
HTML-CSSの場合は
MathJax_Display
クラス、SVGの場合は
MathJax_SVG_Display
クラスになる。
SVGで使っていると起きる現象。 MathJax Output Formats に書いてある。 CommonHTMLかHTML-CSSにすれば直る。 MathJax的にはCommonHTMLがお勧めだそうだ。
これをマジで対策しようとすると、
onresize
で数式番号が付いている部分をすべて再描画させることになる。
iOSなんかでは上端や下端にスクロールしてアドレスバーが出てきたときも、「縦幅が変わった」ことになって
onresize
が発生するので、数式番号が多いとすごくウザいことになる。
SVGを使う場合は数式番号は最低限にしておいた方がいい。
onresize
で再描画しなければいけない要素に対して以下のコードをほどほどに実行する。
MathJax.Callback.Queue(function() { MathJax.Hub.Rerender(elem); });
elem
はエレメントリストにもできるので、リロードが必要な要素には同じクラスを付けておいて(IDは同じものが存在してはいけないのでクラスを使う)、
getElementsByClassName
で一網打尽にすると楽。
ほどほどに、と書いたのは、Chromeとかではマウスでウィンドウのサイズを変えている間中
onresize
が発生するからで、
onresize
のたびに再描画しているとウザいことこの上ない。
また、MathJaxは非同期で動いているので、再描画中に再描画を指示してしまうとにっちもさっちもいかなくなる。
onresize
のときに
setTimeout
かなんかを設定して、タイムアウトしたら再描画するようなコードを書いた方がよい。
リサイズの場合と同じ。
SVGでレンダリングしてるなら実際に表示された時点で再レンダリングすると直る。
ボタンが押されるとコンテンツが表示されるなら、ボタンが押されたときに
onresize
と同じコードを実行すればよい。
この方法だと関係ないところまで再レンダリング起きちゃうけどまぁいいや。
skipStartupTypeset: true
を設定する必要がある。
また、最初から見えてるコンテンツはロード時にタイプセットする必要があるのだが、MathJax本体のロードが終わっていないとタイプセットを指示しても空振りに終わるので、MathJax本体のロードが終わるまで待たなければならない。
結局、onload
時にこんなコードを実行することになる。
MathJax.Hub.Register.StartupHook('End', function () { MathJax.Callback.Queue(function() { MathJax.Hub.Typeset(elem); }); });
世の中にはver3が出回っているが、とりあえずver2の話。 MathJaxは一度レンダリングしてしまうと設定を変更できない。
仕方ないので一度delete window.MathJax
して、MathJaxを読み込むscript要素を新しく(動的に)作ってhead要素に付け加えることで、もう一度MathJaxを最初から読み込む。
このときに<script type="text/x-mathjax-config">
な要素を作り、中にMathJax.Hub.Config(...);
と書いておくとその設定が読み込まれる。
設定は一つのscript要素の中に複数書いてもいいし、複数のscript要素に分けてもよい。
いずれにせよ順にすべての設定が読み込まれる。
Operaかどうか調べているのはOperaではtextでscriptの中身を設定できないかららしい。
この辺は公式の情報そのままである。
設定はJavaScriptのオブジェクトの形で書くが、引数で渡ってきたオブジェクトをscript要素のtext
に設定する時にテキストにしなければならない。
実はJavaScriptはJSONを有効なリテラルとしてそのまま式の中に書けるので、JSON.stringify
するのが一番面倒が少ないと思う。
この手は他の言語から、たとえばPHPの連想配列やら配列やらがごちゃごちゃ混ざったものをJavaScriptに渡す時にも有効で、
let json = <?= json_encode($v) ?>;で済む。 文字列なんかもエスケープをいちいち考えるならJSONにしてしまう方が面倒が少ない。
MathJaxはレンダリング時に次々とstyle要素を作っていくが、再読み込み時に削除してくれないので、自分で書いたstyle要素にdont-remove-me
というクラスを付与しておいて、このクラスが設定されていないstyle要素をまとめて削除している。
querySelectorAll
に:not
を与えるという非常にいい加減な方法で列挙している。
同時に、前回head要素に付け加えたscript要素も削除している。
初回読み込時はこれだけで描画してくれるが、再読み込みした場合はReprocessを呼び出さないと描画処理が走らない。 MathJaxは非同期で動いているので、ReprocessもQueueを通して呼び出す必要がある。 また、描画中にスクリプトのリロードが起きるとよろしくないので、ラジオボタンは初期状態ではディスエーブルにしておき、MathJaxのメッセージフックで描画終了が来たらwindowに適当なメッセージを投げ、そのメッセージを受けてラジオボタンをイネーブルにする。 このときに待ち受けるメッセージも初回はProcess Endになるのに対し、再読み込み時はReprocess Endになる。
ダークモードに切り替えた時に数式の強調色を切り替えようと思ったのが事の始まりで、色設定をTeXのマクロで書いてしまったためにMathJaxをリロードするハメになった。
JSのダークモード切り替え部分は、デフォルトのモードがdivのdatasetに書いてあるのがちょっと珍しいのと、ハンドラのローカル変数に状態をぶっ込んでいる(currentMode
)のがちょっとアレだが、あとは特にトリッキーなところはないと思う。
チェックボックスinput要素のvalue
をdivのclass
に設定する事でスタイルを切り替える。
実用的には設定をクッキーに書いておくと便利である。
ここでもquerySelector
やquerySelectorAll
で要素を狙い撃ちしている。
このふたつと、closest
・maches
あたりは本当に便利。
2次方程式の解の公式の導出 \begin{align*} ax^2+bx+c &= 0 \\ x^2+\frac{b}{a}x+\frac{c}{a} &= 0 \\ \left(x+\frac{b}{2a}\right)^2+\frac{c}{a}-\left(\frac{b}{2a}\right)^2 &= 0 \\ \left(x+\frac{b}{2a}\right)^2 &= \left(\frac{b}{2a}\right)^2 - \frac{c}{a} \\ x+\frac{b}{2a} &= \pm\sqrt{\frac{b^2}{4a^2} - \frac{c}{a}} \\ x&=\pm\sqrt{\frac{b^2-4ac}{4a^2}}-\frac{b}{2a} \\ x&=\frac{\pm\sqrt{b^2-4ac}}{2a}-\frac{b}{2a} \\ x&=\emf{\frac{-b\pm\sqrt{b^2-4ac}}{2a}} \end{align*}
MathJaxによる描画を細かく制御する(Islands in the byte stream)
plainTeX入門 / 数式 (1)(山崎正之さんのページ)
ちょこっと MathJax: 初期設定 (しっぽのさきっちょ)
Copyright (C) 2019-2023 akamoz.jp
$Id: mathjax.htm,v 1.8 2023/10/23 10:24:32 you Exp $