How to generate a nested array from Typst bullet list?

Essentially, I think I need is the inverse of what this dude asked for: How to generate a multilevel list from a data structure? - #2 by miles-1 .

Here’s what I have tried so far:

#let list-to-array(it) = {
  if it.has("children") {
    let content = it.children.filter(it => it.func() != list.item)
    if content.any(it => it != [ ]) {
      (content.join(),)
    }

    let items = it.children.filter(it => it.func() == list.item)
    for item in items {
      (list-to-array(item),)
    }
  } else if it.has("body") {
    list-to-array(it.body)
  } else {
    it
  }
}

This solution almost works, but contains a lot of sequence content elements. Is this to be expected?

Does anyone have a better solution? Thank you in advance!

1 Like

The sequence elements are due to the content.join(), as .join() on an array of content always (i think) creates a sequence. This is not a problem though, sequences are normal content, representing any sequence of elements:

#([Baz "d"],)

gives:


As far as I can tell is your solution quite good.

Small nitpicks
  • I would use items.map(list-to-array) instead of for item in items {...}, seems more elegant
  • Your solution removes the order of child items relative to plain content, e.g.
    - First
      - Bar1
      Second
      - Bar2
    
    i would suggest maybe
    #let list-to-array(it) = {
      if it.has("children") {
        it.children.filter(c => c != [ ]).map(list-to-array)
      } else if it.has("body") {
        list-to-array(it.body)
      } else {
        it
      }
    }
    
    (possibly even without the .filter, as this will also e.g. remove the space in [Baz "d"])