You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用XSL-FO Apache FOP渲染MathML时求和符号显示异常求助

问题:Apache FOP渲染MathML求和符号下限时自动换行

使用XSL-FO结合Apache FOP将MathML渲染为PDF时,多数公式显示正常,但求和符号的下限在输出PDF中被拆分为两行。尝试将MathML的display="block"改为display="inline"后,Oxygen XML Editor(Author模式)内显示正常,但生成PDF时问题仍存在。需要阻止该元素换行的可行方案。

Oxygen XML Editor显示效果

Oxygen中正常显示的公式

输入MathML

<disp-formula id="FD5">
<label>(5)</label>
<mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block" id="M144">
<mml:mrow><mml:msub><mml:mi>y</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>,</mml:mo><mml:mn>1940</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2002;</mml:mo><mml:mo>=</mml:mo><mml:mo>&#x2002;</mml:mo><mml:munder><mml:mo stretchy='true'>&#x2211;</mml:mo><mml:mrow><mml:mi>a</mml:mi><mml:mfenced><mml:mi>i</mml:mi></mml:mfenced><mml:mo>&#x003C;</mml:mo><mml:mn>64</mml:mn></mml:mrow></mml:munder><mml:mrow><mml:msub><mml:mo>&#x00B5;</mml:mo><mml:mrow><mml:mi>a</mml:mi><mml:mfenced><mml:mi>i</mml:mi></mml:mfenced></mml:mrow></mml:msub><mml:mo>&#x2002;</mml:mo><mml:mo>&#x00D7;</mml:mo><mml:mo>&#x2002;</mml:mo><mml:msub><mml:mrow><mml:mi mathvariant="normal">RR</mml:mi></mml:mrow><mml:mrow><mml:mi>i</mml:mi><mml:mo>,</mml:mo><mml:mn>1930</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2002;</mml:mo><mml:mo>+</mml:mo><mml:mo>&#x2002;</mml:mo></mml:mrow><mml:munder><mml:mo stretchy='true'>&#x2211;</mml:mo><mml:mrow><mml:mi>a</mml:mi><mml:mfenced><mml:mi>i</mml:mi></mml:mfenced><mml:mo>&#x003E;</mml:mo><mml:mn>64</mml:mn></mml:mrow></mml:munder><mml:mrow><mml:msub><mml:mi>&#x03B3;</mml:mi><mml:mrow><mml:mi>a</mml:mi><mml:mfenced><mml:mi>i</mml:mi></mml:mfenced></mml:mrow></mml:msub><mml:mo>&#x2002;</mml:mo><mml:mo>&#x00D7;</mml:mo><mml:mo>&#x2002;</mml:mo><mml:msub><mml:mrow><mml:mi mathvariant="normal">RR</mml:mi></mml:mrow><mml:mrow><mml:mi>i</mml:mi><mml:mo>,</mml:mo><mml:mn>1930</mml:mn></mml:mrow></mml:msub><mml:mo>&#x2002;</mml:mo><mml:mo>+</mml:mo><mml:mo>&#x2002;</mml:mo><mml:msub><mml:mi>&#x03B5;</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>,</mml:mo><mml:mn>1930</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:mrow>
</mml:math>
</disp-formula>

期望输出效果

期望的公式显示效果

实际生成PDF效果

生成PDF中换行的求和下限

现有XSL模板

<xsl:template match="mml:math">
    <xsl:choose>
        <xsl:when test="display='block'">
            <fo:block>
                <fo:instream-foreign-object>
                    <xsl:element name="{local-name()}" xmlns="http://www.w3.org/1998/Math/MathML">
                        <xsl:copy-of select="@*"/>
                        <xsl:apply-templates/>
                    </xsl:element>
                </fo:instream-foreign-object>
            </fo:block>
        </xsl:when>
        <xsl:otherwise>
            <fo:instream-foreign-object>
                <xsl:element name="{local-name()}" xmlns="http://www.w3.org/1998/Math/MathML">
                    <xsl:copy-of select="@*"/>
                    <xsl:apply-templates/>
                </xsl:element>
            </fo:instream-foreign-object>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

解决方案建议

1. 为求和下限添加不可换行约束

在MathML的求和下限mrow中添加linebreak="nobreak"属性,强制阻止内部换行:

<mml:mrow linebreak="nobreak">
    <mml:mi>a</mml:mi>
    <mml:mfenced><mml:mi>i</mml:mi></mml:mfenced>
    <mml:mo>&#x003C;</mml:mo>
    <mml:mn>64</mml:mn>
</mml:mrow>

如果需要通过XSL自动处理,新增模板匹配mml:munder/mml:mrow,自动注入该属性:

<xsl:template match="mml:munder/mml:mrow">
    <mml:mrow linebreak="nobreak">
        <xsl:apply-templates select="@* | node()"/>
    </mml:mrow>
</xsl:template>

2. 调整FO容器的换行属性

在fo:instream-foreign-object外层的fo:block或直接在fo:instream-foreign-object上设置wrap-option="no-wrap",限制外部容器的换行行为:

<fo:block wrap-option="no-wrap">
    <fo:instream-foreign-object>
        <!-- MathML内容 -->
    </fo:instream-foreign-object>
</fo:block>

或针对block类型的Math单独设置:

<xsl:when test="display='block'">
    <fo:block wrap-option="no-wrap">
        <fo:instream-foreign-object>
            <!-- ... -->
        </fo:instream-foreign-object>
    </fo:block>
</xsl:when>

3. 升级Apache FOP版本

部分旧版FOP对MathML的布局支持存在缺陷,升级到最新稳定版(如2.8+)可能已修复此类换行异常问题。

4. 调整求和符号的布局属性

给munder标签添加accent="false"属性,强制FOP使用更严格的水平布局规则:

<mml:munder accent="false">
    <mml:mo stretchy='true'>&#x2211;</mml:mo>
    <mml:mrow>...</mml:mrow>
</mml:munder>

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 21:35:00