はじめに
Ruby on Railsで個人開発をした際に、gem rails-latexを使って、ユーザーが入力したTeXコードをコンパイルしてPDFを作成する機能を実装しました。
関連する記事があまりなかったので、どのようにしたのかを残そうと思います。
設定
PDF作成には LatexToPdf.generate_pdf(code, config)
メソッド(rubydoc)を利用するので、gemをインストール後、その設定を行います。初期設定は以下の通りです。
(注)「・・・」の部分は、Users/・・・/(appのルートディレクトリ)
が入ります。
LatexToPdf.config
=>
{:recipe=>[],
:command=>"pdflatex",
:arguments=>["-halt-on-error"],
:default_arguments=>["-shell-escape", "-interaction=batchmode"],
:workdir=>
#<Proc:0x00000001135d1830 /・・・/vendor/bundler/ruby/3.1.0/gems/rails-latex-2.3.4/lib/rails-latex/latex_to_pdf.rb:16 (lambda)>,
:preservework=>false,
:basedir=>"/・・・/tmp/rails-latex",
:parse_runs=>1}
今回、platex, dvipdfmxを実行してTeXコードをPDFに変換するので、設定の command
をそのように書き換えます(Rails で LaTeX を使って帳票出力を参考にしました)。
config/initializers/rails_latex.rb
# frozen_string_literal: true
LatexToPdf.config[:command] = Rails.root.join("lib/tasks/platex_dvipdfmx.sh").to_s
lib/tasks/platex_dvipdfmx.sh
#!/bin/bash
platex -halt-on-error -shell-escape -interaction=batchmode input && dvipdfmx input
TeXコードのコンパイル
ユーザーが入力したTeXコードをコンパイルしてPDFを作成します。
以下のコードは、渡されたcode(文字列)をコンパイルして、コンパイルが成功すればPDFのpathを、失敗すればログを返すコードです。
# code をコンパイルする
begin
pdf_binary = LatexToPdf.generate_pdf(code, LatexToPdf.config)
pdf_path = Rails.root.join("public/hoge/fuga.pdf")
File.open(pdf_path, "w+b") do |f|
f.write(pdf_binary)
end
render json: { url: pdf_path } # コンパイル成功時は pdf_path を返す
rescue RailsLatex::ProcessingError => e
render json: { log_text: e.log } # コンパイル失敗時はログを返す
end
-
LatexToPdf.generate_pdf(code, config)
メソッドにcode
(文字列)とconfig
を渡すと、PDFのバイナリ文字列が得られるので、これをPDFファイルにします。 - コンパイル失敗時には
RailsLatex::ProcessingError
例外(rubydoc)が発生し、その例外オブジェクトe
からe.log
でログのテキストを取得することができます。
参考:READMEーException handling and debugging
このissue にあるように、e.message.scan(/\/.*\.log/).first
でログファイルのパスを取得し、これを利用する手もあります。
注意
READMEに以下のような記述があります。
The last log file is moved to tmp/rails-latex/input.log , and the corresponding source TeX file to tmp/rails-latex/input.tex . If the PDF is not produced the build directory is not removed; an archive script should be written to occasionally clean up the tmp/rails-latex directory.
ログファイルとTeXのソースファイルは tmp/rails-latex
に格納されますが、PDFが作成されない場合、削除されずに残り続けます。そのため、時々tmp/rails-latex
ディレクトリをクリーンアップするスクリプトが必要です。
herokuでの利用
herokuでTeXを利用ために、次のビルドパックを使いました。
heroku-buildpack-tex
デフォルトで最新バージョンのTeX Liveがインストールされますが、TeX Liveをフルでインストールするとherokuのslugサイズの上限を簡単に超えてしまうため、必要最小限のものだけがインストールされます。そのため、必要なものがあれば自分で追加する必要があります。
README-Custom packagesにあるように、レポジトリのルートディレクトリにtexlive.packages
を作成し、そこに必要なものを記述します。
参考: Heroku buildpack - Installing texlive binary package
今回、platex、フォント、tikzを利用するためのパッケージを追加して、以下のようにしました。
texlive.packages
jsclasses
platex
pgf
japanese-otf
haranoaji
haranoaji-extra