数式とUMLが記述できる静的サイト生成 Middleman + Asciidoctor の連携
PlantUMLや数式が記述できる静的サイト生成の環境が欲しいと思い調べたところ、Middleman + Asciidotor + asciidoctor-diagramで実現できたのでメモします。 (Hugoが気に入っていたのですが、現時点ではAsciiDocには対応していませんでした。)
AsciiDocはMarkdownよりも表現力が高く、リッチな文書を記述するのに向いています。 例えば以下の記事 [1]では、書籍 "Pro Git" をAsciidoctorで作成したとあります。
このAsciiDocですが、仕様が2つあります。 1つはオリジナルのAsciiDocで、その変換ツールはPythonで作られています。 もう1つは後発のAsciidoctorで、ツールはRuby製です。 両者の仕様の違いはこちら[2]。 今回は後者を使います。
インストール
環境:
インストールするもの:
- JDK 1.8.0
- Graphviz 2.38.0
- PlantUML 8024
- rbenv 0.4.0
- bundle 1.10.4
- Middleman 3.3.12
- Asciidoctor 1.5.2
- asciidoctor-diagram 1.3.0.preview.1
- 他、依存パッケージ
事前準備
(1) 図の生成に必要なツール
GraphvizとPlantUMLをインストールします。
なお、PlantUMLはJava製のため、Javaをインストールしておく必要があります。
$ brew update $ brew cask install java # 既にJDKをインストール済みの場合は不要 $ brew install graphviz $ brew install plantuml
(2) rbenv, bundle
gemを直接使わず、rbenvとbundleを使うので、先にそれらをインストールします。
インストール方法は以下の記事 [3]が参考になります。
ここではRuby 2.2.2を使いました。なお、Railsはここでは使いません。
既にrbenvとbundlerがインストール済みの場合
既にrbenvとbundlerがインストールしてある場合は、パッケージの依存関係による問題を回避するため、すべてのグローバルなgemを削除してローカルなgemで運用することをお勧めします。
グローバルなgemを削除する:
$ for i in `bundle exec gem list --no-versions | grep -v bundler`; do bundle exec gem uninstall -aIx $i; done
このとき、デフォルトのgemはアンインストールできない旨のエラーメッセージが出ますが、問題は無いので無視して先へ進みます。
Middlemanのインストール
(1) プロジェクトフォルダの作成
まず、任意の場所にプロジェクト用のフォルダを作成します。ここではmysite
というフォルダ名にします。
$ mkdir ~/mysite $ cd ~/mysite
(2) asciidoctor-diagramリポジトリの取得 [暫定対処]
次にasciidoctor-diagramをインストールします。
gemからインストールしたいところですが、現時点でrubygemsに登録されているバージョン1.2.1
は、Middleman経由で画像を生成するとParmission Deniedエラーが発生します。
バージョン1.3.0.preview.1
で試したところ、エラーを回避出来ていたので、今回はこのバージョンを使います。
$ mkdir -p vendor/repo $ cd vendor/repo $ git clone https://github.com/asciidoctor/asciidoctor-diagram.git $ cd asciidoctor-diagram $ git checkout v1.3.0.preview.1
注意:
バージョンアップなどで、将来的には挙動が変わるかもしれません。
エラーの原因については、後述の「おまけ:エラーの原因」を参照してください。
(3) Gemfileの編集
Gemfileを生成するために、まずmysite
フォルダでbundle init
を実行します。
$ cd ~/mysite $ bundle init
ここでGemfile
が作成されるので、次のように編集します。
# If you do not have OpenSSL installed, update # the following line to use "http://" instead source 'https://rubygems.org' gem "middleman", "~>3.3.12" # Live-reloading plugin gem "middleman-livereload", "~> 3.1.1" # For faster file watcher updates on Windows: gem "wdm", "~> 0.1.0", :platforms => [:mswin, :mingw] # Windows does not come with time zone data gem "tzinfo-data", platforms: [:mswin, :mingw, :jruby] # Activate support for AsciiDoc gem "asciidoctor", "~> 1.5.2" # Enable to embed diagrams in AsciiDoc documents. gem 'asciidoctor-diagram', "=1.3.0.preview.1", :path => "vendor/repo/asciidoctor-diagram"
(4) gemのインストール
Gemfileの編集が終わったらgemをインストールしていきます。
--path
オプションを指定するのを忘れないで下さい。
$ bundle install --path vendor/bundle
これでインストールは完了です。
Middlemanのセットアップ
(1) サイトの生成
まずGemfileのバックアップをとり、mysite
フォルダにてmiddleman init
コマンドでサイトを作ります。このときGemfileが上書きされるので、バックアップから元に戻しておきます。
$ cd ~/mysite $ cp Gemfile Gemfile.bk $ bundle exec middleman init . $ mv Gemfile.bk Gemfile
(2) config.rb
次に設定ファイル(config.rb
)のconfigure :build do ... end
ブロックの中に、次の行を追加します。
Asciidoctorでは文書の様々な属性を指定できますが、共通的に指定しておきたいものはここで設定しておきます。
config.rb:
... configure :build do ... # Asciidoctor set :asciidoc_attributes, %w(source-highlighter=coderay coderay-css=style) end
(3) MathJaxの設定
Asciidoctorで記述した数式は、HTMLに変換されるときにMathJaxのコードになります。
数式が表示されるように、MathJax.jsを読み込むようlayout.erb
を編集します。
source/layouts/layout.erb
を開き、<head> ... </head>
ブロックの中に以下の行を追記します。
MathJaxにはいくつかの設定パラメータがありますので[4]、必要に応じて設定してください。
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"> </script>
(4) サーバ起動
それではサーバを起動してみます。
$ bundle exec middleman server
次の画面が表示されたら成功です。
(5) サーバ終了
サーバの終了はCtrl+C
で行います。
ページを作る
ページファイルはsource
フォルダに格納します。必要に応じて任意のサブフォルダに格納することもできます。
他のSSGのように_post
フォルダに置く、といった決まりはありません。
また、ページファイルのフォーマットもMarkdownやAsciidoctorだけでなく、ERBやHaml(エクステンションを追加すればSlimも)が使えるので柔軟なWebサイトの構成が可能です。
サンプルページ
では、Asciidoctor形式のページを作ります。
source
フォルダ直下に、次のファイルを置いてください。
ファイル中のditaaやUML図は公式ドキュメント [5]のサンプルを使いました。
sample.adoc
:
:stem: latexmath = ドキュメントタイトル これは本文です。 == 数式を書く インラインの数式 latexmath:[\lambda \vec{x}.M]. .ブロック形式の数式 [latexmath] ++++ \begin{align*} e &::= c \mid x \\ &\phantom{::}\mid \lambda x.e \mid e\;e \end{align*} ++++ == 図を書く .ditaaによる図 [ditaa, dia-ditaa, png] .... +-------------+ | Asciidoctor |-------+ | diagram | | +-------------+ | PNG out ^ | | ditaa in | | v +--------+ +--------+----+ /---------------\ | | --+ Asciidoctor +--> | | | Text | +-------------+ | Beautiful | |Document| | !magic! | | Output | | {d}| | | | | +---+----+ +-------------+ \---------------/ : ^ | Lots of work | +-----------------------------------+ .... .PlantUMLによるクラス図 [plantuml, dia-classes, png] .... class BlockProcessor class DiagramBlock class DitaaBlock class PlantUmlBlock BlockProcessor <|-- DiagramBlock DiagramBlock <|-- DitaaBlock DiagramBlock <|-- PlantUmlBlock ....
ページをビルドする
middleman build
コマンドを使います。
ただしPlantUMLやditaaなどで図を記述した場合、今のところLaTeXのように2回ビルドする必要があります。
$ bundle exec middleman build $ bundle exec middleman build
これは1回目で画像ファイルを生成し、2回目で生成された画像ファイルを検知してbuild
フォルダへ移すためです。
ビルド中にasciidoctor-diagramが生成したものを、Middlemanが検知できていないのだと思います。
結果
先ほどと同じようにmiddleman server
コマンドでサーバを起動し、ページを開きます。
sample.adoc
の場合はsource
フォルダの直下においているので、URLはhttp://localhost:4567/sample.html
となります。
sample.adoc
をhtmlに変換した結果は次のようになります。
sample.htmlが表示されない場合
sample.htmlが表示されず、build
フォルダにsample.adoc
が格納されている場合、
Asciidoctorとasciidoctor-diagramがインストールされていない可能性があります。
もう一度Gemfileを確認して、bundle install --path vendor/bundle
を実行してください。
おまけ:エラーの原因
現行のasciidoctor-diagram-1.2.1とMiddleman 3を連携させると、画像の生成でエラーになります。
画像の出力フォルダをimages
とした場合、Middlemanはそれをサイトルート相対パスとして/images
というパスで扱います。しかし、asciidoctor-diagram-1.2.1では、そのパスをそのまま画像の出力フォルダとして扱います。
つまり、ルートディレクトリ直下にあるimages
フォルダとなるので、書き込み権限がなくてエラーになります。
この画像出力の問題で、過去にimagesoutdir
なる属性が追加されたり、いまは消えていたりと、現時点では公式な仕様がまだ確定されていません。[6]
今回は不安定なバージョンである1.3.0.preview.1
を使いましたが、将来的に挙動が変わる可能性があります。
安定版である1.2.1を使いたい場合は、以下にパッチを置いておきますので、利用を検討してみてください。
https://gist.github.com/succzero/34e57c01209ed9581fd9
どちらの方法をとるにせよ自己責任でお願いします。
参考ページ
[1] テクニカルライティングの将来 ー GitHub上のAsciidocで技術書Pro Gitを協働執筆. http://postd.cc/living-the-future-of-technical-writing/
[2] Differences between Asciidoctor and AsciiDoc. http://asciidoctor.org/docs/asciidoc-asciidoctor-diffs/
[3] Rails開発環境の構築(複数バージョン共存可能)(Homebrew編). http://qiita.com/emadurandal/items/e43c4896be1df60caef0
[4] Loading and Configuring MathJax. http://docs.mathjax.org/en/latest/configuration.html
[5] Asciidoctor Diagram. http://asciidoctor.org/docs/asciidoctor-diagram/
[6] Missing documentation on imagesoutdir attribute #59. https://github.com/asciidoctor/asciidoctor-diagram/issues/59