2015/06/28

Re:VIEWで売り物の本を作ってみた(InDesign抜き)

本を作って出版する仕事をしています。 今回、はじめてRe:VIEWを実際の仕事に使ってみたので、忘れないうちに感想とメモを殴り書きしておきます。 ちなみに、作ったのは『エクストリームプログラミング』という本です。

公式サイトのREADMEに「an easy-to-use digital publishing system for books and ebooks」とあるように、 Re:VIEWは日本語の技術書をできるだけ簡単に作るための仕組みです。 テキスト原稿に比較的簡便なマークアップをマニュアルどおりに施し、本全体の構造をYAMLに書けば、それなりに体裁が整った日本語の技術書PDFを編纂してくれます。 同じソースからepubも出せます。InDesignへネイティブに取り込めるような出力もはけるので、テキスト原稿をInDesignに流し込んでバッチ組版とかも可能です。 自分が今回使ったのは、主にpLaTeXを介したPDFの出力機能なので、以降はその話だけします。

「Re:VIEW、わりといいじゃん」と思ったところ

Re:VIEW以外にも、マークアップされたテキスト原稿から書籍PDFを編纂できる仕組みはいくつもあります。 実際、自分も普段はまったく別のツール群を使っています。 Re:VIEWでなければできないことは、特にありません。

Re:VIEWが他のツールに比べて勝っている点は、「それなりに体裁の整った日本語の技術書」がわりと気楽に作れることでしょう。 理由は主に2つあると思います。

とにかくデフォルトの設定だけで、それなりに本の形になる

本の執筆は、ある程度まとまった形になって人に見せられる段階になるまで、どうしても孤独な集中力が要求される作業です。 そんなときに進捗をあきらめないための方策として有効なのは、「自分が書いた文章が本っぽい形になってるようす」をときどき見てにやにやすることでしょう。

Re:VIEWと似た仕組みを提供するツールとしては、Sphinxもあります。 SphinxもRe:VIEWも、原稿を執筆するだけで継続的インテグレーションの開始まで一瞬でもっていけるという点について、優劣はありません。 ただし、そこから実際に本として作り込んでいくところで、かなり使い勝手が変わると思います。 作り込みには、それぞれPythonなりRubyなりを必然的に使うことになるので、そのへんの好みにもよるでしょう。

これは完全に主観ですが、日本語の技術書を書いてみたい、拡張とかいっさい興味ない、という場合、Re:VIEWはよい選択肢です。 まっさらなつるしの状態でツールを使って日本語の技術書らしい体裁を得るなら、いまのところRe:VIEWがいちばん簡単な手段に思えます。 技術書界のRuby on Railsと呼んでもいいかもしれません。

マークアップが妥当

エディタでテキストを編集しているときの見た目は、そのテキストから生成される本のレイアウトに期待するものだと助かります。 InDesignのようなWISIWYGは不要というか邪魔ですが、マークアップとその出力結果には、なるべく自然な対応がついていてほしい。 太字にするつもりだったところが数式として扱われるとか、意図しないところに空白が発生するとか、そういうのは困ります。 Re:VIEWのマークアップとその処理系には、好き嫌いは別にして、そのような問題はあまりありません。

また、どうしても視界にまぎれてくるタグやインデントは、なるべく気が散らない見た目で、なおかつ本文とは違う性質の要素であることが明確にわかるものであってほしい。 この要求をいちばんうまく実装しているマークアップは、たぶんMarkdownでしょう。 しかしMarkdownそのものにはマークアップを拡張するための標準的な仕組みがなく、拡張はすなわち新しい方言の創造を意味します。 これは地獄です。その点、Re:VIEWには、好き嫌いは別にして、標準的なマークアップ拡張の仕組みがあります。

テキスト原稿に対するマークアップに何を選択するかは、宗教化しているかもしれないので断言しにくいのですが、 日本語の技術書を執筆するという目的がはっきりしているならRe:VIEWが採用しているマークアップは妥当だと思いました。

Re:VIEWで商業出版の本を作る

ここから先は、デフォルトのRe:VIEWで作れるPDFでは気が済まない人向けの雑多な話です。 Re:VIEWのバージョンは1.5.0を想定しています。

本の全体構造をいじりたい

本の背骨となる構造はcatalog.ymlというYAMLファイルで与えることになっています。 部や章のような本の中身となるコンテンツは、前づけや本文や付録などのグループに分けてここに並べます。

ただし、目次や索引のような、自分で書くわけでもないしRe:VIEWで生成するわけでもないコンテンツはcatalog.ymlには並べられません。 これらはすべてデフォルトの位置に挿入されてしまいます。 この挙動を変えるには、テンプレート(layouts/layout.tex.erb)の修正が必要です。

局所的に必要になる独自の構造

書籍では、「序文」の末尾に執筆者の署名と日付を入れることがよくあります。 Re:VIEWには、「段落を右寄せにする環境」がデフォルトであるので、同人誌などではこれを使うことで署名をそれっぽい仕上がりにできるでしょう。 しかし商業出版だと、出版社ごとにハウスルールが決まっていたりするので、右寄せにすればいいというわけにもいきません (そもそも、文章の構造の一部になってる要素に対してレイアウトだけ指定して済ませるというのは、あまりお勧めできない)。

このような、局所的な独自構造が必要な場合、自分で新しいマークアップの構文とその挙動を出力形式ごとに定義できます。 新しいインライン要素やブロック要素と、それらのレンダリングの動作を定義するには、 トップディレクトリにreview-ext.rbというファイルを用意し、その中でReVIEWモジュールのLATEXBuilderクラスやHTMLBuilderクラスに追加のメソッドを定義します。

たとえば、署名のための構文をこんなふうに書けるようにしようと考えたとします。

@<signature>{2015年7月|鹿野桂一}

このインライン要素(意味的にはブロック要素にすべきなんだろうけど)に対する処理は、こんな感じに定義すればいいでしょう (LaTeXの\signatureコマンドやCSSのdiv.signatureの定義はそれぞれ別に必要です)。

ReVIEW::Compiler.definline :signature

...(中略)

module ReVIEW
  class LATEXBuilder
    def inline_signature(name_author)
      "\\signature{%s}{}{%s}{}" % name_author.split(/\|/)
    end
  end
  class HTMLBuilder
    def inline_signature(name_author)
      "<div class=\"signature\" sigdate=\"%s\">%s</div>" \
        % name_author.split(/\|/)
    end
  end
end

なお、Re:VIEWにはLaTeXを経由してPDFを作るときに標準的に使える索引のためのマークアップがありません(InDesign用ならあるようです)。 そのため、たとえばmendexを使って索引が作りたかったら、LaTeXの\indexコマンドにマッピングされるような独自のマークアップをreview-ext.rbで同じように定義し、 layouts/layout.tex.erbに手を入れて\printindexを読み込むようにする必要があります。

このへん、公式のドキュメントがほとんどないので辛いのですが、がんばろう。

メタ情報

ドキュメントに埋め込みたいメタ情報(タイトル、著者名など)は、YAMLファイルに記述しておいて、それをreview-pdfmakerの実行時に指定します。 このYAMLには、標準で用意されているキー・値のペア以外にも、好きなキーと好きな値のペアを記述してよいようです。 たとえば奥付に初刷の情報だけでなく最新刷の情報も出力したい場合には、

date:    平成27年6月25日 # これは標準で用意されているキーと値
...(中略)
latestd: 平成27年7月1日  # これらは標準にはない
latestp: 第1版第2刷

のようなキーと値のペアをYAMLに書いておいて、これらをlayouts/layout.tex.erbで使えばよいでしょう。

レイアウト

二倍長ダッシュのような記号が必要な場合、デフォルトではサポートされていないので、やはりreview-ext.rbに独自マークアップとして定義するしかなさそうです。 ただし、少なくともバージョン1.5.0にはインラインの要素を入れ子にできないという問題があるため、この方法だと他のマークアップの中で二倍長ダッシュを使うことはできません。 次期バージョンでは入れ子のインライン要素に対応するらしいので期待しましょう。

一般に、レイアウトに対する特別な要求はLaTeXやCSSの側で解決することになるはずです。 裏を返せば、Re:VIEWで簡単に本が作れるとはいっても、見た目をよりよくしようと思ったらLaTeXやCSSをがんばるしかないという話です。

デフォルトで生成されるLaTeXソースの問題

LaTeXのhyperrefパッケージをincludeしている場所が、ユーザの独自スタイルファイルがincludeされる場所より前にあるので、自分のスタイルファイルで定義した\chapterがうまく動作しない、といった可能性があります。 また、デフォルトでgeometryパッケージが使われています。 いずれもlayouts/layout.tex.erbを編集することで回避できます。

オーバーライドできないマークアップ

ほとんどの定義済みマークアップはreview-ext.rbでオーバーライドできるのですが、たとえば章見出しのための行頭「=」は再定義ができません。 そのため、章扉と目次や柱とで見出しを変更したい場合(つまり\chapter[foo]{bar}したい場合)、上記のような通常の拡張方法が使えません。 LATEXBuilderのheadlineメソッドを全面的に修正するくらいしか方法が思いつきませんでした。

Re:VIEWは商業出版のデファクトになるか

というわけでRe:VIEWで商業出版は、中の人が中にいる特別なプロダクションさんでなくても、ソースを見ながらLaTeXをがんばれば割と可能です。 とはいえ、「じゃあおまえこれからはRe:VIEWで売り物の本を毎回作るつもり?」と言われたら、たぶんそんなことはないです。

そもそも、書籍っていうのはわりと「一点もの」な性格の商品なので、「その本で独自に必要とされるセマンティクスのための構文と表現を考える」という作業は商業出版だとどうしてもくっついてくるものだと思っています(異論がある人はどこかでビールでも)。 で、その作業がRe:VIEWでやりやすいかといったら特別そういうわけではないし、そういうのはむしろXMLのお家芸だったりします。かといって山括弧を手書きしないと原稿が書けないような執筆環境はありえないし、痛し痒しですね。え、LaTeX?

手に入れた原稿(翻訳なら原書)のソース形式を最大限に生かす方向で今後もがんばります。