How to display the table of contents in two columns with an even distribution?

Is it possible to display the table of contents in two columns and split the entries evenly between the left and right column?

The following does not work. In this case, the left column grows as much as possible before the content continues in the right column.

#columns(2)[
  #outline(title: none)
]

= AAA

= BBB

= CCC

= DDD

@Olaf,

It seems that it is not possible to achieve this automatically at this time. See How to balance columns? and other posts Search results for 'Balance columns' - Typst Forum on this forum.

There is an open issue about this. Balancing the contents of multiple columns to the same vertical space · Issue #466 · typst/typst · GitHub

This is possible with some measuring:

#let balance(content) = layout(size => {
  let count = content.at("count")
  let textheight = measure(content, width: size.width).height / count
  let height = measure(content, height: textheight + 9pt, width: size.width).height
  block(height: height, content)
})
#balance(columns(2)[
  #outline(title: none)
])

Notes:

  • The balance function only takes columns, as it requires the count property. (However, it should also work for e.g. 3 columns)
  • You might need to adjust the + 9pt if it breaks the columns too early. It should be slightly under one line height. (If this is too low, it will make the last column longer, if it is to high it will make the first column(s) taller than neccesary.)
  • In very complicated documents this can lead to the layout not converging, if it has trouble figuring out how many pages the outline needs. This can be fixed by adding an explicit #pagebreak(weak:true) after the outline.
4 Likes