トップ «前の日記(2015年03月29日) 最新 次の日記(2015年04月25日)» 編集

アペフチ


2015年04月21日 EPUBと中身のファイルをウェブの用語で結び付ける [長年日記]

二か月くらい考えてるんだけど、このまま更に半年くらい無意味に進展させなさそうなので、全く初期段階だけど、吐き出しときます。でも吐き出したら満足してもう忘れてしまうことも充分考えられるので、興味持ってもらえた人はあとを引き取るなり声をかけるなりしてもらえると嬉しいです。

_ [EPUB][Web] EPUBと中身のファイルをウェブの用語で結び付ける

EPUBファイルがあって、ウェブブラウザーとかで

http://example.com/nice/book.epub

にアクセスするとダウンロードできるとする。
このEPUBを(ZIPファイルとして)展開したものが

http://example.com/nice/book/

以下で取得できるとする。 例えば、どのEPUBも持っている「META-INF/container.xml」というファイルは、

http://example.net/nice/book/META-INF/container.xml

というURLで取得できる。
表紙画像を「contents/images/cover.png」という所に置いているEPUBファイルだったら、

http://example.net/nice/book/contents/images/cover.png

にアクセスすれば画像が手に入る。

こういう状況設定の上で、

http://example.net/nice/book.epub

にアクセスした時、その展開版である

http://example.net/nice/book/

に誘導するような仕組みというか取り決めがあるといいなあとここのところ考えています。

Web Linkingのようなやつ

HTTPヘッダーの使い方の提案にWeb LinkingっていうRFCがある。
https://tools.ietf.org/html/rfc5988

これは例えば

http://example.net/nice/book.epub

にアクセスした時に、同内容のPDFも取得可能な場合、

Link: </nice/book.pdf>; rel="alternate"; type="application/pdf"

といったようにそのURLとかメディアタイプ(PDFということ)とかの情報をHTTPヘッダーに書きましょうという仕様。
HTMLのページなら<link>要素を使えばいいんだけど、EPUBやPDFみたいなファイルになると、そういう他のリソース(URL)との関係を書く標準的な方法もないし、書きたくないことも多いだろうから、HTTPヘッダーでできると便利だと思う。

で、先の問題設定の場合にどうしたらいいか。既存の語彙を使うならrevはどうだろうかと思っている。Web LinkingのrelとかtypeはHTMLの<link>をベースにしていて、HTML5では無くなってしまったけどrev属性(relの反対)も使えることになっている。ので、

Link: </nice/book/>; rev="alternate"; type="application/epub+zip"
(追記。これtypeがおかしくて、リンク先のメディアタイプを書かないといけない。)

というのなら、 http://example.net/nice/book.epub にアクセスしたクライアントが、展開済みの物に直接アクセスできることを知れる。

ユースケース

それが分かってどうするのか、というと、ブラウザーで動くタイプのEPUBリーダーに使ってほしい。

ブラウザーでEPUBファイルを閲覧できるのって、Readiumepub.jsBiB/iがポピュラーだと思う(個人的にはFirefoxアドオンのEPUB Readerも使っていて、気に入っているけど)。そのどれも、EPUBファイルを直接取得して自力で展開させるより、展開済みディレクトリー(?)のURLを教えてやってそれにアクセスさせるほうが、パフォーマンスがいい(ちょっと見たところepub.jsはそもそも使い方がそうなってるように見える)。

のであれば、

  1. XMLHttpRequestでEPUBファイルにアクセスする
  2. HTTPヘッダー見たところでLinkヘッダーがあって、その形式に対応できることが分かる
  3. 今のXMLHttpRequestを中断して、リンク先からコンテンツを取得する

ということができるようになる。

e-book要素

BiB/iとかepub.jsとか使ったことある人は知っていると思うんだけど、このリーダーは、リーダーアプリを置いているのと同じサーバー(オリジン)にEPUBファイルとか展開済みコンテンツを置く必要がある。同じサーバーに置くということは自分でコントロールできるということで、それだったら自分で展開済みコンテンツを置いて、自分でそれを示すURLを書けばいいんじゃないの、ということになるだろう。その通りです。

それなのにこんなことを考えている動機はごく個人的な物です。今、<e-book>っていうカスタムエレメントを作り始めている。これはHTML5の<video>要素みたいに、本のURLを与えるとそれを表示して、ページを進めたりするボタンコントロールを提供したりする物(まだ全然出来てないです)。

で、<video>要素みたいに、ということは、

<e-book src="http://example.net/nice/book.epub"></e-book>

みたいに書きたい、この時のsrc属性は、ドメインの違いなんて気にしないで書きたい。ここに

<e-book src="http://example.net/nice/book/"></e-book>

みたいな展開済みURLを書くのは不自然というか<video>からのアナロジーが利かないし、そもそも違うドメインの管理者がEPUBだけじゃなくて展開済みコンテンツを用意してくれているか調べるのがだるい。

そんなわけで、HTML書く人は気にせず「*.epub」って書いて、EPUBリーダーの内部動作とサーバーの設定で勝手にパフォーマンスのいい方が選ばれるといいなと思っているのでした。

(余談だけどウェブコンポーネンツの枠組みでやってるので、XMLHttpRequestを使うことになって、クロスオリジンアクセスの対応は必要ではある。)

コンテントネゴシエーションのようなやつ

こういったユースケースを満たすには、Web Linkingみたいな方法じゃなくてコンテントネゴシエーションのような方法もある。

コンテントネゴシエーションは、サーバー側で一つのコンテンツに対して複数の表現がある時に、ブラウザーの対応可能範囲と照らして適切な表現を選ぶための枠組み。

例えば

http://example.net/nice/book

というURLにアクセスする時に、ブラウザーは
「EPUBとHTMLとJSONとPDFなら対応可能で、優先順位はこの順番でほしい」
と、HTTPヘッダーを使ってサーバーに伝える。
サーバーは自分の状況を見て、EPUBを提供できるならEPUBを、無理なら次はHTMLを探してあればそれを……という風に提供する物を決めて、それを送る。

言語の決定にも使えて、ブラウザーが(ユーザーによる言語設定に従って)
「日本語と英語と中国語が読めるから、この順番で優先順位付けてコンテンツを欲しい」
と伝えて、サーバーは日本語がなければ英語のコンテンツを……というようにコンテンツの言語を変えて提供することができる。

これを使って、ブラウザー(XMLHttpRequest)が 「『EPUBを展開したやつ』とEPUBの両方対応可能です」 と伝えつつ

http://example.net/nice/book.epub

にアクセスした時に、サーバー側に「展開したやつ」があれば、そっちにリダイレクトする、という動きでもかまわない。

「パッケージを展開した物という関係を示す名前」や「複数URLのまとまり」を表すメディアタイプがない

こんなことを考えつつ吐き出さないでずるずる来てしまったのは、「名前」の問題が大きい。

EPUB -> それを展開したやつ

という関係を示す、relに書けるような名前がない。上で書いたようにrevでいいような気もしないでもないけど、HTML5で消えてしまったわけだし(事情は知らないけど)、relの方がなんとなく気持ちがいい。

それに、個人的な事情だけど、<e-book>を<video>のアナロジーに頼って作っているので、

<e-book>
  <source src="http://example.net/nice/book/" rel="...">
</e-book>

という風にも書けるようにしたいのだ。

それから、この

http://example.net/nice/book/

を表すメディアタイプを見付けられなかった。 このURLにアクセスすると、典型的なApacheの設定だと401エラーか、直下のファイル/ディレクトリー一覧が表示されると思う。その表現は多くの場合HTMLだ。でも、だからといってtext/htmlにするのはなんか違うし、そもそもJSONだったりすることも普通にある。
だいたい、EPUBリーダーの方は、このURLにアクセスしない。実際のEPUBの中身にアクセスする時の基準をここに置くだけだ。そういった「軸」を表す物、それか「複数のファイルを一つのURLに集約した物」とも見られるのでそういう物、を表現するメディアタイプを僕は知らない(あれ、書きながら思ったけどHTMLの<base>ってヒントになるかも?)。

なければ作ればいいんだろうけど、僕が考えると「epub-ocf-root」みたいなセンスのない名前になってしまう。

この辺、何かアイディアとか、知見とか、ある人いませんか?

余談だけどこういう要求にはPackaging on the Webが中々よさそう、残念ながら僕のこのケースでは完全にはフィットしないのだけど。

まとめ

まとめはない。
こんな感じで、ぼんやりとたまに考えつつ過ごしてます。興味ある人がもしいたら教えてください。
あるいはあとを引き取って完成させてIDPFとかに提案して採択までいってもらえると大変楽でよいです。