#help using contexts to adjust enumerated list format?

5 messages · Page 1 of 1 (latest)

harsh rain
#

I've hacked something together that sort of does what I want... See #bot-corner message for an example. I'm wondering if there's a cleaner way.

Basically I want nested enumerated lists with all the item numbers flush with the left column (not indented), but the item contents indented. My current hack (see the source code before the bot response above) is moving the item numbers around inside the enum number formatter. I need to store state, namely the width of the parent item's indent, to "undo" the indent from the parent. For that I need contexts to access the stored state.

My solution is fragile. I'm sure I don't understand the semantics of contexts. I'm wondering if there is a clean semantic model that I am missing. I also don't understand the semantics of show and set, and how they might interact. So when I am coding I am just trying uneducated guesses and seeing what seems to work.

For example, I was wondering if instead one could just track the indent level, then explicitly add some spacing in front of the enum item body. That seems like a cleaner approach, but I keep running into unexpected behaviors that I don't understand, partly about the interactions between show and set, and partly about contexts. I'm only one day into typst so perhaps this is not surprising.

I'm wondering if someone could point me to documentation of the semantic model for these things (I mean, I have a vague idea but not precise enough to have any confidence coding stuff). Alternatively, maybe somebody could take a look at the code and suggest other approaches?

#

Here's a small example code:

#
#let PREV = state("PREV", "")
#let WIDTH = state("WIDTH")

#let block(
    head: "",
    width: 100%,
    x
) = {
    WIDTH.update(width)

    set enum(
    full: true,
    indent: 0em,
    body-indent: 0em,
    numbering: (..n) => {
        style(
        styles => {
            let num1 = {
            set text(9pt)
            numbering("1.1.1.1", ..n)
            }
            let num = {
            set align(horizon + left)
            box(
                width: 3em * n.pos().len(),
                height: 8pt,
                num1
            )
            }
            let prev = PREV.get()
            let pw = measure(prev, styles).width
            let w = measure(num, styles).width
            PREV.update(num)
            pad(left: - pw, box(width: w, num))
        }
        )
    }
    )

    pad(
    x: 0.5em,
    y: 0.5em,
    {
        if head != "" {
        pad(
            left:0.2em,
            bottom:-0.4em,
            head
        )
        }
        pad(
        left: 0.5em,
        x
        )
    }
    )
}
#block(
    head: [on input $n$:],
    width: 30em,
)[
    +  for $i in \{0, 1, ..., n\}$ do: #[
    +  if $i = i-1$: #[
        +  express surprise
    ]
    ]
    + return $n$
]
#

output: