圧倒亭グランパのブログ

30年後の自分にもわかるように書くブログ

Re:VIEW+CSS組版の執筆環境を簡単に構築できるようにしました

【追記(2019/02/10 9:53)】

現在開いているこの記事は技術書典5に向けての記事です。 技術書典6に向けての最新記事は以下をご参照ください。 使いやすくなったり、Re:VIEWなどのバージョンが更新されています。

at-grandpa.hatenablog.jp

【追記おわり】

Re:VIEW+CSS組版の環境は、わかめさんの vvakame/review-css-typesetting で整いつつあります。今回は、個人的に欲しい機能を追加した、という話です。いい感じに回っているのでブログにまとめることにしました。

 

目次

Re:VIEWとは

Re:VIEW形式で書かれたファイルを様々なファイルフォーマットに変換できるツールです。

github.com

技術書典4で頒布した「におうコードの問題集」でも使用しました。

https://grand-pa-ma.booth.pm/items/920906grand-pa-ma.booth.pm

目次の生成やページ数表示、脚注など、一通りのことを自動でやってくれるので便利でした。Re:VIEW記法についても、やりたいことさえ覚えてしまえばそれほど苦ではありませんでした。記法については日本語のドキュメントがまとまっています。

review/format.ja.md at master · kmuto/review · GitHub

Re:VIEWの環境構築は、こちらのこのすみさんの記事がわかりやすいです。

www.konosumi.net

CSS組版とは

まず「組版」とはなんでしょうか。自分はこれすら知らない状態から技術書を書き始めました。Wikipediaによると以下のように書かれています。

組版(くみはん)とは、原稿及びレイアウト(デザイン)の指定に従って,文字・図版・写真などを配置する作業の総称[1]。印刷の一工程としては、文字や図版などの要素を配置し、紙面を構成すること。

組版 - Wikipedia

CSS組版とは、これをCSSでやろうという試みです。通常の組版自体は専用のツールを使うなどハードルが高いイメージですが、CSSにすることでそのハードルを下げようという試みだと思います。CSSを扱えるなら、Webページを作る要領で紙面を作ることができます。便利ですね。

CSS組版の話題に必ず挙がってくるのが「Vivliostyle」です。

vivliostyle.org

Vivliostyleは、電子出版=Web出版の時代にマッチする新しい組版エンジンを、Web標準技術で作るオープンソース・プロジェクトです。

ChromeFirefoxなどのWebブラウザで書籍の組版ができます。PDF出力は 、ブラウザ上で Vivliostyle Viewer を開き、ブラウザの印刷機能で出力するという流れです。Vivliostyleは、実際にオライリー・ジャパンで出版されている本の組版にも使われたことがあります。

https://vivliostyle.com/ja/pressrelease/2016/07/css-secrets/vivliostyle.com

CSS組版やVivliostyleについてはイベント開催や資料も見つけられるので、興味がある方は追ってみてください。

Markdown+CSS組版での技術系同人誌制作時の環境 | 吉川ウェブ

speakerdeck.com

www.slideshare.net

 

Re:VIEW+CSS組版

さて、ここまで説明した Re:VIEWCSS組版ですが、この2つを組み合わせると自分にとってはかなり都合が良いのです。

まず、技術書典4で苦労した点は以下でした。

  • 問題集風味なデザインにできなかった
    • 見出しや箇条書きなどのデザインを凝りたかった
    • しかし、Re:VIEWのPDF出力はLaTeX経由
    • 諦めた
  • Re:VIEWの使い勝手が良いので他に移行したくなかった
    • 脚注やページ数、コードのincludeや画像のリンクなど、様々なことをいい感じにやってくれるので、ベースとしてはRe:VIEWが良かった
    • githubで管理できたり、エディタを好きなものにできたり、textlintなどのツールも使えたり
    • というか、今から移行してたら間に合わん...というスケジュール感

書き切ることが第一だったので、デザインは諦めました。技術書典4では Re:VIEW のデフォルトデザインで頒布しました。

と、ここで、わかめさんが Re:VIEW+CSS組版リポジトリを公開します。

github.com

Re:VIEW+CSS組版きた!

このリポジトリでpdfをbuildすると、Re:VIEW+CSS組版に関するわかめさんの挑戦が読めます。

これだ!と思い読み進めていると、フォント埋め込みなど、まだ細かい問題点があるようでした。特に自分が欲しかった機能としては、

  • コマンド一発でPDF出力
  • コマンド一発でブラウザ確認
  • circleciでPDF生成

の3点です。他の問題はちょっとわからなかったので、まだ手を付けていません。

 

環境構築

欲しい機能を実現するために環境構築をしました。基本的に、ローカルには何もインストールしないようにしました。dockerのコンテナを立ち上げて、全てその上で実行するようにしました。結果、出来上がったものがこちらのリポジトリの下記ブランチです。

github.com

わかめさんのリポジトリをforkして作成しました。本家にもPRを送っています。

github.com

もしPRがmergeされたら、自分のリポジトリは閉じようと思います。

使い方

必要なものは dockermake だけです。makeはタスクランナーとして使っています。このリポジトリでできることは以下です。git clone して、ブランチを docker-env-for-vivliostyle-and-pdf に切り替えてから試してみてください。

  • make setup で環境構築完了
  • make css/pdf でPDF出力
  • make css/browser でブラウザにて内容確認
  • circleciでPDFの生成

f:id:at_grandpa:20180818080410p:plain
出力したpdfの様子

f:id:at_grandpa:20180818081322p:plain
Vivliostyle viewer + Chrome Dev Tool

PDF出力は自分のMacで40秒くらいでした。Vivliostyle viewerでの表示は25秒くらいでした。もう少し早くできたら嬉しいですね。Vivliostyle viewerでは Chrome Dev Tool でCSSの確認もできます。

やってること

実際どのような処理を行っているのかを書きます。

  • make setup
    • dockerコンテナの build & up
    • review環境のsetup
      • 既存の setup.sh を叩く
    • vivliostyle環境のsetup
      • vivliostyleのzipをダウンロードして解凍
  • make css/pdf
    • htmlのbuild
    • httpサーバを起動して book.html のserve
    • vivliostyleのサーバを起動
    • puppeteer を用いて vivliostyle サーバ経由で book.html をpdf出力
  • make css/browser
    • htmlのbuild
    • httpサーバを起動して book.html のserve
    • vivliostyleのサーバを起動
    • ブラウザで Vivliostyle viewer にアクセス
  • circleci
    • サーバセットアップからpuppeteerでpdf出力

「サーバを起動してブラウザで見る or PDFで出力する」というシンプルな形です。

 

デザインの変更

今回の環境構築の話とは別なのですが、デザイン変更の方法も大体わかったので記します。「CSSを編集する」と「htmlを編集する」の2つを説明します。

CSSを編集する

出力されるhtmlは articles/book.html です。適用されるCSSarticles/book.css です。このCSSファイルを編集すればデザインを変更することができます。どのような要素があるかは、htmlをbuildして articles/book.html の中身を見るか、ブラウザで Vivliostyle viewer を開いて Chrome Dev Tool で確認してください。

htmlを編集する

デザインを考えているときに、「ここにdiv要素を追加したい」や「任意のclassを設定したい」という要望があると思います。しかし、 articles/book.html は自動生成されるので、この要望を満たすにはひと工夫必要です。アプローチとしては3つあります。

  • .re ファイルに直接htmlを記述する
  • 完成した articles/book.html に後処理を加える
    • htmlを nokogiri などでパースして変更を加え、再度htmlに出力する
  • review-ext.rb を使う

1つ目は自由度は高いですがメンテし辛いです。2つ目も自由度が高いですが、スクリプトをうまくメンテするのがめんどくさい印象です。今回は3つ目の review-ext.rb について説明します。

review-ext.rbRe:VIEW を拡張できるファイルです。articles/review-ext.rb に配置します。使い方は Re:VIEW knowledgereview-ext.rb による拡張 という項目にまとまりつつあります。大まかな仕組みとしては、 Re:VIEWrubyメソッドをオーバーライドして出力を変えてしまう、というものです。例を見てみましょう。

例えば、Re:VIEW記法の箇条書きのデザインを変更しましょう。

sample.re

 * リスト1
 * リスト2
 * リスト3

Re:VIEW記法では、アスタリスクの前に空白が一つ必要な点に注意してください。)

これを出力すると以下のようになります。

f:id:at_grandpa:20180819073617p:plain:w500
デフォルトデザインの箇条書き

このデザインを変更していきましょう。出力された articles/book.html をみると <ul><li> で構成されていることがわかります。

<ul>
<li>リスト1</li>
<li>リスト2</li>
<li>リスト3</li>
</ul>

このhtmlは Re:VIEWによってどのように出力されているかというと、下記のrubyメソッドが関係しています。

github.com/kmuto/review - lib/review/htmlbuilder.rb#L306-L320

lib/review/htmlbuilder.rb#L306-L320

    def ul_begin
      puts '<ul>'
    end

    def ul_item_begin(lines)
      print "<li>#{lines.join}"
    end

    def ul_item_end
      puts '</li>'
    end

    def ul_end
      puts '</ul>'
    end

ReVIEW::HTMLBuilder クラスのメソッドです。これらのメソッドをオーバーライドして出力を変えましょう。「太字」と「斜体」にしてみます。 review-ext.rb は以下のようになります。

review-ext.rb

# encoding: utf-8

class ReVIEW::HTMLBuilder
  def ul_item_begin(lines)
    print "<li><b><i>#{lines.join}</i></b>"
  end
end

ReVIEW::HTMLBuilder#ul_item_begin メソッドをオーバーライドし、<li>の中身を <b><i> で囲みました。htmlをbuildし、PDF出力して確認すると以下のようになっています。

f:id:at_grandpa:20180819080946p:plain:w500
太字と斜体の適用

articles/book.html は以下のようになっています。

<ul>
<li><b><i>リスト1</i></b></li>
<li><b><i>リスト2</i></b></li>
<li><b><i>リスト3</i></b></li>
</ul>

<li>の要素が <b><i> で囲まれています。

このように Re:VIEWrubyメソッドをオーバーライドしてしまえば、Re:VIEW記法からのhtml出力をある程度自由に扱えます。好きなhtmlを出力させることが可能です。ただ、「どのRe:VIEW記法がどのrubyのメソッドか」は自力で探すしかないようです。自分の場合は、出力されたhtmlの特徴的な文字列で、Re:VIEWリポジトリhtmlbuilder.rb に検索をかけています。

また、 review-ext.rb は任意のRe:VIEW記法(命令)を定義できます。PDF出力のスクリーンショットにあった「会話形式の吹き出し」は、下記のような命令を独自に定義して使っています。

talk.re

//talka[{人物Aの画像ID}]{
人物Aの発言
//}

//talkb[{人物Bの画像ID}]{
人物Bの発言
//}

この命令を処理するrubyメソッドを定義して、そこからhtmlを出力し、対応するCSSを記述する、という流れです。1回書いてしまえばあとは楽です。

このように、 review-ext.rb を使えばある程度デザインの幅は広がります。ぜひ試してみてください。

 

完成したPDFは印刷所で印刷可能か(確認完了)

できあがったPDFはフォントが埋め込まれていません。なので、Macの場合は プレビュー.app を用いて埋め込みます。

  • Re:VIEW+CSS組版 でできあがったPDFをプレビュー.appで開く
  • ファイル → PDFとして書き出す でPDFとして保存します
  • 新たに保存されたPDFはフォントが埋め込まれています

この作業は技術書典4でも行いました。問題なく印刷できたのでこれで良いと思います。

【追記 2018/08/20 12:58】

@kmuto さんから、フォントの埋め込みについてご指摘いただきました。

このあたりの知識はなかったので助かりました。ご指摘ありがとうございました。

【追記終わり】

 

次に「CSS+Vivliostyleで作成されたPDFが正しく印刷できるか」が気になりました。おそらく大丈夫だと思うのですが、念のため印刷会社さんに聞いています。聞いたのは ねこのしっぽ さんです。結果がわかり次第、ここに追記しようと思います。(現在返信待ち)

※ 最終的な責任は自己責任でお願いします

 

【追記 2018/09/05 7:49】

以下の手順で行えば、ねこのしっぽさんで問題なく印刷できることが確認できました。

  1. make css/pdf でpdf作成(デフォルトA5)
  2. プレビュー.app で開き、「ファイル」→「PDFで書き出す」を選択
  3. デフォルトではA4での書き出しになっているので、下部の「詳細を表示」から「用紙サイズ」を「A5」にする
  4. 書き出したpdfは「A5」かつ「フォントのアウトライン化」ができている
    • (印刷用はコレ。PDF用はリンク遷移できるようにするため、アウトライン化はしない)

【追記終わり】

 

まとめ

Re:VIEW+CSS組版リポジトリに対して、以下のことを行いました。

  • make setup だけで環境構築できるようにした
  • make css/pdf でPDF出力できるようにした
  • make css/browser でブラウザ確認できるようにした
  • circleciでPDFを生成できるようにした
  • CSSの編集方法やhtmlの編集方法をみつけた

Re:VIEW+CSS組版 をやってみたい方は、ぜひ使ってみてください。