ikuzakの備忘録

数学関連のツールTeX,Tikz,Manim,Geogebraなどの備忘録です。

【Manim】数式テキストを表示

日本語混じりのものとかにそこそこ苦戦した。

MathTexクラスとTexクラス

MathTexクラス

数式だけだったらこっちのクラスっぽい。 \mathrm{\LaTeX}でのalign*環境に相当するのかな。
なので、\mathbf{\LaTeX}数式のみのテキストを入れるならコレ。

基本的な使い方は

equation = MathTex(
    r"e^{\pi i}&=-1\\",
    r"\sum_{n=1}{\infty}\frac{1}{n^2}&=\frac{\pi^2}{6}"
    )

みたいな感じ。 align*環境だから、ちゃんと&つければ揃えてくれるし、改行もそのままっぽい。
ちなみに、r"文字列"でRaw文字列(エスケープ文字をそのまま使える)をこのとき始めて知る。
ExampleでRaw文字列で書きまくってあったので、最初は「このr、なんやねん…」ってなってた。

そういや、Rubyで`raw(文字列)`ってあったっけ。 プログラミングとかしばらく触れなかったから、忘れてた

Texクラス

こっちが結構苦労した。
先のMathTexとは違って、\mathrm{\LaTeX} を介したテキストを入れるのはこっちみたい(説明が難しい)。

基本的な使い方は

text = Tex(r"Hello, \LaTeX")

みたいな感じ。$...$でインライン数式も混じったテキストも入れられる。

苦労したのは、日本語の文

↓ こんな感じで、テキストを追加したかった

text = Tex(r"日本語混じりの\LaTeX を書きたい。")

のだけど、Manimレンダリングで最初はエラーが出た。
予め分かってた情報としては、日本語混じりにしたいときは使うTeXコンパイラ\mathrm{Lua\LaTeX}が良いらしいこと。
なので、\mathrm{Lua\LaTeX}を介して、Texを使いたいときにTexTemplateを設定しておく必要がある。

preamble_text=r"""
\usepackage{luatexja}
\usepackage{amsmath}
\usepackage{amssymb}
"""
luatex_template = TexTemplate(
    tex_compiler="lualatex",
    output_format=".pdf",
    documentclass=r"\documentclass[preview]{standalone}",
    preamble=preamble_text
)
Tex.set_default(tex_template=luatex_template)
text = Tex(r"日本語混じりの\LaTeX")

preamble_textはプリアンブルに入るそのもの。日本語入れるのが目的なので、luatexjaは絶対入れなきゃね。
必須というわけでもないが、

text = Tex(r"日本語混じりの\LaTeX",tex_template=luatex_template)

のように毎回tex_templateの指定は面倒なので、Tex.set_defaultで書き換えといた方がいいかも。
で、Manim側のTexTemplateクラスの設定で、

  • tex_compilerにはlualatex
  • output_formatには.pdf (ちなみにlualatexを使うなら".pdf"のみ。)
  • documentclassにはstandaloneを入れたけど、これはデフォルトでこれなので、わざわざ書かなくてもこれになるっぽい。
特に大事なのが、output_formatはピリオド以下の拡張子が必要だったみたいで、このピリオドが抜けてるせいでも痛い目を見た

そして、「いざ!」と思ったのも束の間、これでもエラーが出てうまくいかなかった。 PDFまで作られておきながら、実際に埋め込むためのSVGにコンバートされなかったのである。

dvisvgmの罠

どうやらPDFからSVGへコンバートできないことが原因らしい。
エラーメッセージで出てきた参照リンクをよく読んだらdvisvgm周りでの設定が足りなさそう。
次の要件を満たす必要があるようで。

  • dvisvgmのversionが2.4以上であること。(dvisvgm --versionでバージョン確認)
  • dvisvgmがPostScript specialsをサポートしていること。(dvisvgm -lとしたときに出てくるリストにps dvips PostScript specialsが無いと要注意)
    • 上記でps dvips PostScript specialsが無かった場合
      dvisvg -hでコマンドオプションの一覧を出したときに
      • Processing options内に--libgs=filenameがない場合は、dvisvgmの他のバイナリが必要
      • Processing options内に--libgs=filenameがある場合は、Ghostscriptのdllへのパスを変数名LIBGSで入れて読み込めるようにしておく必要がある。
        Windowsだとgsdll64.dllまたはgsdll32.dllまでの拡張子まで含めたファイルへのパスを値として設定。
        これで再度dvisvgm -lとしたときにps dvips PostScript specialsが出現するはず。
  • 最後にdvisvgm -V1でGhostscriptのバージョン名が確認できればOK。

これで自分の環境ではひとまず、Manimでの日本語まじりのTexレンダリングできるようになった。

と思ったのも束の間

ある日突然、Texレンダリングでまた同じエラーが出るようになった。

もちろん、設定とか全くいじってないから、心当たりがなさすぎた。

原因を調べるのに骨が折れたが、dvisvgmがドライブをまたいでは動かないからだった。
エラーが出たとき、Cドライブじゃなく、別のDドライブとかにコードを保存していた。
システムのデフォルトの一時フォルダがCドライブ内である場合、Dドライブ内で実行しようとしても動かないよねー。ってことだったらしい。

Googleドライブ内で複数PCで作業フォルダを共有したかったので、遅かれ早かれぶち当たる問題だった。

とりあえず、一時フォルダの設定の書き換えとかが面倒くさそうだったので、 mklinkを使ってCドライブ内にManimの作業フォルダへのジャンクションを作って対処は成功。

けど、原因調べるのに辿り着いた GithubのIssue報告 では、「dvisvgmのバージョンが2.6.3由来のもので、2.8以上なら改善されている」みたいな記述もあって「????」ってなってる。
まぁ、動くので深くは追求せずに放置。

/* -----codeの行番号----- */