概説EPUB(構造解説編)
これ何
EPUBの構造と、各ファイルの役割を解説する文章です。私自身がEPUBを作ろうと思って調べました。EPUBに必要なファイルと夫々の役割が理解できることを目指しています。とりあえず、空っぽのサンプルを用意してみました。これを見つつ読めば、いくらか理解しやすいと思われます。僕はこのテンプレートをもとにEPUBを作ってますが、これ単体ではEPUBとして成立してないので、ご注意を。
EPUBを構成するよく分からないファイル達
EPUBは、乱暴に説明するならば『ZIPファイル』です。以下の解説は、冒頭で紹介したサンプルファイルの構造を基準に書いてあります。これを展開して構造を見ながら読むといいと思います。そんなわけで、夫々のファイルがどんな役割を果たしているのかを解説していきます。
mimetype
これは「オマジナイ」だと考えてください。EPUBのファイルを開いたアプリケーションは、最初にこのファイルの中身を確認します。そして内容が『zapplication/epub+zip』であることを確認します(もし内容が違っていたり、このファイルが存在しない場合には、アプリケーションはそのEPUBが正しい構造ではないと判断して、処理を中止します)。
このファイルに関しては、何も考えるべきことはありません。
META-INF/container.xml
このファイルは、内容が変わることもありますが、基本的にはほぼ固定の内容です。また、ファイル名とパスは固定です。要するに、EPUBのzipファイルの中に入っている『使われてるファイル一覧』みたいなデータがどこに書かれているかを指し示しています。この例では『OEBPS/content.opf』というファイルの場所を指し示しています。以下がcontainer.xmlの内容です。
<?xml version="1.0" encoding="UTF-8"?> <container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0"> <rootfiles> <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml" /> </rootfiles> </container>
OEBPS/content.opf
このファイルの中には以下のような情報が格納されています。
とりあえずファイルの全貌を紹介します。
<?xml version="1.0" encoding="UTF-8"?> <package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId"> <!-- EPUBのメタ情報 --> <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf"> <dc:title>タイトル</dc:title> <dc:creator opf:role="aut">著者名</dc:creator> <dc:language>ja</dc:language> <dc:publisher>EPUB作った人</dc:publisher> <dc:identifier id="BookId">urn:uuid:d.hatena.ne.jp/HowManyFiles/book001</dc:identifier> </metadata> <!-- EPUBで使われるファイルの一覧 --> <manifest> <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" /> <item id="style" href="default.css" media-type="text/css" /> <item id="html-001" href="001.html" media-type="application/xhtml+xml" /> <item id="html-002" href="002.html" media-type="application/xhtml+xml" /> <item id="html-003" href="003.html" media-type="application/xhtml+xml" /> <item id="html-004" href="004.html" media-type="application/xhtml+xml" /> <item id="img_001" href="fig001.png" media-type="image/png"/> <item id="img_002" href="fig002.png" media-type="image/png"/> </manifest> <!-- ファイルの並び順 --> <spine toc="ncx"> <itemref idref="html-001" /> <itemref idref="html-002" /> <itemref idref="html-003" /> </spine> </package>
一気に構造が複雑になった気がしますが、大したことはないです。XMLなので複雑に見えるだけというか。
『EPUBのメタ情報』とコメントが書かれた下に書かれているのが、本のタイトルは何で・著者が誰で・言語は何で……みたいな情報です。これはコンテンツの内容によって変わります。あと、この情報は必ずしも全部が必要というわけではないみたいです。例えばpublisherの情報とかは無いなら無いで表示できました。
『EPUBで使われるファイルの一覧』とコメントが書かれた下にあるのが、そのまんまですがファイル一覧です。ページデータの本体であるXHTMLファイルや画像ファイル・CSSファイル・目次のためのncxファイルなどが書かれています。id属性値で夫々のファイルにIDを与え、href属性値でファイル名を明示し、media-type属性値でそれがどんな種類のファイルであるかを明示しています。当然の話ですが、IDは一つのEPUBの中では同じものを使えません。
『ファイルの並び順』とコメントが書かれた下にあるのは、順当にページをめくっていったときにどんな順番で内容を表示していくかの指定です。この時、先程ファイル一覧のところで各ファイルに与えたIDで並び順を指定しています。XHTMLのなかで使われるだけのCSSファイルや画像ファイルは当然ここには登場しません。
OEBPS/toc.ncx
このファイルの中には、本の目次情報が入っています。例えばiBooksではこのファイルをもとにちゃんと目次ページを生成してくれるので『二章三節まで読んだ』とかそういうアクセスが簡単にできます。目次項目には『~.html#foobar』のようにファイルの途中をIDで指定することも出来るので、XHTMLファイルを正しくマークアップしておけば、整然とした目次を作ることが出来ます。
とりあえず中身を見てみましょう。
<?xml version="1.0" encoding="UTF-8"?> <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1"> <head> <meta name="dtb:uid" content="d.hatena.ne.jp/HowManyFiles/book001"/> <meta name="dtb:depth" content="1"/> <meta name="dtb:totalPageCount" content="0"/> <meta name="dtb:maxPageNumber" content="0"/> </head> <docTitle> <text>タイトル</text> </docTitle> <docAuthor> <text>著者</text> </docAuthor> <navMap> <navPoint id="html-001" PlayOrder="1"> <navLabel> <text>第一章</text> </navLabel> <content src="001.html"/> <vavPoint id="html-001-001" PlayOrder="2"> <navLabel> <text>第一章一節</text> </navLabel> <content src="001.html#c001"/> </navPoint> </navPoint> </navMap> </ncx>
なんかまた複雑ですが、ここもパート別に見ていけばなんてことは無いです。
head要素の中身は、そんなにいじることはないはずです。唯一変更すべき場所は、最初に書かれたmeta要素のidで、これはcontent.opfで指定したidと同じものを指定しておけばいい感じです。このへんなんだか冗長な感じがしますが、たぶん色々都合があるんだと思います。
同じように、docTitle要素とかdocAuthor要素とかも、content.opfで指定したものと同じにしておけばいいと思います。iBooksで試してみたところ、基本的にcontent.opfに書かれた情報が使用されるみたいですが、そこはきっと環境によりけりなので、トラブルを防ぐ意味でも同じ内容にしておいたほうがいいんじゃないでしょうか。
navMapの部分に関してはXHTMLで言うところの入れ子リストみたいなもんだと思えばいいです。目次を階層化出来るというか。基本的には目次はnavPoint要素の集合体で、navPoint要素の中にnavPoint要素が入っていることがあります。まあ、実際には精々二階層くらいまでで、そんなに派手に多層化することはないと思います。
navPoint要素には必須の属性値が二つあり、一つはidで、これは他とかぶってなきゃなんでもいいです。もう一つは PlayOrder で、これはnavPoint要素の登場順に1から数字が割り振られます。
navPoint要素の中にはnavLabel要素とcontent要素が入っています。navLabel要素の中に更にtext要素が入っていて、そこに目次として表示したい文字列が書かれています。で、content要素は空要素で、src属性値によって、コンテンツの場所を指定します。で、入れ子リストみたいな感じで、navPointのなかにはさらにnavPointを入れることが出来ます。
navMapに登場してないXHTMLファイルであっても、目次に載らないというだけで、端末のページを捲っていけば普通に読めます。基本的にはきちんと目次を作ることが望ましいと思うのですが、ゲームブックとかではあえて目次には載せないページがあってよいいんじゃないかと思います。
文章を構成するファイル達
XHTMLファイル
これがEPUBの本分を構成する主たるパーツになります。他のファイルはいわばEPUBとしての体裁を整えるためのお飾りみたいなもんです。基本的にはまともなXHTMLであればそれほど問題ないですが、貴方がまともだと思っているXHTMLが実は糞みたいなものだって可能性は捨てきれないので、一度きちんとXHTMLの仕様を勉強してみることをおすすめします。