備忘録: asciidoctorでpdf作成を行うメモ(Ubuntu18)


目的

自習用のメモ用途。お外の人と共有するのは主目的でない。

  • 数学・工学用途のPDFを作りたい
    • PlantUMLなどと親和性の高いツールを使いたい
  • PDFにしたいのは次の理由
    • オフラインでも参照したい
    • 自習目的の数式は途中の数式は省略しないので長くなりがちで、MathJaxだと表示のたびに、非常に時間を要する。
  • PDFの埋め込み画像は、PNGだと汚くなるので、SVGを採用したい
    → 英語(Windows-1252)だけでなく、Unicodeを含む文字も埋め込めるようにする

前提環境/使用ソフトウェア

  • OS: Ubuntu18
  • ruby 2.5.1p57
  • asciidoctor: 1.5.8
    • asciidoctor-mathematical
      mingwの環境ではビルドできず。仕方なく、UbuntuのVMとした。

インストールが必要だったもの

sudo apt-get -qq -y install ruby ruby-dev cmake
sudo gem install asciidoctor
sudo gem install prawn --version 2.1.0
sudo gem install prawn-svg --version 0.26.0
sudo gem install prawn-templates --version 0.0.4
sudo gem install asciidoctor-pdf --pre
sudo gem install asciidoctor-pdf-cjk-kai_gen_gothic
sudo asciidoctor-pdf-cjk-kai_gen_gothic-install
sudo apt-get -qq -y install bison flex libffi-dev libxml2-dev libgdk-pixbuf2.0-dev libcairo2-dev libpango1.0-dev fonts-lyx
sudo gem install asciidoctor-mathematical

補足

asciidoctor-pdf-cjk-kai_gen_gothic は、日本語を含む svg を扱う場合に必要となる。

The following text could not be fully converted to the Windows-1252 character set:
| α
The following text could not be fully converted to the Windows-1252 character set:
| α
...

prawn たちのバージョン指定をしないと、次のようなエラー(--trace指定で表示される内容)になる。Asciidoctor PDF | AsciidoctorのPrerequisites(前提条件)通りにしないとダメだよ。という話。

/usr/lib/ruby/2.5.0/rubygems/specification.rb:2327:in `raise_if_conflicts': Unable to activate asciidoctor-pdf-1.5.0.alpha.16, because prawn-svg-0.28.0 conflicts with prawn-svg (< 0.28.0, >= 0.21.0) (Gem::ConflictError)

実行時に食わせるスクリプト

AsciiDoc のテーブルのセル中に LaTeXの数式を埋め込むためのもの。

元ネタは、 Process inline stem macros inside AsciiDoc table cells · Issue #20 ... を参照。

mathematical-treeprocessor.rb

require 'asciidoctor/extensions'

Asciidoctor::Extensions.register do
  treeprocessor do
    process do |doc|
      mathematicalProcessor = MathematicalTreeprocessor.new
      (table_blocks = doc.find_by context: :table).each do |table|
        (table.rows[:body] + table.rows[:foot]).each do |row|
          row.each do |cell|
            mathematicalProcessor.process cell.inner_document if cell.style == :asciidoc
          end
        end
      end
    end
  end
end

asciidoctor-pdf-cjk-kai_gen_gothic.rb
SVG中でUnicodeを埋め込むためのもの。
詳しくは、asciidoctor-pdfで日本語を含むSVG画像を扱う を参照。

require 'prawn-svg'
Prawn::Svg::Font::GENERIC_CSS_FONT_MAPPING.merge!(
  'sans-serif' => 'KaiGen Gothic JP'
)

Makefile

PDF_LIST=\
aaa.pdf \
bbb.pdf

all: pdf $(HTML_LIST)
pdf: $(PDF_LIST)

%.pdf: %.adoc.txt
        asciidoctor --trace --backend=pdf -r `pwd`/asciidoctor-pdf-cjk-kai_gen_gothic.rb -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicJP -r asciidoctor-mathematical -a mathematical-format=svg -r `pwd`/mathematical-treeprocessor.rb -o "$@" "$<"
        rm -f img/stem-*.svg

html/%.html: %.adoc.txt
        mkdir -p html
        asciidoctor -r asciidoctor-mathematical -r `pwd`/mathematical-treeprocessor.rb --backend=html5 -a mathematical-format=svg -a mathematical-inline=true -o "$@" "$<"

clean:
        rm -f stem-*.png stem-*.svg

ドキュメントの例(抜粋)

:stem: latexmath
:imagesdir: img

...

==== 導出方法
image::geogebra-export_cos_alpha_minus_beta_clipped.svg[]

[stem,latexmath]
++++
\begin{align*}
\left(\begin{array}{c} \cos \alpha \\ \sin \alpha \end{array} \right)
\left(\begin{array}{c} \cos \beta \\ \sin \beta \end{array} \right)
&= \left|\left(\begin{array}{c} \cos \alpha \\ \sin \alpha \end{array} \right)\right|
\left|\left(\begin{array}{c} \cos \beta \\ \sin \beta \end{array} \right) \right| \cos(\alpha - \beta) \\
\cos \alpha \cos \beta + \sin \alpha \sin \beta &= \cos (\alpha - \beta)
\end{align*}
++++

PDFの出力例
画像中のα、βがきちんと表示されるようになった。
asciidoctor-mathematical の数式表示は汚くはあるが、意味が分かる程度の表示は出来ている。PDF作成の高速さを考えると許容範囲。