Skip to content

Commit be98d12

Browse files
CopilotOrangeX4
andcommitted
Fix nested theorem numbering by stepping counter at frame start
Move frame-counter.step() to the beginning of each frame body so that child counters (e.g. corollary inside theorem) inherit the correct parent number. Remove the +1 adjustment in display-number since the counter is already at the right value when here() is evaluated. Update theorion-display-number to use the metadata location (after the step) for accurate counter reads. Add regression test. Co-authored-by: OrangeX4 <34951714+OrangeX4@users.noreply.github.com>
1 parent 2beb48e commit be98d12

3 files changed

Lines changed: 47 additions & 7 deletions

File tree

core.typ

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,21 @@
258258
return ""
259259
} else {
260260
assert(type(el.numbering) == function, message: "The numbering must be a function with get-loc.")
261-
let res = (el.numbering)(get-loc: () => el.location())
261+
// Use the metadata location (placed inside the frame body, after the counter step)
262+
// so that the counter value is already correct and no "+1" adjustment is needed.
263+
// The first <theorion-frame-metadata> after el.location() is always this frame's
264+
// own metadata, because the metadata is emitted as the very first content inside
265+
// the figure body (right after the step label). Any later metadata elements
266+
// belong to subsequent frames.
267+
let get-loc = () => {
268+
let metadata-els = query(selector(<theorion-frame-metadata>).after(el.location()))
269+
if metadata-els.len() > 0 {
270+
metadata-els.first().location()
271+
} else {
272+
el.location()
273+
}
274+
}
275+
let res = (el.numbering)(get-loc: get-loc)
262276
if type(res) == dictionary {
263277
assert(
264278
"kind" in res and "value" in res and res.at("kind") == "static",
@@ -304,13 +318,13 @@
304318
let supplement-i18n = theorion-i18n(supplement-map)
305319
let display-number(get-loc: here, .._args) = (counter: frame-counter, ..args) => context {
306320
let loc = get-loc()
307-
// We need to add 1 to the counter value.
321+
// The counter is stepped at the beginning of the frame body, before this location,
322+
// so the value already reflects the current frame's number.
308323
let counter-value = if type(counter) == dictionary {
309324
(counter.at)(loc)
310325
} else {
311326
counter.at(loc)
312327
}
313-
counter-value = counter-value.slice(0, -1) + (counter-value.at(-1) + 1,)
314328
std.numbering(get-numbering(get-loc()), ..counter-value)
315329
}
316330

@@ -337,6 +351,11 @@
337351
outlined: outlined,
338352
numbering: if number == auto { numbering } else { (..args) => (kind: "static", value: number) },
339353
{
354+
// Step the counter first so that nested child-counter frames (e.g. a corollary
355+
// placed inside a theorem body) can inherit the correct parent number.
356+
if numbering != none and number == auto {
357+
(frame-counter.step)()
358+
}
340359
[#metadata((
341360
identifier: identifier,
342361
number: number,
@@ -362,10 +381,6 @@
362381
..args,
363382
body,
364383
)
365-
// Update the counter.
366-
if numbering != none and number == auto {
367-
(frame-counter.step)()
368-
}
369384
},
370385
)
371386
/// Frame without the counter.
19.3 KB
Loading
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// Test: nested theorem numbering - corollary inside theorem inherits parent number
2+
#import "/lib.typ": *
3+
#import cosmos.fancy: *
4+
5+
#set page(width: 300pt, height: auto, margin: (x: 15pt, y: 15pt))
6+
#set heading(numbering: "1.1")
7+
8+
#show: show-theorion
9+
10+
= Nested Numbering
11+
12+
#theorem()[
13+
#corollary()[Corollary inside Theorem 1 (should be 1.1.1)]
14+
]
15+
16+
#theorem()[
17+
#corollary()[Corollary inside Theorem 2 (should be 1.2.1)]
18+
]
19+
20+
= Multiple Corollaries
21+
22+
#theorem()[
23+
#corollary()[First corollary (2.1.1)]
24+
#corollary()[Second corollary (2.1.2)]
25+
]

0 commit comments

Comments
 (0)