この記事は SATySFi Advent Calendar 2019 20日目の記事です.19日目はhsjoihsさんによるMathJaxで私が書くぐらいの内容をSATySFi化するツールでした.21日目はmonaqaさんです.
LaTeXには言わずと知れた数式画像化ツールであるLaTeXiTがあります.
最近SATySFi用にLaTeXiT的なことをするクラスファイルを作ったので共有したいと思います.
追記
LaTeXにはstandaloneというパッケージがあってsatysfi-itと概ね同じことをしてくれるらしいです (知らんかった) ただstandaloneという名前のクラスファイルは既にSATySFiの標準ライブラリに存在していてかつLaTeXのstandaloneとは違って自動でページサイズが小さくならないので混乱を避けるためにこのままsatysfi-itという名前を使い続けます.
LaTeXiTとは
LaTeXの形式で数式を入力すると画像ファイルとして出力してくれる便利なツールです.

上記の入力をpngとして出力した場合は以下のような結果が得られます.(背景が透明なのでわかりづらいですが数式のサイズにぴったりなサイズのpngファイルです)

LaTeXiTはMacだとMacTeXをインストールするときにGUIインストーラーのチェックボックスを外すのを忘れると勝手にインストールされてしまうツールとしても有名ですね.単純な数式だけでなく次のように図式も描けたりします.

昔はKeynoteでスライドを作るのによく使っていました(Beamerの不自由さがあまり好きではなかったので.)最近は目がComputer Modernしか受け付けなくなってしまったので使わなくなってしまいました.
SATySFi-iT
LaTeXiTのようなことをSATySFiで実現するのはそんなに難しくありません.もちろんpdfしか出力できませんしSATySFiからGUIを作ることはできないのでざっくりLaTeXiTっぽい感じの出力結果になる(入力の数式にぴったりなサイズの出力が得られる)クラスファイルが作れるという意味です.
実際のクラスファイルのコード (satysfi-it.satyh) は以下のような感じです.
@require: base/base
@require: base/fn
@require: base/inline
@require: base/block
@require: base/pager
@require: base/context
@require: base/option-ext
let satysfi-it ?:text-width ?:margin math =
let text-width = text-width |> Option.unwrap-or 440pt in
let (top, right, bottom, left) = margin |> Option.unwrap-or (3pt, 3pt, 3pt, 3pt) in
let default-ctx = Context.make text-width in
let ib = default-ctx |> Inline.of-math math in
let (w, h) = (Inline.natural-width ib +' left +' right, Inline.natural-height ib +' top +' bottom) in
Pager.make-document
(Page.custom w h)
(Fn.const (| text-height = 0pt; text-origin = (left, top) |))
(Fn.const (| header-content = Block.nil; header-origin = (0pt, 0pt); footer-content = Block.nil; footer-origin = (0pt, 0pt) |))
(default-ctx |> Block.of-inline false false (Fn.const ib))
satysfi-baseの開発版がインストールされていることが前提です.使う時は以下のような感じ.
@import: satysfi-it
satysfi-it ${1 + 2 = 3}
そして組版の結果が以下のようになります.

簡単な解説
特に解説するほどの長さでもないですが一応簡単に説明します.
satysfi-it
はmath
型の値を受け取ってそれをdocument
型に変換します.変換の際Inline.natural-width
とInline.natural-height
で受け取ったmathの自然なサイズを計算してそれをページサイズとしています.documentを作るにはPager.make-document
を使うのですが,この際渡すヘッダ・フッタの設定は適当に潰してあります.
上の例では1 + 2 = 3
というとても簡単な数式にしてありますが当然可換図式も書けます.ただし現在のところSATySFiで可換図式を簡単に書く方法がないのでここでは省きます.
今後の展望
SATySFi-iTはもともとsatysfiで回帰テストを書く際にほしいということで作られました(関連issue: Create LaTeXiT-sh class file #14)LaTeXiTと使われ方が異なるあたりがとてもsatysfiっぽいです.一方LaTeXiTと同じユースケースでも便利に使えると思います.GUIなどあるとなお良いかもしれません.