
EPUBのファイルを一章・目次・表紙付きで作るなら、最初に「入力」と「生成物内部の参照」を一枚の契約表へ置くのが答えです。入力はchapter原稿とcover.png。生成物ではnav.xhtml、content.opf、cover.xhtml、chapter.xhtml、colophon.xhtml、container.xml、mimetype、格納後のcover.pngを互いに結びます。ファイルがあるだけでは足りず、OPFのIDとhref、spineのidref、目次の本文href、表紙ページの画像srcまで解決できれば、入力漏れを場所ごとに切り分けられます。
この記事は一章+目次+表紙の「パッケージ契約」を作る記事です。Rune Studioの6ページのEPUBウィザードで三章を選び、画面を進めて生成する操作は別の実践として切り分けます。ここでは生成物の中に何が必要で、どの参照が切れてはいけないかへ集中します。
入力二件を先に固定する
作り始める前に、次の二件を入力票へ記録します。
| 入力ID | 正本パス | 検査する内容 |
|---|---|---|
| CHAPTER-01 | source/chapter.md | 章見出し、本文、文字コード、章ID |
| COVER-01 | source/cover.png | 採用画像、ファイル形式、正本パス |
作品名、著者、言語、識別子、更新日時も同じ票に書きます。ファイル名だけを作品情報の代わりにしません。chapter原稿の章見出しは、後でnav.xhtmlのラベルと移動先を照合する基準になります。cover.pngは候補を複数混ぜず、採用した一件をCOVER-01として固定します。
パッケージの八実体を配置する
一章、目次、表紙、奥付を持つ標本は、次の八実体へ固定します。
| 番号 | EPUB内のパス | 役割 |
|---|---|---|
| 1 | mimetype | EPUBの媒体型を示す |
| 2 | META-INF/container.xml | package文書の場所を示す |
| 3 | OEBPS/content.opf | 書誌、資源登録、読む順を定義する |
| 4 | OEBPS/nav.xhtml | 読者用の目次ナビゲーション |
| 5 | OEBPS/Text/cover.xhtml | 表紙画像を表示するページ |
| 6 | OEBPS/Text/chapter.xhtml | CHAPTER-01から作る本文一章 |
| 7 | OEBPS/Text/colophon.xhtml | 著者・発行情報を示す奥付 |
| 8 | OEBPS/Images/cover.png | COVER-01から格納する表紙画像 |
入力票の二件と、格納後の八実体は別の表です。source/cover.pngがあることと、EPUB内のOEBPS/Images/cover.pngがOPFと表紙ページから参照されることを混同しません。
chapter、cover、奥付のXHTMLを作る
chapter.mdを整形式のOEBPS/Text/chapter.xhtmlへ変換します。XML名前空間、head、title、bodyを持つ完全なXHTMLにし、本文見出しへid="c01"を付けます。navのhrefはこのIDまで含めてText/chapter.xhtml#c01へ向けます。
OEBPS/Text/cover.xhtmlには、../Images/cover.pngを参照するimgを一件置きます。画像の実パスとsrcの大文字小文字まで一致させます。奥付はOEBPS/Text/colophon.xhtmlへ分け、著者、発行者、発行日など、入力票で採用した情報を記載します。
nav.xhtmlをEPUB 3の目次にする
nav.xhtmlは、単にリンクを置いたXHTMLではありません。OPFのmanifestでnav資源を正確に一件登録し、そのitemへproperties="nav"を付けます。さらにnav.xhtml側ではepub名前空間を宣言し、正確に一件のnav epub:type="toc"を置きます。
目次本体は順序付きリストにし、一章の項目をText/chapter.xhtml#c01へ結びます。合格条件は次の三点です。
- OPFに
properties="nav"を持つnav itemが一件ある - nav.xhtmlに
epub:type="toc"を持つnavが一件ある - toc内のhrefがchapter.xhtmlの
c01へ解決し、表示ラベルが章見出しと一致する
この三点のどれかが欠ければ、見た目にリンクがあっても目次契約は不合格です。
content.opfでcover・manifest・spineを結ぶ
content.opfのmetadataには作品名、識別子、言語、著者、更新日時を一度だけ定義します。表紙画像はmanifestのitemへproperties="cover-image"を付けて登録します。古い読み手との互換情報を持たせる構成では、metadataのcover指定も同じ表紙画像IDへ向け、別IDへ分岐させません。
manifestでは最低でも次の五資源を登録します。
- nav:
nav.xhtml、properties="nav" - cover-image:
Images/cover.png、properties="cover-image" - cover-page:
Text/cover.xhtml - chapter:
Text/chapter.xhtml - colophon:
Text/colophon.xhtml
spineは表示する読む単位をcover-page、chapter、colophonの順に参照します。cover画像そのものをspineへ入れるのではなく、cover画像を表示するcover.xhtmlを入れます。各itemrefのidrefからmanifestのIDへ進み、そのhrefが実ファイルへ解決するところまでたどってください。
container.xmlとmimetypeで入口を作る
META-INF/container.xmlのrootfileはOEBPS/content.opfを指すようにします。OPFが存在していてもfull-pathが別の場所なら、入口からパッケージへ到達できません。
ルートのmimetypeにはapplication/epub+zipだけを入れます。EPUBへ固めるときはmimetypeを最初のZIPエントリーとして無圧縮で格納し、その後にMETA-INFとOEBPSを追加します。拡張子を.epubへ変えただけでは、この入口条件は成立しません。
四本の参照鎖で入力漏れを探す
ZIP化後は、見た目ではなく次の順に検査します。
- container.xml → OEBPS/content.opf
- OPF manifest → nav、cover-image、cover-page、chapter、colophonの各実体
- OPF spine → cover-page → chapter → colophon
- nav toc href → chapter.xhtml#c01、cover.xhtml img src → Images/cover.png
合わせてmimetypeの内容、ZIP内の先頭位置、無圧縮格納を確認します。エラーは「開かなかった」でまとめず、入口、登録、読む順、目次移動先、表紙参照のどこで切れたかを記録します。そうすれば、chapter原稿の変換漏れとcover.pngの格納漏れを別々に直せます。
参照が切れたときは、生成物へファイルを足す前に契約表へ戻ります。containerからOPFへ届かないなら入口、OPFに項目がないなら登録、idrefが解決しないなら読む順、画像srcだけ切れるなら表紙参照の問題です。該当する一段を直した後も四本すべてを先頭から再確認し、修正で別のhrefやIDを壊していないことまで確認します。
Rune Studioの確認済み範囲を混ぜない
実際の画像なしEPUBでは、mimetype、META-INF、OEBPS、XHTML、nav、NCX、content.opfのmetadata・manifest・spine、奥付を確認し、パッケージ検査を通過しました。
表紙を含む別のEPUBでは、ZIP内部のOEBPS/Images/cover.png、OPF manifest、cover.xhtmlから表紙画像への参照は実在しました。一方、検査結果は実在する画像を欠落扱いしています。したがって「表紙ファイルと参照は確認済み」ですが、「表紙入りEPUBの検査合格」は判断待ちです。画像が無かったとも、完成検査に通ったとも書けません。

入力票と参照契約を残してから生成する
EPUBのファイル作り方で入力漏れを防ぐには、chapter原稿とcover.pngを固定し、八実体の配置を決め、navのproperties="nav"とtoc nav、OPFのcover・manifest・spine、container、mimetype、奥付を一つずつ結ぶことが重要です。
一章の内部契約が通った後に、Rune Studioの6ページのEPUBウィザードで三章を選び、生成した三つの目次ラベルと移動先を試す段階へ進みます。現行Mac版の製品範囲は、Rune Studioの商品ページで確認できます。


