typst
typst copied to clipboard
Provide enum nesting depth to numbering function even without `full: true`
Description
#set enum(
numbering: (..numbers) => {
let numbers = numbers.pos();
if numbers.len() == 1 {
return numbering("1.", numbers.at(0))
}
if numbers.len() == 2 {
return numbering("a.", numbers.at(1))
}
},
full: false
)
+ + Hello
#set enum(
numbering: (..numbers) => {
let numbers = numbers.pos();
if numbers.len() == 1 {
return numbering("1.", numbers.at(0))
}
if numbers.len() == 2 {
return numbering("a.", numbers.at(1))
}
},
full: true
)
+ + Hello
#set enum(numbering: "1.a.", full: false)
+ + Hello
#set enum(numbering: "1.a.", full: true)
+ + Hello
The output is:
I intuitively expect
#set enum(numbering: s)
And
#set enum(numbering: nums => numbering(s, nums))
Should be equivalent. However that's not the case: when using a string argument, the indices of outer layers are considered (at least they are supplied as placeholders to trigger different numbering styles) even if full is set to false. When using a function argument, if full is set to false, the indices of outer layers are not passed to the function, resulting in the function not knowing which layer it is at.
I think all the indices of outer layers should be passed to the numbering function, since supplying a custom numbering function is an attempt to override the default behavior. Also the current behavior of full is very non-orthogonal: when using numbering strings, it doesn't behave by only considering the current single enum, contrast to when using numbering functions.
Reproduction URL
No response
Operating system
Linux
Typst version
- [ ] I am using the latest version of Typst
This is due to numbering trimming, a process explained in https://github.com/typst/typst/issues/3089#issuecomment-1871195540 which I don't think is documented anywhere.
The problem is that in https://forum.typst.app/t/why-isnt-there-a-function-to-output-to-stdout/3362/1 when using 1. (a) pattern, it will output 1) for 1st level and 1. (a) for the second level. It makes no sense to me that 1) used and not 1.. It doesn't match the trimming thing, the way I see it. And this is without a custom numbering function.
@MDLC01
#set enum(
numbering: (..numbers) => {
let numbers = numbers.pos();
if numbers.len() == 1 {
return numbering("1.", numbers.at(0))
}
if numbers.len() == 2 {
return numbering("a.", numbers.at(1))
}
},
full: false
)
+ + Hello
I believe this isn't related to number trimming. Here I believe the problem lies within the number of parameters passed to the numbering function. f(1,1) should be called instead of f(1).
Sorry, I completely miss read the issue. This is indeed unrelated to number trimming.
I intuitively expect
#set enum(numbering: s)And
#set enum(numbering: nums => numbering(s, nums))
That's not the case. Did you mean this?
#set enum(numbering: (..nums) => numbering(s, ..nums))
Nonetheless, it's true that patterns have special treatment to know their layer without full: true.
The problem occurs regardless of full state:
#set enum(full: true, numbering: "1. (a)")
+ #lorem(5)
+ #lorem(5)
+ #lorem(5)
+ #lorem(5)
+ #lorem(5)
+ #lorem(5)
+ #lorem(5)
+ #lorem(5)
It supposed to output this:
Although I guess there are now 2 issues in one.
I've created https://github.com/typst/typst/issues/6088 (https://github.com/typst/typst/issues/905).
@Andrew15-5 That's unrelated.
@laurmaedje, this is related to the post, it was created from, but I only understood that something is off after the updated title. Now I clearly see what this issue is about.