2020年8月26日水曜日

ruby で gepub を使って EPUB ファイルを作成してみた

概要

ePUB ファイルを ruby で作成してみました
gepub という gem があったのでそれを使っています

環境

  • macOS 10.15.6
  • Ruby 2.7.1p83
    • gepub 1.0.11

インストール

  • bundle init
  • vim Gemfile
gem "gepub"
  • bundle config path vendor
  • bundle install

サンプルコード

ちょっと長いですがやっていることは単純で本のコンテンツを作成して ePUB オブジェクトにコンテンツを追加しているです
後述で詳細を説明しています

  • vim app.rb
# coding: utf-8
require "gepub"

# 最初に本のコンテンツ情報を定義します
cover_image_file = "cover.png"
book_title = "自分の本のタイトル"
book_creator = "hawksnowlog"

cover_title = "Cover Page"
cover_content = StringIO.new(<<-EOF)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>#{cover_title}</title>
</head>
<body>
<h1>#{book_title}</h1>
<img src="../img/#{cover_image_file}" />
</body>
</html>
EOF

capter1_name = "チャプタ 1"
c1_s1_title = "Section1"
c1_s1_content = StringIO.new(<<-EOF)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>#{c1_s1_title}</title>
</head>
<body>
<p>capter1 section1 page</p>
</body>
</html>
EOF
c1_s2_title = "Section2"
c1_s2_content = StringIO.new(<<-EOF)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>#{c1_s2_title}</title>
</head>
<body>
<p>capter1 section2 page</p>
</body>
</html>
EOF

capter2_name = "チャプタ 2"
c2_s1_title = "Section3"
c2_s1_content = StringIO.new(<<-EOF)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>#{c2_s1_title}</title>
</head>
<body>
<p>capter2 section1 page</p>
</body>
</html>
EOF

nav_content = StringIO.new(<<-EOF)
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
  <title>Table of contents</title>
</head>
<body>
<nav epub:type="toc" id="toc">
  <h1>Table of contents</h1>
  <ol>
    <li><a href="chap1-1.xhtml">#{capter1_name}</a></li>
    <li><a href="chap2-1.xhtml">#{capter2_name}</a></li>
  </ol>
</nav>
</body>
</html>
EOF

# ここから ePUB 情報を生成していきます 
book = GEPUB::Book.new
book.primary_identifier('https://hawksnowlog.blogspot.com/', 'BookID', 'URL')
book.language = 'ja'

book.add_title(
  book_title,
  title_type: GEPUB::TITLE_TYPE::MAIN,
  lang: 'ja',
  display_seq: 1
)
book.add_creator(
  book_creator, 
  display_seq: 1
)

File.open("./#{cover_image_file}") do |io|
  book.add_item("img/#{cover_image_file}", content: io).cover_image
end

# 本のコンテンツ部分を生成します
book.ordered {
  book.add_item(
    'text/cover.xhtml',
    content: cover_content).landmark(type: "cover", title: cover_title)
  book.add_item(
    'text/nav.xhtml',
    content:nav_content).add_property('nav')
  book.add_item(
    'text/chap1-1.xhtml',
    content: c1_s1_content).toc_text(capter1_name).landmark(type: "bodymatter", title: c1_s1_title)
  book.add_item(
    'text/chap1-2.xhtml',
    content: c1_s2_content)
  book.add_item(
    'text/chap2-1.xhtml',
    content: c2_s1_content).toc_text(capter2_name)
}

# ePUB ファイルの書き出し
epubname = File.join(File.dirname(__FILE__), 'my_book.epub')
book.generate_epub(epubname)
  • bundle exec ruby app.rb

解説

わかりやすいように本のコンテンツは最初にすべて定義しました
基本は xhtml で作成できるので装飾文字やリストなどは好きなように定義できます
作成したコンテンツは GEPUB::Book のオブジェクトにセットしていきます
add_title, add_creator で本のタイトルと著者を設定します
add_item でコンテンツを追加していきます
追加する際にはチャプタを設定しましょう
またコンテンツは IO を渡すのでコンテンツごとに別ファイルで管理しても OK です
いわゆる目次を作成するには add_item をした上で add_property('nav') を設定しましょう
nav_content の xhtml を見るとわかりますが単純にチャプタ先頭のファイルにリンクを貼ることで目次からチャプタに飛ぶことができます

また .epub ファイルはただの圧縮ファイルです
中身を確認すると xhtml やメタ情報のファイルが確認されています

M Filemode      Length  Date         Time      File
- ----------  --------  -----------  --------  ------------------------
  -rw-r--r--        20  26-Aug-2020  01:22:02  mimetype
  -rw-r--r--       252  26-Aug-2020  01:22:02  META-INF/container.xml
  -rw-r--r--    145170  26-Aug-2020  01:22:02  OEBPS/img/cover.png
  -rw-r--r--      1742  26-Aug-2020  01:22:02  OEBPS/package.opf
  -rw-r--r--       137  26-Aug-2020  01:22:02  OEBPS/text/chap1-1.xhtml
  -rw-r--r--       137  26-Aug-2020  01:22:02  OEBPS/text/chap1-2.xhtml
  -rw-r--r--       137  26-Aug-2020  01:22:02  OEBPS/text/chap2-1.xhtml
  -rw-r--r--       178  26-Aug-2020  01:22:02  OEBPS/text/cover.xhtml
  -rw-r--r--       353  26-Aug-2020  01:22:02  OEBPS/text/nav.xhtml
  -rw-r--r--       793  26-Aug-2020  01:22:02  OEBPS/toc.ncx
- ----------  --------  -----------  --------  ------------------------
                148919                         10 files

ePUB にはルールがあり gepub はそれにそって必要なファイルを自動的に生成してくれる gem になります
もし gepub で操作できないタグなどがあった場合には自分でこれらのファイルを編集してアーカイブし直しても OK です

ePUB Reader のインストール

何でも OK です
Mac の場合は Apple Books のアプリでも epub ファイルを確認できるのでそれでも OK です

もしない場合には Chrome のエクステンションなどもあるのでそれでも OK です
こちらからインストールしてください

動作確認

  • open my_book.epub

Apple Book アプリだと以下のように確認できました

最後に

gepub を使って Ruby から ePUB ファイルを作成してみました
手動で作成することもできますが面倒なのでこういったジェネレータを使うことをオススメします
プログラムから操作できることで例えばブログの情報を取得して ePUB で出版するなんてことも簡単にできるようになるかなと思います
あとはデータベースなんかにある情報も ePUB にできるかなと思います

参考サイト

0 件のコメント:

コメントを投稿