]> git.stg.codes - stg.git/blobdiff - doc/help/xslt/epub/bin/lib/docbook.rb
xslt filters moved upper, Makefiles fixed to use bundled xslt filters
[stg.git] / doc / help / xslt / epub / bin / lib / docbook.rb
diff --git a/doc/help/xslt/epub/bin/lib/docbook.rb b/doc/help/xslt/epub/bin/lib/docbook.rb
deleted file mode 100755 (executable)
index 14110d6..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-require 'fileutils'
-require 'rexml/parsers/pullparser'
-
-module DocBook
-
-  class Epub
-    CHECKER = "epubcheck"
-    STYLESHEET = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', "docbook.xsl"))
-    CALLOUT_PATH = File.join('images', 'callouts')
-    CALLOUT_FULL_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', CALLOUT_PATH))
-    CALLOUT_LIMIT = 15
-    CALLOUT_EXT = ".png"
-    XSLT_PROCESSOR = "xsltproc"
-    OUTPUT_DIR = ".epubtmp#{Time.now.to_f.to_s}"
-    MIMETYPE = "application/epub+zip"
-    META_DIR = "META-INF"
-    OEBPS_DIR = "OEBPS"
-    ZIPPER = "zip"
-
-    attr_reader :output_dir
-
-    def initialize(docbook_file, output_dir=OUTPUT_DIR, css_file=nil, customization_layer=nil, embedded_fonts=[])
-      @docbook_file = docbook_file
-      @output_dir = output_dir
-      @meta_dir  = File.join(@output_dir, META_DIR)
-      @oebps_dir = File.join(@output_dir, OEBPS_DIR)
-      @css_file = css_file ? File.expand_path(css_file) : css_file
-      @embedded_fonts = embedded_fonts
-      @to_delete = []
-      
-      if customization_layer
-        @stylesheet = File.expand_path(customization_layer)
-      else
-        @stylesheet = STYLESHEET
-      end
-
-      unless File.exist?(@docbook_file)
-        raise ArgumentError.new("File #{@docbook_file} does not exist")
-      end
-    end
-
-    def render_to_file(output_file, verbose=false)
-      render_to_epub(output_file, verbose)
-      bundle_epub(output_file, verbose)
-      cleanup_files(@to_delete)
-    end
-
-    def self.invalid?(file)
-      # Obnoxiously, we can't just check for a non-zero output...
-      cmd = %Q(#{CHECKER} "#{file}")
-      output = `#{cmd} 2>&1`
-
-      if $?.to_i == 0
-        return false
-      else  
-        STDERR.puts output if $DEBUG
-        return output
-      end  
-    end
-
-    private
-    def render_to_epub(output_file, verbose)  
-      @collapsed_docbook_file = collapse_docbook()
-
-      chunk_quietly =   "--stringparam chunk.quietly " + (verbose ? '0' : '1')
-      callout_path =    "--stringparam callout.graphics.path #{CALLOUT_PATH}/"
-      callout_limit =   "--stringparam callout.graphics.number.limit #{CALLOUT_LIMIT}"
-      callout_ext =     "--stringparam callout.graphics.extension #{CALLOUT_EXT}" 
-      html_stylesheet = "--stringparam html.stylesheet #{File.basename(@css_file)}" if @css_file
-      base =            "--stringparam base.dir #{OEBPS_DIR}/" 
-      unless @embedded_fonts.empty? 
-        embedded_fonts = @embedded_fonts.map {|f| File.basename(f)}.join(',')
-        font =            "--stringparam epub.embedded.fonts \"#{embedded_fonts}\"" 
-      end  
-      meta =            "--stringparam epub.metainf.dir #{META_DIR}/" 
-      oebps =           "--stringparam epub.oebps.dir #{OEBPS_DIR}/" 
-      options = [chunk_quietly, 
-                 callout_path, 
-                 callout_limit, 
-                 callout_ext, 
-                 base, 
-                 font, 
-                 meta, 
-                 oebps, 
-                 html_stylesheet,
-                ].join(" ")
-      # Double-quote stylesheet & file to help Windows cmd.exe
-      db2epub_cmd = %Q(cd "#{@output_dir}" && #{XSLT_PROCESSOR} #{options} "#{@stylesheet}" "#{@collapsed_docbook_file}")
-      STDERR.puts db2epub_cmd if $DEBUG
-      success = system(db2epub_cmd)
-      raise "Could not render as .epub to #{output_file} (#{db2epub_cmd})" unless success
-      @to_delete << Dir["#{@meta_dir}/*"]
-      @to_delete << Dir["#{@oebps_dir}/*"]
-    end  
-
-    def bundle_epub(output_file, verbose)  
-
-      quiet = verbose ? "" : "-q"
-      mimetype_filename = write_mimetype()
-      meta   = File.basename(@meta_dir)
-      oebps  = File.basename(@oebps_dir)
-      images = copy_images()
-      csses  = copy_csses()
-      fonts  = copy_fonts()
-      callouts = copy_callouts()
-      # zip -X -r ../book.epub mimetype META-INF OEBPS
-      # Double-quote stylesheet & file to help Windows cmd.exe
-      zip_cmd = %Q(cd "#{@output_dir}" &&  #{ZIPPER} #{quiet} -X -r  "#{File.expand_path(output_file)}" "#{mimetype_filename}" "#{meta}" "#{oebps}")
-      puts zip_cmd if $DEBUG
-      success = system(zip_cmd)
-      raise "Could not bundle into .epub file to #{output_file}" unless success
-    end
-
-    # Input must be collapsed because REXML couldn't find figures in files that
-    # were XIncluded or added by ENTITY
-    #   http://sourceforge.net/tracker/?func=detail&aid=2750442&group_id=21935&atid=373747
-    def collapse_docbook
-      # Double-quote stylesheet & file to help Windows cmd.exe
-      collapsed_file = File.join(File.expand_path(File.dirname(@docbook_file)), 
-                                 '.collapsed.' + File.basename(@docbook_file))
-      entity_collapse_command = %Q(xmllint --loaddtd --noent -o "#{collapsed_file}" "#{@docbook_file}")
-      entity_success = system(entity_collapse_command)
-      raise "Could not collapse named entites in #{@docbook_file}" unless entity_success
-
-      xinclude_collapse_command = %Q(xmllint --xinclude -o "#{collapsed_file}" "#{collapsed_file}")
-      xinclude_success = system(xinclude_collapse_command)
-      raise "Could not collapse XIncludes in #{@docbook_file}" unless xinclude_success
-
-      @to_delete << collapsed_file
-      return collapsed_file
-    end  
-
-    def copy_callouts
-      new_callout_images = []
-      if has_callouts?
-        calloutglob = "#{CALLOUT_FULL_PATH}/*#{CALLOUT_EXT}"
-        Dir.glob(calloutglob).each {|img|
-          img_new_filename = File.join(@oebps_dir, CALLOUT_PATH, File.basename(img))
-
-          # TODO: What to rescue for these two?
-          FileUtils.mkdir_p(File.dirname(img_new_filename)) 
-          FileUtils.cp(img, img_new_filename)
-          @to_delete << img_new_filename
-          new_callout_images << img
-        }  
-      end  
-      return new_callout_images
-    end
-
-    def copy_fonts
-      new_fonts = []
-      @embedded_fonts.each {|font_file|
-        font_new_filename = File.join(@oebps_dir, File.basename(font_file))
-        FileUtils.cp(font_file, font_new_filename)
-        new_fonts << font_file
-      }
-      return new_fonts
-    end
-
-    def copy_csses
-      if @css_file 
-        css_new_filename = File.join(@oebps_dir, File.basename(@css_file))
-        FileUtils.cp(@css_file, css_new_filename)
-      end
-    end
-
-    def copy_images
-      image_references = get_image_refs()
-      new_images = []
-      image_references.each {|img|
-        # TODO: It'd be cooler if we had a filetype lookup rather than just
-        # extension
-        if img =~ /\.(svg|png|gif|jpe?g|xml)/i
-          img_new_filename = File.join(@oebps_dir, img)
-          img_full = File.join(File.expand_path(File.dirname(@docbook_file)), img)
-
-          # TODO: What to rescue for these two?
-          FileUtils.mkdir_p(File.dirname(img_new_filename)) 
-          puts(img_full + ": " + img_new_filename) if $DEBUG
-          FileUtils.cp(img_full, img_new_filename)
-          @to_delete << img_new_filename
-          new_images << img_full
-        end
-      }  
-      return new_images
-    end
-
-    def write_mimetype
-      mimetype_filename = File.join(@output_dir, "mimetype")
-      File.open(mimetype_filename, "w") {|f| f.print MIMETYPE}
-      @to_delete << mimetype_filename
-      return File.basename(mimetype_filename)
-    end  
-
-    def cleanup_files(file_list)
-      file_list.flatten.each {|f|
-        # Yikes
-        FileUtils.rm_r(f, :force => true )
-      }  
-    end  
-
-    # Returns an Array of all of the (image) @filerefs in a document
-    def get_image_refs
-      parser = REXML::Parsers::PullParser.new(File.new(@collapsed_docbook_file))
-      image_refs = []
-      while parser.has_next?
-        el = parser.pull
-        if el.start_element? and (el[0] == "imagedata" or el[0] == "graphic")
-          image_refs << el[1]['fileref'] 
-        end  
-      end
-      return image_refs.uniq
-    end  
-
-    # Returns true if the document has code callouts
-    def has_callouts?
-      parser = REXML::Parsers::PullParser.new(File.new(@collapsed_docbook_file))
-      while parser.has_next?
-        el = parser.pull
-        if el.start_element? and (el[0] == "calloutlist" or el[0] == "co")
-          return true
-        end  
-      end
-      return false
-    end  
-  end
-end