XSL-FO 分页符、寡妇和孤儿

XSL-FO page breaks, widows and orphans

我有一个大型语料库,它基于以下简化的 XML 结构的 XSL-FO 3.0 转换生成 PDF:

<corpus>
  <deposition>
     <text>
       <deposition-title>foo title</deposition-title>
       <seg>foo paragraph 1</seg>
       <seg>foo paragraph 2</seg>
       <seg>foo paragraph 3</seg>
       <appnotes>
         <appitem>foo apparatus item 1</appitem>
       </appnotes>
       <footnotes>
         <footitem>foo note 1</footitem>
         <footitem>foo note 1</footitem>
       </footnotes>
     </text>
  </deposition>
  <deposition>
     <text>
       <deposition-title>foo title</deposition-title>
       <seg>foo paragraph 1</seg>
       <seg>foo paragraph 2</seg>
      <appnotes/>
       <footnotes>
         <footitem>foo note 1</footitem>
       </footnotes>
     </text>
  </deposition>
   [...]
</corpus>

我使用如下所示的 XSL-FO 3.0(减去上标和斜体的一些内联标记):

<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fo="http://www.w3.org/1999/XSL/Format" 
xmlns:xd="http://www.pnp-software.com/XSLTdoc"
version="3.0">

<xsl:template match="/">
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master 
                master-name="page-recto"
                page-height="29.7cm"  page-width="21cm"
                margin-top="2cm" margin-bottom="2cm" 
                margin-left="3cm" margin-right="1.5cm">
                <fo:region-body 
                    region-name="xsl-region-body"/>
            </fo:simple-page-master>
        </fo:layout-master-set>

        <fo:page-sequence master-reference="page-recto">
            <fo:flow flow-name="xsl-region-body" 
                font-family="Times" font-weight="normal" 
                font-size="8pt" space-before="8pt" space-after="8pt"
                text-align="justify" end-indent="120pt">
                <xsl:apply-templates/>
            </fo:flow>
        </fo:page-sequence>

    </fo:root>
</xsl:template>

<xsl:template match="text">
    <fo:block widows="10" orphans="10"
        font-size="9pt" font-weight="bold" 
        padding-bottom="1cm" end-indent="120pt">
        <xsl:apply-templates/>
    </fo:block>
</xsl:template>


<xsl:template match="seg">
    <fo:block
        font-family="Times" font-weight="normal" line-height="12pt" line-stacking-strategy="font-height"
        font-size="10pt" space-before="10pt" space-after="10pt" text-align="justify" end-indent="120pt">
        <xsl:apply-templates/>
    </fo:block>
</xsl:template>

<xsl:template match="appnotes">
   <xsl:choose>
       <xsl:when test="./appitem">
            <fo:leader leader-pattern="rule" leader-length="2cm" rule-style="solid" rule-thickness=".2pt"/>      
            <fo:block font-size="8pt" font-weight="normal" end-indent="120pt">
                <xsl:for-each select="./appitem">
                    <fo:inline keep-together="always"><xsl:apply-templates/>&#160;&#160;&#160;</fo:inline>
                </xsl:for-each>
            </fo:block></xsl:when>
       <xsl:otherwise></xsl:otherwise>
   </xsl:choose>
</xsl:template>

<xsl:template match="footnotes">
    <xsl:choose>
        <xsl:when test="./footitem">
            <fo:leader leader-pattern="rule" leader-length="2cm" rule-style="solid" rule-thickness=".2pt"/>  
                <xsl:for-each select="./footitem">
                    <fo:block font-size="8pt" font-weight="normal" end-indent="120pt">
                       <xsl:apply-templates/>
                    </fo:block>
                </xsl:for-each>
            <fo:leader leader-pattern="rule" leader-length="2cm" rule-style="solid" rule-thickness=".2pt"/>      
        </xsl:when>
        <xsl:otherwise>
            <fo:leader leader-pattern="rule" leader-length="2cm" rule-style="solid" rule-thickness=".2pt"/>      
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

它生成的可重复部分通常如下所示:

但是 XSL-FO 会产生一些分页问题,​​我似乎无法使用 keep together、widows、orphans 等的组合来解决这些问题

<deposition-title><seg>

中断

<seg><appnotes><footnotes>

中断

目标:我想应用以下两条规则来分页 <text>:

  1. <deposition-title>坚持第一个<seg>

  2. <appnotes><footnotes> 坚持到最后 <seg>

提前感谢您的任何见解。

如果你添加

<xsl:template match="deposition-title">
    <fo:block keep-with-next="always">
        <xsl:apply-templates/>
    </fo:block>
</xsl:template>

那么标题应该和你生成的第一个段块放在同一页上。

应用注释和脚注应该采用与 keep-with-previous 类似的结构,据我了解,您想将它们与最后一个 seg 块放在一起,因此也许可以更改 <xsl:apply-templates/>在模板匹配 text 中应更改为 <xsl:apply-templates select="node() except footnotes/>,然后在模板匹配 appnotes 中创建包装器并处理脚注,例如

<xsl:template match="appnotes">
  <fo:block keep-with-previous="always">
    ...
    <xsl:apply-templates select="following-sibling::footnotes"/>
  </fo:block>
</xsl:template>

为了跟进已接受的答案,我将针对评论中确定的一个问题在此处发布修改后的代码。现在<appnotes><footnotes>是一个模板,里面是一个<fo:block>。这是用 RenderX 处理的。

<xsl:template match="footnotes | appnotes">
    <fo:block font-size="8pt" font-weight="normal" end-indent="120pt" keep-with-previous="always">
        <xsl:choose>
            <xsl:when test="./appitem">
                <fo:leader leader-pattern="rule" leader-length="2cm" rule-style="solid" rule-thickness=".2pt" keep-with-previous="always"/>      
                <fo:block keep-with-previous="always">
                    <xsl:for-each select="./appitem">
                        <fo:inline><xsl:apply-templates/>&#160;&#160;&#160;</fo:inline>
                    </xsl:for-each>
                </fo:block>
            </xsl:when>
        </xsl:choose>
        <xsl:choose>
            <xsl:when test="./footitem">
                <fo:leader leader-pattern="rule" leader-length="2cm" rule-style="solid" rule-thickness=".2pt" keep-with-previous="always"/>  
                <xsl:for-each select="./footitem">
                    <fo:block keep-with-previous="always">
                        <xsl:apply-templates/>
                    </fo:block>
                </xsl:for-each>     
                <fo:leader leader-pattern="rule" leader-length="2cm" rule-style="solid" rule-thickness=".2pt" keep-with-previous="always"/> 
            </xsl:when>
        </xsl:choose>
    </fo:block>
</xsl:template>