Повторное отображение текущего заголовка после разрыва страницы

Я создаю документ с помощью 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:

введите описание изображения здесь

Я хочу, чтобы First section отображался как тег <h1> вверху на левой странице.

Я хотел бы сделать как эту запись tex.stackexchange, которая , насколько я понимаю, в основном состоит в проверке, превышает ли текущий номер страницы текущее общее количество страниц, и если это так, вставка последнего встречающегося заголовка раздела.

Я не знаю о возможности сделать это в HTML, существует ли она? Есть ли обходной путь для этого? Если нет, возможно ли, чтобы WeasyPrint выполнял пользовательский код Python на каком-то крючке page-break?


person Right leg    schedule 15.11.2018    source источник


Ответы (1)


Хотя в настоящее время это невозможно, вы все равно можете использовать отличный обходной путь.

При печати на каждой странице автоматически воспроизводятся только три вида элементов:

  • элементы с фиксированным положением
  • заголовки, объявленные с помощью @top-left, @top-center, @top-right и т. д.
  • нижние колонтитулы, объявленные с помощью @bottom-left и т. д.

Мы должны использовать один из них для создания решения только для 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-я страница: «Первый раздел»
  • 2-я страница: «Первый раздел»… затем начнется второй раздел на той же странице с его собственным заголовком.
  • 3-я страница: «Второй раздел»

заголовки глав на 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: hidden или font-size: 0 или color: 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;
}
person Kalamun    schedule 16.11.2018