🎄

🎄SATySFiでクリスマスのお手紙🎄

2022/12/18に公開・約7,200字

はじめに

本記事はSATySFi Advent Calendar 2022の17日目の投稿です。
メリークリスマス〜!!!🎄
クリスマスソングを聴くとテンションが上がって、諸々のパフォーマンスが上がる日々です。

先日、技術書典で自作のコピー本の配布をしました。
しかし、文章として原稿が仕上がったのが締め切り1週間で、大慌てで「組版!組版!」と叫びながら組版にチャレンジするような事態でした。
様々な既存のサービスを試した中で、トラシュー時間を含めて、最も早くキャッチアップ出来たのが意外にもSATySFiでした。短い期間でしたので、基本のスタイルに加えてフォント変更・フォント色変更・チャプター設定程度の変更になりましたが、書籍の見栄えが良くなり、自分の作品への愛情が深まりました。
気軽に導入できるので、皆さんも適当な文章をSATySfiで好みの組版しちゃうといいと思います(๑˘ω˘ )و✧

今回は感謝の気持ちも込めて、ゆるゆるとSATySFiでサンタさんへのお手紙用便箋でも作ろうかなと思います〜
念の為に言っておくと、既にバチバチ使っている皆さんにとっては知っている内容だと思います!&色々と雑ですみません。

私と同じように初めて扱う人へ

インストール方法は、検索で出てくるような諸記事を読むと出来ます。
https://qiita.com/yasuo-ozu/items/8f57489fa15cc26aedac

近々SATySFiはバージョン0.1.0をリリースするかもしれないとのことで、インストール方法が変わる可能性もありますね。

初めてSATySFiを知った人が実際に組版する際には、The SATySFi Bookという制作者によるドキュメントを読んで取り組むのがお勧めルートです。

私は説明書かっ飛ばしてとりあえず触って遠回りをしてから、反省して説明書を読み始める種族なのですが、流石にThe SATySFi Bookは読んだ方がイイと思いました。(今読んでいます。)

特にミニマム実装から自分が確実に知っている記述を生やしてクラスファイルを作りたい人は、The SATySfi Bookの例12.1 135ページに「多少なりともまともに使える,実質的に最小のクラスファイル」を参考にすると良い...のかな。私は2回目からは、minimum.satyhファイルを作ってコピペして、自前のlocal.satyhで@import: minimumと宣言してから、生やしたい記述を増やすのを試しています。

逆にとりあえず触りたい人、急ぎで組版をしなくてはならない人は、公式雛形のstdjabookやstdjareportをそのまま流用するか、雛形をローカルにコピーしてstdjabooklocal.satyhファイルにして名前空間等の修正を加え、@importすることで、求めているものに仕上げていくのも一つの手ではあると思います。

The SATySFi Bookの2章と7章から、@requireはインストール経由でのパッケージ読み込み、@importは同一ディレクトリに設置されたパッケージファイルの読み込みとして提供されています。
(余談ですが、@requireで設定したファイルをSATySFi側が見つけられなかった時、探索を試みた設置が想定されるパス候補をリストアップしてくれたのは気が利いているなと思いました。)

何作るの?

とりあえずおしゃれな枠を作ってみたいなーと思うので、クリスマスカードにしました。
サンタさんへのお手紙の便箋です。
他にも色々作る予定でしたが、あいにく間に合わないので次回チャレンジします。

環境

iMac M1 2021, Apple M1, Ventura 13.0.1[1]
SATySFi v0.0.7[2]
Satyrographos v0.0.2.11
satysfi-ruby v0.1.2

作業開始

$ git clone https://github.com/gfngfn/SATySFi.git
$ mkdir card && cd card
$ cp ../SATySFi/demo/Makefile Makefile
$ touch minimum.satyh (最小限のクラスファイルをコピーします)
$ touch card.saty
$ touch local.satyh
$ make

Makefileの中身を書き換えます。

TARGETS = \
	card.pdf \ ※文章を書く側のファイル(.saty)と名前を揃える

SATYSFI ?= satysfi

.PHONY: all clean

.SUFFIXES: .saty .pdf

.saty.pdf:
	$(SATYSFI) $< -o $@

all:: $(TARGETS)

clean:
	rm -f *.pdf *.satysfi-aux

minimum.satyh(The SATySFi Book 135ページ「多少なりともまともに使える,実質的に最小のクラスファイル」)

let-inline ctx \math m =
  script-guard Latin (embed-math ctx m)
let-block ctx +p it =
  line-break true true ctx (read-inline ctx it ++ inline-fil)
let document bt =
  let ctx =
    get-initial-context 440pt (command \math)
      |> set-dominant-narrow-script Latin
  in
  let bb = read-block ctx bt in
  page-break A4Paper
    (fun _ -> (|
      text-origin = (80pt, 100pt);
      text-height = 630pt;
    |))
    (fun _ -> (|
      header-origin  = (0pt, 0pt);
      header-content = block-nil;
      footer-origin  = (0pt, 0pt);
      footer-content = block-nil;
|)) bb

これを核にクラスファイルを作成して本当に良いのかはちょっと確信持てていない。足りていない要素ありそうだけど、下記と合わせてとりあえずコンパイルが通るようになる。

local.satyh

@import: minimum
let font-size-normal  = 12pt ※本来必要ない想定だったが、何かしら変数を定義でもしないとmakeできなかった。

card.saty

@import: local

document '<
      +p{もふもふ}
>

枠を編む

card.satyでドキュメント直下にframeタグを付与する。

@import: local
document '<
  +frame<
      +p{もふもふ}
  >
>

vdecosetの実装とThe SATySFi Bookの9.3章を見ながら、自分用のデコレーションクラスファイルを作る。
deco.satyh

@require: color
@require: gr

module Deco : sig
val frame-design : length -> color -> deco-set
end=struct


let frame-design t scolor =
  let dash = (t, t *' 3.0, 0pt) in
  let strokef = stroke t scolor in
  let strokeDashFunc = dashed-stroke t dash scolor in
  let space = t +' 25.0pt in
  let spaceNarrow = t +' 20.0pt in
  let img = load-image `./crown.jpeg` in
  let imgSize = 30pt in
  let decoS (x, y) w h d =
    [
      strokeDashFunc (Gr.rectangle (x, y -' d) (x +' w +' 10pt, y +' h));
      strokef (Gr.rectangle (x -' space, y -' d -' space) (x +' w +' space, y +' h +' space));
      strokef (Gr.rectangle (x -' spaceNarrow, y -' d -' spaceNarrow) (x +' w +' spaceNarrow, y +' h +' spaceNarrow));
      draw-text ((x +' w *' 0.5 -' imgSize *' 0.5) , y +' 3pt) (use-image-by-width img imgSize);
      draw-text ((x +' w *' 0.5 -' imgSize *' 0.5) , y +' h -' imgSize -' 3pt) (use-image-by-width img imgSize);
    ]
  in
  let decoH (x, y) w h d =
    [略]
  in
  let decoM (x, y) w h d =
    [略]
  in
  let decoT (x, y) w h d =
    [略]
  in
    (decoS, decoH, decoM, decoT)

end

The SATySFi Book P115ページに「deco-set 型の 4 つ組は, 典型的に はそれぞれ 「ロ」 形,「匚」 形,「ニ」 形,「コ」 形をしたグラフィックスを返すような 函数である.」とあるように、frame内の文章がページを跨いでframeが切れた時の装飾設定をそれぞれ設定しておくみたい。

枠に画像を持ってくるのどうやったら良いかわからなかったけれど、doc-privitivesという提供されている関数が想定する引数の型と返り値の型のドキュメントのお陰で、関数型言語あるあるの「なんかかちゃかちゃやっているとできる感じ」でなんとかなった。裏側の努力は色々あるのだろうが、ユーザーとしては割と何も考えずに実装できる。

これでimportできるようになる。
フォント設定は、現時点でのバージョンでは色々いじる必要がある模様、とはいえそんなに難しくなかった。パッケージが使えるという話もチラッと見た。
SATySFiでフォントを変更する方法

@import: minimum
@import: deco

let font-cjk-kokoro   = (`kokoro`    , 1.2  , 0.)
let font-latin-italic = (`Junicode-it`, 1.2, 0.)

let-block ctx +frame content =
  let pads = (5pt, 5pt, 40pt, 40pt) in
  let decoset = Deco.frame-design 2pt (Color.gray 0.75) in
  let ctx-font =
    ctx |> set-font-size 15pt
    |> set-font Kana font-cjk-kokoro
    |> set-font HanIdeographic font-cjk-kokoro
    |> set-font Latin font-latin-italic
    |> set-dominant-wide-script Kana
    |> set-language Kana Japanese
    |> set-language HanIdeographic Japanese
    |> set-text-color (Color.gray 0.3)
    |> set-min-gap-of-lines 20pt
  in
    block-frame-breakable ctx pads decoset (fun ctx -> read-block ctx-font content)

ドットの下線は自分で実装できそうだったけれど、ulineを@importして\dotulineタグを使わせてもらって、こんな感じ。
生成した画像
枠を可愛くするだけでも満足度が高い😊
フォントやランゲージの設定は本当はframeではなくてdocumentの方に設定しておきたいのだけど、document変数の上書きが可能かわからなかった。ドキュメントの左右が全体的に枠線に近すぎるのが気になるのだが、パディングを設定したら設定が悪かったのか、さらに崩れてしまった。操作していく中で細かい疑問が発生した瞬間があったので、ちゃんとSATySFiコミュニティを頼った方が良い気がしている。

感想

今回後半戦で時間が足りずシンプルに終えましたが、SATySFiでもっと色々可愛いもの・洒落た工作が出来そうだと感じています。沢山実装したいもののアイデアはあるので、ゆるゆると気が向いた時に作品を出していけたら良いですね...
本記事を読んだ方も是非色々作ってみてください〜

rubyをパッケージを使うと良い感じにルビも振れます。
cuppa

「打倒 LaTeX」はイケそうだなという印象です。国内学会の論文のテンプレートでも提供されれば、使う人多いのではないでしょうか。応用例はアイデア次第で沢山考えられるので、「こんなもの作ってみましたー」報告が増えると良さそうですねーではでは。

脚注
  1. VenturaにOSアップデートしたら、brew updateが出来なくなって、brew自体の削除・再インストールをして解決しました。上手く消して戻せるのか不安で、怖かったです。 ↩︎

  2. 最新はv0.0.8ですが、執筆時点でSatyrographosでパッケージとして提供されているバージョンはv0.0.7なので、そちらを使わせてください。 ↩︎

Discussion

ログインするとコメントできます