Re-displaying 分页后的当前标题

Re-displaying the current heading after a page break

我正在使用 Wea​​syPrint 创建文档。 我有一些有名称的部分,其中一些可能跨越多个页面。 当一个部分太长时,会发生分页。我想要做的是 re-display 当前部分的名称,最好使用相同的格式。

以下 MWE 显示分页符后如何不显示节标题:

<html>
    <body>
        <h1>First section</h1>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>

        <p style="break-after: always;"></p>

        <p>Lorem ipsum...</p>
    </body>
</html>

weasyprint example.html example.pdf 的输出:

我希望 First section 作为 <h1> 标签显示在左侧页面的顶部。

我想按照 this tex.stackexchange post 做,据我了解,主要是检查当前页码是否超过当前总页数,如果超过,则插入遇到最后一节标题。

我不知道在 HTML 中可以这样做,它存在吗? 有什么解决方法吗?如果不是,是否可以让 WeasyPrint 在某些 page-break 挂钩上执行自定义 Python 代码?

虽然目前不可能,但您仍然可以使用一个很棒的解决方法。

打印时,每页只自动重现三种元素:

我们必须使用其中之一来构建 css-only 解决方案:我们将选择 headers。 所以,问题的第一部分是:如何为每个页面设置不同的header? 或者换句话说,如何设置章节的[=101] =]?

实现这个目标非常简单:一旦决定了哪个标签或 class 应该包含章节的标题,为它设置一个新的 CSS string:

h1 {
  string-set: doctitle content();
}

然后显示header中的字符串:

@page {
  size: A4;
  margin: 1.6cm .6cm 1.2cm .6cm;

  @top-center {
    content: string(doctitle);
  }
}

现在你会有这样的东西:

让我为您添加一些代码:

<html>
    <body>
        <h1>First section</h1>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>

        <p style="break-after: always;"></p>

        <p>Lorem ipsum...</p>

        <h1>Second section</h1>
        <p>Lorem ipsum 2...</p>
        <p>Lorem ipsum 2...</p>
        <p>Lorem ipsum 2...</p>
        <p>Lorem ipsum 2...</p>

        <p style="break-after: always;"></p>

        <p>Lorem ipsum 2...</p>
    </body>
</html>

在这种情况下,您的 header 将是:

  • 第 1 页:"First section"
  • 第二页:"First section"...然后将在同一页开始第二部分,并有自己的标题
  • 第 3 页:"Second section"

下一步:为 header 和章节标题设置相同的样式,因此 header 可以与标题具有相同的外观:

h1 {
  string-set: doctitle content();
  font-family: 'Liberation Serif';
  font-size: 28pt;
  line-height: 1.2em;
}

@page {
  size: A4;
  margin: 1.6cm .6cm 1.2cm .6cm;

  @top-left {
    content: string(doctitle);
    font-family: 'Liberation Serif';
    font-size: 28pt;
    line-height: 1.2em;
  }
}

然后你会得到这样的东西:

现在,我们需要解决最新的问题:第一页的标题看起来重复了,因为标题和header都存在。

修复它非常简单:

body h1:first-of-type {
  position: absolute;
  left: -30cm;
}

我已将第一个标题放在打印区域之外。不幸的是,将其设置为 display: none 将导致甚至不会显示 header。你还有其他选择,比如visibility: hiddenfont-size: 0color: transparent,但这三个选项总是会在header和第一段之间留下一些空白space .

现在可能是时候增加 header 的高度了,将 top-padding 添加到 @top-left; 结果应如下所示:

此技术并非 100% 安全:如果不是第一章的章节恰好在新页面开始,header 和标题都会显示,一个靠近另一个。无论如何,这种情况并不常见。

进一步的改进可以考虑使用不同的分页方法。

<html>
    <body>
        <section class="chapter">
            <h1>First section</h1>
            <p>Lorem ipsum...</p>
            <p>Lorem ipsum...</p>
            <p>Lorem ipsum...</p>
            <p>Lorem ipsum...</p>
            <p>Lorem ipsum...</p>

            <h1>Second section</h1>
            <p>Lorem ipsum 2...</p>
            <p>Lorem ipsum 2...</p>
            <p>Lorem ipsum 2...</p>
        </section>
        <section class="chapter">
            <h1>Third section</h1>
            <p>Lorem ipsum 3...</p>
            <p>Lorem ipsum 3...</p>
            <p>Lorem ipsum 3...</p>
            <p>Lorem ipsum 3...</p>
        </section>
    </body>
</html>

对章节进行样式设置 page-breaks,并管理任何章节第一 child 的标题隐藏:

section.chapter {
    break-after: always;
}
section.chapter h1:first-of-type {
    position: absolute;
    left: -30cm;
}