markuptypsttypesetting

Page break after re-setting margin in Typst


Hi there nice people from SO

Problem

I am trying to create a template in typst. I'd like to stylize my title section with a big block of colored background extending beyond the margin (see attached screenshot). My current implementation goes like this:

  1. set page(margin: 0);
  2. block([ headings, authors, affiliations all rendered here... ], fill: accent-dark);
  3. set page(margin: page-config.margin);
  4. doc

Where page-config is a dictionary containing margin of correct type and accent-dark a pre-computed color.

My problem now is I'm encountering a page break on the third step.

I'm no professional in typesetting, and it's my first time using Typst. Can anyone who know typesetting give

Thanks


Attachment:

Minimal Reproducible Snippet

= Some Title // on page 1
#set page(margin: 2in)
Content // on page 2

Screenshot

A screenshot of current compilation result


Solution

  • Explanation on why the page break happened

    This is by design, because set page might change the page in a way which is incompatible with the current setup of the page, so it creates a new conforming page. See the Page setup guide:

    The set rule of the page element is where you control all of the page setup. If you make changes with this set rule, Typst will ensure that there is a new and conforming empty page afterward, so it may insert a page break. Therefore, it is best to specify your page set rule at the start of your document or in your template.

    One potential solution could be to use negative padding and using a block width of the size of the page, for example:

    #set page(margin: 2in)
    #set heading(numbering: "1.")
    
    #set text(fill: black)
    #context(
      align(center + top,
        pad(top: -page.margin, bottom: 5em, {
          let bg-color = blue
          block(width: page.width, stroke: bg-color, fill: bg-color, inset: 1in)[
            #set text(fill: white, size: 5em)
            Report Title
          ]
        })
      )
    )
    
    = Some section
    
    #lorem(200)
    

    Note the pad(top: -page.margin, ...) which moves the block inside the margin. Because this expression accesses page.margin and page.width it needs to be wrapped inside a context expression.

    There might be better ways to solve this though. Might be worth asking on the Typst Forum as well, but in that case please cross-link between your question here and the forum post to avoid duplicate answers.