如何为DITA图书图生成的PDF添加带编号的书签(含/不含部件)
解决DITA OT PDF书签缺失自定义编号的问题
我之前也碰到过一模一样的情况——标题和目录的编号逻辑都调得妥妥的,但书签就是不跟着同步编号,核心问题是DITA OT默认的书签生成逻辑是独立于标题编号流程的,得自定义XSLT把编号同步过去。以下是具体解决步骤:
1. 定位书签生成的核心文件
DITA OT默认处理PDF书签的模板在官方org.dita.pdf2插件的xsl/fo/bookmarks.xsl里。我们不用直接修改官方插件,而是在自己的自定义插件里覆盖这个文件。
2. 自定义书签模板,注入编号逻辑
在你的自定义插件里创建路径xsl/fo/,新建bookmarks.xsl文件,添加以下模板(覆盖默认的书签生成逻辑):
<xsl:template match="*[contains(@class, ' topic/topic ')]" mode="bookmark"> <fo:bookmark> <xsl:attribute name="internal-destination"> <xsl:call-template name="generate-id"/> </xsl:attribute> <fo:bookmark-title> <!-- 先输出标题的编号(复用标题处理时生成的@number属性) --> <xsl:if test="./topicmeta/navtitle/@number"> <xsl:value-of select="./topicmeta/navtitle/@number"/> <xsl:text> </xsl:text> </xsl:if> <!-- 再输出标题文本 --> <xsl:value-of select="normalize-space(./topicmeta/navtitle)"/> </fo:bookmark-title> <!-- 递归处理子主题的书签 --> <xsl:apply-templates select="*[contains(@class, ' topic/topic ')]" mode="bookmark"/> </fo:bookmark> </xsl:template>
这个逻辑的关键是复用标题处理阶段已经生成的navtitle/@number属性——既然你已经搞定了标题和目录的编号,这个属性里肯定已经存了正确的编号(比如Part I Chapter 1、1.1这类格式),直接拿来用就不用重新计算编号序列了。
3. 配置插件加载自定义XSLT
在你的自定义插件的plugin.xml里添加扩展点,让DITA OT优先使用你的bookmarks.xsl:
<plugin id="com.yourcompany.custom.pdf"> <!-- 其他插件配置 --> <feature extension="dita.xsl.xslfo" file="xsl/fo/bookmarks.xsl"/> </plugin>
4. 测试验证
- 清理DITA OT的临时输出目录(避免缓存干扰)
- 重新运行PDF生成命令,检查书签是否显示正确的编号
额外注意点
- 如果你的编号是通过自定义的标题编号模板生成的,确保模板里正确设置了
navtitle的@number属性,这样书签模板才能拿到正确的值。 - 对于部件、章节、附录的编号重置逻辑,只要标题的
@number是对的,书签就会自动同步,不用额外处理。
内容的提问来源于stack exchange,提问作者Susanne Muris
相关产品推荐
相关产品推荐

