rails/guides/rails_guides/epub.rb

95 lines
2.8 KiB
Ruby

#!/usr/bin/env ruby
# frozen_string_literal: true
require "nokogiri"
require "fileutils"
require "yaml"
require "date"
require "rails_guides/epub_packer"
module Epub # :nodoc:
extend self
def generate(output_dir, epub_outfile)
fix_file_names(output_dir)
generate_meta_files(output_dir)
generate_epub(output_dir, epub_outfile)
end
private
def open_toc_doc(toc)
Nokogiri::XML(toc).xpath("//ncx:content", "ncx" => "http://www.daisy.org/z3986/2005/ncx/")
end
def generate_meta_files(output_dir)
output_dir = File.absolute_path(File.join(output_dir, ".."))
Dir.chdir output_dir do
puts "=> Using output dir: #{output_dir}"
puts "=> Generating meta files"
FileUtils.mkdir_p("META-INF")
File.write("META-INF/container.xml", <<~CONTENT)
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
<rootfiles>
<rootfile full-path="OEBPS/rails_guides.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
CONTENT
end
end
def generate_epub(output_dir, epub_outfile)
output_dir = File.absolute_path(File.join(output_dir, ".."))
Dir.chdir output_dir do
puts "=> Generating EPUB"
EpubPacker.pack("./", epub_outfile)
puts "=> Done Generating EPUB"
end
end
def is_name_invalid(name)
name.match?(/\A\d/)
end
def fix_file_names(output_dir)
book_dir = File.absolute_path(output_dir)
Dir.chdir book_dir do
puts "=> Using book dir: #{book_dir}"
puts "=> Fixing filenames in Table of Contents"
# opf file: item->id and itemref->idref attributes does not support values starting with a number
toc = File.read("toc.ncx")
toc_html = File.read("toc.html")
opf = File.read("rails_guides.opf")
doc = open_toc_doc(toc)
doc.each do |c|
name = c[:src]
if is_name_invalid(name)
FileUtils.mv(name, "rails_#{name}")
toc.gsub!(name, "rails_#{name}")
toc_html.gsub!(name, "rails_#{name}")
opf.gsub!(name, "rails_#{name}")
end
end
File.write("toc.ncx", toc)
File.write("toc.html", toc_html)
File.write("rails_guides.opf", opf)
end
end
def add_head_section(doc, title)
head = Nokogiri::XML::Node.new "head", doc
title_node = Nokogiri::XML::Node.new "title", doc
title_node.content = title
title_node.parent = head
css = Nokogiri::XML::Node.new "link", doc
css["rel"] = "stylesheet"
css["type"] = "text/css"
css["href"] = "#{Dir.pwd}/stylesheets/epub.css"
css.parent = head
doc.at("body").before head
end
end