マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

徹底検証! SATySFiはLaTeXの代わりになるか

これは「SATySFi Advent Caleandar 2020」の22日目の記事です。
(21日目は bd_gfngfn さん、23日目は amutake さん です。)

時の経つのは早いもので、SATySFiもその正式公開1からもう2年以上も経っています。この間にSATySFiを取り巻くエコシステム(例えばパッケージマネージャであるSatyrographosなど)も徐々にではありますが整えられつつある状況です。

今の状況に至ったところで、改めて「SATySFiの元来の目的」について思い返してみましょう。

そう、SATySFiは「LaTeXを置き換える」ことを目的にして開発されたのでした。

現状のSATySFiは「LaTeXを置き換える存在」になっているのでしょうか?

そもそもLaTeXとは何だったのか

この疑問に答えるには、まずLaTeXの存在意義」という究極の問いについて考察する必要があります。LaTeX(拡張エンジンを含む)を使うと数式や日本語や英語などを高い組版品質をもって出力できるわけですが、LaTeXは究極的に何のためにあるのでしょうか?

極めて本質的な答えですね。しかし最近は状況が少し変わっています。

このように、最近では単に☃を出力するだけでは不十分で、☃を回転させることまで要求されるようになっています。

まとめると、LaTeXの目的は究極的には「☃を回すこと」であると結論づけて間違いないでしょう2

SATySFiで☃を回せそうにない話

LaTeXの目的についての本質的な理解が得られたところで、いよいよSATySFiについて考えてみます。果たしてSATySFiで「☃を回すこと」は可能でしょうか。

LaTeXでは「PDF上でのアニメーション」を実現するためのanimateというパッケージがあり、また、この機能を利用して「テキストを回転させる」ためのtcfaspinというパッケージが作られています。tcfaspinを使うことで簡単に☃を回転できます。

一方で、SATySFiには現状で「PDF上でのアニメーション」を実現するための機能が欠けています。このためSATySFi上でfcfaspinに相当するパッケージを実装することは、残念ながら現状では不可能です。やはり、SATySFiはLaTeXを置き換える存在にはなりえないのでしょうか。

それでもSATySFiで☃を回したい話

一見して絶望的な状況ですが、ここでまた最近のLaTeXのトレンドを見てみると、希望が見えてきます。

すなわち、LaTeXの主戦場が最近ではPDF文書からGIFアニメ画像に移行しつつあるといっても過言ではないでしょう3

とはいっても、LaTeXエンジンにGIFアニメ画像を出力する機能はありません。「LaTeXでGIF画像をつくる」にはtcspingifという補助のスクリプトを利用する必要があります。

このtcspingifは「普通の(静止した)複数のPDF画像からGIFアニメ画像に変換する」という処理を行うものです。そのことを考えると、SATySFiについても可能性が見えてきます。tcspingifをSATySFiに対応させればよさそうです。

tcspingifで「TeX以外」する話

というわけで、tcspingifを少し改修してみました。

今まで、エンジン(-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 → document
      framem n は出力したいGIFアニメ画像の「​n フレーム中の m フレーム目」の画像を表す文書。

この仕様とtcspingifの仕様を繋ぐためのシェルスクリプトを用意します。

[tcsg-satysfi]
#!/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.shtcsg-satysfiに変更すべき。

SATySFiでとにかく☃を回す話

これで準備は整ったので、いよいよ☃を回すことにしましょう。必要なのは、「☃を回す」ためのパッケージファイルを作ることです。そこで、次のようなframe函数を定義するscframeパッケージを実装します。

  • framem n」は時計回りに (​m​/​n​) 回転分だけ傾いた☃の絵を中央に配置した文書を作る。

この仕様は現在のSATySFiで十分に実装可能です。

新版の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を表示させてみると……。

f:id:zrbabbler:20201220013805g:plain
回転する☃(素敵😊)

SATySFiで☃を回せました!

まとめ

やっぱり「回転する☃」はトッテモ素敵😊


  1. 2017年度の未踏事業成果報告会があった2018年2月11日を正式公開の日と見なすことにする。

  2. 異論については地中深くに10万年くらい埋めておくことにしましょう。

  3. 異論については地中深くに10万年くらい埋めておくことにしましょう。