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/>   </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>
:
<deposition-title>
坚持第一个<seg>
<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/>   </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>
我有一个大型语料库,它基于以下简化的 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/>   </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>
:
<deposition-title>
坚持第一个<seg>
<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/>   </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>