使用Saxon 12时,如何在XSL生成的LaTeX中添加amsmath包引用?
问题描述
我使用Saxon 12.8将XML源文件编译为TEX文件,采用TEIC/Stylesheets项目中的LaTeX转换XSL样式表。但XML源文件包含需要amsmath包支持的数学公式,例如:
<formula notation="latex" type="inline">\tfrac{3}{4}</formula>
我希望生成的TEX文件自动包含\usepackage{amsmath}语句,避免手动编辑的繁琐与错误。尝试重写XSL模板后无效,生成的TEX文件因缺少amsmath包编译报错(未定义控制序列)。我编写的样式表如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0" exclude-result-prefixes="tei"> <!-- Import the main TEI→LaTeX stylesheet --> <xsl:import href="/home/myusername/saxon-he/Stylesheets/profiles/tei/latex/to.xsl"/> <!-- Inject amsmath into the LaTeX preamble --> <xsl:template name="latex-preamble"> <xsl:call-template name="latex-preamble"/> <xsl:text>\usepackage{amsmath}</xsl:text> </xsl:template> <!-- Handle formula elements --> <xsl:template match="tei:formula[@notation='latex']"> <xsl:choose> <!-- If explicitly marked as block/display --> <xsl:when test="@rend='display'"> <xsl:text> \[</xsl:text> <xsl:value-of select="."/> <xsl:text>\] </xsl:text> </xsl:when> <!-- Default: inline --> <xsl:otherwise> <xsl:text>$</xsl:text> <xsl:value-of select="."/> <xsl:text>$</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
解决方案
问题核心在于latex-preamble模板的递归调用——直接调用同名模板会触发无限递归,导致添加amsmath包的代码根本无法执行。结合TEIC Stylesheets的XSLT 3.0特性,正确实现方式如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0" exclude-result-prefixes="tei"> <!-- 导入主TEI→LaTeX样式表 --> <xsl:import href="/home/myusername/saxon-he/Stylesheets/profiles/tei/latex/to.xsl"/> <!-- 使用xsl:override安全修改导入的模板 --> <xsl:override> <!-- 扩展原latex-preamble模板 --> <xsl:template name="latex-preamble"> <!-- 先执行原模板生成默认导言区内容 --> <xsl:next-iteration/> <!-- 添加amsmath包声明,换行保证TeX格式整洁 --> <xsl:text> \usepackage{amsmath} </xsl:text> </xsl:template> </xsl:override> <!-- 保留formula元素处理逻辑,优化匹配规则 --> <xsl:template match="tei:formula[@notation='latex']"> <xsl:choose> <xsl:when test="@rend='display' or @type='display'"> <xsl:text> \[ </xsl:text> <xsl:value-of select="."/> <xsl:text> \] </xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>$</xsl:text> <xsl:value-of select="."/> <xsl:text>$</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
关键细节说明
<xsl:override>是XSLT 3.0专属特性,专门用于修改导入的模板,彻底避免模板优先级冲突和递归问题。<xsl:next-iteration/>会调用原导入模板的内容,而非当前模板,确保先生成原有LaTeX导言区,再追加amsmath包声明。- 添加换行符(
)保证生成的TeX代码格式整洁,避免与其他导言区内容挤在一起。
验证时,查看生成的TEX文件导言区,会发现\usepackage{amsmath}已自动添加,此时\tfrac等amsmath命令可正常编译。
内容的提问来源于stack exchange,提问作者SO Stinks
相关产品推荐
相关产品推荐

