(21日目は bd_gfngfn さん、23日目は amutake さん です。)
時の経つのは早いもので、SATySFiもその正式公開1からもう2年以上も経っています。この間にSATySFiを取り巻くエコシステム(例えばパッケージマネージャであるSatyrographosなど)も徐々にではありますが整えられつつある状況です。
今の状況に至ったところで、改めて「SATySFiの元来の目的」について思い返してみましょう。
初心忘るべからず。#satysfi #TeX以外 pic.twitter.com/RPvhgwPYzv
— 某ZR(ざんねん🙃) (@zr_tex8r) 2020年11月8日
そう、SATySFiは「LaTeXを置き換える」ことを目的にして開発されたのでした。
現状のSATySFiは「LaTeXを置き換える存在」になっているのでしょうか?
そもそもLaTeXとは何だったのか
この疑問に答えるには、まず「LaTeXの存在意義」という究極の問いについて考察する必要があります。LaTeX(拡張エンジンを含む)を使うと数式や日本語や英語などを高い組版品質をもって出力できるわけですが、LaTeXは究極的に何のためにあるのでしょうか?
LaTeXなんて、ゆきだるま☃さえ出力できればいいんですよ#TeX #えっ
— 某ZR(ざんねん🙃) (@zr_tex8r) 2016年3月9日
極めて本質的な答えですね。しかし最近は状況が少し変わっています。
新しいLaTeXがイロイロと🍣なので、☃を回すしかない……😫 #ナントカ pic.twitter.com/IMcB8QaUYd
— 某ZR(ざんねん🙃) (@zr_tex8r) 2020年9月13日
正立☃️→倒立☃️→回転☃️
— ワトソン (@wtsnjp) 2020年5月10日
という展開があったようだ.#ナントカ #ナントカ考古学
このように、最近では単に☃を出力するだけでは不十分で、☃を回転させることまで要求されるようになっています。
まとめると、LaTeXの目的は究極的には「☃を回すこと」であると結論づけて間違いないでしょう2。
SATySFiで☃を回せそうにない話
LaTeXの目的についての本質的な理解が得られたところで、いよいよSATySFiについて考えてみます。果たしてSATySFiで「☃を回すこと」は可能でしょうか。
LaTeXでは「PDF上でのアニメーション」を実現するためのanimateというパッケージがあり、また、この機能を利用して「テキストを回転させる」ためのtcfaspinというパッケージが作られています。tcfaspinを使うことで簡単に☃を回転できます。
- これからの時代はLaTeXを回転させよう!(Qiita/@zr_tex8r)
一方で、SATySFiには現状で「PDF上でのアニメーション」を実現するための機能が欠けています。このためSATySFi上でfcfaspinに相当するパッケージを実装することは、残念ながら現状では不可能です。やはり、SATySFiはLaTeXを置き換える存在にはなりえないのでしょうか。
それでもSATySFiで☃を回したい話
一見して絶望的な状況ですが、ここでまた最近のLaTeXのトレンドを見てみると、希望が見えてきます。
美文書第☃︎版「現代的なTeX(LuaTeXなど)の出力形式はPDFというもので、Adobe Readerなどのソフトウェアで開いて中身をみられますが、ツイッタァーに上げるためにはPNGやGIFなどの画像形式に変換する必要があります」#TeX #ナントカ #えっ
— 某ZR(ざんねん🙃) (@zr_tex8r) 2020年8月18日
すなわち、LaTeXの主戦場が最近ではPDF文書からGIFアニメ画像に移行しつつあるといっても過言ではないでしょう3。
とはいっても、LaTeXエンジンにGIFアニメ画像を出力する機能はありません。「LaTeXでGIF画像をつくる」にはtcspingifという補助のスクリプトを利用する必要があります。
- LaTeXでつくる「回転ゆきだるまGIF画像」(マクロツイーター)
このtcspingifは「普通の(静止した)複数のPDF画像からGIFアニメ画像に変換する」という処理を行うものです。そのことを考えると、SATySFiについても可能性が見えてきます。tcspingifをSATySFiに対応させればよさそうです。
tcspingifで「TeX以外」する話
というわけで、tcspingifを少し改修してみました。
- tcspingif.pl(Gist/zr-tex8r)
今まで、エンジン(-e
オプション)にはLaTeXのコマンドを指定することのみを想定していましたが、ここで任意のコマンドを指定することにします。この場合、オプションの指定の方式がLaTeX用のものだと不便なので、もう少し汎用的な呼出形式を--interface=env
で選択できるようにしました。
従来(既定値の--interface=latex
を指定した時)は「nフレーム中のmフレーム目」のPDF画像を生成するのに特定の呼出形式でLaTeXのコマンドを起動していた(参考)のですが、--interface=env
を指定すると代わりに以下のコマンド行が実行されるようになります。
<コマンド名> <入力ファイル> <一時出力ファイル>
<コマンド名>
は-e
オプションの値。<入力ファイル>
はtcspingifに与えた入力ファイル名。<一時出力ファイル>
はこのコマンドが出力すべきPDF画像のファイル名。(実際のtcspingifの実行中には自動生成のファイル名が指定される。)- 以下の環境変数の値が設定される:
FASTOPTICKS
:上の説明中の「m」の値。FAALLTICKS
:上の説明中の「n」の値。
すなわち、上記の規約を満たすプログラムを作成して、そのコマンド名を-e
に指定すればいいわけです。
tcspingifでSATySFiする話
tcspingifの新機能に基づいて、「SATySFIでフレーム画像を生成する」仕組をつくってみます。次のような仕様にします。
- 入力ファイルは「SATySFiのパッケージファイル(
*.satyh
)」とする。 - パッケージの中で以下の函数
frame
を定義する必要がある。frame
: int → int → documentframe
m n は出力したいGIFアニメ画像の「n フレーム中の m フレーム目」の画像を表す文書。
この仕様とtcspingifの仕様を繋ぐためのシェルスクリプトを用意します。
#!/bin/bash set -eu if [[ ! ( $# == 2 && -f $1 ) ]]; then exit 1 fi stop=$((${FASTOPTICKS})) all=$((${FAALLTICKS})) ibase=${1%.satyh} obase=${2%.pdf} if [[ ! ( 0 -le $stop && $stop -lt $all &&\ $1 != $ibase && $2 != $obase ) ]]; then exit 1 fi cat <<EOT >$obase.saty @import: $ibase frame $stop $all EOT ${SATYSFI:-satysfi} $obase.saty if [[ ! -f $2 ]]; then exit 1 fi rm $obase.saty
- tcsg-satysfi(Gist/zr-tex8r)
※ファイル名をtcsg-satysfi.sh
→tcsg-satysfi
に変更すべき。
SATySFiでとにかく☃を回す話
これで準備は整ったので、いよいよ☃を回すことにしましょう。必要なのは、「☃を回す」ためのパッケージファイルを作ることです。そこで、次のようなframe
函数を定義するscframeパッケージを実装します。
- 「
frame
m n」は時計回りに (m/n) 回転分だけ傾いた☃の絵を中央に配置した文書を作る。
この仕様は現在のSATySFiで十分に実装可能です。
- scframe.satyh(Gist/zr-tex8r)
新版のtcspingifとtcsg-satysfiを実行可能にした上で、scframe.satyh
を置いたディレクトリで以下のコマンドを実行しましょう!
tcspingif -e tcsg-satysfi --interface=env -t 32 -b 2 scframe.satyh
次のように端末に表示された上で、結果のGIFアニメ画像ファイルscframe.gif
が出力されました。
$ tcspingif -e tcsg-satysfi --interface=env -t 32 -b 2 scframe.satyh tcspingif: convert: scframe.satyh -> scframe.gif tcspingif: parameters: density=72; ticks=32 tcspingif: generate frame: 0 tcspingif: generate frame: 1 tcspingif: generate frame: 2 ……(略)…… tcspingif: generate frame: 31 tcspingif: generate gif: scframe.gif
scframe.gifを表示させてみると……。
SATySFiで☃を回せました!
まとめ
やっぱり「回転する☃」はトッテモ素敵😊