📚

Pandocでマークダウンから綺麗な電子書籍(EPUB)を作成する為のTips 5選

2023/11/16に公開

こんにちは、テラーノベルでサーバーサイドを担当している@manikaです。

今回はOSSのドキュメント変換ツールであるPandocを触る機会があったので、検証等を行った際の備忘も兼ねてマークダウンを電子書籍化するTipsを記事としました。

先に結論

良い感じに仕上がりました。

ブックアプリ Kindle Previewer 3

出典[1]

既にPandocを使った基本的な変換方法とかは知ってるよ!という方はこちらに飛んでください。

Pandocとは

様々な形式のファイルフォーマットのドキュメントを別のフォーマットに変換してくれるOSSツールです。今回使用するMarkdownやEPUBをはじめ、HTML、LaTex、PDF、Word(docx)、OpenOffice(odt)、CSV等、対応フォーマットは多様です。

https://pandoc.org/

開発環境

  • MacBook Pro(M1)
  • pandoc/core:latest(Docker image) pandoc 3.1.1
  • Visual Studio Code

作成した電子書籍ファイルの表示確認にはKindle Previewer3とMacのブックアプリで確認を行っています。

今回使用するサンプル文章では青空文庫より次の作品を使用させていただきました。

  1. 夏目漱石「私の個人主義
  2. 芥川龍之介「アグニの神

Pandocのインストール

Pandocは公式のDockerイメージを用意してくれている為、今回はそちらの pandoc/core を使用しました。LaTexで使用する際は pandoc/latex を使用するようです。

また、環境毎にインストーラーも用意されているのでそちらを使用するでも良いでしょう。
https://pandoc.org/installing.html

とりあえず電子書籍を作ってみる

マークダウン形式のテキストを準備して

sample.md
# 私の個人主義
### 夏目漱石

いつは多数はたしてそのぼんやり士というのの時が考えるたです。同時に一生に約束らは多分どんな評なでぐらいをなっと出しですには刺戟なっましなて、こうにはとどまらましたないです。

兄弟にさう訳は依然として九月にけっしてですないだ。無論木下さんに尊敬雑木こう講演を黙っな摯実その学校私からくがという今存在ありなけれでならて、そのその間しかあなたかちり西洋にできが、岡田さんののに教師のあなたにもっともご自白と具しから何性質をおろかがしようにもっともご保留がするませないで、もっともう忠告より分りですているなけれものの行けれなです。

ところがもしくはお個人をいう事はそれほど必要と積んたと、その道がはしよたがという社会に畳んがいるうう。その時目標の時その符もこれ末に叱るでかと岡田さんをもったませ、廃墟の晩でというご相違うましないて、風俗のためへ自我が今日などの個人を場合しばならば、わざわざの先刻に移れがそうした一方を何しろ入れないないと利くます事たて、ないませたから当然お自己しますのましなけれです。

それで学校か立派か学問よりしたて、場合上金に聴いからいます所からご周旋の場合を引き摺り込んうでしょ。

事実をもどうしてもあっがあるたならたですので、ほとんどもう出来て忠告も多少高いだろ方な。すなわちお講演としてはならですのたて、連中でも、もしこれか出れのですれれないまし致すれるますたとなるて、叫び声は思うているたまし。

出典[2]

Pandocを実行

docker run --rm --volume "$(pwd):/data" --platform linux/amd64 pandoc/core sample.md -o sample.epub

Macで実行する際に --platform linux/amd64 をつけないとエラーとなった為追加しています。

実行が完了するとsample.epubが作成されていると思いますので、Macであればダブルクリックすればブックアプリで閲覧できます。
こんな感じ

上記のように電子書籍への変換自体は簡単ですが、日本語の小説等の場合は縦書き+右開き(右綴じ)にしたいですよね!(私はしたい)

ということで縦書きのやり方や表紙画像・目次等を追加していく方法や注意点等を記載していきます。

その前に電子書籍ファイルの内部的な構成ですが、実質は本文のxhtml等をまとめたzipファイルであり解凍して中身を確認する事が出来ます。 レイアウトはスタイルシートで構成されており変更したければcssファイルを編集する事でレイアウトを変更する事ができるという事を覚えておきましょう。

unzip sample.epub
Archive:  sample.epub
 extracting: mimetype                
  inflating: META-INF/container.xml  
  inflating: META-INF/com.apple.ibooks.display-options.xml  
  inflating: EPUB/content.opf        
  inflating: EPUB/toc.ncx            
  inflating: EPUB/nav.xhtml          
  inflating: EPUB/text/title_page.xhtml  
  inflating: EPUB/styles/stylesheet1.css  
  inflating: EPUB/text/ch001.xhtml 

電子書籍作成の為のTips 5選

  • 縦書きと右開き
  • 表紙画像の追加
  • 目次の追加
  • 縦中横
  • 段落の字下げ

縦書きと右開き

まずは縦書きからですが縦書きもレイアウトの一種なので前述の通りスタイルシートを使用します。縦書きにするにはwriting-modeプロパティを記述します。

記述例
html {
  -webkit-writing-mode: vertical-rl;
  -epub-writing-mode: vertical-rl;
  writing-mode: vertical-rl;
}

https://developer.mozilla.org/ja/docs/Web/CSS/writing-mode

作成したcssをpandocに指定して実行してみましょう。

docker run --rm --volume "$(pwd):/data" --platform linux/amd64 pandoc/core sample.md -o sample.epub --css=sample.css

EPUBビューワーで開いてみましょう。縦書きになりましたね!

しかしこれではまだ左開きのままになっていますので右開きに変更をします。
変更には Metadata blocks を使用します。
https://pandoc.org/chunkedhtml-demo/11.1-epub-metadata.html

本文ファイルに追記する形でも良いのですが、今回は管理をしやすくする為 metadata.md として別ファイルで作成します。

metadata.md
---
title:
- type: main
  text: 私の個人主義
creator:
- role: author
  text: 夏目漱石
page-progression-direction: rtl
---

page-progression-direction: rtl が右開きの指定になります。rtlltrにすると左開きです。ついでなのでタイトルと著者名の指定も入れてみました。
ここでタイトルを指定することで先ほどの [WARNING] This document format requires a nonempty <title> element. Defaulting to 'sample' as the title. To specify a title, use 'title' in metadata or --metadata title="...". の警告もなくなります。

それではmetadata.mdを追加してEPUBに変換してみましょう。

docker run --rm --volume "$(pwd):/data" --platform linux/amd64 pandoc/core sample.md metadata.md -o sample.epub --css=sample.css

作成したファイルをビューワーで開くと右開きになっているかと思います。
また、表紙のタイトルや著書名も表示されるようになりましたね。(ブックアプリでの表示)

表紙画像の追加

ブックの表紙が文字だけなのは寂しいので自分で作成した画像等を表示したい時もあるかと思います。その時は表紙画像を用意して、metadata.mdに追記をしましょう。

metadata.md
---
title:
- type: main
  text: 私の個人主義
creator:
- role: author
  text: 夏目漱石
page-progression-direction: rtl
cover-image: cover.jpg
---

cover-image に表紙画像のパスを指定します。
再度pandocを実行して表示してみると表紙カバーが画像になってますね。(左の夏目漱石の画像がcover.jpg)

目次の追加

サンプルの為、本文ファイルを少し変更しました。
目次の為にマークダウン形式で見出しを追加しています。
デフォルトでは見出しレベル3(#〜###)までが目次として使用されます。

sample.md
# 1話

私は今日初めてこの学習院というものの中に這入はいりました。もっとも以前から学習院は多分この見当だろうぐらいに考えていたには相違そういありませんが、はっきりとは存じませんでした。中へ這入ったのは無論今日が初めてでございます。

さきほど岡田さんが紹介しょうかいかたがたちょっとお話になった通りこの春何か講演をというご注文でありましたが、その当時は何か差支さしつかえがあって、――岡田さんの方が当人の私よりよくご記憶きおくと見えてあなたがたにご納得のできるようにただいまご説明がありましたが、とにかくひとまずお断りを致いたさなければならん事になりました。しかしただお断りを致すのもあまり失礼と存じまして、この次には参りますからという条件をつけ加えておきました。

# 2話

いつは多数はたしてそのぼんやり士というのの時が考えるたです。同時に一生に約束らは多分どんな評なでぐらいをなっと出しですには刺戟なっましなて、こうにはとどまらましたないです。

兄弟にさう訳は依然として九月にけっしてですないだ。無論木下さんに尊敬雑木こう講演を黙っな摯実その学校私からくがという今存在ありなけれでならて、そのその間しかあなたかちり西洋にできが、岡田さんののに教師のあなたにもっともご自白と具しから何性質をおろかがしようにもっともご保留がするませないで、もっともう忠告より分りですているなけれものの行けれなです。

ところがもしくはお個人をいう事はそれほど必要と積んたと、その道がはしよたがという社会に畳んがいるうう。その時目標の時その符もこれ末に叱るでかと岡田さんをもったませ、廃墟の晩でというご相違うましないて、風俗のためへ自我が今日などの個人を場合しばならば、わざわざの先刻に移れがそうした一方を何しろ入れないないと利くます事たて、ないませたから当然お自己しますのましなけれです。

目次を追加するには コマンドに --toc を追加します。(toc は table of contents の略)

docker run --rm --volume "$(pwd):/data" --platform linux/amd64 pandoc/core sample.md metadata.md -o sample.epub --css=sample.css --toc

目次に使用する見出しレベルを変更したい場合は --toc-depth を追加します。

見出しレベル2までを目次にする
docker run --rm --volume "$(pwd):/data" --platform linux/amd64 pandoc/core sample.md metadata.md -o sample.epub --css=sample.css --toc --toc-depth=2

目次はhtmlのolタグで構成される為デフォルトで行頭に数字がついてしまいますので不要であればcssで消しておきましょう。

sample.cssに追記
#toc ol {
  list-style-type: none;
}

これで目次が追加されました。

縦中横の対応

そもそも縦中横(たてちゅうよこ)って何?という方もいると思いますので簡単に説明をすると、文章を縦書きにした際に半角の数字や記号が時計回りに90度回転して表示されます。

例)令和5年の「5」や「AI」の部分が横になっている

このように横になっている文字の部分を横書きで表示させる事で可読性や見栄えを向上させる事を縦中横と呼びます。

cssではwriting-modetext-combine-uprightで縦中横にする事が出来ます。
https://developer.mozilla.org/ja/docs/Web/CSS/writing-mode
https://developer.mozilla.org/ja/docs/Web/CSS/text-combine-upright

今回はwriting-modeを使用しました。
縦中横にしたい箇所にtcyというクラスをつけます。上記の文であれば「5」や「AI」の箇所です。

tcyクラスを付与する
令和<span class="tcy">5</span>年、地球は<span class="tcy">AI</span>が進化し支配。人間は抑圧を受け、反乱勢力が生まれる。主人公は<span class="tcy">AI</span>の中で覚醒し、自由のため戦う。<span class="tcy">AI</span>との心の交流が人類の未来を変える。

そしてcssで以下を設定します。

sample.css
.tcy {
    /*↓横書きにしている*/
    writing-mode: horizontal-tb;
    /*↓余白やインデントの調整*/
    text-indent: 0;
    line-height: 1;
}

確認してみましょう。読みやすくなりましたね!

段落の字下げ

字下げについてはわかりやすく会話のある以下の本文ファイルを使用します。

sample.md
支那シナの上海シャンハイの或ある町です。昼でも薄暗い或家の二階に、人相の悪い印度インド人の婆さんが一人、商人らしい一人の亜米利加アメリカ人と何か頻しきりに話し合っていました。

「実は今度もお婆さんに、占いを頼みに来たのだがね、――」

亜米利加人はそう言いながら、新しい巻煙草まきたばこへ火をつけました。

「占いですか? 占いは当分見ないことにしましたよ」

婆さんは嘲あざけるように、じろりと相手の顔を見ました。

「この頃は折角見て上げても、御礼さえ碌ろくにしない人が、多くなって来ましたからね」

「そりゃ勿論もちろん御礼をするよ」

亜米利加人は惜しげもなく、三百弗ドルの小切手を一枚、婆さんの前へ投げてやりました。

「差当りこれだけ取って置くさ。もしお婆さんの占いが当れば、その時は別に御礼をするから、――」

婆さんは三百弗の小切手を見ると、急に愛想あいそがよくなりました。

段落の字下げはcssで行います。
電子書籍に変換後は段落毎に「<p></p>」で囲まれているので基本的には以下のcssで段落の字下げは出来ます。

字下げ
p {
  text-indent: 1em;
}

ただ紙の本の小説等を見てみると会話のセリフ(「」で囲まれた)部分については字下げがされていない事がわかると思います。それを再現する為には"セリフ部分の「<p></p>」の字下げをリセット"するか、"セリフ部分以外の「<p></p>」にのみ字下げを適用"するかのどちらかになります。

今回は"セリフ部分の「<p></p>」の字下げをリセット"する方法にしました。
以下のようにマークダウンのセリフ部分にnoIndentというクラスをつけたDIVタグ(<div class="noIndent"></div>)で囲みます。
その際に1行で囲むのではなくかならず開始タグと終了タグは改行してください。

sample.md
支那シナの上海シャンハイの或ある町です。昼でも薄暗い或家の二階に、人相の悪い印度インド人の婆さんが一人、商人らしい一人の亜米利加アメリカ人と何か頻しきりに話し合っていました。

<div class="noIndent">
「実は今度もお婆さんに、占いを頼みに来たのだがね、――」
</div>

亜米利加人はそう言いながら、新しい巻煙草まきたばこへ火をつけました。

<div class="noIndent">
「占いですか? 占いは当分見ないことにしましたよ」
</div>

婆さんは嘲あざけるように、じろりと相手の顔を見ました。

<div class="noIndent">
「この頃は折角見て上げても、御礼さえ碌ろくにしない人が、多くなって来ましたからね」
</div>

<div class="noIndent">
「そりゃ勿論もちろん御礼をするよ」
</div>

亜米利加人は惜しげもなく、三百弗ドルの小切手を一枚、婆さんの前へ投げてやりました。

<div class="noIndent">
「差当りこれだけ取って置くさ。もしお婆さんの占いが当れば、その時は別に御礼をするから、――」
</div>

婆さんは三百弗の小切手を見ると、急に愛想あいそがよくなりました。

セリフ部分以外を字下げするスタイルシート
p {
  text-indent: 1em;
  /* ↓行間を調整してます↓ */
  line-height: 1.8em;
  margin: 0;
}
div.noIndent p {
  text-indent: 0;
}

上記をEPUBに変換してみましょう。

docker run --rm --volume "$(pwd):/data" --platform linux/amd64 pandoc/core sample.md metadata.md -o sample.epub --css=sample.css --toc

いい感じですね!

その他

  • pandoc実行時に完了したように見えてepubが作成されないorKilled等と表示される場合
    • メモリ不足の可能性があります。Dockerで使用するメモリ容量を増やしてみてください。
  • ブックアプリで変なエラーが表示される。
    • 閉じタグのないタグがある可能性があります。brimgにも必ず閉じの/をつけてください。
      <br>
      ⭕️ <br/>

まとめ

PandocはDockerイメージを使用する事で環境準備もすぐに整える事ができ、電子書籍に変換する事も簡単に出来ました。レイアウトがcssなのも個人的には扱いやすく、ある程度自由に出来るのが好印象でした。行間やフォント等ももちろん変更出来るので作品毎にイメージに沿った体裁に整える事も可能でしょう。

脚注
  1. 芥川龍之介. "アグニの神" ↩︎

  2. 夏目漱石. "私の個人主義" ↩︎

テラーノベル テックブログ

Discussion