# PublishR -- Fast publishing for ebooks and paper # Copyright (C) 2012 Michael Franzl # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . module Publishr class EpubRenderer def initialize(name,inpath,outpath,metadata,rails_resources_url='') @name = name @inpath = inpath @outpath = outpath @metadata = metadata @gempath = Publishr::gempath @rails_resources_url = rails_resources_url @html_files = [] @image_files = [] end def render make_epub_directory_structure render_htmls compile_xmls end def make_epub_directory_structure FileUtils.rm_rf @outpath FileUtils.cp_r File.join(@gempath,'lib','epub_skeleton'), @outpath FileUtils.cp Dir[File.join(@inpath,'images','*.jpg')], @outpath FileUtils.cp File.join(@inpath,'cover.jpg'), @outpath @image_files = Dir[File.join(@outpath,'*.jpg')] # users can provide an overriding css file FileUtils.cp_f File.join(@inpath,'epub.css'), @outpath if File.exists?(File.join(@inpath,'epub.css')) end def render_htmls kramdown_options = { :auto_ids => false, :smart_quotes => @metadata['kramdown_options']['smart_quotes'], :template => File.join(@gempath,'lib','epub_templates','kramdown.html') } Dir[File.join(@inpath,'*.txt')].each do |infilepath| kramdown = File.open(infilepath, 'r').read html = Kramdown::Document.new(kramdown, kramdown_options).to_html degraded_html = HtmlProcessor.new(html,@inpath,@metadata,@rails_resources_url).degrade outfilepath = File.join(@outpath, File.basename(infilepath).gsub(/(.*).txt/, '\1.html')) File.open(outfilepath, 'w'){ |f| f.write degraded_html } end @html_files = ([File.join(@outpath,'covertext.html')] + [File.join(@outpath,'frontmatter.html')] + [File.join(@outpath,'toc.html')] + Dir[File.join(@outpath,'*.html')].sort).uniq end def compile_xmls File.open(File.join(@outpath,'content.opf'),'w'){ |f| f.write render_content_opf } File.open(File.join(@outpath,'toc.ncx'),'w'){ |f| f.write render_toc_ncx } Dir.chdir @outpath filename = File.join(@inpath,"#{ @name }.epub") `zip -X0 #{ filename } mimetype` `zip -Xur9D #{ filename } *` end def render_content_opf erb = File.open(File.join(@gempath,'lib','epub_templates','content.opf.erb'),'r').read spine_items = render_spine_items manifest_items = render_manifest_items ERB.new(erb).result binding end def render_toc_ncx erb = File.open(File.join(@gempath,'lib','epub_templates','toc.ncx.erb'),'r').read nav_points = render_nav_points ERB.new(erb).result binding end def render_nav_points erb = File.open(File.join(@gempath,'lib','epub_templates','nav_points.erb'),'r').read results = [] i = 0 @html_files.each do |h| filename = File.basename(h) id = filename.gsub '.','' i += 1 results << (ERB.new(erb).result binding) end results.join("\n") end def render_manifest_items image_files = Dir[File.join(@outpath,'*.jpg')] erb = File.open(File.join(@gempath,'lib','epub_templates','manifest_items.erb'),'r').read results = [] (@html_files + @image_files).each do |h| filename = File.basename(h) id = filename.gsub '.','' mediatype = case File.extname(h) when '.html' then 'application/xhtml+xml' when '.jpg' then 'image/jpeg' when '.png' then 'image/png' end results << (ERB.new(erb).result binding) end results.join("\n") end def render_spine_items erb = File.open(File.join(@gempath,'lib','epub_templates','spine_items.erb'),'r').read results = [] @html_files.each do |h| id = File.basename(h).gsub '.','' results << (ERB.new(erb).result binding) end results.join("\n") end end end