Pandocで生成したEPUBをRubyで修正してみる
スポンサーリンク
Pandocネタの続き。おそらく正しい対処法はPandocのfilter機能を使う方法。解説というよりは備忘録です。あしからず。
その場しのぎのやっつけとして適当なスクリプト言語で書き換える。
背景
PandocでEPUBを作る際に、--number-sections
オプションを使うと章番号、セクション番号を自動的に割り振ってくれる。
しかし、「第n章」や「Chapter n」のようにはしてくれない。CSS疑似要素である程度は設定できるが、いずれにしろ標準機能では対応していない。
Pandocのバージョンは2.2.3.2。フォーマットはEPUB3。
EPUBと目次
EPUBの正体はCSSとHTML(正確に言うとXMLベース)の寄せ集めをZipで圧縮したものなので展開して編集して再度圧縮すれば問題ない。
EPUBには目次用のファイルとしてEPUB2用のtoc.ncx
とEPUB3系のnav.xhtml
、さらに目次ページが存在している。
問題はnav.xhtml
。EPUBビューワーで目次ページとして表示する場合はCSSが使える。そのためCSS疑似要素で章番号のフォーマットをいじることができる。
残念ながらこのnav.xhtml
はナビゲーションパネルにも使用され、その場合はCSSは機能しない。故にCSSの疑似要素で章番号のスタイルを変えるという方式は
中途半端になってしまう*1。
実際の対応
hav.xhtml
とtoc.ncx
はスクリプトで書き換えて、本文側はCSSで擬似要素として実現する方式。
追加の要件として「付録」という見出しの章はセクションを含めて特別扱いする。
ただ、疑似要素による章見出しはKindle化した際に見栄えが良くないかも。
nav.xhtmlの修正
nav.xhtml
は<nav>
要素で<ol><li><a>...
というリストをラップしているだけ。もちろん<ol>
要素が入れ子担っている点を考慮する必要がある。
NokogiriのXPath指定で<a>
タグを取り出して条件に合うところだけ書き換える。XMLなのでnamespace
を考慮する。
chapter_node = node.xpath('./xmlns:a')
章番号、セクション番号ともに<a>
タグの内側に<span>
タグで囲まれているので正規表現でマッチしたところを書き換える。
toc.ncxの修正
章の見出しだけ書き換える。<navLabel>
というタグの要素を取り出す。
ncx_xml.xpath('//xmlns:navLabel/xmlns:text')
<navLabel>
というタグの下に<navLabel>
というタグがあるので親のタグだけ書き換える。
本文側の修正
./EPUB/text/ch00X.xhtml
の各ファイルを修正する。以下のような形式なので対して難しくない。
<h1><span class="header-section-number">5</span>
付録扱いしたいChapterだけ<span>
タグのクラスを置き換えて対処。それ以外はCSSで対応。
h1 > span.header-section-number::before { content: "第" ; } h1 > span.header-section-number::after { content: "章" ; }
スクリプトによる修正
EPUBを_temp
というフォルダに展開しているという前提。
EPUBビューワーの目次ページではCSSが効くが、目次パネル(?)ではCSSが効かないのでこういう微妙な対処方法に。
書き換えの対象
Nokogiriのインストール
$ gem install nokogiri
コード
Pandocで生成したepubファイルの目次情報と章番号を修正するRubyスクリプト
ザ・やっつけ仕事ですが似たようなことをやる人の参考になりますようにということで。
展開と再圧縮
これも備忘録。実際はRakeで一気にやっています。
展開
$ unzip -q temp.epub -d _temp
temp.epub
というEPUB3形式のファイルを_temp
に展開。
再圧縮
必要な箇所を修正したら再度圧縮する。mimetype
というファイルだけ圧縮率0にする。
展開先のディレクトリ(この例では_temp
)に移動してから再圧縮。
$ cd _temp
まずmimetype
というファイルだけ入ったファイルを作り、その後で残りのファイルを圧縮してくっつけるイメージ。
$ zip -0Xq output.epub mimetype $ zip -Xr9Dq outoput.epub *
これでOK。
参考
EPUB生成のpandocのコマンドは下記のとおり。
$ pandoc -f markdown -t epub3 --epub-metadata=metadata.xml -o temp.epub title.txt *.md --epub-cover-image=image.png --css=github.css --toc --toc-depth=2 --epub-chapter-leve=1 --number-sections --no-highlight
title.txtはタイトルと著者、元データはMarkdown。
参考にしたサイトは次のとおり。
まとめ
EPUBがWeb技術ベースなのでこれまでの知識がかなり活用できている。EPUBの仕様策定に関わった方々の好判断の賜物。
ちゃんとPandocのfilter機能を勉強するのが一番だけど。
- 作者: 林拓也
- 出版社/メーカー: 技術評論社
- 発売日: 2012/08/25
- メディア: 大型本
- この商品を含むブログ (2件) を見る
プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)
- 作者: 伊藤淳一
- 出版社/メーカー: 技術評論社
- 発売日: 2017/11/25
- メディア: 大型本
- この商品を含むブログを見る
*1:もちろんナビゲーションパネルと目次ページ、本文で章番号の形式が変わってもいいなら問題ない