Fix/change: Keep headings on the same page as fist content:

By default, the heading should "stick" to the content, and be on the same page as the following block/content.
Avoids headings without content on the same page.

Replaces older, buggy implementation attempt with a newer Typst feature.

New parameter `keep_heading_with_content` replaces old `heading_pagebreak_percentage`
This commit is contained in:
Laurenz 2025-07-14 15:33:54 -07:00
parent f078966e06
commit 7843a4a7b1
Signed by: C0ffeeCode
SSH key fingerprint: SHA256:prvFOyBjButRypyXm7X8lbbCkly2Dq1PF7e/mrsPVjw

View file

@ -150,11 +150,10 @@
// This is *not* required anymore // This is *not* required anymore
// first_chapter_title: none, // first_chapter_title: none,
// Factor of page location when to pagebreak headings // If headings should stick to the following block
// to avoid a heading without content on the same page. // to avoid a heading without content on the same page.
// Can be disabled by setting it to none // Can be disabled by setting it to `false`
// WARNING: can result in "layout did not converge within 5 attempts" issue keep_heading_with_content: true,
heading_pagebreak_percentage: none,
// set automatically by using the template via `#show: thesis.with(...) // set automatically by using the template via `#show: thesis.with(...)
body, body,
@ -227,24 +226,9 @@
// (weak = no pagebreak on already blank pages) // (weak = no pagebreak on already blank pages)
if it.level == 1 { if it.level == 1 {
pagebreak(weak: true) pagebreak(weak: true)
} else if heading_pagebreak_percentage != none {
// If a heading would start at the very end of a page,
// it would not look right => pagebreak
context {
let here_abs = here().position().y
let here_rel = here_abs.abs / page.height
if here_rel > heading_pagebreak_percentage {
// Write but hide to assess location correctly
// Hidden will not have any influence
// on the output besides correct calculation
hide[#here_abs.abs #page.height rel: #here_rel%]
pagebreak(weak: true)
}
}
} }
[ block(sticky: keep_heading_with_content)[
#set text(size: sizes.at(2)) #set text(size: sizes.at(2))
#v(sizes.at(0)) #v(sizes.at(0))
#if it.numbering != none [ #if it.numbering != none [