nanocでブログをEPUB3電子書籍化する

このブログはRuby製静的CMSのnanocで構築しています。nanocについて詳しくは「nanoc導入メモ」をご覧ください。

nanocは本来、静的Webサイトを構築するためのツールですが、使い方次第ではEPUB3フォーマットでの電子書籍の生成に活用することができます。

これにより、面倒な目次の生成などは自動化し、haml・sassでレイアウトを定義してmarkdownでEPUB3を作るということが可能になります。

今回は、nanocで作成したブログをEPUB3化する際のポイントについて紹介します。

EPUB3出力用nanocサイトの作成

EPUB3出力用のサイトを新規に作成します。

> nanoc create EPUB3出力用サイト名

config.yamlの設定

config.yamlは既存サイトのものをそのまま流用します。

Rulesの設定

Rulesファイルでポイントになるのは、ファイルのルーティング設定です。mimetypeや.opfが正しいファイル名で出力されるよう設定します。

~中略~
route '/mimetype' do
  '/mimetype'
end
route '/OEBPS/package' do
  '/OEBPS/package.opf'
end
route '/OEBPS/toc' do
  '/OEBPS/toc.ncx'
end

route '*' do
  if item.binary?
    item.identifier.chop + '.' + item[:extension]
  else
    case item[:extension]
      when 'sass'
        item.identifier.chop + '.css'
      when 'css'
        item.identifier.chop + '.css'
      when 'js'
        item.identifier.chop + '.js'
      when 'xml'
        item.identifier.chop + '.xml'
      else
        item.identifier.chop + '.xhtml'
    end
  end
end
~中略~

lib/default.rbの設定

ブログのコンテンツをEPUB3化するにあたり、不要なタグ等を除去するフィルタを追加します。以下はiframeタグを除去する例です。

~中略~
class Epub3Filter < Nanoc::Filter
  identifier :epub3_filter

  def run(content, params={})
    mod_content = mod_content.gsub(/^<iframe .*?<\/iframe>/, '')
  end
end
~中略~

EPUB3出力用nanocコンテンツの作成

EPUB3の作り方」で書いた内容に相当するコンテンツを作成します。

「content/mimetype」と「content/META-INF/container.xml」は前記事内容のまま使用できるため説明を省略します。

content/OEBPS/package.hamlの作成

.opfファイルとして出力するためのものです。

!!! XML
%package{"unique-identifier" => "BookID", :version => "3.0", :xmlns => "http://www.idpf.org/2007/opf"}
  %metadata{"xmlns:dc" => "http://purl.org/dc/elements/1.1/"}
    %dc:title= "#{@config[:title]}"
    %dc:identifier#BookID= @config[:base_url].sub(/^http:\/\//,'')
    %dc:language ja
    %meta{:property => "dcterms:modified"}= "#{sorted_articles.first[:created_at]}T12:00:00Z"
    %dc:date= "#{sorted_articles.first[:created_at]}T12:00:00Z"
    %dc:creator= @config[:author_name]
    %dc:publisher= @config[:author_uri]
  %manifest
    %item#nav{:href => "contents.xhtml", "media-type" => "application/xhtml+xml", :properties => "nav"}/
    %item#coverpage{:href => "cover.xhtml", "media-type" => "application/xhtml+xml"}/
    %item#ncx{:href => "toc.ncx", "media-type" => "application/x-dtbncx+xml"}/
    %item#stylesheet{:href => "stylesheets/style.css", "media-type" => "text/css"}/
    - sorted_articles.reverse.each do |article|
      = %Q[<item id="article_#{article.identifier.sub(/^\/OEBPS\/articles\/(.*)\//, '\1')}" href="#{article.path.sub(/^\/OEBPS\//,'')}" media-type="application/xhtml+xml" />]
  %spine{"page-progression-direction" => "ltr", "toc" => "ncx"}
    %itemref{:idref => "coverpage", :linear => "yes"}/
    %itemref{:idref => "nav", :linear => "yes"}/
    - sorted_articles.reverse.each do |article|
      = %Q[<itemref idref="article_#{article.identifier.sub(/^\/OEBPS\/articles\/(.*)\//, '\1')}" linear="yes" />]

content/OEBPS/cover.hamlの作成

表紙です。

!!! XML
!!! 5
%html{:lang => "ja", "xml:lang" => "ja", :xmlns => "http://www.w3.org/1999/xhtml", "xmlns:epub" => "http://www.idpf.org/2007/ops"}
  %head
    %title= "#{@config[:title]}"
    %link{:href => "stylesheets/style.css", :rel => "stylesheet", :type => "text/css"}/
  %body
    #cover
      %h1
        = @config[:title]
      %h2
        = "#{sorted_articles.last[:created_at]} ~ #{sorted_articles.first[:created_at]}"
        %br/
        = "全#{sorted_articles.count}件"
      %p
        Author : #{@config[:author_name]}
        %br/
        #{@config[:author_uri]}

content/OEBPS/contents.hamlの作成

EPUB3の目次です。

!!! XML
!!! 5
%html{:lang => "ja", "xml:lang" => "ja", :xmlns => "http://www.w3.org/1999/xhtml", "xmlns:epub" => "http://www.idpf.org/2007/ops"}
  %head
    %title= "#{@config[:title]}"
    %link{:href => "stylesheets/style.css", :rel => "stylesheet", :type => "text/css"}/
  %body
    %nav#toc{"epub:type" => "toc"}
      %h1 目次
      %ul
        %li= link_to("表紙", "cover.xhtml")
        %li= link_to("目次", "contents.xhtml")
      - grouped_articles.reverse.each do |yearmonth, articles_this_month|
        %h2= "#{yearmonth.first}年#{yearmonth.last}月"
        %ul
          - articles_this_month.reverse.each do |article|
            %li
              %span= "#{Time.parse(article[:created_at]).strftime("%d日")}"
              = link_to("#{article[:title]}", article.path.sub(/^\/OEBPS\//,''))

content/OEBPS/toc.hamlの作成

EPUB2互換の目次です。(Sony Readerでの目次機能にはこれが必要)

!!! XML
! 

content/OEBPS/articles/の作成

記事本文の.mkdファイルを配置します。

content/OEBPS/images/の作成

記事本文で使用する画像ファイルを配置します。

content/OEBPS/stylesheets/style.sassの作成

スタイルシートです。

#cover
  :font-family sans-serif
  :text-align center
  :border 3px double #000
  :margin 2em 1em
  :padding 0.5em
#page
  h3
    :border-left 6px solid #EB538C
    :border-right 6px solid #EB538C
    :border-top 1px solid #EB538C
    :border-bottom 1px solid #EB538C
    :padding 3px 4px
  h4
    :border-left 4px solid #1BE497
    :padding 3px 3px
  h5
    :display inline
    :border-left 2px solid #666
    :border-right 2px solid #666
    :background-color #F3F3F3
    :padding 2px 5px
  pre
    :font-family monospace, sans-serif
    :font-size small
    :line-height 95%
    :color #fff
    :background-color #333
    :margin 0 1em
    :padding 5px
    :word-wrap break-word
#page h1
  :display none

layouts/default.hamlの作成

記事本文表示用のレイアウトです。

!!! XML
!!! 5
%html{:lang => "ja", "xml:lang" => "ja", :xmlns => "http://www.w3.org/1999/xhtml", "xmlns:epub" => "http://www.idpf.org/2007/ops"}
  %head
    %title= "#{@item[:title]}"
    %link{:href => "../stylesheets/style.css", :rel => "stylesheet", :type => "text/css"}/
  %body
    #page
      #header
        %h1= "#{@config[:title]}"
      #section
        #article
          %h2= "#{@item[:title]}"
          %p.article_meta
            Created at: #{"#{@item[:created_at]}"} | Tags: #{"#{tags_for(@item, {:base_url => "http://n.blueblack.net/tags/index.html#"})}"}
          = yield

EPUB3出力用.batファイルの作成

コンテンツが用意できたらnanocサイトのコンパイルと、.epubファイルのパッケージングを行います。この作業は修正の度に繰り返し実行することになるため、.bat化しておくと便利です。

tools/nanoc_compile.batの作成

cd "C:\path\to\nanoc_site"
cmd /C nanoc compile
pause
del "C:\path\to\nanoc_site\book.epub"
cd "C:\path\to\nanoc_site\output"
zip -0 -X ../book.epub mimetype
zip -r ../book.epub * -x mimetype
pause

おわりに

上記手順により、本ブログの現在までの記事をEPUB3化しました。以下からダウンロードして全記事を読むことができます。なお、本ファイルの再配布は禁止します。

Sony Reader(PRS-T1:2.0.02.06220)で表示確認していますが、リーダによっては不具合が出るかもしれないので自己責任で使用して下さい。

既知の問題として、Sony Readerでは<pre><code>タグ内のコードが改行されず、画面に収まらない行末の部分が隠れてしまいます。CSSでの対処法等分かれば教えてもらえると助かります。

追記@2012-08-29

以下のとおり修正しました。

  • dc:identifier、idを修正(無効な文字、先頭の数字など)
  • 目次に「表紙」「目次」を追加
  • EPUB2互換(toc.ncx)によるSony Readerの目次表示に対応
  • 記事のxhtml出力先をOEBPS直下からarticles配下に変更
  • .opfファイル名をbook.opfからpackage.opfに変更
  • EPUB3目次ファイル名をnav.xhtmlからcontents.xhtmlに変更
blog comments powered by Disqus