📝

Vivliostyle: 技術同人誌をつくって入稿用PDFをビルドする(後編)

18 min read

この記事は Markdown Advent Calendar 2020 の25日目です。

この記事は4つの記事で構成されています。(注意:中編が膨れ上がってしまったので、2つに分割しています)

技術同人誌をつくる流れ

本稿では「Markdown原稿をもとにした技術同人誌の制作」を想定します。Create Book(Vivliostyle)によるCSS組版をベースに、本の構成および同人向け印刷所のためのPDF生成までを解説します。

企画から入稿・イベント当日までの全体の流れは『技術同人誌を書こう! アウトプットのススメ』に全部書いてあります。はじめて技術同人誌を書く方は、ぜひ1冊買いましょう。

https://nextpublishing.jp/book/9625.html

表紙やプロジェクトマネジメント・イベント当日などは本稿で扱いません。

本稿では特に本文PDFをつくっていく流れを紹介します。次の流れは例なので、実際の順番は前後します。

  1. vivliostyle.config.js をある程度入力しておく
    • メタ情報(タイトル・著者名)、設定(本のサイズなど)を入力する
    • ラフに章立て(entry)を決める
  2. 扉と奥付用のページを作成する
  3. 入稿用のPDF設定をする
  4. 執筆を進める
    • 複数の章を立てるなら、この時点で manuscript.md は削除・リネームしてもよい
    • 1で定義した章立てにしたがい、どんどん書いていく
    • 章立てが気に入らない場合は、1に戻って章立てを変えて、新しい原稿ファイル(.md)をつくる
    • 適宜、PDFに出力して確認する
  5. 推敲する
    • 極力、紙に印刷して赤入れする(もしくはiPad & Apple Pencilなど紙に近いデバイスを使う)
  6. ページ数調整(頑張ってページを埋める or 空白ページを無理矢理つくる)
    • 通常、同人向け印刷所に入稿する際にはページ数を「4の倍数(例:32ページ、48ページなど)」にする必要がある
  7. 奥付を仕上げる
  8. 入稿用PDFに仕上げる
    • PDFを印刷所入稿に適した形式へ変換する
  9. 入稿する

以下、順番は前後しますが、Vivliostyleで本を作るためのTipsを紹介します。

サンプルプロジェクト

今回つくる本のサンプルプロジェクトをGitHubに上げています。

底本は青空文庫から転載・改変しました。

プロジェクトの新規作成

今回は次のようにプロジェクトを作成します。

  • descriptionとauthor emailは省略したいのでEnterキーのみ
    • author emailがデフォルトで記入される場合は、あとで削除します
  • ライセンスはCC0(パブリックドメインと同等)
$ npm create book sample-book-kagakunofushigi
? description 【Enterキーのみ】
? author name アンリイ・ファブル(大杉栄、伊藤野枝訳)
? author email 【Enterキーのみ】
? license CC0-1.0
? choose theme @vivliostyle/theme-techbook - Techbook (技術同人誌) theme

メタ情報・章立て・設定

まずはじめに、メタ情報・章立て・設定を vivliostyle.config.js に入力していきます。実際に本を書き始める際は、仮のものでも構いません。

メタ情報

メタ情報としてタイトル(title)と著者名(author)を設定します。npm create bookの時点でメタ情報がすでに記入されていますが、書き換えます。

titleは半角英数字(+半角記号)である必要があります。日本語名だと後述のpress-readyで失敗するためです。

  • authorに自分のEメールアドレスが入っている場合もありますが、この時点で削除しておきます(必要な場合は残しておいてください)
  • 行中の // 以降はコメントなので削除して構いません
vivliostyle.config.js
module.exports = {
-  title: 'sample-book-kagakunofushigi', // populated into `manifest.json`, default to `title` of the first entry or `name` in `package.json`.
-  author: 'アンリイ・ファブル(大杉栄、伊藤野枝訳) <自分のEメールアドレス>', // default to `author` in `package.json` or undefined.
+  title: 'STORY-BOOK OF SCIENCE', 
+  author: 'アンリイ・ファブル(大杉栄、伊藤野枝訳)',
  (略)
}

コードの書き換え例はdiff記法で示します。行頭の-は削除、+は追加を意味します。

章立て

章立て(ファイルの読み込み順)は entry に書いていきます。

今回は原稿のMarkdownファイル(VFM)が、01.mdから09.mdまであるとします(第NN章が NN.md に対応します)。またフォルダは manuscripts に置くとします(あとの設定で指定します)。

ついでに、index.md(扉)とcolophon.md(奥付)も設定します。これらはあとで説明します。

つまりディレクトリ構成は次のようになります。

.
├── manuscripts
│   ├── index.md ※ あとで追加(扉)
│   ├── 01.md
│   ├── 02.md
│   ├── 03.md
│   ├── 04.md
│   ├── 05.md
│   ├── 06.md
│   ├── 07.md
│   ├── 08.md
│   ├── 09.md
│   └── colophon.md ※ あとで追加(奥付)
├── (略)
├── package.json
└── vivliostyle.config.js

vivliostyle.config.js を次のように変更します。

vivliostyle.config.js
module.exports = {
  (略)
  entry: [
-    'manuscript.md', // `title` is automatically guessed from the file (frontmatter > first heading).
+    'index.md',
+    '01.md',
+    '02.md',
+    '03.md',
+    '04.md',
+    '05.md',
+    '06.md',
+    '07.md',
+    '08.md',
+    '09.md',
+    'colophon.md',
  (略)
  ], // `entry` can be `string` or `object` if there's only single markdown file.
  (略)
}

実際には、執筆状況に応じてentryの章立ても変わっていくでしょう。

設定

次のように設定を変えます(以下は例です)。

  • 紙のサイズはB5(JIS-B5
    • 注意:「B5サイズ」にはJIS規格とISO規格があるため、明示的に書く
  • 原稿を置くフォルダは manuscripts
vivliostyle.config.js
module.exports = {
  title: '科学の不思議', 
  author: 'アンリイ・ファブル(大杉栄、伊藤野枝訳)', 
  // language: 'ja', // default to `en`.
-  // size: 'A4', // paper size.
+  size: 'JIS-B5', // paper size.
  theme: '@vivliostyle/theme-techbook', // .css or local dir or npm package. default to undefined.
-  // entryContext: './manuscripts', // default to '.' (relative to `vivliostyle.config.js`).
+  entryContext: './manuscripts', // default to '.' (relative to `vivliostyle.config.js`).
  entry: [
    (略)
  ], // `entry` can be `string` or `object` if there's only single markdown file.
  // toc: true, // whether generate and include toc.html or not (does not affect manifest.json), default to `true`. if `string` given, use it as a custom toc.html.
  // cover: './cover.png', // cover image. default to undefined.
  // workDir: './dist', // default to `.vivliostyle`.
}

表紙を開いて最初のページを扉と呼びます。このページはタイトル・著者名(+サークル名など)を書いておきたいところです。

扉の内容を manuscripts/index.md に書きます[1]

index.md
# 科学の不思議

アンリイ・ファブル(大杉栄、伊藤野枝訳)

![](./milky-way.jpg){width=400}

PDFを生成すると(後述)、次のような扉のページができます[2]

扉

本来は同様の手順で目次も作成できるはずですが、今回の検証ではうまく生成できませんでした。詳細は記事の後半をご覧ください。

奥付ページをつくる

奥付は出版責任を明確にする上で、非常に重要です。

  • 必須:タイトル、著者名、発行者(サークル名)、発行年月日、連絡先、印刷所名
  • 任意:注意事項やSNS・WebのURL、読者へのメッセージなど

奥付の内容を manuscripts/colophon.md に書いておきます。今回はシンプルなレイアウトにしていますが、HTML/CSSでテーブルをつくってもよいでしょう。

colophon.md
<section id="colophon" role="doc-colophon">

## 科学の不思議

20xx年x月x日 初版発行

- 発行 某サークル
- 著者 アンリイ・ファブル
- 翻訳 大杉栄、伊藤野枝
- 編集 sky-y
- 連絡先 foo@example.com
- 印刷 サンプル印刷

底本は青空文庫から転載・改変しました。

- ファーブル ジャン・アンリ『科学の不思議』(大杉 栄、伊藤 野枝 訳)

© 某サークル, 20xx

</section>

奥付

ページ数の調整

同人向け印刷所では「ページ数は4の倍数」といったページ数の縛りが通常あります。もしこの基準を満たしていなければ、コラムなどを書いてページ数を増やすか、空白ページを無理矢理つくる(改ページ)などの対策が必要です。

今回のサンプルプロジェクトでは、そのままビルドすると全部で30ページになります。32ページ(4の倍数)へ合わせるために、2ページ分の空白ページを無理矢理つくってみます。

できればコラムを書いたり画像を入れたりして、頑張ってコンテンツを増やしましょう。

テーマをコピーしてCSSを追記する

改ページを行うためにはCSSを書く必要があります。そのために今回使っているテーマ @vivliostyle/theme-techbook をコピーしてカスタマイズしていきます(一般にCSSをカスタマイズする際の基本手順となります)。

次のように @vivliostyle/theme-techbook のディレクトリをコピーします。

$ cp -R node_modules/@vivliostyle/theme-techbook/ my-theme/

vivliostyle.config.js を次のように書き換えます。

vivliostyle.config.js
module.exports = {
  (略)
-  theme: '@vivliostyle/theme-techbook', // .css or local dir or npm package. default to undefined.
+  theme: 'my-theme', 
  (略)
}

my-theme/theme.css の末尾で次のように追記します[3]

theme.css
nav#toc li a::after,
nav[role='doc-toc'] li a::after {
  text-align: right;
  content: target-counter(attr(href), page);
  align-self: flex-end;
  flex: none;
  order: 2;
}

/*# sourceMappingURL=theme.css.map */

+ /* hrで改ページ */
+ hr.page-wrap {
+     break-before: page;
+     visibility: hidden;
+     margin: 0px;
+     padding: 0px;
+     height: 1px;
+ }

改ページをする

上記の設定により、Markdownファイルに <hr class="page-wrap" /> と書けば改ページできるようになりました。

09.md(奥付の手前にある最後のMarkdownファイル)に、このコードを書いてみます。

09.md
『三千年だよ。そしてもし私が外国の或る木の事をお前達に話さうものならまだもつと古い昔まで溯つて行かなくてはならないんだよ。』
+ 
+ <hr class="page-wrap" />
+ 
+ <hr class="page-wrap" />

空白ページを2ページ分を追加できました。奥付でちょうど32ページとなります。

空白ページを2ページ分追加

入稿用PDFの設定をする

同人向け印刷所に入稿するための要件はいくつかあります。日光企画さんを例にリストアップしてみます。

本文PDFの要件(日光企画):

  • カラー:CMYK or グレースケール
    • グレースケールの場合、解像度は600dpi推奨
  • フォントを埋め込む
  • ノンブル(ページ番号)は全ページに必要 → Done
    • ノンブル始まりは奇数から(本文は「1」から、もしくは「3」から)
  • 仕上がりサイズ+天地左右各3mmの塗り足しのサイズが必要 → Done(たぶん)
    • トンボはなくてもよい
    • 今回は文章中心のテーマで余白が十分あるので、仕上がりサイズちょうどでいける?(要確認)

実際にはもっと細かい要件がありますし、別途表紙にも要件があります。本文PDFに関しては、とりあえず上記を満たしていれば無難な原稿になるでしょう。不備があった場合(かつ締切に余裕がある場合)は、印刷所の方が指示を出してくれます。

サークル主目線でもう少し細かい話は次の記事にあります。

【技術書典5 入稿編】『神対応!』はじめての印刷所は日光企画で決まり!?涙ありトラブルありの入稿日 - VTRyo Blog

本稿の記載事項は、安全な入稿を保証するものではありません。入稿の際は各自で要件をよく読んだ上で、各自の責任で入稿してください。

press-readyでできること

press-readyができることは次のとおりです。

  • カラーをCMYKもしくはグレースケールに変換する
    • カラープロファイルは「Japan Color 2001 Coated」という無難なものが使われる
  • フォントを埋め込む

この2つは従来において、CSS組版をオープンソースソフトウェアで行う上での障壁でした。press-readyの登場により、(少なくとも同人出版のレベルでは)大きな問題はなく入稿できるようになったと思われます。

注意としては、一般にカラーを「RGB→CMYK」と変換する際は、カラー印刷であっても色味が変わります。本文の色味にこだわる場合は、IllustratorなどでCMYKカラーの画像をつくるか、最初から本文をInDesignなどのDTPソフトでつくることを推奨します。

また繰り返しになりますが、press-readyを通したからといって安全な入稿が必ず行えるとは限りません。「マシになる」ぐらいに思ってください。

press-readyでビルドする設定(シンプル編)

Create Bookでは、内部でvivliostyle/vivliostyle-cliを呼んでいます。実際にはvivliostyleコマンドが呼びだされます。

npm run buildというコマンドは package.json の"scripts"に定義されています。

package.json
{
  "name": "sample-book-kagakunofushigi",
  "description": "sample-book-kagakunofushigi",
  "version": "0.0.0",
  "author": "アンリイ・ファブル(大杉栄、伊藤野枝訳) < >",
  "scripts": {
    "build": "vivliostyle build",
    "preview": "vivliostyle preview"
  },
  "dependencies": {
    "@vivliostyle/cli": "next",
    "@vivliostyle/theme-techbook": "^0.2.0"
  },
  "license": "CC0-1.0",
  "private": true
}

npm runを使わずに手動でビルドを実行するにはには、次を実行します[4]

npx vivliostyle build

press-readyを有効にした状態でビルドするには、次のように実行します。

npx vivliostyle build --press-ready

このコマンドをnpm runで実行できたらちょっとだけ楽ですね。

次のように package.json を編集します。

package.json
{
  "name": "sample-book",
  "description": "sample-book",
  "version": "0.0.0",
  "author": "  < >",
  "scripts": {
    "build": "vivliostyle build",
+    "press-ready": "vivliostyle build --press-ready",
    "preview": "vivliostyle preview"
  },
  "dependencies": {
    "@vivliostyle/cli": "next",
    "@vivliostyle/theme-techbook": "^0.2.0"
  },
  "license": "CC-BY-3.0",
  "private": true
}

これでnpm runを通してpress-readyを実行できるようになります。

$ npm run press-ready

ただし、この状態ではCMYKカラーのままです。入稿で大きなトラブルにならないとは思いますが、印刷所の申込時に本文白黒のプランを選んだ場合は印刷所の方から確認が入るでしょう。

press-readyの罠:入力ファイル名を日本語にしてはいけない

現状(2020-12-24時点)でのpress-readyには、大きな罠が1つあります。press-readyの入力ファイル名は半角英数字(+半角記号)でなければなりません。

たとえば「科学の不思議」といった日本語のタイトルをvivliostyle.config.jsのtitleに書くと、npm run buildで生成されるPDF名も日本語名になります(科学の不思議.pdf)。titleは柱とも連動します。

この科学の不思議.pdfをpress-readyに入力すると、エラーになります。しかしPDFは(真っ白な状態で)生成されるため、このまま入稿してしまう可能性もあります。

今回は泣く泣くですが、vivliostyle.config.jsのtitleを半角英数字(+半角記号)にします。今回は vivliostyle.config.js を次のように半角英数字(+半角記号)で設定しています。

vivliostyle.config.js
module.exports = {
  title: 'STORY-BOOK OF SCIENCE', 
  (略)

Issueとして投げた[5]ので、いずれ修正されることを祈ります。

press-ready Error when Title is non-ASCII on macOS · Issue #90 · vivliostyle/vivliostyle-cli

press-readyでビルドする設定(カスタマイズ編)

vivliostyle build --press-readyでは、press-readyが持っているオプションを使えません。特に

  • --gray-scale: グレースケール化

というオプションが使えず惜しいです。

単品で--gray-scale付きのpress-readyを実行するには次のコマンドを使います(input.pdfpress-ready.pdfはそれぞれ入力ファイル・出力ファイルの例です)。

npx press-ready build -i input.pdf -o press-ready.pdf --gray-scale
  • -i: 入力ファイル名(ビルド後のPDF)
  • -o: press-ready適用後の出力ファイル名

npm run buildから生成されるファイルはSTORY-BOOK OF SCIENCE.pdfですが、今回は半角スペースが入っているので次のように読み替える必要があります。

  • コマンドライン上:STORY-BOOK\ OF\ SCIENCE.pdf
  • package.json上:STORY-BOOK\\ OF\\ SCIENCE.pdf

npm run press-readyで実行したい場合は、次のように仕込んでおきます(press-readyの出力を press-ready.pdf とします)。

package.json
{
  "name": "sample-book",
  "description": "sample-book",
  "version": "0.0.0",
  "author": "  < >",
  "scripts": {
    "build": "vivliostyle build",
+    "press-ready": "vivliostyle build && press-ready build -i STORY-BOOK\\ OF\\ SCIENCE.pdf -o press-ready.pdf --gray-scale",
    "preview": "vivliostyle preview"
  },
  "dependencies": {
    "@vivliostyle/cli": "next",
    "@vivliostyle/theme-techbook": "^0.2.0"
  },
  "license": "CC-BY-3.0",
  "private": true
}

これで、press-ready.pdfが無事に「グレースケール」「フォント埋め込み」の状態で生成されました。少なくとも扉の画像はグレースケールになったことがわかります。

扉の画像:グレースケール

本当に正しく変換されたかを確かめるために、Adobe Acrobat DCのプリフライト機能で解析してみます。「PDF/X-1a (Japan Color 2001 Coated) に変換」というプロファイルを使います。

Adobe Acrobat DCのプロファイル

press-readyにかける前のファイル(STORY-BOOK OF SCIENCE.pdf)の解析は次のとおりになりました。

press-ready前のプリフライト

press-readyで変換したファイル(press-ready.pdf)は次のとおりになりました。

press-ready後のプリフライト

無事に「問題なし」となりました!

入稿する

あとは表紙を頑張ってつくりましょう。 表紙と本文の両方が揃えば、実際に入稿します。上記に書いていない想定外のトラブルが起こりえるので、入稿は余裕を持って早めに行いましょう(なかなか難しいですが……)。

補足:目次に関して(2020-12-24時点)

筆者の調査不足により、本来Vivliostyleで実現できるはずの目次をうまくつくれませんでした。問題が解決し次第、追記します。

Create Book(Vivliostyle)には目次をつくる機能があります。

方法は次のとおり2つあります。

  • (a) vivliostyle.config.js で toc: true を指定する
    • メリット:自動的に目次が生成される
    • デメリット
      • 公式チュートリアルに載っていない
      • 見た目がよくない
      • 扉ページを作成できない
  • (b) vivliostyle.config.js の entry にて、ファイル先頭に次のような index.md をつくる
    • 公式チュートリアル: 目次の追加
    • メリット
      • テーマのデフォルトCSSでも綺麗に表示される(はず)
      • 扉ページをつくれる
    • デメリット
      • 手動で目次をつくる必要がある

(a)の方法は「できるけどイマイチ」という状態です。(筆者がカスタマイズの方法を知らないだけかもしれないので、ご存じの方は教えていただければ幸いです)

目次:(a)の方法

(b)の方法では、次のように index.md をつくり、vivliostyle.config.js の entry に追記します。

index.md
# 科学の不思議

<nav id="toc" role="doc-toc">

## 目次

- [一 六人](./01.md)
- [二 お伽話と本当のお話](./02.md)
- [三 蟻の都会](./03.md)
- [四 牝牛](./04.md)
- [五 牛小舎](./05.md)
- [六 悧巧な坊さん](./06.md)
- [七 無数の家族](./07.md)
- [八 古い梨の木](./08.md)
- [九 樹木の齢](./09.md)

</nav>
vivliostyle.config.js
module.exports = {
  (略)
  entry: [
    'index.md',
    '01.md',
    '02.md',
    '03.md',
    '04.md',
    '05.md',
    '06.md',
    '07.md',
    '08.md',
    '09.md',
  ], // `entry` can be `string` or `object` if there's only single markdown file.
  // toc: true, // この行はコメントアウトする
}

しかし今回の検証において、npm run buildを実行すると最後の index.md のビルドが無限ループに入ってしまいます。

(b)の方法:無限ループ

詳細を調べると、内部でエラーになっていたようです。その詳細はIssueに書いたので、分かる方はヘルプをお願いします🙇‍♂️

Infinite Loop on TOC Generation by index.md · Issue #14 · vivliostyle/create-book

おわりに

今回は「Markdown原稿から技術同人誌をつくる」ことを前提として、本文PDFを構成して入稿用に仕上げるまでの手順を紹介しました。

実際に入稿までの手順やってみると、それなりに大変です。筆者も想像していなかった落とし穴がいくつか見つかりました。できれば執筆の初期に、入稿用PDFを生成する練習をしておくのがベターでしょう。またVivliostyleエコシステムは発展途上のため、マインドとしては「トラブルを楽しめる余裕をもつ」ぐらいがよいのかもしれません。

HTML/CSSおよびJavaScriptに自信のある方は、迷わずCSS組版(Vivliostyle)の道に進むとよいと思います。そうではなく「ただ本を書くことに集中したい(それ以外のコストは払いたくない)」という場合には、いくつかの仕様を諦める必要もあるでしょう。

「Markdownで本を作る」他の選択肢としては、次のようなものがあります。

他にもMarkdownにこだわらなければ、次の選択肢もあります。

  • LaTeX本体(pLaTeX、LuaLaTeX)
  • Word、LibreOfficeなどのワードプロセッサ
  • InDesign

どの手段も一長一短あり、何かしらのコストや印刷・入稿に関する最低限の知識も要求されます。

その中でVivliostyleのエコシステムは、これからの「伸びしろ」があるのではないでしょうか。その「伸びしろ」に掛けるという意味で、「Markdownで書いてCreate BookでPDF生成」はこれからベターな選択肢になっていくと筆者は信じています。

参考

脚注
  1. HTML形式で書く場合は index.html でも構いません。 ↩︎

  2. 柱にこのページの章(h1)が残っています。本来なら消したいのですが、私がカスタマイズをサボっています。 ↩︎

  3. 本来なら「scssファイルに追記してビルド」という手順が正規ですが、急場しのぎのためCSSファイルに直接書きます。 ↩︎

  4. npxを使うと、次の順でパッケージを探してスクリプトを実行します。(1) ローカルの node_modules/.bin/ 以下でスクリプトを探して見つかれば実行する、(2) 見つからなければNPMリポジトリを検索してパッケージを実行する。 ↩︎

  5. press-readyのIssueでもありますが、悩んだ末にvivliostyle/vivliostyle-cliのIssueとして報告しました。npx vivliostyle build --press-readyで問題が起こるのと、類似Issueがあったためです。 ↩︎

Discussion

ログインするとコメントできます