How can I get diffrent indents for different levels of enums?

as in the title. I essentially want to do

#set enum(indent: 1em)
#set enum.where(level = 2)(indent: 0.5em)

I know this pseudo-syntax doesn’t work ;)
This is what I want to achieve without inner #set rules:

#set page(height: 12cm, width: 12cm)
#set enum(indent: -1.25em, spacing: 1.5em, numbering: "1. a.")

#lorem(20)

+ First: #lorem(15)
  
  
  #[
  #set enum(indent: 1em)
  + first subitem
  + second subitem
]
  #lorem(20)
+ Second: #lorem(12)
  
  #[
  #set enum(indent: 1em)
  + first subitem
  + second subitem
  ]

i think you could achieve this with state:

#let enum-level = state("enum-level", 1)
#show enum.item: it => {
  enum-level.update(l => l + 1)
  it
  enum-level.update(l => l - 1)
}

#show enum: it => context {
  set enum(indent: 20pt) if enum-level.get() == 2
  set enum(indent: 0pt) if enum-level.get() != 2
  it
}

+ a
  + b
    + c

1 Like

hmm, I’m not sure if I understand what this code is supposed to do.

#set page(height: 12cm, width: 12cm)
#[
#set enum(numbering: "1. a. I.")
#let enum-level = state("enum-level", 0)

#show enum.item: it => {
  enum-level.update(l => l + 1)
  it
  enum-level.update(l => l - 1)
}

#show enum: it => context {
  set enum(indent: -5em) if enum-level.get() == 1
  set enum(indent: 0em) if enum-level.get() == 2
  set enum(indent: 5em) if enum-level.get() == 3
  it
}

#lorem(20)

+ First: #lorem(15)  
  + first subitem
    + sub
  + second subitem
    + sub
    + sub
    
  #lorem(20)
  
+ Second: #lorem(12)
  + first subitem
  + second subitem

#lorem(20)
]

does not apply the negative indent, nor it applies the zero indent; instead below level 1 everything is indented by 5em per level.

I guess the enum-level increment should happen not every enum.item, but rather every enum?

you should start the state at 1. i don’t remember exactly why but yeah it’s kinda hacky so starting it at 0 gives you like an off-by-one error. but it should work, as you can see in the original example.

#let enum-level = state("enum-level", 1)

then, i think your show rule isn’t working for the top-level enum (level == 1) because what we’re basically doing is: for every enum, apply the set rule only starting from its children (not to the enum itself). given that the top-level enum isn’t inside any other enum, it’ll never have the rule applied. instead you should do just a regular set rule for the top-level, and have your show rule override this for all subsequent levels:

#set enum(indent: -5em)
#show enum: it => context {
  set enum(indent: 0em) if enum-level.get() == 2
  set enum(indent: 5em) if enum-level.get() == 3
  it
}

that should give you this:

1 Like

Thanks, tbh. that sounds unnecessarily hacky for such a simple formatting task ;P

Sometimes I’m surprised by the flexibility of typst, but other times (like this one) it feels like a very blunt tool…

1 Like

yeah, thankfully this this would be fixed with just more queryable fields, in this case enum.level!