7

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

以下 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>标签显示在左页的顶部。

我想做这个 tex.stackexchange帖子,据我了解,基本上包括检查当前页码是否超过当前总页数,如果超过,则插入遇到的最后一节标题。

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

4

1 回答 1

8

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

打印时,每页仅自动复制三种元素:

我们必须使用其中一个来构建纯 CSS 解决方案:我们将选择标头。所以,问题的第一部分是:如何为每个页面设置不同的标题?或者,换句话说,如何设置章节标题?

实现这个目标非常简单:一旦决定了哪个标签或类应该包含章节的标题,就为其设置一个新的CSS 字符串

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

然后在标题中显示字符串:

@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>

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

  • 第 1 页:“第一部分”
  • 第二页:“第一部分”……然后将在同一页开始第二部分,用他自己的标题
  • 第三页:“第二部分”

3页的章节标题

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

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;
  }
}

然后你会有这样的东西:

章节标题样式为标题的页面

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

修复它非常简单:

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

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

现在可能是时候增加标题的高度了,将顶部填充添加到@top-left;结果应如下所示:

章节标题和隐藏标题

这种技术不是 100% 安全的:如果不是第一个章节的章节巧合地从新页面开始,标题和标题都会显示,一个靠近另一个。无论如何,这不是常见的情况。

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

<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>

为章节设置分页符样式,并为任何章节的第一个子项管理标题隐藏:

section.chapter {
    break-after: always;
}
section.chapter h1:first-of-type {
    position: absolute;
    left: -30cm;
}
于 2018-11-16T15:37:40.720 回答