すったもんだの末、小説「ハムスターに水を」のオンライン出版にこぎ着けた不詳高橋ですが、ePubファイルを作るのが大変だったのでここのその軌跡を記します。【目指せePub出版】Webkitでtext-align:justifyに挑戦するの続きです。
結論を短くまとめると以下の通りです。HTML、CSS、JavaScriptおよびePubの知識がないと意味がわからないと思います。
- 縦書きは現時点(2010/10/15)無理
- テキスト両端揃えはできないことはないが、メモリが足りないので使い所注意
- ルビはまあできないことはない
- ルビやテキスト両端揃えに対応した時点で、Adobe Degital EditionsやKindleに対応するのは難しくなる。
- 圏点はできる
というわけで、つらつら書いていきます。
iBooks向けのePubを作る際に押さえておきたいこと
まず、iBooksというアプリケーションはWebkitベースで作成されています。iPhone SDKをちょっとでもいじった人はわかると思うのですが、UIWebViewというWebkitベースの巨大なViewクラスがあって、それがベースだと思います。iPhoneに入っているSafariもこれを拡張したものだと思います。
同じ会社が作っているものなので、当然リソースは共有されるでしょうし、基本的な開発順序は以下のようになっているはずです。
- PC用のSafari
- Mobile Safari
- iBooks
事実、PC用のSafariではすでにWeb-fontやルビがサポートされていますが、iBooksはまだ(SVGフォントじゃないと駄目)です。
他の電子書籍リーダーについても同じことがいえます。
AdobeのDegital EditionsはおそらくAIR + TextLayoutFrameworkでしょうし、開発リソースはAdobe社のものが優先して使われるはずです。
したがって、各社の端末および電子書籍リーダーは様々な実装のレベルを持つため、一つのePubでどの端末でもまともな見栄えを保つというのは、かなり難しいでしょう。
実際、「ハムスターに水を」はルビを表示できるようにしたため、Degital Editionsではルビの部分が消えてしまうことになりました。
小室哲哉がTwitterを始めた電子書籍元年においても、やはり標準化は「届きそうで届かないイチゴ」なのでした。
1. iBooksで縦書きは無理っぽい
縦書きですが、現状のCSS3ではサポートされていません。CSS3の仕様にはwriting-modeとして含まれる予定のようですが、CSS3を実装するePub3.0は2011年5月に標準勧告予定なので、実装はまだ先になると思います。上手く行けばAppleが先行実装してくれるかもしれません。
1ページだけ縦書きを実現するのはそんなに難しくない(涅槃とか竹取JSを使う)ですが、普通の長編小説や雑誌等はもっと長いので無理だと思います。「くっ、メモリが足りない!」となってあっさり落ちます。
またもっとも致命的なのはiBooksでは「綴じ方向」の概念がないことです。このため、次のページは必ず右側にあります。
これを変えることができれば縦書きでの実装も可能だと思いますが、いつになるかはよくわかりません。もしかしたらもう作ってるのかな。
「Helvetica」という映画に詳しいのですが、スティーブ・ジョブズは大学時代にタイポグラフィの授業に感動して、Mac開発時にライノタイプ社に突撃、Macの豊かなフォント環境を準備したそうです。同じ情熱を日本語に対してもぶつけてくれると嬉しいのですが…まあ、無理か。
[429] [429] Client error: `POST https://webservices.amazon.co.jp/paapi5/getitems` resulted in a `429 Too Many Requests` response: {"__type":"com.amazon.paapi5#TooManyRequestsException","Errors":[{"Code":"TooManyRequests","Message":"The request was de (truncated...)
追記@2010-10-17 ちなみに、iPadにはヒラギノ明朝がインストールされていますが、CSSで指定しても反映されません。くわしくはnovi’s pageさんの「iBooks で好きなフォントを使用する」をご覧下さい。追記@2010-10-20 やっぱりできました。
2. テキスト両端揃え
以前のエントリーで書いた通り、やろうと思えばできます。両端揃えしたい段落のすべての文字の間に幅0かつ半角スペースが入っているspanタグ(活版印刷に敬意を表してintelというクラス名がいいと思います)を挟んでやればいいのです。
<p class="justify">私は心天をいやらしい意味に捉えていました。</p> <!-- ↓こうする--> <p class="justify">私<span class="intel"> </span>は<span class="intel"> </span>心<span class="intel"> </span>天<span class="intel"> </span>を<span class="intel"> </span>い<span class="intel"> </span>や<span class="intel"> </span>ら<span class="intel"> </span>し<span class="intel"> </span>い<span class="intel"> </span>意<span class="intel"> </span>味<span class="intel"> </span>に<span class="intel"> </span>捉<span class="intel"> </span>え<span class="intel"> </span>て<span class="intel"> </span>い<span class="intel"> </span>ま<span class="intel"> </span>し<span class="intel"> </span>た。</p>
これはひどいマークアップですね…
/*両端揃えにしたいpタグ*/ .justify{ text-align:justify; } /*挿入用spanタグ*/ .intel{ width:0; font-size:0; overflow:hidden; }
理想としては、レイアウト用の余計なタグは入れたくないので、Javascriptによって動的に挿入していくことなのですが…これがうまくいきません。
1,2ページの文章ならいいのですが、「ハムスターに水を」のような長編小説にJavascriptによるDOM操作をやると、前回書いた通り、iBooksが落ちたり、ページネーションが壊れちゃいます。理由は以下の2つです。
- iBooksはJavascriptをサポートしているが、JSによってDOMを変更した場合、再描画がうまくいかない。っていうか再描画しようとさえしてなくない?
- Javascriptで使えるメモリは凄く少ないので、ものすごく時間がかかるか、落ちる。
ちなみにMobile Safariだと上記の問題はおきず、上手くいきました。
これは単なる予想ですが、iBooksはUIWebViewにラッパーかぶせてるだけじゃなくて、UIWebViewを継承して激しくオーバーライドしてるんじゃないですかねー。Objective-Cはぜんぜん詳しくありませんが。
iBooksは最初にファイルを読み込んでからキャッシュを作成するようなので、そこら辺の実装がMobiel Safariよりも動的なレンダリングを苦手とする要因のように思えます。
とにかく、テキスト両端揃えを実現するには、動的にspan.intelを差し込んでいくのではなく、あらかじめファイルに入れておく必要があります。これにより、テキストが奇麗にジャスティファイされます。
これを実現するためのPHPクラスintel-injectorをGistに上げておいたので、PHPerの方は勝手に使ってください。DOMってるだけです。
ただし、全文に対してspanタグを入れると、フォントサイズ変更時に十中八九メモリを使いきって落ちます。また、起動も死ぬほど遅くなります。
したがって、ピンポイントで使う必要があり、全文をテキスト両端揃えすることはいまのところあきらめた方がよろしいです。
iPadならいけるんですけどねー。
使いどころに関しては次項のルビと併せてご覧下さい。
3.ルビは実現可能
ルビは早い話、実現可能です。
gistにソースを上げておきましたが、マークアップをこんな風にすれば大丈夫です。
<p>私は<span class="ruby"><span class="rb">心天</span><span class="rt">ところてん</span></span>をいやらしい意味に捉えていました。</p>
なぜrubyタグではなくspanタグを使っているかというと、iBooks自体はrubyタグでもオッケーなんですが、僕がiBookStoreへの出品を申し込んだLulu.comというサービスのバリデーション(Threepress Consulting Inc.のバリデータと同じ)でrubyタグが通らなかったんですね。
一応、xhtml1.1にはrubyタグが拡張モジュールとして入っているはずなんですが、なぜか駄目でした。したがってspanタグにしています。
僕のように出品するのではなく、直接ダウンロードなどで配信するだけならば、以下のようなマークアップでも大丈夫です。
<p>私は<ruby><rb>心太</rb><rt>ところてん</rt></ruby>をいやらしい意味に捉えていました。</p>
で、肝はCSSです。
.ruby{ overflow:hidden; width:auto; display:inline-table; line-height:2.2em; vertical-align:text-bottom; border-collapse:collapse; border-width:0; padding:0; margin:0; text-indent:0; } .rb { line-height:1.1em; text-align:center; vertical-align:baseline; display:table-row-group; text-indent:0; margin:0; padding:0; border-width:0; } .rt { font-size:0.5em; display:table-header-group; text-align:center; text-justify:distribute-all-lines; line-height:1.1; text-indent:0; }
全部が必要な指定というわけではないですが、おまじない的に書いておきました。これでもベースラインより少し下に下がってしまいますが、まあ現状では我慢ですね。
iBooksのキャッシュは相当強力なので、CSSの微調整は絶望的に面倒です。追記@2010-10-17 メタ情報のIDを変更することでキャッシュ関係無しに最新のデータが表示されますが、iTunesに取り込む作業が面倒過ぎて死にます。
さて、これでrubyが実現できて嬉しーとなるのですが、衝撃的な問題が発生します。それは、「ルビの後に謎のスペースが出たり出なかったりする」です。
スペースができるのは以下の条件が重なったときです。
- rubyがその行内に存在する
- その行が段落の最後ではない(=禁則処理が行われる)
要するに、最後の行以外にルビがあると謎のスペースが出現するんですね。ePubはリフロー型なので、「ルビが必ず最後の行に来る」ということは確証しづらいですよね。
出現条件はわかりましたが、なぜこうなるかはさっぱりわかりません。やはりinline-tableは高度なのでしょうか。
試行錯誤の末、上記で紹介したテキスト両端揃えを適用すると直るということがわかりましたので、「ハムスターに水を」ではルビの入っている段落だけspan.intelを挿入しています。
幸いというか、あえてそうしたのですが、「ハムスターに水を」は登場人物名ぐらいにしかルビが使われていません。しかし、総ルビの作品なんかはメモリが足りなくなると思います。
4.ルビや両端揃えを実装すると他の端末で見られないかも
今回の「ハムスターに水を」はiBooksを利用できるユーザーを想定して作成しました。
ただ、僕が販売先として選んだLulu.comではなぜかAdobe Degital Editionのマークがでかでかとあるので、それで見るものだと勘違いしてしまう方も多かろうと思います。しかし、実はiBooks専用です。
さんざんiBooksの悪口を行ってきましたが、HTML+CSSのレンダラーとしてはDegital EditonsよりWebkit(Cocoa Touchフレームワーク?)の方がはるかに高度です。
Degital Editionsだとinline-tableが使えないうえ、入れ子になったspanタグもrubyのように認識されないタグも消えます。
これはTextLayoutFrameworkがそういう仕様なので、どうしようもありません。みんなAdobeのTLFフォーラムで戸惑ってます。
また、ePuber(そんな言葉ある?)の @naokisatoname さんが検証してくれたのですが、kindlegenでこのePubを変換しても崩れるようです。
というわけで、iBooksに併せて色々とやると他の端末で見られなくなるというブラウザ戦争の悲劇がここでもまた繰り返されていますね。
どうして世の中から戦争はなくならないの…? 僕は悲しいです。
5.圏点はできる
圏点はけっこう簡単です。こんな感じです。ゴマっぽい画像を用意してください。
<p>ヘーゲルの本では<strong>世</strong><strong>界</strong><strong>内</strong><strong>存</strong><strong>在</strong>という言葉に圏点がついている</p>
strong{ height:2em; display:inline-block; vertical-align:baseline; padding:0; line-height:2em; text-indent:0; background:url(../Images/dot.png) center top no-repeat; font-weight:normal; }
また気持ち悪いマークアップになりましたが、しょうがないですね。
もしiBooksが動的なDOMいじりに対応してくれれば、こんなことにはならないのですが…
次回予告:そうはいっても電子出版はやさしい
というわけで、制作の部分について自分が困ったことを記してみました。
他はあんまり困らなかったというか、ググれば出てくると思います。Sigliとか使えばDreamWeaverっぽくできますし、InDesignからの書き出し実験をしている方も多いです。
ただ、本を出すだけではしょうがないので、色々と試行錯誤して売ってみたいと思っています。
その結果については12月の文学フリマで出る破滅派七号やこのブログでの続報をお楽しみに。