It’s a known issue, but in my thesis I had to fix this + first line indent issue. The code I used is too complicated, and I need to extract it, so I don’t wanna do this. But I copied the core logic down and changed it a bit:
#let fix-multi-line-outline-entries = it => {
let indent = {
let indent = outline.indent
if type(indent) != relative {
indent = 0pt
}
h(indent * (it.level - 1))
}
let count = counter(heading).at(it.element.location())
let space-width = measure("| |").width - measure("||").width
let make-entry(body) = {
let content = [#body #box(width: 1fr, it.fill) #it.page]
let content = if it.element.numbering != none {
grid(
columns: 2,
gutter: space-width,
numbering(it.element.numbering, ..count),
content,
)
} else {
content
}
link(it.element.location(), content)
}
box(layout(((width, height)) => {
let entry = make-entry(it.element.body)
// Fix long headings that don't trigger filler to extend to the end.
if measure(indent + box(entry)).width > width {
let content = it.element.body
// If heading is `sequence`.
if content.func() == [].func() {
let mapper = x => if x != [ ] { x.text } else { " " }
content = content.children.map(mapper).join()
content = [#content]
}
assert(content.func() == text, message: "not implemented")
let parts = content.text.split()
let last = parts.pop()
let first = parts.join(" ")
let new = first + parbreak() + last
// Ignore headings that are long enough to trigger the filler.
if measure(new).width <= width {
entry = make-entry(new)
}
}
indent + box(entry)
}))
}
#show outline.entry: fix-multi-line-outline-entries
#outline()
#let prefix = "This is a" + " very" * 16
= #prefix long titl
= #prefix long title
= #prefix long titlee
#set heading(numbering: "1.")
= #prefix longg
= #prefix long tit
= #prefix long titl
What I didn’t attempt is duplicate @Andrew’s indentation of follow-up lines: for example, the word “title” in the second line of the third entry starts to the left of the start of the entry. Other than that, I think this solution worked pretty well.