Повторное отображение текущего заголовка после разрыва страницы - PullRequest
0 голосов
/ 15 ноября 2018

Я создаю документ с помощью 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> в верхней части левой страницы.

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

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

1 Ответ

0 голосов
/ 16 ноября 2018

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

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

Мы должны использовать один из них для создания решения только для css: мы выберем заголовки. Итак, первая часть вопроса: как я могу установить разные заголовки для каждой страницы? Или, другими словами, как я могу установить заголовок главы?

Достижение этой цели довольно просто: однажды решив, какой тег или класс должен содержать заголовок главы, установите для него новую строку CSS :

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>

В этом случае ваши заголовки будут:

  • 1-я страница: «Первый раздел»
  • 2-я страница: «Первый раздел»… затем начнется второй раздел на той же странице с собственным заголовком
  • 3-я страница: «Второй раздел»

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: hidden или font-size: 0 или color: transparent, но эти три параметра всегда будут оставлять пробел между заголовком и первым абзацем.

Теперь, вероятно, пришло время увеличить высоту заголовка, добавив top-padding к @ 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;
}
...