Fenriswolf 程式筆記

奮利斯狼的地盤,小綿羊勿入

用 Ant 建立 Docbook 文件

Docbook 是一個基於 XML 的文件管理系統,尤其是廣泛用於技術類的文件
好處是撰寫時只要專注在文件的內容而不用管格式,字型等等美化的工作
當內容寫完後可以套用不同的 CSS 及 XSL 產生 HTML 及 PDF 檔
有名的 spring framework 也是利用他來寫 reference document

基本的 Docbook XML tags 定義非常的多,有興趣者可以參考這個網站
但是一般不會直接寫 XML,我個人是使用 XMLMind 這個 IDE,有免費的 Personal Edition 可供下載
雖然 Professional Edition 可以幫你產生 HTML 等格式的文件,但我會希望這個流程可以自動化
整合進 Ant script 和程式碼一起打包並佈署到客戶端

1. 先來看個有結構的範例
1.1 建一個主文件 sample.xml。Docbook 最大的好處是可以模組化,有共用的部分可以用 tag 來 include。這裡的主文件就只有文件 title, 版本號及作者名,真正的內容是在 intro.xml 及 content.xml 裡
這裡要注意的是 content.xml 裡面有兩個章節,我只想加入 basic 那章,可以用 xpointer 屬性指定要加入的章節 id

<?xml version="1.0" encoding="UTF-8"?>
<book version="5.0" xmlns="http://docbook.org/ns/docbook"
      xmlns:xi="http://www.w3.org/2001/XInclude">
      
  <title>DocBook Framework Overview</title>

  <bookinfo>
    <releaseinfo>V 1.0</releaseinfo>
    <author>Fenris
    </author>
  </bookinfo>  
  <toc/>
  
  <xi:include href="intro.xml" />
  <xi:include href="content.xml" xpointer="basic" />  
</book>

1.2 建立 intro.xml

<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.0" xmlns="http://docbook.org/ns/docbook"
      xmlns:xi="http://www.w3.org/2001/XInclude">
      
    <title>Introduction</title>
    <para>
        DocBook is simple to use and provides a rich set of tags 
        for common elements.
    </para>      
</chapter>

1.3 建立 content.xml
一個好習慣是幫各章節定義一個 unique id,方便其他的 XML 可以單獨 include

<book version="5.0" xmlns="http://docbook.org/ns/docbook"
      xmlns:xi="http://www.w3.org/2001/XInclude">
      
    <chapter xml:id="basic">
        <title>Basic Elements</title>
        <para>This section describes the basic tags.</para>
    </chapter>
    
    <chapter xml:id="advanced">
        <title>Advanced Elements</title>
        <para>This section describes the advanced tags.</para>
    </chapter>
</book>

這是 sample.xml 在 XMLMind 裡顯示的結果

這是我放的目錄結構
docbook 是根目錄, Ant build.xml 也是放這裡
css/html: 裡放的是 CSS files,給 HTML pages 用的
images: 文件用到的圖檔
output: 產生的文件目錄
下面會再細分 html, htmlsingle 和 pdf
docbook-xml-4.4, docbook-xsl-1.70.0 和 tmp 是暫存目錄,檔案產生後就可以殺掉了
src: 所有 docbook xml files
styles: 產生 HTML 或 PDF 會用到的 XSL files

如果不知道 CSS 和 XSL 要怎麼寫,可以拿 Docbook Framework 裡的範例檔或 spring framework 的檔案來用

2. 下載 Velocity Docbook Framework 並解壓縮

3. 下載 Xerces
並把所有的 jar files 放到 Docbook Framework Home 的 lib 目錄下,這是為了能支援 tag

4. 修改 Docbook Framework Home 下的 build-docbook.xml
找到下面這段設定並把 jvmarg 參數加上以使用 Xerces 提供的 XIncludeParser

<java classname="com.icl.saxon.StyleSheet" fork="true"
    dir="${basedir}" classpathref="dbf.classpath">
        <jvmarg value="-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl" />
        <jvmarg value="-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl" />
        <jvmarg value="-Dorg.apache.xerces.xni.parser.XMLParserConfiguration=org.apache.xerces.parsers.XIncludeParserConfiguration" />
    <arg line="-x org.apache.xml.resolver.tools.ResolvingXMLReader"/>
    <arg line="-y org.apache.xml.resolver.tools.ResolvingXMLReader"/>
    <arg line="-r org.apache.xml.resolver.tools.CatalogResolver"/>
    <arg value="-o"/>
    <arg value="@{output}"/>
    <arg value="@{input}"/>
    <arg value="@{style}"/>
</java>

5. 改寫 org.apache.xerces.xpointer.ShortHandPointer.java
compile 後更新到 xercesImpl.jar 裡。現在 Xerces 2.11 版並沒有支援 xml:id 這個屬性,執行會產生以下的錯誤

[java] org.xml.sax.SAXParseException: Include operation failed, reverting to fallback. 
Resource error reading file as XML (href='content.xml'). 
Reason: XPointer resolution unsuccessful.
[java] Error on line 15 column 53 of file:/D:/Project/googlecode/src/com/fw/docbook/src/sample.xml:
[java]   Error reported by XML parser: An 'include' failed, and no 'fallback' element was found.

為了支援這個屬性,可以下載我提供的 xercesImpl.jar 2.11 版或自行修改 ShortHandPointer.java
下方的 if 判斷式是原有的程式碼(大約是第 166 行),找到之後再加上 xml:id 的判斷式

if (normalizedValue == null && attributes != null) {
    for (int i = 0; i < attributes.getLength(); i++) {
        if ("xml".equals(attributes.getPrefix(i)) && "id".equals(attributes.getLocalName(i))) {
            normalizedValue = attributes.getValue(i);
            break;
        }
    }
}

if (normalizedValue != null
        && normalizedValue.equals(fShortHandPointer)) {
    return true;
}

6. 寫 Ant build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="docbook" default="doc">
    <target name="doc">
        <property name="docbook.dir" value="D:/Project/googlecode/lib/DocBook-Framework-1.0"/>
        <mkdir dir="${basedir}/output"/>        
        
        <ant antfile="${docbook.dir}/build-docbook.xml" inheritAll="false">
            <property name="dbf.basedir" value="${docbook.dir}"/>
            <property name="docbook.dir" value=""/>
            <property name="docbook.file" value="sample"/>

            <property name="docbook.src.dir" value="${basedir}/src"/>
            <property name="images.src.dir" value="${basedir}/images"/>
            <property name="css.src.dir" value="${basedir}/css"/>
            <property name="style.src.dir" value="${basedir}/style"/>
            <property name="target.dir" value="${basedir}/output"/>

            <target name="html"/>                    
            <target name="htmlsingle"/>
            <target name="pdf"/>
        </ant>
    </target>
</project>

dbf.basedir: Docbook Framework 的目錄
docbook.dir: 這是當你有多個檔案需要建立時才給的名字,例如 manual, faq 等等。Docbook 會依這個名字在 output 目錄下建子目錄來放各別的 HTML 或 PDF
docbook.file: 要建立的 XML 檔檔名,去掉 .xml
docbook.src.dir: XML 檔的目錄
images.src.dir: 圖檔目錄
css.src.dir: CSS 檔目錄
style.dir: XSL 目錄
target.dir: 產生 HTML, PDF 或暫存檔的目錄
最後三個 tags 淺顯易懂,就是產生 HTML, HTML single page 和 PDF 檔
然後在根目錄下執行 ant 就可以了

下面是 HTML single page 的輸出結果

 
 
執行環境
JDK 1.6.0_23
Velocity Docbook Framework 1.0
Xerces-2.11

參考資料
XMLmind
Velocity Docbook Framework
Xerces
DocBook: Write Once, Read Anywhere Documentation

程式下載
build.xml
build-docbook.xml
sample.xml
intro.xml
content.xml
xercesImpl-2.11-fenris.jar

廣告

2012/03/21 - Posted by | Java Tool | ,

仍無迴響。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

w

連結到 %s

%d 位部落客按了讚: