How to Resume Nested Numbered Lists?

I like to format answers to numbered questions without indentations. For a single level, this works as I can manually number the list.

1.  First Question

First Answer

2. Second Question

Second Answer
...

However for multi-level numbering, this doesn’t seem possible.

1. First Question

  1. First Part

First Part Answer

  2. Second Part

Second Part Answer

The above results in “Second Part” being a level 1 list, on the same level as “First Question”.

I’ve managed to get the list to render correctly by wrapping the answers like so,

1. First Question

  1. First Part
    #[
First Part Answer
    ]
  2. Second Part
    #[
Second Part Answer
    ]

but that results in having the answers indented in the output pdf.

Is there a way to resume a nested list, or a different way to not have the answer indented?

Hello and welcome @Bolt! FYI, this is tracked in Resumable enum numbering · Issue #325 · typst/typst · GitHub, where you might find interesting workarounds.

EDIT: related topic How to continue `enum` throughout entire document? - #6 by Mc-Zen

Thanks I saw a workaround using restyled headings, but there doesn’t seem to be a way to do nested numbering easily, as heading doesn’t have a full attribute like enum does. And I also don’t see a way to indent a heading.

A complex system of counters might be the best solution. I’m working on adapting the solution offered by @Mc-Zen, but I’m not finding how to get an enum’s level.

Edit: It also seems like:

  • enums can’t be selected in queries
  • when trying to get its counter, enum is not locatable
  • there is no mechanism to get the ancestor of content

Something like this shouldn’t be this hard. Thinking back, I might have gone through this same ordeal a year ago, and then decided not to use Typst. I really hope that this is now possible and I’m just missing something, because otherwise Typst is so nice.

Edit 2: I tried a (very) hacky approach with position to see how indented it is.

#set enum(start: 0)
#let c = counter("numbered-list");
#c.update((0, 0))
#show enum: it => {
  if it.start != 0 { return it }
  let args = it.fields()
  let items = args.remove("children")
  context {
    let index = if here().position().at("x") < 80pt {
      0
    } else {
      1
    }
    enum(..args, start: c.get().at(index) + 1, ..items)
    c.update((..args) => {
      let counters = args.pos()
      counters.at(index) += items.len()
      for i in range(index + 1, counters.len()) {
        counters.at(i) = 0
      }
      counters
    })
  }
}

This correctly tracks the numeration for arbitrary nesting, so long as I update the index calculation and fill the counter with enough 0s. However because even an indented + does not create a level 2 enum, there is no way to resume the nested counting anyways.

Welcome to the forum @Bolt! I’ve updated your post’s title to comply with our question post guidelines: How to post in the Questions category

Make sure your title is a question you’d ask to a friend about Typst. :wink:


Unfortunately, the only way you can do this is by indenting your text further than the list’s markers. Otherwise, Typst will understand that you are breaking the list. You should write as follows:

1. First Question

  1. First Part

      First Part Answer  // note the indentation

  2. Second Part

      Second Part Answer

Thanks for the feedback, I’ll keep that in mind for future posts.

Sadly I haven’t been able to replicate this result. When I indent the text past the nested lists’ marker (either a standard two-space, or the four spaces in your example), it appears at the same level of indentation as the question’s text.

That is to say, both:

1. First Question

  1. First Part

    First Part Answer

  2. Second Part

    Second Part Answer

and

1. First Question

  1. First Part

      First Part Answer

  2. Second Part

      Second Part Answer

result in


while I’m looking for something like

(which was approximated with manual spacing, not viable for a document)

Edit: I might not have made it clear. While I like unindented answers in the source, my primary goal is for them to be unindented in the resulting pdf.

I came across a similar request some time ago, but only going one level of enumeration deep.
Maybe it helps and you can figure it out from there?

#show enum: it => context {
  let max = it.children.len() + it.start
  let w = measure(
            numbering(it.numbering, max)
          ).width
  set par(
    hanging-indent: -it.body-indent - w
  )
  it
}

also wrote it up here