lib/review/epubmaker.rb in review-1.7.2 vs lib/review/epubmaker.rb in review-2.0.0.beta1
- old
+ new
@@ -9,20 +9,19 @@
#
require 'review'
require 'rexml/document'
require 'rexml/streamlistener'
require 'epubmaker'
-require 'review/htmltoc'
module ReVIEW
class EPUBMaker
include ::EPUBMaker
include REXML
def initialize
@producer = nil
- @htmltoc = nil
+ @tochtmltxt = "toc-html.txt"
@buildlogtxt = "build-log.txt"
end
def log(s)
puts s if @params["debug"].present?
@@ -50,11 +49,10 @@
begin
log("Created first temporary directory as #{basetmpdir}.")
call_hook("hook_beforeprocess", basetmpdir)
- @htmltoc = ReVIEW::HTMLToc.new(basetmpdir)
## copy all files into basetmpdir
copy_stylesheet(basetmpdir)
copy_frontmatter(basetmpdir)
call_hook("hook_afterfrontmatter", basetmpdir)
@@ -200,11 +198,11 @@
else
htmlfile = "part_#{part.number}.#{@params["htmlext"]}"
build_part(part, basetmpdir, htmlfile)
title = ReVIEW::I18n.t("part", part.number)
title += ReVIEW::I18n.t("chapter_postfix") + part.name.strip if part.name.strip.present?
- @htmltoc.add_item(0, htmlfile, title, {:chaptype => "part"})
+ write_tochtmltxt(basetmpdir, "0\t#{htmlfile}\t#{title}\tchaptype=part")
write_buildlogtxt(basetmpdir, htmlfile, "")
end
end
part.chapters.each do |chap|
@@ -215,27 +213,25 @@
end
def build_part(part, basetmpdir, htmlfile)
log("Create #{htmlfile} from a template.")
File.open("#{basetmpdir}/#{htmlfile}", "w") do |f|
- @body = ""
- @body << "<div class=\"part\">\n"
- @body << "<h1 class=\"part-number\">#{ReVIEW::I18n.t("part", part.number)}</h1>\n"
+ f.puts header(CGI.escapeHTML(@params["booktitle"]))
+ f.puts <<EOT
+<div class="part">
+<h1 class="part-number">#{ReVIEW::I18n.t("part", part.number)}</h1>
+EOT
if part.name.strip.present?
- @body << "<h2 class=\"part-title\">#{part.name.strip}</h2>\n"
+ f.puts <<EOT
+<h2 class="part-title">#{part.name.strip}</h2>
+EOT
end
- @body << "</div>\n"
- @language = @producer.params['language']
- @stylesheets = @producer.params["stylesheet"]
- if @producer.params["htmlversion"].to_i == 5
- tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
- else
- tmplfile = File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
- end
- tmpl = ReVIEW::Template.load(tmplfile)
- f.write tmpl.result(binding)
+ f.puts <<EOT
+</div>
+EOT
+ f.puts footer
end
end
def build_chap(chap, base_path, basetmpdir, yamlfile, ispart=nil)
filename = ""
@@ -322,31 +318,55 @@
end
first = true
headlines.each do |headline|
headline["level"] = 0 if ispart.present? && headline["level"] == 1
if first.nil?
- @htmltoc.add_item(headline["level"], filename+"#"+headline["id"], headline["title"], {:chaptype => chaptype})
+ write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}##{headline["id"]}\t#{headline["title"]}\tchaptype=#{chaptype}")
else
- @htmltoc.add_item(headline["level"], filename, headline["title"], {:force_include => true, :chaptype => chaptype+prop_str})
+ write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}\t#{headline["title"]}\tforce_include=true,chaptype=#{chaptype}#{prop_str}")
first = nil
end
end
end
def push_contents(basetmpdir)
- @htmltoc.each_item do |level, file, title, args|
- next if level.to_i > @params["toclevel"] && args[:force_include].nil?
- log("Push #{file} to ePUB contents.")
+ File.open("#{basetmpdir}/#{@tochtmltxt}") do |f|
+ f.each_line do |l|
+ force_include = nil
+ customid = nil
+ chaptype = nil
+ properties = nil
+ level, file, title, custom = l.chomp.split("\t")
+ if custom.present?
+ # custom setting
+ vars = custom.split(/,\s*/)
+ vars.each do |var|
+ k, v = var.split("=")
+ case k
+ when "id"
+ customid = v
+ when "force_include"
+ force_include = true
+ when "chaptype"
+ chaptype = v
+ when "properties"
+ properties = v
+ end
+ end
+ end
+ next if level.to_i > @params["toclevel"] && force_include.nil?
+ log("Push #{file} to ePUB contents.")
- hash = {"file" => file, "level" => level.to_i, "title" => title, "chaptype" => args[:chaptype]}
- if args[:id].present?
- hash["id"] = args[:id]
+ hash = {"file" => file, "level" => level.to_i, "title" => title, "chaptype" => chaptype}
+ if customid.present?
+ hash["id"] = customid
+ end
+ if properties.present?
+ hash["properties"] = properties.split(" ")
+ end
+ @producer.contents.push(Content.new(hash))
end
- if args[:properties].present?
- hash["properties"] = args[:properties].split(" ")
- end
- @producer.contents.push(Content.new(hash))
end
end
def copy_stylesheet(basetmpdir)
if @params["stylesheet"].size > 0
@@ -364,78 +384,128 @@
if @params["titlefile"].nil?
build_titlepage(basetmpdir, "titlepage.#{@params["htmlext"]}")
else
FileUtils.cp(@params["titlefile"], "#{basetmpdir}/titlepage.#{@params["htmlext"]}")
end
- @htmltoc.add_item(1, "titlepage.#{@params['htmlext']}", @producer.res.v("titlepagetitle"), {:chaptype => "pre"})
+ write_tochtmltxt(basetmpdir, "1\ttitlepage.#{@params["htmlext"]}\t#{@producer.res.v("titlepagetitle")}\tchaptype=pre")
end
if @params["originaltitlefile"].present? && File.exist?(@params["originaltitlefile"])
FileUtils.cp(@params["originaltitlefile"], "#{basetmpdir}/#{File.basename(@params["originaltitlefile"])}")
- @htmltoc.add_item(1, File.basename(@params["originaltitlefile"]), @producer.res.v("originaltitle"), {:chaptype => "pre"})
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["originaltitlefile"])}\t#{@producer.res.v("originaltitle")}\tchaptype=pre")
end
if @params["creditfile"].present? && File.exist?(@params["creditfile"])
FileUtils.cp(@params["creditfile"], "#{basetmpdir}/#{File.basename(@params["creditfile"])}")
- @htmltoc.add_item(1, File.basename(@params["creditfile"]), @producer.res.v("credittitle"), {:chaptype => "pre"})
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["creditfile"])}\t#{@producer.res.v("credittitle")}\tchaptype=pre")
end
end
def build_titlepage(basetmpdir, htmlfile)
File.open("#{basetmpdir}/#{htmlfile}", "w") do |f|
- @body = ""
- @body << "<div class=\"titlepage\">"
- @body << "<h1 class=\"tp-title\">#{CGI.escapeHTML(@params["booktitle"])}</h1>"
+ f.puts header(CGI.escapeHTML(@params["booktitle"]))
+ f.puts <<EOT
+<div class="titlepage">
+<h1 class="tp-title">#{CGI.escapeHTML(@params["booktitle"])}</h1>
+EOT
+
if @params["aut"]
- @body << "<h2 class=\"tp-author\">#{@params["aut"].join(", ")}</h2>"
+ f.puts <<EOT
+<h2 class="tp-author">#{@params["aut"].join(", ")}</h2>
+EOT
end
if @params["prt"]
- @body << "<h3 class=\"tp-publisher\">#{@params["prt"].join(", ")}</h3>"
+ f.puts <<EOT
+<h3 class="tp-publisher">#{@params["prt"].join(", ")}</h3>
+EOT
end
- @body << "</div>"
- @language = @producer.params['language']
- @stylesheets = @producer.params["stylesheet"]
- if @producer.params["htmlversion"].to_i == 5
- tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
- else
- tmplfile = File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
- end
- tmpl = ReVIEW::Template.load(tmplfile)
- f.write tmpl.result(binding)
+ f.puts <<EOT
+</div>
+EOT
+ f.puts footer
end
end
def copy_backmatter(basetmpdir)
if @params["profile"]
FileUtils.cp(@params["profile"], "#{basetmpdir}/#{File.basename(@params["profile"])}")
- @htmltoc.add_item(1, File.basename(@params["profile"]), @producer.res.v("profiletitle"), {:chaptype => "post"})
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["profile"])}\t#{@producer.res.v("profiletitle")}\tchaptype=post")
end
if @params["advfile"]
FileUtils.cp(@params["advfile"], "#{basetmpdir}/#{File.basename(@params["advfile"])}")
- @htmltoc.add_item(1, File.basename(@params["advfile"]), @producer.res.v("advtitle"), {:chaptype => "post"})
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["advfile"])}\t#{@producer.res.v("advtitle")}\tchaptype=post")
end
if @params["colophon"]
if @params["colophon"].instance_of?(String) # FIXME:このやり方はやめる?
FileUtils.cp(@params["colophon"], "#{basetmpdir}/colophon.#{@params["htmlext"]}")
else
File.open("#{basetmpdir}/colophon.#{@params["htmlext"]}", "w") {|f| @producer.colophon(f) }
end
- @htmltoc.add_item(1, "colophon.#{@params["htmlext"]}", @producer.res.v("colophontitle"), {:chaptype => "post"})
+ write_tochtmltxt(basetmpdir, "1\tcolophon.#{@params["htmlext"]}\t#{@producer.res.v("colophontitle")}\tchaptype=post")
end
if @params["backcover"]
FileUtils.cp(@params["backcover"], "#{basetmpdir}/#{File.basename(@params["backcover"])}")
- @htmltoc.add_item(1, File.basename(@params["backcover"]), @producer.res.v("backcovertitle"), {:chaptype => "post"})
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["backcover"])}\t#{@producer.res.v("backcovertitle")}\tchaptype=post")
end
end
+ def write_tochtmltxt(basetmpdir, s)
+ File.open("#{basetmpdir}/#{@tochtmltxt}", "a") do |f|
+ f.puts s
+ end
+ end
+
def write_buildlogtxt(basetmpdir, htmlfile, reviewfile)
File.open("#{basetmpdir}/#{@buildlogtxt}", "a") do |f|
f.puts "#{htmlfile},#{reviewfile}"
end
+ end
+
+ def header(title)
+ # titleはすでにエスケープ済みと想定
+ s = <<EOT
+<?xml version="1.0" encoding="UTF-8"?>
+EOT
+ if @params["htmlversion"] == 5
+ s << <<EOT
+<!DOCTYPE html>
+<html xml:lang='ja' xmlns:ops='http://www.idpf.org/2007/ops' xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+ <meta charset="UTF-8" />
+EOT
+ else
+ s << <<EOT
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xml:lang='ja' xmlns:ops='http://www.idpf.org/2007/ops' xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+ <meta http-equiv='Content-Type' content='text/html;charset=UTF-8' />
+ <meta http-equiv='Content-Style-Type' content='text/css' />
+EOT
+ end
+ if @params["stylesheet"].size > 0
+ @params["stylesheet"].each do |sfile|
+ s << <<EOT
+ <link rel='stylesheet' type='text/css' href='#{sfile}' />
+EOT
+ end
+ end
+ s << <<EOT
+ <meta content='Re:VIEW' name='generator'/>
+ <title>#{title}</title>
+</head>
+<body>
+EOT
+ end
+
+ def footer
+ <<EOT
+</body>
+</html>
+EOT
end
class ReVIEWHeaderListener
include REXML::StreamListener
def initialize(headlines)