はじめに
- 既存のコンバータでepubを作ったら汚かった
- epub仕様を把握して自分でepubドキュメントを作ろうと思った
- 昔自炊した連番JPGをepubにまとめたいので、epub仕様書から必須項目だけ集めてみた
- 最小サンプルセット https://github.com/positrium/create-epub-with-my-hand
- 画像をカバーで1枚、ページで1枚。ただそれだけのセット。
- rubyで連番JPGをepubにするスクリプトを書いてみた
epubコンテナ
.
├── mimetype
├── META-INF/
│ └── container.xml
└── EPUB/
├── images/
│ ├── cover.jpg
│ ├── chap1.jpg
│ └── chap2.jpg
├── nav.xhtml
├── chap1.xhtml
├── chap2.xhtml
└── book.opf
- ファイル拡張子 .epub の ZIPアーカイブ準拠
- 例: https://imagedrive.github.io/Submission/epub32/epub-ocf.html#example
mimetype
mimetype
application/epub+zip
ZIPファイル仕様
mimetypeはZIPファイルの先頭になければならない。
# mimetypeのみ書き込む
zip -X0 ../test_epub.epub mimetype
# mimetypeを除いてそれ以外を追加書き込みする
zip -r9 ../test_epub.epub * -x mimetype -x .*
-
ERROR(PKG-005) mimetypeファイルに長さ28の拡張フィールドがあります. mimetypeファイルでZIPフォーマットの拡張フィールド属性を使うことは許可されていません.
- 対策:
-X
指定ファイル属性を除外する。
- 対策:
-
ERROR(PKG-007): mimetypeファイルは文字列 'application/epub+zip' だけを含み、また圧縮してはいけません.
- 対策:
-0
非圧縮に設定する。 - 補足: 非圧縮にしてもepubcheckはPKG-007を吐くが、iBookは改行を含んでいた場合もエラーなしで読み込むことが出来る。
- epubcheckのバグ? ERROR回避方法があれば教えて欲しい。
- 対策:
-
ERROR(PKG-006): mimetypeファイルエントリが存在しないか、アーカイブの先頭以外の場所に存在しています.
- 対策:
-x
指定名を除外する。
- 対策:
META-INF/container.xml
opfの位置を指定する。
META-INF/container.xml
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="EPUB/book.opf" media-type="application/oebps-package+xml" />
</rootfiles>
</container>
- container#version=1.0はcontainer.xmlスキーマ由来
- EPUB/book.opfは後述のパッケージドキュメントのファイル名と一致する
ドキュメント構成
- パッケージドキュメント
- マニフェスト(出版物リソース)
- EPUBナビゲーションドキュメント
- コンテンツドキュメント
パッケージドキュメント
EPUB/book.opf
<?xml version="1.0" encoding="UTF-8"?>
<package unique-identifier="pub-id" version="3.0" xmlns="http://www.idpf.org/2007/opf">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier id="pub-id">urn:uuid:14109e67-1e75-4360-acc2-1bd5644ecedb</dc:identifier>
<dc:title>MINIMUM SAMPLE</dc:title>
<dc:language>ja-JP</dc:language>
<meta property="dcterms:modified">2019-08-07T00:49:06Z</meta>
</metadata>
<manifest>
<item id="nav" href="./nav.xhtml" properties="nav" media-type="application/xhtml+xml" />
<item id="cover" href="./images/cover.jpg" properties="cover-image" media-type="image/jpeg" />
<item id="chap2" href="./chap2.xhtml" media-type="application/xhtml+xml" />
<item id="chap1" href="./chap1.xhtml" media-type="application/xhtml+xml" />
<item id="imgChap1" href="./images/chap1.jpg" media-type="image/jpeg" />
<item id="imgChap2" href="./images/chap2.jpg" media-type="image/jpeg" />
</manifest>
<spine page-progression-direction="rtl">
<itemref idref="chap1" />
<itemref idref="chap2" />
</spine>
</package>
-
package.version
は3.0にしなければならないと記述があるので3.2ではいけない。 -
package#unique-identifier
に指定する中身はドキュメントユニークであれば何でも良い。 -
package.metadata.meta#property
の中身 -
package.manifest.item
は順序を保証しない。順序はspine(脊椎)で保証する。 -
package.manifest.item#media-type
の中身- 補足: https://imagedrive.github.io/Submission/epub32/epub-spec.html#sec-cmt-supported に定義されている。(jpg ->
image/jpeg
)
- 補足: https://imagedrive.github.io/Submission/epub32/epub-spec.html#sec-cmt-supported に定義されている。(jpg ->
-
package.manifest.item#properties="nav"
とし、EPUBナビゲーションドキュメントを記述しなければならないらしい。 -
package.spine.itemref#linear="no"
の用途は、本文ではない注釈向け。 - 拡張子opf であれば良い。
- book.opf中で相対パスを書いているが、これも正しい。
-
package.spine.itemref
にはimage/jpeg
なid参照は出来なかった。 -
package.manifest.item
にはコンテナ内のリソースをすべて書き込まなければならないので画像用のエントリを追記。
(*) Online UUID Generator: https://www.uuidgenerator.net/version4
EPUBナビゲーションドキュメント
目次に相当。
nav.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
<title>nav</title>
</head>
<body>
<nav epub:type="toc">
<ol>
<li><a href="chap1.xhtml">chapter 1</a></li>
<li><a href="chap2.xhtml">chapter 2</a></li>
</ol>
</nav>
</body>
</html>
-
nav#epub:type
が指定されている場合にのみ有効とあるが、必須項目だった。 -
nav#epub:type
は、 https://imagedrive.github.io/Submission/epub32/epub-packages.html#sec-package-nav-def-types に定義されている。 - chapter, section, subsectionなどはHTMLのol-liの構造と同じ。ol > li > ol > li と掘っていく。
- 拡張子xhtmlのファイル。package.manifest.item#id="nav"ではnav.xhtmlとして参照してる。
コンテンツドキュメント
本文に相当。
chap1.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>chapter 1</title>
</head>
<body>
<img src="./images/chap1.jpg"/>
</body>
</html>
- html5ドキュメントで良い。
- chap2.xhtmlも同様。
付録 : macでepub作成シェルスクリプト
epubcheckを利用。
#!/bin/sh
echo "clean: "
rm test_epub.epub
# epub作成 .DS_Storeなどをしたい
echo " "
echo "create: "
cd test_epub/
zip -X0 ../test_epub.epub mimetype
zip -r9 ../test_epub.epub * -x mimetype -x .*
cd ..
# mimetypeファイルがZIPファイルの先頭にあるのを確認したい
echo " "
echo "list: "
unzip -l test_epub.epub
# EPUBコンテナの妥当性を検証したい
echo " "
echo "check: "
epubcheck test_epub.epub