How to use textbook problem numbers ("1.1") in the second level of a numbered list?

I am writing solutions to a set of homework problems, and I need to number them as they are numbered in the assignment. The top-level questions are numbered using the 1. numbering pattern. Each top-level question may contain multiple textbook problems, which are numbered using the 1.1 pattern (the chapter and then the problem number), and these numbers generally don’t follow any particular pattern. Then, a textbook problem or a top-level question may contain parts labelled using the (a) pattern.

Here is roughly what I want my document to look like:

1. Textbook problems:
   1.23 First textbook problem
   4.56 This problem contains multiple parts:
        (a)  Part a
        (b)  Part b
2. A problem not from the textbook
   (a) Part a

Below is my current way of achieving this in Typst. It is an indecent hack, so I would like to find out how to do this idiomatically. The idea is that I set a numbering function so that enums always display what I want, and I use the problem_number counter to keep track of the number of the current textbook problem. (If making everything a numbered list isn’t the idiomatic way to do this, I am open to other solutions, but I would like the indentation to be the same.)

#let problem_number = counter("problem_number")

#let enum_numbering(..args) = {
  let nums = args.pos();
  let length = nums.len();
  if length == 1 {
    numbering("1.", nums.at(0))
  } else if length == 2 {
    context problem_number.display()
  } else if length == 3 {
    numbering("(a)", nums.at(2))
  }
}

#set enum(full: true, numbering: enum_numbering)

#let set_problem_number(arr) = {
  context problem_number.update(arr)
  hide(text(size: 0pt)[#context problem_number.display()]) // this is needed to update the problem number (otherwise, both numbers in part 1 below display as 1.23), but it is hacky and messes up the spacing.
}

1. Textbook problems:

  #set_problem_number((1, 23))
  + First textbook problem

  #set_problem_number((4, 56))
  + This problem contains multiple parts:

    + Part a

    + Part b

3. A problem not from the textbook

  #set enum(full: false, numbering: "(a)")
  + Part a

I found a cleaner way to do this using the itemize and numbly packages:

#import "@preview/itemize:0.2.0" as el
#import "@preview/numbly:0.1.0": numbly

#show: el.default-enum-list

#set enum(full: true, numbering: numbly(
  "{1:1}.",
  "({2:a})"
))

1. Textbook problems:

  - #el.item[1.23]
    First textbook problem

  - #el.item[4.56]
    This problem contains multiple parts:

    + Part a

    + Part b

2. A problem not from the textbook

  + Part a
2 Likes