How to create an exam header with rotated text?

I would like to create an exam header with rotated text like this image.

Currently I’m using a grid to create the header and an image on the right to achieve the rotated text, like this.

#grid(
    columns: (1fr, 7cm),
    // rows: (auto, 60pt),
    gutter: 3cm,
    
    // titre
    align(
    left,
    {
      text(size: 16pt, weight: 700, "Université Côte d'azur")
      linebreak()
      text(size: large-size, weight: 400, "Institut Universitaire de Technologie")
      linebreak()
      underline(text(size: large-size, weight: 400, "Département INFORMATIQUE"))
      linebreak()
      v(20pt, weak: true)
      text(size: large-size, weight: 700, "Epreuve:")
      line(length: 100%)
      linebreak()
      text(size: footnote-size, "Date")
      line(length: 100%)
      rect(height: 2.5cm, width: 2.5cm,"NOTE")
      text(size: footnote-size, "Nbre d'interacalaires: .........")
    },
  ),
     image("UCA-coin.png")
    
  ))

Is it possible to create the rotated text and corner directly in typst for consistency. If necessary cetz can be used.

Bonjour @benabel! Welcome :smiley:!

It is possible to rotate any content using … rotate!

By tweaking the origin parameter, you will be able to obtain the following result after moving the content slightly

#let large-size = 12pt
#let footnote-size = 8pt
#grid(
    columns: (1fr, 7cm),
    // rows: (auto, 60pt),
    gutter: 3cm,
    
    // titre
    align(
    left,
    {
      text(size: 16pt, weight: 700, "Université Côte d'azur")
      linebreak()
      text(size: large-size, weight: 400, "Institut Universitaire de Technologie")
      linebreak()
      underline(text(size: large-size, weight: 400, "Département INFORMATIQUE"))
      linebreak()
      v(20pt, weak: true)
      text(size: large-size, weight: 700, "Epreuve:")
      line(length: 100%)
      linebreak()
      text(size: footnote-size, "Date")
      line(length: 100%)
      rect(height: 2.5cm, width: 2.5cm,"NOTE")
      text(size: footnote-size, "Nbre d'interacalaires: .........")
    },
  ),
  rect(
    rotate(
      45deg,
      move(dx: -1.5em, dy: 3em, {
        set align(center)
        [Semestre : ]
        box(line(length: 5em))
        h(1em)
        [Groupe : ]
        box(line(length: 5em))
        
        parbreak()
        [Nom : ]
        box(line(length: 6cm))

        parbreak()
        [Prénom : ]
        box(line(length: 5cm))

        parbreak()
        text(size: .8em)[_Aucun signe distinctif\ ne doit figurer\ en dehors de ce cadre_]
      }),
      origin: bottom + left
    ),
    stroke: 1pt + black,
    width: 8cm,
  height: 8cm
  )
))

As for the corner, I suggest to take a look at pattern. After creating that pattern, you can use it to fill a triangle using polygon. Placing the content then is the same as previously: move + rotate.

As a starting point, you can try this pattern

#{
  let pat = pattern(
    size: (7.0pt, 7.0pt),
    relative: "parent",
    spacing: (0pt, 0pt),
    place(
      dx: 1pt,
      dy: 1pt,
      rotate(45deg, origin: center, square(
        size: 5pt,
        fill: black,
      )),
    ),
  )
  
  rect(fill: pat, width: 8cm, height: 8cm)
}

Don’t hesitate to make sure your example is reproducible before posting! You can read more tips at How to post in the Questions category.

1 Like

Thank you very much @quachpas, no need for cetz. I added the pattern based on your direction using place(top, polygon(..., pattern).

Here is the full mwe for my layout.

#let large-size = 12pt
#let footnote-size = 8pt
#grid(
    columns: (1fr, 8cm),
    gutter: 3cm,
    // titre
    align(
    left,
    {
      text(size: 16pt, weight: 700, "Université Côte d'azur")
      linebreak()
      text(size: large-size, weight: 400, "Institut Universitaire de Technologie")
      linebreak()
      underline(text(size: large-size, weight: 400, "Département INFORMATIQUE"))
      linebreak()
      v(20pt, weak: true)
      text(size: large-size, weight: 700, "Epreuve:")
      line(length: 100%)
      linebreak()
      text(size: footnote-size, "Date")
      line(length: 100%)
      rect(height: 2.5cm, width: 2.5cm,"NOTE")
      text(size: footnote-size, "Nbre d'interacalaires: .........")
    },
  ),
  {
rect(
    rotate(
      45deg,
      move(dx: -1.5em, dy: 3em, {
        set align(center)
        [Semestre : ]
        box(line(length: 5em))
        h(1em)
        [Groupe : ]
        box(line(length: 5em))

        parbreak()
        [Nom : ]
        box(line(length: 6cm))

        parbreak()
        [Prénom : ]
        box(line(length: 5cm))

        parbreak()
        text(size: .8em)[_Aucun signe distinctif\ ne doit figurer\ en dehors de ce cadre_]
      }),
      origin: bottom + left
    ),
    stroke: 3pt + black,
    width: 8cm,
    height: 8cm,
)
  place(top, polygon(
  fill: pattern(
  size: (7.0pt, 7.0pt),
  relative: "parent",
  spacing: (0pt, 0pt),
  place(
    dx: 1pt,
    dy: 1pt,
    rotate(
      45deg,
      origin: center,
      square(
        size: 5pt,
        fill: luma(40%),
      ),
    ),
  ),
),
  (17pt, 17pt),
  (8cm-17pt, 17pt),
  (8cm-17pt, 8cm-17pt)
  ))
}
)

That renders like the desired output.

1 Like

That’s great!

Just a note, if you want text and a line on the same line, then you can try for example.

#text(size: footnote-size, "Date: ")
#box(line(length: 85%))