Skip to content

Instantly share code, notes, and snippets.

@chengluyu
Created June 20, 2023 15:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chengluyu/d8f02c6f07d194f1f539a0bec313d1b0 to your computer and use it in GitHub Desktop.
Save chengluyu/d8f02c6f07d194f1f539a0bec313d1b0 to your computer and use it in GitHub Desktop.
Include chapter numbers in numbering figures and tables.
#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