顯示具有 Xslthl 標籤的文章。 顯示所有文章
顯示具有 Xslthl 標籤的文章。 顯示所有文章

2013年8月3日 星期六

將 DocBook 轉換成 PDF 格式

這是上一篇文章「DocBook 的 Line Numbering 和 Code Highlighting」的續集,今天我們要將 DocBook 輸出為 PDF 格式,但在這邊要先提醒一下:Apache FOP 似乎不認得 xslthl 轉出來的 tags,所以如果你想將 DocBook 輸出成 PDF,可能就要先放棄 Code HighLighting 的功能。小弟自己在嘗試過多次以後,已經宣告放棄了...XD

我本身使用的 OS 是 Windows 7 Pro 64bit,JVM 版本則是 Oracle JDK 1.6.0_43,建議您盡量採用和我一樣的環境與軟體版本,以免遭遇到其他問題。

接下來進入正題,開始說明轉換的步驟:

一、FOP 的取得、安裝及設定

請到「http://archive.apache.org/dist/xmlgraphics/fop/binaries/」下載 fop-1.0-bin.zip,因為我只試過這個版本,而且沒遇到什麼問題,所以建議您跟我採用一樣的版本吧!

上一篇文章一樣,也請解壓縮在「D:\docbook」下方,所以這個資料夾下方應該要長的像下面這樣才對:
  • docbook-xsl-1.78.1\
  • fop-1.0\
  • output\
  • saxon6-5-5\
  • tools\
  • xerces-2_11_0\
  • xslthl-2.1.0\
  • my_article.xml
  • my_article.xsl
  • my_code.java 
接下來,請修改「D:\docbook\fop-1.0\conf\fop.xconf」的內容,在「renders/render/fonts」區段加入如下內容( START 到 END 之間),讓  FOP 可以使用你系統內的字型(包含中文字型),這部分我是參考「Docbook开发手记」的:

<fop version="1.0">
    ...
  <renderers>
    <renderer mime="application/pdf">
        ...
      <fonts>
        ...
        
        <!-- START -->
         <!-- register all the fonts found in a directory and all of its sub directories (use with care) -->
         <directory recursive="true">file:///c:/windows/fonts/</directory>

         <!-- automatically detect operating system installed fonts -->
         <auto-detect/>
        <!-- END -->
      </fonts>

二、修改 my_article.xsl:

請將 my_article.xsl 替換成如下的內容:

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:saxon="http://icl.com/saxon"
                extension-element-prefixes="saxon"
                version='1.0'>
 
<xsl:import href="file:///D:/docbook/docbook-xsl-1.78.1/fo/docbook.xsl"/>
 
<!--=====================================​=======================================
line numbering
====================================================​=========================-->
<xsl:param name="linenumbering.everyNth">1</xsl:param>
<xsl:param name="linenumbering.width">4</xsl:param>
<xsl:param name="linenumbering.separator"><xsl:text> </xsl:text></xsl:param>

<!--====================================================​========================
font setting
====================================================​=========================-->
<xsl:param name="title.font.family">Microsoft JhengHei</xsl:param>
<xsl:param name="body.font.family">Microsoft JhengHei</xsl:param>
<xsl:param name="monospace.font.family">MingLiU</xsl:param>
<xsl:param name="symbol.font.family">Cambria Math</xsl:param>

<!-- add bookmark and support more type of figure -->
<xsl:param name="fop1.extensions">1</xsl:param>

<!-- no indent for body content -->
<xsl:param name="body.start.indent">0pt</xsl:param>

</xsl:stylesheet>

三、使用以下指令進行轉換(在「D:\docbook」下面):

1. 先使用 Saxon 或 Xalan 來產生 fo 檔:

Saxon:
java -cp "D:\docbook\saxon6-5-5\saxon.jar;D:\docbook\docbook-xsl-1.78.1\extensions\saxon65.jar" com.icl.saxon.StyleSheet -o output\my_article.fo my_article.xml my_article.xsl use.extensions=1


Xalan:
java -cp "D:\docbook\tools\xalan.jar;D:\docbook\xerces-2_11_0\xml-apis.jar;D:\docbook\xerces-2_11_0\xercesImpl.jar;D:\docbook\docbook-xsl-1.78.1\extensions\xalan27.jar" org.apache.xalan.xslt.Process -OUT output\my_article.fo -IN my_article.xml -XSL my_article.xsl -L -PARAM use.extensions 1

產生的 fo 檔案位於「D:\docbook\output\my_article.fo」。

2. 再以 fop.bat 指令將 fo 檔轉成  PDF 檔:

fop-1.0\fop.bat -c d:\docbook\fop-1.0\conf\fop.xconf -fo output\my_article.fo -pdf my_article.pdf

產生的 PDF 檔案在「D:\docbook\my_article.pdf」。在執行的過程中,我是有看到一些錯誤訊息(請參考本文最下方),但是最終產生的 PDF 看起來是正常的,所以應該沒什麼關係。

我這邊轉出來的檔案就像下面這個樣子,希望你也成功了。


my_article.pdf



上一篇文章遭遇的問題一樣,Xalan 在轉換外部檔案my_code.java」時,即使有在 <textdata> 標籤加上「encoding="UTF-8"」屬性,中文(在註解的位置)仍會變成亂碼,但 Saxon 就不會。

如果您還想更深入瞭解 DocBook ,建議再參考以下這些網站:
總結來說,DocBook 確實是一套很不錯的文件格式標準(可以轉換成不同的文件格式),個人認為比較可惜的是:(1) 許多相關的文件與資料都已經很舊、過時了,(2) 相關的社群似乎也不再熱絡了。所以每次遇到問題時、要找答案或解決方式,都很困難...

附錄、執行 FOP 時看到的錯誤訊息

D:\docbook>fop-1.0\fop.bat -c d:\docbook\fop-1.0\conf\fop.xconf -fo output\my_ar
ticle.fo -pdf my_article.pdf
2013/8/3 下午 04:53:55 org.apache.fop.apps.FopFactoryConfigurator configure
資訊: Default page-height set to: 11in
2013/8/3 下午 04:53:55 org.apache.fop.apps.FopFactoryConfigurator configure
資訊: Default page-width set to: 8.26in
2013/8/3 下午 04:53:56 org.apache.fop.events.LoggingEventListener processEvent
警告: Font "Cambria Math,normal,700" not found. Substituting with "Cambria Math,
normal,400".
2013/8/3 下午 04:53:57 org.apache.fop.hyphenation.Hyphenator getHyphenationTree
嚴重的: Couldn't find hyphenation pattern zh_tw
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: This is a TrueType collection file with 3 fonts
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: Containing the following fonts:
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: MingLiU <-- selected
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: PMingLiU
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: MingLiU_HKSCS
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: This is a TrueType collection file with 3 fonts
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: Containing the following fonts:
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: MingLiU <-- selected
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: PMingLiU
2013/8/3 下午 04:53:57 org.apache.fop.fonts.truetype.TTFFile checkTTC
資訊: MingLiU_HKSCS

2013年7月31日 星期三

DocBook 的 Line Numbering 和 Code Highlighting

最近在製作 DocBook 文件時,遇到了「Line Numbering」和「Code Highlighting」問題,花了三天的時間終於解決,特別筆記在此紀錄一下解決的步驟。

首先,說一下前置作業:
  1. 取得「docbook-xsl」。從 SourceForge下載「docbook-xsl-1.?.?.zip」,請特別留意版本號!不要太新、也不要太舊,網址在:http://sourceforge.net/projects/docbook/files/docbook-xsl/ ,我自己下載的是 「docbook-xsl-1.78.1.zip」。
  2. 取得 XSLT 1.0 proccessor —— Saxon 或 Xalan,也一樣請留意版本號:
    1. Saxon:請從 http://saxon.sourceforge.net/#F6.5.5 下載,取得 Saxon 6.5.5 就好了,我自己下載的是「saxon6-5-5.zip」。
    2. Xalan:它被包在 Xerces2 Java 裡了,請從 http://xerces.apache.org/mirrors.cgi#binary
      下載 Binary 和 Tools,我自己下載的是「Xerces-J-bin.2.11.0.zip」和「Xerces-J-tools.2.11.0.zip」。
  3. 取得 XSLT Syntax Highlight  —— xslthl,請從 http://sourceforge.net/projects/xslthl/ 下載,我自己下載的是「xslthl-2.1.0-dist.zip」。
  4. 下載完上述檔案後,把它們解開在「D:\docbook」下方,也就是像這樣:
    • docbook-xsl-1.78.1\
    • saxon6-5-5\
    • tools\
    • xerces-2_11_0\
    • xslthl-2.1.0\
  5. 閱讀「DocBook XSL: The Complete Guide 4th Edition」的這兩篇:
    1. Chapter 27. Program listings - Line numbering
    2. Chapter 27. Program listings - Syntax highlighting
此外,要提醒的是:只有「Saxon」和「Xalan」才支援「Line Numbering」和「Code Highlighting」這兩項功能, xmltproc 並不支援喔!

接著,請準備好以下三個檔案(其內容列於本文底部),並盡量都使用一樣的編碼(如 UTF-8),也放到 D:\docbook  下面:
  1. my_article.xml:DocBook 文件。
  2. my_article.xsl:DocBook XSL 樣式檔。
  3. my_code.java:一段 Java 程式碼。
然後,在 D:\docbook 下執行以下指令,就可將 DocBook 格式轉換為 HTML 格式了:
  1. 如果你是用 Saxon 的話:
    java -cp "D:\docbook\xslthl-2.1.0\xslthl-2.1.0.jar;D:\docbook\saxon6-5-5\saxon.jar;D:\docbook\docbook-xsl-1.78.1\extensions\saxon65.jar" -Dxslthl.config="file:///D:/docbook/docbook-xsl-1.78.1/highlighting/xslthl-config.xml" com.icl.saxon.StyleSheet -o output\my_aritcle.html my_article.xml my_article.xsl use.extensions=1
    
  2. 如果你是用 Xalan 的話:
    java -cp "D:\docbook\xslthl-2.1.0\xslthl-2.1.0.jar;D:\docbook\tools\xalan.jar;D:\docbook\xerces-2_11_0\xml-apis.jar;D:\docbook\xerces-2_11_0\xercesImpl.jar;D:\docbook\docbook-xsl-1.78.1\extensions\xalan27.jar" -Dxslthl.config="file:///D:/docbook/docbook-xsl-1.78.1/highlighting/xslthl-config.xml" org.apache.xalan.xslt.Process -OUT output\my_article.html -IN my_article.xml -XSL my_article.xsl -L -PARAM use.extensions 1
    

轉換完的 my_article.html 內容就像下面這個樣子:



加上行號與程式碼 highlight 的 my_article.html

最後,我發現一個問題,就是 Xalan 在轉換外部檔案my_code.java」時,即使有在<textdata> 標籤加上「encoding="UTF-8"」屬性,中文(在註解的位置)會變成亂碼,但 Saxon 就不會。

至於其原因,我暫時沒時間去探究。因此,如果你也遇到同樣的問題,建議就先改用 Saxon 吧!(或者幫忙查一下原因,並回饋給小弟,:-p)

前面所提到的三個檔案內容如下:

1. my_article.xml
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<article lang="zh_tw">
  <title>快來測試 Line Numbering 和 Code Highlighting 的功能吧!</title>
  <sect1>
    <title>my_code.java</title>
      <programlisting linenumbering="numbered" startinglinenumber="1" language="java"><?dbhtml linenumbering.everyNth="1" linenumbering.separator=" " linenumbering.width="4"?><?dbfo linenumbering.everyNth="1" linenumbering.separator=" " linenumbering.width="4"?><textobject><textdata fileref="file:///D:/docbook/my_code.java" encoding="UTF-8" /></textobject></programlisting>        
  </sect1>
</article>
2.  my_article.xsl
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:saxon="http://icl.com/saxon"
                extension-element-prefixes="saxon" 
                version='1.0'>

<xsl:import href="file:///D:/docbook/docbook-xsl-1.78.1/html/docbook.xsl"/>
<xsl:import href="file:///D:/docbook/docbook-xsl-1.78.1/html/highlight.xsl"/>

<xsl:output method="html" 
            encoding="UTF-8"
            indent="yes"
            saxon:character-representation="native;decimal"/>
<!--=====================================​=======================================
Code Line Numbering & Highlighting Global Settings
====================================================​=========================-->
<xsl:param name="linenumbering.extension" select="1"></xsl:param>
<xsl:param name="linenumbering.everyNth">1</xsl:param>
<xsl:param name="linenumbering.width">4</xsl:param>
<xsl:param name="linenumbering.separator"><xsl:text> </xsl:text></xsl:param>
<xsl:param name="highlight.source" select="1"></xsl:param>
</xsl:stylesheet>
3. my_code.java
/**
 * 使用「Adapter」Design Pattern 
 */
abstract class HumanWorkerAdpater implements IWorker {
   public void work();
   public void eat();
}
abstract class RobotWorker implements IWorker {
   public void work();
}
IWoker HumanWorker = new HumanWorkerAdpater() {
   public work() {
      // working....
   }
   public eat() {
      // eating....
   }
}
IWoker RobotWorker = new RobotWorkerAdpater() {
   public work() {
      // working....
   }
}