]> granicus.if.org Git - docbook-dsssl/commitdiff
Adding primitive support for embedding a single font
authorKeith Fahlgren <abdelazer@users.sourceforge.net>
Wed, 9 Jul 2008 18:58:32 +0000 (18:58 +0000)
committerKeith Fahlgren <abdelazer@users.sourceforge.net>
Wed, 9 Jul 2008 18:58:32 +0000 (18:58 +0000)
xsl/epub/bin/dbtoepub
xsl/epub/bin/lib/docbook.rb
xsl/epub/bin/spec/epub_spec.rb
xsl/epub/bin/spec/files/DejaVuSerif.otf [new file with mode: 0644]
xsl/epub/bin/spec/files/test.css
xsl/epub/docbook.xsl

index abe176def2840b560c6d02b1978ef9f06e005420..a6a4316597361460aa9ab8dcffa4612778e579cf 100755 (executable)
@@ -11,6 +11,7 @@
 # Specific options:
 #     -c, --css [FILE]                 Use FILE for CSS on generated XHTML.
 #     -d, --debug                      Show debugging output.
+#     -f, --font [OTF FILE]            Embed OTF FILE in .epub.
 #     -h, --help                       Display usage info.
 #     -s, --stylesheet [XSL FILE]      Use XSL FILE as a customization
 #                                        layer (imports epub/docbook.xsl).
@@ -27,6 +28,7 @@ require 'docbook'
 verbose = false
 debug = false
 css_file = nil
+otf_files = []
 customization_layer = nil
 
 # Set up the OptionParser
@@ -43,6 +45,7 @@ opts.banner = "Usage: #{File.basename($0)} [OPTIONS] [DocBook Files]
 Specific options:"
 opts.on("-c", "--css [FILE]", "Use FILE for CSS on generated XHTML.") {|f| css_file = f}
 opts.on("-d", "--debug", "Show debugging output.") {debug = true; verbose = true}
+opts.on("-f", "--font [OTF FILE]", "Embed OTF FILE in .epub.") {|f| otf_files << f}
 opts.on("-h", "--help", "Display usage info.") {puts opts.to_s; exit 0}
 opts.on("-s", "--stylesheet [XSL FILE]", "Use XSL FILE as a customization layer (imports epub/docbook.xsl).") {|f| customization_layer = f}
 opts.on("-v", "--verbose", "Make output verbose.") {verbose = true}
@@ -55,7 +58,7 @@ end
 
 db_files.each {|docbook_file|
   dir = File.expand_path(File.join(Dir.tmpdir, ".epubtmp#{Time.now.to_f.to_s}"))
-  e = DocBook::Epub.new(docbook_file, dir, css_file, customization_layer)
+  e = DocBook::Epub.new(docbook_file, dir, css_file, customization_layer, otf_files)
   epub_file = File.basename(docbook_file, ".xml") + ".epub"
   puts "Rendering DocBook file #{docbook_file} to #{epub_file}" if verbose
   e.render_to_file(epub_file)
index 96ed0cf40efca08e893eb31d79f93e050cca3cd2..3b622ae377ccb142742c250ff024df0cdb4d0329 100755 (executable)
@@ -19,12 +19,14 @@ module DocBook
 
     attr_reader :output_dir
 
-    def initialize(docbook_file, output_dir=OUTPUT_DIR, css_file=nil, customization_layer=nil)
+    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
+      raise NotImplementedError if @embedded_fonts.length > 1
       @to_delete = []
       
       if customization_layer
@@ -65,9 +67,22 @@ module DocBook
       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? 
+        font =            "--stringparam epub.embedded.font \"#{File.basename(@embedded_fonts.first)}\"" 
+      end  
       meta =            "--stringparam epub.metainf.dir #{@meta_dir}/" 
       oebps =           "--stringparam epub.oebps.dir #{@oebps_dir}/" 
-      options = "--xinclude #{chunk_quietly} #{callout_path} #{callout_limit} #{callout_ext} #{base} #{meta} #{oebps} #{html_stylesheet}"
+      options = ["--xinclude", 
+                 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 = "#{XSLT_PROCESSOR} #{options} \"#{@stylesheet}\" \"#{@docbook_file}\""
       STDERR.puts db2epub_cmd if $DEBUG
@@ -84,6 +99,7 @@ module DocBook
       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
@@ -110,6 +126,16 @@ module DocBook
       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))
index 17b62a5725c112530826183a2991ab6a067c23b7..08c8bedac63247b5fbe60fe9bb95a9d76cbc8337 100755 (executable)
@@ -36,7 +36,10 @@ describe DocBook::Epub do
 
     @css_file_base = "test.css"
     @css_file = File.join(@filedir, @css_file_base)
-    @css_epub = DocBook::Epub.new(File.join(@testdocsdir, "book.002.xml"), @tmpdir, @css_file)
+    customization_layer = nil
+    @embedded_font_file_base = "DejaVuSerif.otf"
+    embedded_fonts = [File.join(@filedir, @embedded_font_file_base)]
+    @css_epub = DocBook::Epub.new(File.join(@testdocsdir, "book.002.xml"), @tmpdir, @css_file, customization_layer, embedded_fonts)
     @css_epubfile = File.join(@tmpdir, "css.epub")
     @css_epub.render_to_file(@css_epubfile, $DEBUG)
 
@@ -180,7 +183,7 @@ describe DocBook::Epub do
     end
   end
 
-  it "should include a CSS link in OPF file when a CSS file has been provided" do
+  it "should include a reference in the OPF manifest to the provided CSS file" do
     begin
       tmpdir = File.join(Dir::tmpdir(), "epubcsshtmltest"); Dir.mkdir(tmpdir) rescue Errno::EEXIST
       
@@ -196,6 +199,37 @@ describe DocBook::Epub do
     end
   end
 
+  it "should include a reference in the OPF manifest to the embedded font" do
+    begin
+      tmpdir = File.join(Dir::tmpdir(), "epubfontman"); Dir.mkdir(tmpdir) rescue Errno::EEXIST
+      
+      success = system("unzip -q -d #{File.expand_path(tmpdir)} -o #{@css_epubfile}")
+      raise "Could not unzip #{@css_epubfile}" unless success
+      opf_files = Dir.glob(File.join(tmpdir, "**", "*.opf"))
+      opf_links = opf_files.find_all {|opf_file| File.open(opf_file).readlines.to_s =~ /<item [^>]*#{@embedded_font_file_base}/}
+      opf_links.should_not be_empty
+    rescue => e
+      raise e
+    ensure
+      FileUtils.rm_r(tmpdir, :force => true)
+    end
+  end
+
+  it "should include the embedded font file in the bundle" do
+    begin
+      tmpdir = File.join(Dir::tmpdir(), "epubfontbundle"); Dir.mkdir(tmpdir) rescue Errno::EEXIST
+      
+      success = system("unzip -q -d #{File.expand_path(tmpdir)} -o #{@css_epubfile}")
+      raise "Could not unzip #{@css_epubfile}" unless success
+      font_files = Dir.glob(File.join(tmpdir, "**", @embedded_font_file_base))
+      font_files.should_not be_empty
+    rescue => e
+      raise e
+    ensure
+      FileUtils.rm_r(tmpdir, :force => true)
+    end
+  end
+
   it "should include a TOC link in rendered epub files for <book>s" do
     begin
       tmpdir = File.join(Dir::tmpdir(), "epubtoctest"); Dir.mkdir(tmpdir) rescue Errno::EEXIST
diff --git a/xsl/epub/bin/spec/files/DejaVuSerif.otf b/xsl/epub/bin/spec/files/DejaVuSerif.otf
new file mode 100644 (file)
index 0000000..e69de29
index 2301cef9f8f59efd4b0e268beb650808211cc0dc..cd70946dc3e0e1bc3eae57e30f655bcc36423a6c 100644 (file)
@@ -1,4 +1,11 @@
+@font-face {
+  font-family: "DejaVu Serif";
+  font-style: normal;
+  font-weight: normal;
+  src:url(DejaVuSerif.otf);
+}
 h2 {
+  font-family: "DejaVu Serif";
   text-align: center;
   color: #dda0dd;
 }
index ab850115a032881db111afd28a8b192eef5633b2..b2d32496782d8b28377d430ae937e430f2387906 100644 (file)
@@ -41,6 +41,8 @@
   <xsl:param name="epub.html.toc.id">htmltoc</xsl:param>
   <xsl:param name="epub.metainf.dir" select="'META-INF/'"/> 
 
+  <xsl:param name="epub.embedded.font"></xsl:param>
+
   <!-- Per Bob Stayton:
        """Process your documents with the css.decoration parameter set to zero. 
           That will avoid the use of style attributes in XHTML elements where they are not permitted."""
         </xsl:element>
       </xsl:if>  
 
+     <xsl:if test="$epub.embedded.font != ''">
+        <xsl:element name="item">
+          <xsl:attribute name="xmlns">http://www.idpf.org/2007/opf</xsl:attribute>
+          <xsl:attribute name="id">epub.embedded.font</xsl:attribute>
+          <xsl:attribute name="href"><xsl:value-of select="$epub.embedded.font"/></xsl:attribute>
+          <xsl:choose>
+            <xsl:when test="contains($epub.embedded.font, 'otf')">
+              <xsl:attribute name="media-type">font/opentype</xsl:attribute>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:message terminate="yes">
+                <xsl:text>ERROR: Only OpenType fonts are supported in .epub! (</xsl:text>
+                <xsl:value-of select="$epub.embedded.font"/>
+                <xsl:text>)</xsl:text>
+              </xsl:message>
+            </xsl:otherwise>
+            </xsl:choose>
+        </xsl:element>
+     </xsl:if>
+
       <!-- TODO: be nice to have a id="titlepage" here -->
       <xsl:apply-templates select="//part|
                                    //book[*[last()][self::bookinfo]]|