PAYATHON 2026

XSL Formatter 如何让总页数为4的倍数且版权封底位于最后?

数据小许

在版权封底之前增加一个补页用的 page-sequence,使该序列结束时的文档累计页数满足 4k + 3。随后输出一页版权封底,并将封底的 force-page-count 改为 no-force。这样总页数就是 4k + 4,补页也都位于封底之前。

该方案要求版权封底自身只占一页,且所用 Antenna House Formatter 的版本和版本类型支持下述扩展。

为什么当前设置会在封底之后补页?

force-page-count 约束当前 page-sequence 的结束位置。需要补页时,页面会添加到该序列末尾,不会把已经排好的版权内容向后移动。XSL 1.1 的 force-page-count 定义说明了这一行为。

还要注意,end-on-doubly-even 约束的是序列最后一页的页码。如果前面重置过页码,它约束的页码与整份文档的物理总页数不一定一致。对于整份文档的页数要求,应使用基于文档累计页数的约束。Antenna House 扩展说明列出了这些取值的区别。

在版权封底之前补到 4k + 3 页

保留已有的 Notes section 和封底前空白页,在版权封底的 page-sequence 之前插入:

<!-- 插在原有封底前空白页之后、版权封底之前 -->
<fo:page-sequence
    master-reference="XY-letter-back-cover-page"
    force-page-count="document 4 3"/>

document 4 3 表示从文档开头累计,页数应满足 4k + 3。这里复用原有的 XY-letter-back-cover-page;如果它带有背景或其他装饰,请换成专门用于空白补页的 page master。

这个序列不包含 fo:flow。Antenna House 支持用这样的空 page-sequence 调整页数;如果累计页数已经满足条件,它可以不生成页面。官方补页示例也采用了这种方式。

接着,把原版权封底 page-sequence 上的属性从:

force-page-count="end-on-doubly-even"

改为:

force-page-count="no-force"

版权封底中的 fo:static-content、marker 和正文内容可以继续保留。调整后的顺序为:

Notes section
原有封底前空白页
自动补页序列:累计页数达到 4k + 3
版权封底:一页,no-force

例如,进入自动补页序列之前已经有 10 页,则补 1 页达到 11 页,随后版权封底成为第 12 页。如果已经有 11 页,补页序列无需产生页面,直接输出第 12 页封底。这是按上述规则计算的示例,并非对所给 FO 的实测结果。

调整时需要确认什么?

  • 版权封底必须只生成一页。原代码包含 break-before="page"、page-break-before="always" 和绝对定位容器。由于没有提供完整的 page master,仅凭片段无法确定这些内容最终占几页,应检查实际输出,排除额外分页或溢出。
  • 确认原有封底前空白页实际生成。该页的 fo:flow 只有 marker,不宜仅凭代码意图认定它一定会输出一页,应在生成结果中确认。
  • Notes 至少两页的要求需要单独保证。force-page-count="even" 表达偶数页约束;仍应通过实际内容或明确的分页安排保证至少两页。
  • 确认扩展可用。document 4 3 和省略 fo:flow 的空 page-sequence 属于 Formatter 扩展,相关文档标有版本类型限制,不能当作所有 XSL-FO 处理器都支持的标准功能。扩展及空序列说明

如果当前环境不支持这些扩展,可以采用两次排版:第一次取得版权封底之前的实际页数 N,再计算补页数 p = (4 - ((N + 1) mod 4)) mod 4;第二次在封底前明确插入 p 页,并让一页版权封底以 no-force 结束。计算中的 +1 为最后一页版权封底预留位置。

备注:内容仅供参考。