How can I create a tag list for a CV?

I’m trying to make a nice-looking tag list, such as this one:

#let tag(body) = {
  set text(black)
  highlight(fill: none, radius: 25%, extent: 3pt, stroke: 0.4pt + black, [#body])
}

#let grid_list(..items) = {
  grid(
    columns: 20,
    fill: none,
    inset: 5pt,
    ..items
  )
}

#(
grid_list(
  [#tag("a")], [#tag("b")], [#tag("c")], [#tag("d")],
  [#tag("e")], [#tag("f")], [#tag("g")], [#tag("h")]
  )
)

It’s nice, looks great, but if the tag text gets too long, it breaks and looks strange. Is there a nicer way to do this?
It’s the first time i dabble with typst let alone typst functions, so please don’t mind if this is pretty nooby.

You can use a simple block wrapping tags as boxes to allow it breaks to the next line as a whole.

#let tag(body) = {
  box(block(highlight(fill: none, radius: 25%, extent: 3pt, stroke: 0.4pt + black, [#body]), breakable: false))
}

#let grid_list(..items) = {
  block(items.pos().join(h(0.8em)))
}

#(
  grid_list(
    [#tag("a")],
    [#tag("b")],
    [#tag("c")],
    [#tag("d")],
    [#tag("e")],
    [#tag("f dfsdf")],
    [#tag("ghhhhhhhhhhhhhh ddddddddd dddddddddd dhh dddddddddddd")],
    [#tag("hsss ssss sss ssssssssssssssssssssssssssssss")],
  )
)
2 Likes

That works nicely! Thanks :)

Though now I notice, the outline of the first tag item is horizontally before the start of the line, because the text is aligned with the line of course. With the grid, that was not the case. What’s the best way to line them up? I tried putting it in a grid or joining a h(), but failed

#let tag(body) = {
  box(
    block(
      box(
        radius: 25%,
        stroke: 0.4pt + black,
        inset: 3pt,
        body,
      ),
      breakable: false,
    ),
  )
}

#let grid_list(..items) = {
  block(items.pos().join(h(0.2em)))
}

Use inset of box