この記事はOkinawa.rb Advent Calendar 2018の1日目です。
2日目は @hanachin_ さんのRe: Ruby で季節のような循環する概念を表したいです。
RailsアプリケーションでSATySFiを使ってPDFを出力する方法を紹介します。
SATySFiとは
型による静的検証能力の高い組版システムです。
SATySFi(英単語の “satisfy” と同様に発音します)は,新しい組版処理システムとその言語です。構文は主にテキスト部分とプログラム部分からなり,前者はLaTeX風の構文で文書を執筆するために,後者はコマンドを定義するために使われます。いわゆる函数型プログラミングの要領でコマンドが定義でき,かつ静的に型がつけられるため,柔軟な記述とわかりやすいエラー報告が実現されています。
https://github.com/gfngfn/SATySFi/blob/master/README-ja.md
RailsのviewでSATySFiを使う方法
SATySFi-rails gemを使うとPDFを出力するviewをSATySFiで書けます。
必要なソフトウェア
SATySFiがインストールされPATHが通っている必要があります。
SATySFiのREADMEを頼りにインストールしましょう。
インストール方法
Gemfileに追記してbundle install
します。
gem "SATySFi-rails"
使い方
app/views/**/*
以下に.pdf.saty
の名前でテンプレートをおくとSATySFiで実行されPDFが出力されます。
let-inline ctx \fizzbuzz m = script-guard Latin (embed-math ctx m) in
let ctx = get-initial-context 440pt (command \fizzbuzz) in
let fizzbuzz-str n =
match ((n mod 3), (n mod 5)) with
| (0, 0) -> `FizzBuzz`
| (0, _) -> `Fizz`
| (_, 0) -> `Buzz`
| _ -> arabic n
in
let fizzbuzz-line n = line-break true true ctx (read-inline ctx (embed-string (fizzbuzz-str n))) in
let fizzbuzz n upto =
let-rec iter i acc =
if i == upto then
acc +++ fizzbuzz-line i
else
iter (i + 1) (acc +++ (fizzbuzz-line i))
in
iter 1 block-nil
in
page-break
A4Paper
(fun pbinfo -> (|
text-height = 842pt;
text-origin = (0pt, 0pt);
|))
(fun (pbinfo) -> (|
header-content = block-nil;
header-origin = (0pt, 0pt);
footer-content = block-nil;
footer-origin = (0pt, 0pt);
|))
(fizzbuzz 1 100)
デモ
実際にSATySFi-railsでPDFを出力したのが以下です。
https://satysfi-rails-demo.herokuapp.com/fizzbuzz.pdf
ソースコードは以下から確認できます。
https://github.com/hanachin/satysfi-rails-demo
Herokuのデプロイボタンがついているのでかんたんにデプロイできます 1
erbでPDFに文字を埋め込む方法
以下のようにPDFの中にコントローラーから受け取った文字をerbで埋め込むこともできます。2
Rails.application.routes.draw do
resources :greetings, only: :show
end
class GreetingsController < ApplicationController
def show
@name = params[:id]
saty = render_to_string "show.pdf.saty"
render inline: saty, type: :saty
end
end
@require: standalone
let-block ctx +hi = line-break true true ctx (read-inline ctx {<%= "Hello, #{@name}!" %>}) in
standalone '<+hi;>
以下のページを表示し確認すると、idのhanachinが埋め込まれているのが確認できます。
http://localhost:3000/greetings/hanachin.pdf
まとめ
レッツSATySFi
-
heroku-buildpack-SATySFiを利用するとSATySFiをHerokuで利用できるのでべんり、Rails以外でも使えます ↩
-
任意の文字を表示されてしまうと危ないので先程のデモアプリにはデプロイしていませんが https://github.com/hanachin/satysfi-rails-demo/tree/greetings から確認できます ↩