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)