続: エッ!EPUB作れ?

EPUB作成のの顛末記です.CSSに定義されたbackground-imageの件は「止めちゃおう」ということになりました.労多くして得るところが少ないからです.で、なんとかbackground-imageの実装だけをはずして、すべての変換結果をテンポラリフォルダに作るところまでは成功しました.ちょうどEPUBを解凍したイメージを作り出したわけです.
 
あとは、これをZIPして拡張子を.epubにするだけのはずだったのですが、ここでけっこう足を取られました.
まずepubの仕様で、ルートにあるmimetypeというファイルは、コンテンツが"application/epub+zip"という文字列で、しかもこのファイルはZIPファイルの中に入れるにもかかわらず圧縮されていてはならないのです.そしてこのファイルはZIPファイルの最初のエントリーでなくてはいけません.
 
OCF ZIP Containers must include a mimetype file as the first file in the Container, and the contents of this file must be the MIME type string application/epub+zip.
The contents of the mimetype file must not contain any leading padding or whitespace, must not begin with the Unicode signature (or Byte Order Mark), and the case of the MIME type string must be exactly as presented above. The mimetype file additionally must be neither compressed nor encrypted, and there must not be an extra field in its ZIP header.
 
出来たEPUBをチェックするのには、Epubcheckというプログラムを使います.
 
 
が、これがまことに厳しくチェックしてくれるので、上記の要件を満たさないと、
 
ERROR: D:/MyDocu~1/XML2012/out/xxx.epub: Length of the first filename in archive must be 8, but was 6
 
というエラーを出してくれます.これはたぶんZIPの先頭ファイル名がmimetype(8文字)でないからエラーということなのでしょう.
 
いろんなWEBサイトを見ると、このような圧縮のためにはInfoZipを使うのが良いと書いてあるのですが、ダウンロードしてみてもマニュアルを見るだけであまりのオプションの多さに閉口してしまいました.せっかくantを使っているのでZIPタスクでやりたいものです.そこでZIPタスクを3つ作って動かすようにしました.こんな感じです.
 
    <delete file="${output.path}" failonerror="false"/>
    <!-- OEBPS -->
    <zip destfile="${output.path}"
      compress="true"
      filesonly="false"
      update="false">
      <zipfileset dir="${epub.content.dir}" prefix="${epub.content.dirname}"/>
    </zip>
    <!-- META-INF -->
    <zip destfile="${output.path}"
      compress="true"
      filesonly="false"
      update="true"
      keepcompression="true">
      <zipfileset dir="${epub.metainf.dir}" prefix="${epub.metainf}"/>
    </zip>
    <!-- mimetype -->
    <zip destfile="${output.path}"
      compress="false"
      update="true"
      keepcompression="true">
      <zipfileset file="${epub.root.dir}/${epub.mimetype}" />
    </zip>
 
mimetypeが最後なんですが、ZIPタスクは.zipを更新モードで処理すると、処理したものが先頭に、それまであったものをその後に配置してくれます.あとは、更新の際にそれまで行った圧縮を維持するようにkeepcompression="true"を指定します.こうしないと最後のmimetypeのZIPタスクでcompress="false"を指定しているので今までの圧縮結果がすべてパアになってしまい、圧縮率0%になってしまいます.
これを走らせたログは次のようになりました.
 
xhtm2epub_makeepub:
   [delete] Deleting: D:\MyDocu~1\XML2012\out\xxx.epub
      [zip] Building zip: D:\MyDocu~1\XML2012\out\xxx.epub
      [zip] Updating zip: D:\MyDocu~1\XML2012\out\xxx.epub
      [zip] Updating zip: D:\MyDocu~1\XML2012\out\xxx.epub
 
でビルドファイルの最後にepubcheckを自動的に行うようターゲットを追加したのですが、
xhtm2epub_epubcheck:
     [java] Epubcheck Version 3.0b5
     [java]
     [java] Validating against EPUB version 2.0
     [java] No errors or warnings detected.
 
という結果です.めでたしめでたし!
 
ところがAdobeのDigital Editionで表示すると、xml:lang="en"が指定してあるためなのか日本語が全滅で"?"になってしまいます.FireFoxepub plug-inなら表示してくれます.HTMLなんて、いくら先頭にxml:langが指定してあろうとも、日本語文字だって中国語文字だって入り得ます.これはDigital Editionの実装がイマイチな気がします.FireFoxの方は、元がブラウザなのでこんな不具合ははありません.
 
感想ですが、XSL-FOを作るときはほぼXSL-FOの仕様書を見れば事足りるのですけれど、EPUBの場合は仕様がそこらに散らばっていて慣れるのに苦労しました.それでいて、実際出来たEPUBはDigital Editionでも表示はイマイチ綺麗じゃないのですよね~!まあ時代の流れなんでししかたないのでょうか?私はやっぱりデザインをきっちり決められるFOの方が好きです.でもそんなことをいう技術者はこの先数年で化石になっちゃいそうなEPUBの勢いですね.私ももう少し勉強します.