gepub
| Language | Ruby |
|---|---|
| License | BSD-3-Clause |
| Repository | github.com/skoji/gepub |
| Documentation | rubydoc.info/github/skoji/gepub |
| Depends on | nokogiri, rubyzip |
| Read / write | yes / yes (EPUB 2 and EPUB 3) |
gepub reads and writes EPUB files through GEPUB::Book. It supports every metadata element of EPUB 2 and EPUB 3, including refinements such as title types, display order, file-as and alternate-language versions of titles and creator names. When you generate a book it writes the package document, a navigation document and an NCX, and zips the result with mimetype first.
Parsing gives you the metadata, the manifest items with their content, and the spine. gepub doesn’t render or convert XHTML; use Nokogiri on the item content to get text.
Installation#
gem install gepub
Or in a Gemfile: gem "gepub".
Basic usage: read an EPUB#
require "gepub"
book = File.open("book.epub", "rb") { |f| GEPUB::Book.parse(f) }
puts "Title: #{book.title}"
puts "Authors: #{book.creator_list.map(&:to_s).join(', ')}"
puts "Language: #{book.language}"
puts "Version: #{book.version}"
# chapters in reading order
book.spine_items.each do |item|
puts "#{item.href} (#{item.media_type}): #{item.content.bytesize} bytes"
end
How to extract text from an EPUB#
require "gepub"
require "nokogiri"
book = GEPUB::Book.parse(File.open("book.epub", "rb"))
text = book.spine_items.map do |item|
Nokogiri::HTML(item.content).text.strip
end.join("\n\n")
File.write("book.txt", text)
How to extract images#
book.items is a hash of manifest id to item:
Dir.mkdir("images") unless Dir.exist?("images")
book.items.each_value do |item|
next unless item.media_type.to_s.start_with?("image/")
File.binwrite(File.join("images", File.basename(item.href)), item.content)
end
How to create an EPUB#
require "gepub"
require "stringio"
book = GEPUB::Book.new
book.primary_identifier("urn:uuid:9e2f3c1a-4b5d-4c6e-8f70-1a2b3c4d5e6f", "BookId", "UUID")
book.language = "en"
book.add_title "My Book", title_type: GEPUB::TITLE_TYPE::MAIN
book.add_creator "Jane Doe"
File.open("cover.jpg", "rb") do |io|
book.add_item("img/cover.jpg", content: io).cover_image
end
chapters = [
["Chapter 1", "First chapter."],
["Chapter 2", "Second chapter."],
]
# items added inside ordered {} go into the spine in this order
book.ordered do
chapters.each_with_index do |(title, text), i|
xhtml = <<~XHTML
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>#{title}</title></head>
<body><h1>#{title}</h1><p>#{text}</p></body></html>
XHTML
book.add_item("text/chap#{i + 1}.xhtml").add_content(StringIO.new(xhtml)).toc_text(title)
end
end
book.generate_epub("book.epub")
toc_text adds the item to the table of contents; items without it are in the spine but not in the TOC. If you don’t add a navigation document yourself, generate_epub creates one.
How to change the title of an existing EPUB#
book = File.open("in.epub", "rb") { |f| GEPUB::Book.parse(f) }
book.title = "New Title"
book.generate_epub("out.epub")
Tips#
book.generate_epub_streamreturns the EPUB as aStringIO, useful for sending it from a web app.- Metadata getters return
GEPUB::Metaobjects; callto_sto get the string, or.contentand attribute methods (file_as,display_seq) for details. - For EPUB 3 fixed layout, set
book.rendition_layout = "pre-paginated".