If I use justified text, I want text inside lists to be also jsutifed to the same width as the main text. However, sometimes Typst makes the list item narrower:
#set page(width: 8cm, margin: 1cm)
#set par(justify: true)
#place(right, line(angle: 90deg, stroke: 0.5pt + luma(60%), length: 10cm))
#lorem(20)
- #lorem(20)
But
- This doesn’t fill the line fully even though it has a linebreak.
If I add a #h(1fr) after linebreak., this fixes it:
But I don’t want to manually check each list. Is there a way to achieve this via a show or set rule?
(If you look closely, you can see that the first list item in my example is also too narrow, notice the small gap after the “et” and that the dashes protrude slightly less into the margin)
#set page(width: 8cm, margin: 1cm)
#set par(justify: true)
#place(right, line(angle: 90deg, stroke: 0.5pt + luma(60%), length: 10cm))
#let append-to-marker(mark, body) = {
let arr = ()
if type(mark) == content and mark.func() == metadata {
arr = mark.value
}
arr.push(body)
metadata(arr)
}
#let contained-in-marker(mark, body) = {
let arr = ()
if type(mark) == content and mark.func() == metadata {
arr = mark.value
}
body in arr
}
/// Apply a style function, like for a show rule, but block recursive application of it
///
/// - markerlabel (label): unique label for this style function
/// - func (function): the style function; signature function(content) -> content
/// - body (content): the style function argument
/// - allow-nesting (bool): allow nesting of the same show rule, after having
/// blocked repeated calls on the same element once. If you say false here,
/// then no recursion at all is allowed (only outermost table of nested
/// tables are affected by a table rule for example). If you say true here,
/// nested tables are affected in this example.
#let recursion-block(markerlabel, func, body, allow-nesting: false) = {
let sentinel = [#str(markerlabel)]
context {
let orig-title = bibliography.title
[#context {
let ctx-title = bibliography.title
set bibliography(title: orig-title)
if ctx-title != sentinel and (not allow-nesting or not contained-in-marker(ctx-title, body)) {
// set simple recursion marker, just the sentinel
show markerlabel: set bibliography(title: sentinel)
func(body)
} else {
// we arrived back at something we have seen before
// store the whole element in the marker this time
// this guards against global reentrancy (if we have multiple instances of the same rule)
// note: we can store `body` because it comes directly from the document.
// storing `func(body)` from above would match nothing we see again - the document element that
// results from `func(body)` is not exactly equal to that.
let marker = append-to-marker(ctx-title, body)
show markerlabel: set bibliography(title: marker) if allow-nesting
body
}
}#markerlabel]
}
}
#show list.item: recursion-block.with(<__list_recursion>, it => {
list.item(it.body + h(1fr))
})
#lorem(20)
- #lorem(20)
But
- This doesn’t fill the line fully even though it has a linebreak.
This is too overcomplicated for what it does. You can do this in 3 neat lines:
#show list.item: it => {
let children = it.body.at("children", default: ())
if children.at(-1, default: none) == h(1fr) { return it }
list.item(it.body + h(1fr))
}