SATySFi+Dockerでテンプレート作った

[SATySFi Advent Calendar 2021](https://adventar.org/calendars/6336) 5日目の記事です。

諏訪敬之氏によってIPAの未踏IT人材発掘・育成事業(2017)の支援の下に開発された[SATySFi](https://github.com/gfngfn/SATySFi) は便利で高性能な組版システムですが、[SATySFi のインストールチャレンジ(v0.0.6)](https://qiita.com/Blank71/items/37cb773f55e614bad947)や[SATySFi インストールチャレンジ in Windows Subsystem for Linux](https://sokrates7chaos.hatenablog.com/entry/2021/02/04/012911)、[SATySFi インストール手引き 2021年5月版](https://qiita.com/na4zagin3/items/a6e025c17ef991a4c923)などからもわかるように、2021年になってもインストールがLaTeX同様に比較的難しい状態となっています。かくいう自分も一度は[成功](https://qiita.com/ogata-k/items/8238ea10903c8bc62532)したものの別のパソコンにインストール失敗して挫折しています。
まだまだインストールが難しいため、[amutake氏のDockerを利用する試み](https://amutake.hatenablog.com/entry/2020/12/13/000000)（リポジトリ：[GitHub](https://github.com/amutake/docker-satysfi)）や[yasuo_ozu氏のバイナリ形式を利用する試み](https://twitter.com/yasuo_ozu/status/1461029670275915776)（リポジトリ：[GitHub](https://github.com/yasuo-ozu/satyst-dist/tags)）などSATySFiの利用を楽にする試みがいくつか行われています。
そこで自分もSATySFiの利用を楽にするためにamutake氏のDockerイメージを利用してGitHubに[テンプレート](https://github.com/ogata-k/template-satysfi)を作ってみました。

## 前提
Git、Bash、Dockerが使える状態になっていればこの[テンプレート](https://github.com/ogata-k/template-satysfi)を利用できます。Windowsの場合はDockerを入れているならLinux環境に変換できるようにするターミナルも入れているはずなので、Bashも使える状態になっているはずです。[^1]

[^1]: Windowsのターミナルで`bash`や`wsl`と叩いてログイン中のターミナルが切り替われば少なくとも切り替わった先ではBashは使えるはずです。

## テンプレートの紹介
先ほど述べたようにこの[テンプレート](https://github.com/ogata-k/template-satysfi)はSATySFiの利用を楽にするためのテンプレートです。
このテンプレートは指定したSATySFiのパッケージの一覧をDockerイメージをビルドしたときにインストールし、そのイメージをもとにコンテナ内でコマンドを走らせることができるテンプレートとなっています。
この後で使い方を説明していきますが、より詳しくは[README](https://github.com/ogata-k/template-satysfi/blob/main/README.md)を確認してください。
問題や要望などはissueやPRにお願いします。

## テンプレートを使ってPDFを生成する
テンプレートからPDFを生成するまでのStepは7つあります。
今回説明のために自分も[サンプル](https://github.com/ogata-k/satysfi-sample)を作成しているのでこちらも参考にしてみてください。
### Step1：リポジトリ作成
まず、リポジトリを作成していきます。[テンプレート](https://github.com/ogata-k/template-satysfi)からリポジトリを作成するのは、クローンするときと同じ緑色のボタンからできます。この緑色のボタンを押していろいろ設定するとリポジトリが出来上がります。
### Step2：リポジトリのクローン
次に、作成したリポジトリをクローンしてローカルで編集できるようにします。クローンした後は、`bash`コマンドが使えるLinux風のパスが扱えるターミナルでそのリポジトリルートディレクトリを開いておきます。
クローン時に注意してほしいのがGitのAutoCrlf設定です。設定次第でWindowsでは改行コードがCR+LFで保存されてしまい、Bashの実行時に¥rコマンドがわからないなどと言われてしまいます。これを直すには対象ファイルを適当なエディタで開いて改行コードをLFにして保存するか、Gitでクローンしてくるときに改行コードをLFで取ってくるように[設定する](https://futureys.tokyo/what-is-autocrlf-of-git/)かする必要があります。
### Step3：.project-envの設定
ローカル環境で開発環境を用意したので次は環境の設定を行っていきます。環境の設定は.project-envファイルで行います。このファイルはいわゆるenvファイルです。設定項目は四つあります。以下、.project-envで設定できる項目の設定値は$変数名と表記します。

一つ目はmeta情報です。

```bash
projectRoot=$(git rev-parse --show-cdup)
workspace="$projectRoot/workspace"
```
projectRootはリポジトリのルートで、workspaceはsatyファイルやpdfファイルを配置するフォルダのパスです。
これらは変える必要はないので今回はそのままです。

二つ目はプロジェクトの情報です。

```bash
author=ogata-k
projectName=satysfi_sample
```
authorは作者、projectNameはプロジェクト名です。デフォルトでは \$author/$projectNameでDockerのイメージ名になるのでprojectNameはDockerイメージとして解決できる名前にしておく必要があります。
今回は適当に名前つけておきます。

三つめはDockerの情報です。

```bash
dockerTag=${satysfiVersion:-0.0.6}
dockerRoot="$projectRoot/docker"
dockerImage="$author/$projectName:$dockerTag"
dockerFileName=Dockerfile
```
dockerTagはベースイメージの[amutake/satysfi](https://github.com/amutake/docker-satysfi/blob/master/README.md)の全部入りイメージのタグ、dockerRootはDockerFileを置いてあるファイル、dockerImageはDockerイメージの名前、dockerFileNameはDockerfileの名前です。
SATySFiの最新が2021/12/05現在で0.0.6なので今回はデフォルトのままです。

四つ目は$workspace下のSATySFi関係のファイルについてです。

```bash
mainSrcFileName=main.saty
mainPdfFileName=satysfi-sample.pdf
```
mainSrcFileNameはメインのソースファイル、mainPdfFileNameはメインのソースファイルの変換先PDFファイルです。
デフォルトのままだとうまく書き出されたかわからないのでmainPdfFileNameだけ今回は変えておきます。

以上で、.project-envファイルの設定は完了です。

### Step4：.satysfi-packagesの設定
次に利用したいSATySFiのパッケージを指定していきます。
.satysfi-packagesファイルをline-formatのフォーマットで改行区切りで以下のように記述していきます。

```
# line-format = <line>
# <line> = '[:space:]*<package>?[:space:]*<comment>?'
# <package> = '<package name without 'satysfi-'>((\.[:digit:]+){3})?'
# <comment> = '#.*'


// ex. 以下記入例
# base utility
base.1.4.0
siunitx.0.1.1 # SI unit extend
uline
# ruby.0.1.2 # Japanese only
#latexcmds.0.1.0
```
2021/12/05現在で列挙されているパッケージはpuripuri2100氏に[こちらのツイート](https://twitter.com/puripuri2100/status/1463460217371623427?t=97ddc3Yk0wn9y8gErAupNw)で教えていただいたものです。

### Step5：Dockerイメージをビルドする
.package-envと.satysfi-packagesファイルの設定が完了したのでDockerイメージを作成します。
Git管理下からたどるならどこでもよいですが、今回は$projectRoot直下で次のコマンドをたたきます。

``` bash
./cmd/build-docker.sh
```
ビルドに成功すると\$dockerImageのイメージが出来上がります。同時に、ローカルでもSATySFiパッケージを参照できるように$workspace下の.satysfiフォルダ下にパッケージ情報が吐き出されます。

これでPDFを吐き出す環境が整いました。
なお、このDockerイメージはShellスクリプト内で`docker run`するときに自動で指定されるためます。加えて、イメージ内にSATySFiパッケージを含んでいるので.package-envと.satysfi-packagesに変更があった場合は必ずこのコマンドでイメージを生成しなおしてください。

## Step6：main.satyファイルの編集
さて、ソースファイルの$mainSrcFileNameを編集していきます。
今回は初期状態（[SATySFiのデモファイル](https://github.com/gfngfn/SATySFi/blob/v0.0.6/demo/demo.saty)）とは違うことが分かればいいので、タイトルにSampleをつける程度の編集でとどめておきます。

### Step7：PDFの書き出し
先ほどコマンドを叩いたように次のコマンドを叩きます。
このときパスなどの問題が発生しないようにするために、Linuxのファイルパス形式でパスが扱えてなおかつ`bash`コマンドが機能するターミナルでコマンドを叩いてください。

``` bash
./cmd/build-main.sh
```
問題なければ\$mainPdfFileNameという名前でPDFファイルが出来上がります。
$mainSrcFileNameの編集結果が正しく反映されていることがわかります。

## まとめ
今回はSATySFiをインストールせずに利用するために、Dockerを使った[テンプレート](https://github.com/ogata-k/template-satysfi)を作ったので紹介しました。問題や修正点があればissueやPRをお願いします。
このテンプレートで利用できるコマンドにはDockerイメージの作成やPDF作成だけでなく、ほかにもいくつか便利なコマンドも用意してあります。詳しくは[README](https://github.com/ogata-k/template-satysfi/blob/main/README.md)を確認してください。
このテンプレートでSATySFiがより簡単に扱えるようになり、SATySFiを扱える人が増えると幸いです。