分页符后重新显示当前标题

时间:2018-11-15 15:24:26

标签: python html css weasyprint

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

下面的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的输出:

enter image description here

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

我想作为this tex.stackexchange的帖子,据我所知,基本上是检查当前页码是否超过当前总页数,如果确实如此,则插入遇到的最后一个标题。

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

1 个答案:

答案 0 :(得分:2)

虽然目前无法实现,但您仍然可以使用很棒的解决方法。

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

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

实现此目标非常简单:确定哪个标签或类应包含该章的标题后,为其设置新的CSS string

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

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

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

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

现在,您将得到如下内容:

pages with chapter's headers

让我为您添加一些代码:

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

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

  • 第一页:“第一部分”
  • 第二页:“第一部分”…然后将在同一页面中以自己的标题开始第二部分
  • 第三页:“第二部分”

chapter headers on 3 pages

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

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

然后您将看到类似这样的内容:

pages with chapter's headers styled as titles

现在,我们需要修复最新的问题:由于标题和标题都存在,因此首页中的标题看起来像重复的

修复非常简单:

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

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

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

chapter's headers and hidden title

这种技术不是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;
}