How to create a book-style custom header with a colored box with the page number?

Hey @jfdsap, welcome to the forum! I’d like to kindly ask you to read through our question posting guidelines: How to post in the Questions category

In particular:

  • Your title should be a question. I’ve updated it based on what I think you are asking, but you may want to correct it.
  • Your post has no text! Please explain what exactly you need help with. For example, is this an image made with some other software such as LaTeX? What have you tried to do so far, and what have you achieved? Which part seems hard for you?
  • Also include small snippets of code with your current attempts if possible.

Thanks in advance!

3 Likes

There is no need for any text in OP’s post. The question is there in the title and the example they’re looking to emulate is right there in the image. Remember little robot that for us humans, a picture is worth 1000 words.

Hey @Johannes_Rexx ! Actually, it was me who added the question in the title, but I am not sure if it is correct, hence why I requested further explanation:

Your title should be a question. I’ve updated it based on what I think you are asking, but you may want to correct it.

If you’d like to be rude to moderators, you are welcome to do so elsewhere. Thank you!

5 Likes

The title is a good one @PgBiel, and I had hoped it would inspire a few responses. Alas, it was not my intention to be rude by calling you a “little robot.”

Hey there! :wave:

I managed to achieve this using hydra and the place function. If you change the margins, you will have to also edit the dx attributes for the place page function :slight_smile:

Using this code, you will be able to get this header:

#set page(paper: "a4", margin: 2cm, header: context {
  
  if calc.odd(here().page()) {

    box[
      
      #grid(
        columns: 2, rows: (0.25cm), align: horizon, column-gutter: 10pt,
        line(length: 100%, stroke: rgb("#e1e1e1")), emph(hydra(1)))
      
      #place(dx: 2cm, dy: 0.1cm, right + bottom)[
        #box(fill: rgb("#4ca5a5"), inset: (left: 0.2cm, right: 1.2cm, y: 0.1cm))[
          #text(fill: white)[*#here().page()*]
        ]
      ]
    ]
  
  } else {
    
    box[
      #place(dx: -2cm, dy: 0.1cm, bottom)[
        #box(fill: rgb("#4ca5a5"), inset: (left: 1.2cm, right: 0.2cm, y: 0.1cm))[
          #text(fill: white)[*#here().page()*]
        ]
      ]
    
      #grid(
        columns: 2, rows: (0.25cm), align: horizon, column-gutter: 10pt,
        emph(hydra(1)), line(length: 100%, stroke: rgb("#e1e1e1"))
      )
    ]
    
  }
})

See result:

5 Likes

Very nice. To make this work, be sure to include
#import "@preview/hydra:0.6.2": hydra
at the front of the document and then ensure that the code GOST shared appears at the beginning of the document so it applies to all pages.

Here is my attempt. It results in gaps between two items when on the right side. And large numbers get cut out

#let alternateNumbering(
  doc,
  color: black,
  textcolor: white,
  title: "Title",
  titlebg: rgb("#acd1f6"),
  start_from: 1,
) = [


  #set page(
    header: context {
      let world = title
      let pgnumber = {
        set text(fill: textcolor)
        numbering("I", ..counter(page).at(here()).map(x => x))
      }
      if counter(page).at(here()).first() > start_from [

        #if (calc.even(counter(page).at(here()).first())) [
          #place(
            dy: 20pt,
            dx: 72pt,
            top + right,
            stack(
              spacing: 10pt,
              dir: rtl,
              rect(width: 50pt, inset: (x: 30pt, y: 5pt), fill: color, pgnumber),
              rect(fill: titlebg, world),
            ),
          )
        ] else [
          #place(
            dy: 20pt,
            dx: -72pt,
            top + left,
            stack(
              dir: ltr,
              rect(width: 50pt, inset: (x: 30pt, y: 5pt), fill: color, pgnumber),
              rect(fill: titlebg, world),
            ),
          )
        ]
      ]
    },
  )
  #doc
]