一、背景
我比较喜欢采用DocBook5的方式编写文档。其好处就是在编写时,编写的重点在内容而非样式,后期统一进行格式处理转为docx(虽然扩展名也叫docx,但其实是Office Open XML,是MS Word 2007及以上支持的格式)。再转为标准Word或PDF模式。
理论上讲DocBook是可以直接转PDF的。但由于我用的是Linux(en)系统,再加上字体也有很多问题。所以我目前的方式就是在Linux下编写,转docx(Office Open XML)。把文件发送给Win7虚拟机,通过Office或PDFCreator转为PDF。也希望大家不要在此纠结我为什么不直接转为PDF。
采用的编写工具为XMLmind XML Editor Pro 5.7.0(采用Java开发,跨平台),目前的这个版本已经合并了文档转换功能所以还不错。下文该工具简写为XXE。
由于docbook-xsl官方提供的中文xsl样式不是太让人满意所以我定义了自己的中文样式。
二、我的DocBook样式XSL
下面的XML基本都有注释,所以我不会一一说明。重点要说的是前面两个xsl:import语句。第一个是引用你标准docbook.xsl文件的语句,你需要修改第一个import指定到你自己docbook5的xsl。默认XXE下xsl的路径为${xxe}/addon/config/docbook5/xsl/fo/docbook.xsl。
第二个引用是我在标准基础上修改的revhistory.xsl(修订历史)模板,默认模板不符合中国习惯。
main.xsl
<?xml version='1.0' encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="http://docbook.org/ns/docbook"
xmlns:exsl="http://exslt.org/common"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:ng="http://docbook.org/docbook-ng"
xmlns:db="http://docbook.org/ns/docbook"
exclude-result-prefixes="db ng exsl d"
version='1.0'>
<xsl:import href="../xxe-5_7_0-docbook5-xsl/fo/docbook.xsl"/> <!--请根据自身的docbook.xls的位置修改-->
<xsl:import href="./revhistory.xsl"/> <!--加载自定义修订历史模板-->
<xsl:param name="l10n.gentext.language" select="'zh_CN'"/>
<xsl:param name="title.font.family">Microsoft YaHei</xsl:param> <!--设置标题字体微软黑体(Microsoft YaHei)-->
<xsl:param name="body.font.family">Microsoft YaHei</xsl:param> <!--设置内容字体微软黑体(Microsoft YaHei)-->
<xsl:param name="monospace.font.family">Microsoft YaHei</xsl:param> <!--设置等宽字体为微软黑体(Microsoft YaHei)-->
<xsl:param name="body.font.size">12pt</xsl:param> <!--设置内容字体大小12pt-->
<xsl:param name="paper.type" select="'A4'"/> <!--纸张大小A4-->
<xsl:param name="draft.mode" select="'no'"/>
<xsl:param name="body.start.indent">0pt</xsl:param> <!--正文不缩进-->
<xsl:param name="line-height">1.5em</xsl:param> <!--行高1.5倍-->
<xsl:param name="bibliography.numbered" select="1" /> <!--参考资料加编号-->
<xsl:param name="alignment">left</xsl:param> <!--默认左对齐-->
<xsl:attribute-set name="normal.para.spacing"> <!--段首缩进-->
<!--表格中的段落不缩进-->
<xsl:attribute name="text-indent">
<xsl:choose>
<xsl:when test="parent::db:entry">0em</xsl:when>
<xsl:otherwise>2em</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:attribute-set>
<xsl:param name="section.autolabel" select="1"/>
<xsl:attribute-set name="table.properties"> <!--设置表格中的字体大小9pt-->
<xsl:attribute name="font-size">9pt</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="formal.title.properties"> <!--图,表格,列表标题-->
<xsl:attribute name="text-indent">0em</xsl:attribute> <!--不缩进-->
<!--列表字体大小12pt-->
<!--图,表格字体大小9pt -->
<!--
<xsl:attribute name="font-size">
<xsl:choose>
<xsl:when test="parent::db:itemizedlist">12pt</xsl:when>
<xsl:when test="parent::db:orderedlist">12pt</xsl:when>
<xsl:when test="parent::db:variablelist">12pt</xsl:when>
<xsl:otherwise>9pt</xsl:otherwise>
</xsl:choose>
</xsl:attribute> -->
<!--<xsl:attribute name="text-align">center</xsl:attribute> --> <!--标题居中-->
</xsl:attribute-set>
<xsl:attribute-set name="revhistory.table.cell.properties"> <!--设置修订版本表格中的字体大小9pt-->
<xsl:attribute name="font-size">9pt</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="toc.line.properties"> <!--设置目录中的字体大小9pt-->
<xsl:attribute name="font-size">9pt</xsl:attribute>
</xsl:attribute-set>
<xsl:template name="component.toc.separator"> <!--目录后强制分页-->
<fo:block break-after="page"/>
</xsl:template>
<xsl:attribute-set name="revhistory.title.properties"> <!--修定历史表头样式-->
<xsl:attribute name="font-size">9pt</xsl:attribute>
<xsl:attribute name="text-align">left</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="revhistory.table.properties"> <!--修定历史表格样式-->
<xsl:attribute name="border">0.5pt solid black</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="revhistory.table.cell.properties"><!--修定历史表格单元格样式-->
<xsl:attribute name="border">0.5pt solid black</xsl:attribute>
<xsl:attribute name="font-size">9pt</xsl:attribute>
<xsl:attribute name="padding">4pt</xsl:attribute>
</xsl:attribute-set>
</xsl:stylesheet>
revhistory.xsl
<?xml version='1.0' encoding="UTF-8" ?>
<xsl:stylesheet exclude-result-prefixes="d"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="http://docbook.org/ns/docbook"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version='1.0'>
<xsl:template match="d:revhistory" mode="titlepage.mode">
<xsl:variable name="explicit.table.width">
<xsl:call-template name="pi.dbfo_table-width"/>
</xsl:variable>
<xsl:variable name="table.width">
<xsl:choose>
<xsl:when test="$explicit.table.width != ''">
<xsl:value-of select="$explicit.table.width"/>
</xsl:when>
<xsl:when test="$default.table.width = ''">
<xsl:text>100%</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$default.table.width"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:table table-layout="fixed" width="{$table.width}" xsl:use-attribute-sets="revhistory.table.properties">
<fo:table-column column-number="1" column-width="1in"/>
<fo:table-column column-number="2" column-width="1in"/>
<fo:table-column column-number="3" column-width="proportional-column-width(1)"/>
<fo:table-body start-indent="0pt" end-indent="0pt">
<fo:table-row>
<fo:table-cell number-columns-spanned="3" xsl:use-attribute-sets="revhistory.table.cell.properties">
<fo:block xsl:use-attribute-sets="revhistory.title.properties">
<xsl:choose>
<xsl:when test="d:title|d:info/d:title">
<xsl:apply-templates select="d:title|d:info/d:title" mode="titlepage.mode"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="gentext">
<xsl:with-param name="key" select="'RevHistory'"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</fo:block>
</fo:table-cell>
</fo:table-row>
<xsl:apply-templates select="*[not(self::d:title)]" mode="titlepage.mode"/>
</fo:table-body>
</fo:table>
</xsl:template>
<xsl:template match="d:revhistory/d:revision" mode="titlepage.mode">
<xsl:variable name="revnumber" select="d:revnumber"/>
<xsl:variable name="revdate" select="d:date"/>
<xsl:variable name="revauthor" select="d:authorinitials|d:author"/>
<xsl:variable name="revremark" select="d:revremark|d:revdescription"/>
<fo:table-row>
<fo:table-cell xsl:use-attribute-sets="revhistory.table.cell.properties">
<fo:block>
<xsl:if test="$revnumber">
<xsl:call-template name="gentext">
<xsl:with-param name="key" select="'Revision'"/>
</xsl:call-template>
<xsl:call-template name="gentext.space"/>
<xsl:apply-templates select="$revnumber[1]" mode="titlepage.mode"/>
</xsl:if>
</fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="revhistory.table.cell.properties">
<fo:block>
<xsl:apply-templates select="$revdate[1]" mode="titlepage.mode"/>
</fo:block>
</fo:table-cell>
<!--不显示作者-->
<!--
<fo:table-cell xsl:use-attribute-sets="revhistory.table.cell.properties">
<fo:block>
<xsl:for-each select="$revauthor">
<xsl:apply-templates select="." mode="titlepage.mode"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</fo:block>
</fo:table-cell> -->
<fo:table-cell xsl:use-attribute-sets="revhistory.table.cell.properties">
<fo:block>
<xsl:apply-templates select="$revremark[1]" mode="titlepage.mode"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
<!--
<xsl:if test="$revremark">
<fo:table-row>
<fo:table-cell number-columns-spanned="3" xsl:use-attribute-sets="revhistory.table.cell.properties">
<fo:block>
<xsl:apply-templates select="$revremark[1]" mode="titlepage.mode"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:if>-->
</xsl:template>
</xsl:stylesheet>
这个xsl是从原默认titlepage.xsl中提取出来的,对revhistory的fo:table进行来调整,调整效果如下。
+------------------------------------------------------------------+
| <revnumber> | <date> |
+------------------------------------------------------------------+
| <revdescription> - a paragraph containing several sentences - |
| much longer than either revnumber or date. But this rendering |
| is not pleasing |
+------------------------------------------------------------------+
以上为默认的修订历史模板,需要修改为下面的:
+------------------------------------------------------------------+
| <revnumber> | <date> | <revdescription> - a paragraph containing |
| | | several sentences - much longer than |
| | | either revnumber or date. This rendering |
| | | is much preferred, since it has just one |
| | | row and the first two columns are squeezed|
| | | to be just big enough |
+------------------------------------------------------------------+
三、XSL样式下载
附件中包含了上面的2个文件。
四、总结
DocBook以XML的方式来组织文档,虽然在可显化编辑上远比不上Office等工具的强大,但却减轻频繁调整样式给我带来的痛苦。XML的方式还可以很好的支持版本管理,随时知道自己加了什么删除了什么,跨版本比较,还可以打tag。
P.S.
XXE(5.7.0)工具是收费的。收的钱确实很多,所以我只能破解了(替换一个JAR),有需要破解JAR的人留email给我。