2018-10-25

湊川さんに言及されたのでCSS組版について書きます。

しがないラジオでもちこさん(@mochikoAsTech)と湊川さん(@llminatoll)がゲストで技術書典5についてお話ししてました。
前回のエントリーの通り私は湊川さんと本を作ったのですが、その時の組版についてしがないラジオの中でも言及されていたので、ちょっと解説記事を書こうと思います。

まず、基本的にはVivliostyleによる組版でVivliostyleまかせです。私はあんまり何もしてない感じなので簡単ですよ。
Vivliostyleについては、vvakameさんの「CSS組版やっていき!」やpentapodさんの「CSSではじめる同人誌制作 増訂版」が詳しいです。 そちらを参考にしてください。

vvakameさんの本はRe:VIEWからCSS組版をするものでした。 私も前作2作はRe:VIEWで書いていたので、Re:VIEWから書こうと思いました。

ところが、私が書きたかった内容が黒猫先生としんらちゃんとの対話形式で話を進めていくということでした。
そのため吹き出しのような表現ができるということが要件になります。CSS組版を選んだのもそのためです。

一方、VivliostyleはHTML+CSSで自由に組版できます。Re:VIEWを使わなくてもHTML+CSSが作れればよいわけです。逆にRe:VIEWを経由すると制約が多くなって、ちょっと自由にレイアウトするのが難しかったりします。
私はRe:VIEWで本を書くときでも、最初はMarkdownで原稿を書いてからRe:VIEW形式に変換しているのですが、 それならばRe:VIEWを経由しなくてもMarkdownから直接HTMLを生成できればよいのではないかと考えたわけです。

MarkdownからHTMLを生成するのはredcarpetを使えばお手のものです。
私はGibierというプレゼンテーションツールを作っているのですが、そこでもredcarpetで変換しています。 (GibierではRubyのコードを生成しています。)

redcarpetからHTMLを生成するのは簡単です。

require "redcarpet"

markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
markdown.render File.read("content.md")

のようにすればHTMLが生成されます。(お好きな名前でファイルに保存してください。)

そのままVivliostyleに読ませるだけでも立派に技術書になります。
これに前述のCSS組版の本などを参考にCSSを書けば見栄えもよくなってテンションがあがります。

さて、肝心の会話のシーンですが、私は以下のような会話の文章を書いたら吹き出し付きのスタイルが当るようにredcarpetのRenderクラスをカスタマイズします。

[begin dialog]

黒猫先生「わしは黒猫じゃ名前などない。」

しんらちゃん「名前がない!?それじゃあ呼ぶのに不便だから、黒猫の先生ってことで黒猫先生と呼ばせてね。」

黒猫先生「ふむ。物事に名前をつけることは重要なことじゃ、そう呼ぶとよい。かのまつもとゆきひろも『名前重要』とよく言っておる。」

...中略...

黒猫先生「たしかに自然言語処理や機械学習のための道具だてはPythonのほうが多く揃ってきている。しかし、Pythonではそういった道具をうまく使いこなすことが重要になるが、Rubyではそれを作ることから始める必要がある。ゼロから学ぶにはかえって良いと思うぞ。」

しんらちゃん「うーん。なんか納得できないなぁ…」

[end dialog]

[begin dialog][end dialog]は会話のはじまりとおわりを表すマークです。黒猫先生「...」とかしんらちゃん「...」というのは正規表現で引っ掛けます。

上の文章は以下のようなhtmlになります。

<div class='dialog'>
<div class="speech kuroneko">
<div class="icon"></div>
<div class="baloon">
<p>わしは黒猫じゃ名前などない。</p>
</div>
</div>
<div class="speech shinra">
<div class="icon"></div>
<div class="baloon">
<p>名前がない!?それじゃあ呼ぶのに不便だから、黒猫の先生ってことで黒猫先生と呼ばせてね。</p>
</div>
</div>
<div class="speech kuroneko">
<div class="icon"></div>
<div class="baloon">
<p>ふむ。物事に名前をつけることは重要なことじゃ、そう呼ぶとよい。かのまつもとゆきひろも『名前重要』とよく言っておる。</p>
</div>
</div>

...中略...

<div class="speech kuroneko">
<div class="icon"></div>
<div class="baloon">
<p>たしかに自然言語処理や機械学習のための道具だてはPythonのほうが多く揃ってきている。しかし、Pythonではそういった道具をうまく使いこなすことが重要になるが、Rubyではそれを作ることから始める必要がある。ゼロから学ぶにはかえって良いと思うぞ。</p>
</div>
</div>
<div class="speech shinra">
<div class="icon"></div>
<div class="baloon">
<p>うーん。なんか納得できないなぁ…</p>
</div>
</div>
</div>

このソースコードはgistに公開しています。https://gist.github.com/youchan/52569644ff4ce3fef48cccee96f16c33

実際に使ったソースコードは本当にこれだけです。とてもシンプルでしょ?
このようにRe:VIEWなどのつくりこまれたシステムを使わなくてもそれなりのものが作れます。
むしろこういう形のほうが自分で自由にタグを設定したりできるので自由度が高いです。 本に合わせて都度コードを書いてもさほど手間ではないので、私は結構この方法がとても気にいっています。

それとちょっとポジショントークをしてしまうとRubyはやっぱりこういうときにサクサクとコードを書いてそれなりのものが作れてよいです。こういうちょっとしたツールを作っているときがRuby最高だなって思います。
Ruby on RailsだけではなくこういうところでRubyの良さをもっと知ってもらえたらいいなって思っています。

そういうわけで、しながいラジオのなかでも湊川さんが紹介されていましたが、Rubyの入門書を書こうと思っています。
こういう実用的なプログラミングではないですがトイプログラミングでRubyの楽しさが伝わるといいなと思っています。
乞うご期待ください!