技術本を作る技術

はじめに

前回の記事で、技術書典5に出典するためにAlexaの本を書いたことを書きました。

Alexaの本を書いて技術書典5で販売するまで

今回は実際にはどうやって本を作ったのか、技術的な観点で説明したいと思います。

どういった流れで本を書くか

今回は共著で本を書きました。メンバーは全員エンジニアです。その為エンジニアライクな方法を選択しました。

Markdown形式で執筆 => RE:View形式に変換 => PDFに変換

印刷所への納品方法はPDFで良いということだったのでこの方式にしました。 この後に説明するコードは全て次のレポジトリに置いてあるので参考にしてください。

tochi/make-technical-book-sample: 技術本を作る技術のサンプルコード

文体を揃える

共著で書くと、人によっては文体が異なってしまいます。 「です・ます調」で書くように事前にルールを決めて、他の人が内容を確認する方法も可能です。 しかし、毎回書くたびに文体チェックするのは面倒なので自動化しました。

lintを使ってある程度の統一感を出せるようにしました。 導入したlintは次の通りです。

# .textlintrc
{
  "rules": {
    "preset-japanese": true,
    "spellcheck-tech-word": true,
    "no-mix-dearu-desumasu":  {
      "preferInHeader": "ですます",
      "preferInBody": "ですます",
      "preferInList": "ですます",
      "strict": true
    },
    "preset-japanese": {
      "sentence-length": {
        "max": 100
      },
      "no-doubled-joshi": {
        "separatorChars": ["。","?","!","?","!","・"]
      },
    },
  }
}

後はnpm run lintを実行すると文体が検証されます。 例えば次の様な「である」と「です」が混在している文章がありました。

AlexaはAmazonのサービスである。
Google HomeはGoogleのサービスです。

この状態でnpm run lintを実行するとエラーが発生します。

32:18  error  本文: "である"調 と "ですます"調 が混在
=> "である。" がである調
Total:
である  : 1
ですます: 1
preset-japanese/no-mix-dearu-desumasu

✖ 1 problem (1 error, 0 warnings)

また助詞の重複も確認してくれます。(これにはかなり助けられました。)

それはキーボードやマウスを使わずに指だけで直感的な操作が出来ることが大きかったと思う。
32:34  error  一文に二回以上利用されている助詞 "が" がみつかりました。  preset-japanese/no-doubled-joshi
✖ 1 problem (1 error, 0 warnings)

この様に共著で起こりがちな「ですます調」の混在や、日本語としての正しさを検証することができます。 後は、git pushするたびにCircleCIでnpm run lintすれば自動的に文章を検証してくれます。

# .circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: circleci/node:7.10
    working_directory: ~/repo
    steps:
      - checkout
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "package.json" }}
          - v1-dependencies-
      - run: npm install
      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}
      - run: npm run lint

MarkdownからRE:Viewに変換

次にMarkdownで書いた文章をRE:View形式に変換します。RE:Viewについて後述します。 RE:View形式に変換する方法として下記のgemを利用しました。

takahashim/md2review: a converter from Markdown into Re:VIEW, using redcarpet

それではRE:View形式に変換するために準備をします。ファイル構成は次のようにしました。 chaptersフォルダの下にMarkdown形式の文章を保存してRE:View形式に変換後のファイルをreviewsフォルダの下に保存します。

.
├── chapters
│   ├── chapter-1.md
│   └── chapter-2.md
└── reviews

まずはmd2reviewを準備します。Gemfileを準備してbundle installしておきます。

# reviews/Gemfile
source 'https://rubygems.org'

gem 'md2review'

後は、ターミナルでmd2review chapters/chapter-1.md > reviews/chapter-1.reを実行すればRE:View形式に変換されます。 ただし、調べた限りだとmd2reviewには複数ファイルを一括で変換する機能は無さそうだったので自作のRubyコードで一括変換できるようにしました。

# convert.rb
Dir.glob('./chapters/*.md').each do |markdown_file|
  review_file = markdown_file.gsub('./chapters', './reviews').gsub('.md', '.re')
  system("md2review #{markdown_file} > #{review_file}")
end

これで、ターミナルからruby convert.rbを実行すれば一括でRE:View形式に変換されます。

RE:ViewからPDFに変換

RE:Viewとは電子書籍を作成するための「書籍執筆支援システム」です。 RE:ViewはPDFの他にEPUBやHTMLにも変換可能です。

kmuto/review: Re:VIEW is flexible document format/conversion system

今回は印刷所の納品形式であるPDFに変換します。

Gemfileにrakereviewを追加してbundle installします。

   # reviews/Gemfile
   source 'https://rubygems.org'

+ gem 'rake'
+ gem 'review'
   gem 'md2review'

次にターミナルからreview-init reviews -fでRE:Viewの初期ファイルを作成します。 reviews/catelog.ymlに目次を追加すれば最小限の準備は完了です。

# reviews/catelog.yml
PREDEF:
CHAPS:
  - chapter-1.re
  - chapter-2.re
APPENDIX:
POSTDEF:

ただし、PDF変換を行うにはLaTeXが必要です。MacでのLaTeXの導入は次のブログを参考に進めました。

MacTeX 2018 のインストール&日本語環境構築法 - TeX Alchemist Online

最後にreviewsの下でrake pdfを実行すればPDFが作成されます。

markdown to pdf

RE:Viewにはその他に本のレイアウトやデザインの調整、印刷サイズの指定など多くの機能があります。 詳しくは公式サイトや次の「はじめてのReVIEW」を参考にしてください。 「はじめてのReVIEW」は非常に丁寧に書かれているのでオススメです。

TechBooster/FirstStepReVIEW: 「はじめてのReVIEW」

画像を挿入する

これでMarkdownからPDFを作成することが出来るようになりました。 ただ、本に画像や図を差し込みたい場合は多々あると思います。 そんな時には少しだけルールを意識する必要があります。

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

RE:Viewは画像ファイルの探索にルールがあります。例えばchapter-1.mdに次のように画像を挿入します。

# chapter-1.md
![aguuu.com](images/chapter-1/aguuu-com.png)

これをchapter-1.reに変換すると、images/chapter-1/がなくなり画像の階層はフラットになってしまいます。

//image[aguuu-com][aguuu.com]{
//}

このため、画像を配置する場合にはRE:Viewの画像の探索ルールに従う必要があります。 今回の場合だとchapter-1.mdに差し込みたいaguuu-com.pngの階層は次のようになります。

.
├── chapter-1.md
└── images
    └── chapter-1
        └── aguuu-com.png

後は、reviewsフォルダの下にchapters/imagesへのシンボリックリンクを貼ったimagesフォルダを作成すれば完成です。

$ cd reviews/
$ ln -s ../chapters/images images

画像を挿入

まとめ

今回はできませんでしたが、Markdown => RE:View => PDFへの変換をCIで自動化して常に最新のPDFを自動作成することもできると思います。 ぜひ皆さんも自分が持っている知識を本にしてみてください!

最後に告知。今回の仕組みを使って作った技術本である「俺たちの知りたかったAlexaの話」を技術書典5で販売します。 Alexaスキル開発をより本格的に実践的に行うための技術書になっているので是非お近くの方は遊びにきて手にとってみてください。

サークル詳細 \| ITO \| 技術書典

当日は現地に行きたいけど「俺たちの知りたかったAlexaの話」が気になる方には朗報です。 実はこの本はオープンソースとして公開する予定です。(※ Markdown形式のみ)

book-of-alexa/alexa-basic

後日、PDF版を電子書籍として販売することも検討しています。

Let’s enjoy writing!