Created
June 20, 2023 15:01
-
-
Save chengluyu/d8f02c6f07d194f1f539a0bec313d1b0 to your computer and use it in GitHub Desktop.
Include chapter numbers in numbering figures and tables.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#let figureCounters = state("thm", | |
( | |
"counters": ("heading": ()), | |
"latest": () | |
) | |
) | |
#let figureInstances = state("instances", (:)) | |
#let createFigureRenderer(identifier, base, base_level, render) = { | |
let global_numbering = numbering | |
return ( | |
body, | |
caption: none, | |
subcaption: none, | |
numbering: "1.1", | |
base: base, | |
base_level: base_level | |
) => { | |
let number = none | |
if not numbering == none { | |
locate(loc => { | |
figureCounters.update(thmpair => { | |
let counters = thmpair.at("counters") | |
// Manually update heading counter | |
counters.at("heading") = counter(heading).at(loc) | |
if not identifier in counters.keys() { | |
counters.insert(identifier, (0, )) | |
} | |
let tc = counters.at(identifier) | |
if base != none { | |
let bc = counters.at(base) | |
// Pad or chop the base count | |
if base_level != none { | |
if bc.len() < base_level { | |
bc = bc + (0,) * (base_level - bc.len()) | |
} else if bc.len() > base_level{ | |
bc = bc.slice(0, base_level) | |
} | |
} | |
// Reset counter if the base counter has updated | |
if tc.slice(0, -1) == bc { | |
counters.at(identifier) = (..bc, tc.last() + 1) | |
} else { | |
counters.at(identifier) = (..bc, 1) | |
} | |
} else { | |
// If we have no base counter, just count one level | |
counters.at(identifier) = (tc.last() + 1,) | |
let latest = counters.at(identifier) | |
} | |
let latest = counters.at(identifier) | |
return ( | |
"counters": counters, | |
"latest": latest | |
) | |
}) | |
}) | |
number = figureCounters.display(x => { | |
return global_numbering(numbering, ..x.at("latest")) | |
}) | |
} | |
render(number, caption, subcaption, body) | |
} | |
} | |
#let createFigure( | |
identifier, | |
head, | |
base: "heading", | |
base_level: 1, | |
) = { | |
let boxfmt(number, caption, subcaption, body) = { | |
let supplement = head | |
if not number == none { | |
supplement += " " + number | |
} | |
figureInstances.update(entries => { | |
let entry = entries.at(head, default: ()) | |
entries.insert(head, (..entry, (number: number, caption: caption))) | |
return entries | |
}) | |
align(center)[ | |
#body | |
#supplement #caption\ | |
#subcaption | |
] | |
} | |
return createFigureRenderer(identifier, base, base_level, boxfmt) | |
} | |
#let citeFigure( | |
label, | |
fmt: auto, | |
makelink: true, | |
..body | |
) = { | |
if fmt == auto { | |
fmt = (nums, body) => { | |
if body.pos().len() > 0 { | |
body = body.pos().join(" ") | |
return [#body #numbering("1.1", ..nums)] | |
} | |
return numbering("1.1", ..nums) | |
} | |
} | |
locate(loc => { | |
let elements = query(label, loc) | |
let locationreps = elements.map(x => repr(x.location().position())).join(", ") | |
assert(elements.len() > 0, message: "label <" + str(label) + "> does not exist in the document: referenced at " + repr(loc.position())) | |
assert(elements.len() == 1, message: "label <" + str(label) + "> occurs multiple times in the document: found at " + locationreps) | |
let target = elements.first().location() | |
let number = figureCounters.at(target).at("latest") | |
if makelink { | |
return link(target, fmt(number, body)) | |
} | |
return fmt(number, body) | |
}) | |
} | |
#let figureCustom = createFigure("figure", "Figure") | |
#let tableCustom = createFigure("table", "Table") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment