mirror of
https://github.com/JustAnyones/ktu-paper.git
synced 2026-11-04 00:30:18 +00:00
feat: add support for figure names without numbering if they're single
This commit is contained in:
2 files changed
+72
-17
No files matched your search
+60
-8
@@ -8,11 +8,13 @@
|
|||||||
/// Localizations for the recognized referenceable figure kinds, keyed by `repr(func)`.
|
/// Localizations for the recognized referenceable figure kinds, keyed by `repr(func)`.
|
||||||
/// - supplement: used in captions (the caption adds the separator, e.g. "1 pav.").
|
/// - supplement: used in captions (the caption adds the separator, e.g. "1 pav.").
|
||||||
/// - ref-name: used in references, e.g. "(žr. 1 pav.)".
|
/// - ref-name: used in references, e.g. "(žr. 1 pav.)".
|
||||||
|
/// - single-name: full word used when the figure is the only one of its kind and
|
||||||
|
/// therefore unnumbered, e.g. "Paveikslas. ..." and "(žr. paveikslas)".
|
||||||
#let __figure-kinds = (
|
#let __figure-kinds = (
|
||||||
table: (supplement: "lentelė", ref-name: "lentelė"),
|
table: (supplement: "lentelė", ref-name: "lentelė", single-name: "lentelė"),
|
||||||
image: (supplement: "pav", ref-name: "pav."),
|
image: (supplement: "pav", ref-name: "pav.", single-name: "paveikslas"),
|
||||||
raw: (supplement: "kodo frag", ref-name: "kodo frag."),
|
raw: (supplement: "kodo frag", ref-name: "kodo frag.", single-name: "kodo fragmentas"),
|
||||||
equation: (supplement: "lygtis", ref-name: "formulė"),
|
equation: (supplement: "lygtis", ref-name: "formulė", single-name: "lygtis"),
|
||||||
)
|
)
|
||||||
|
|
||||||
/// Figure kinds registered by the document author via `ktu-paper(figureKinds: ...)`.
|
/// Figure kinds registered by the document author via `ktu-paper(figureKinds: ...)`.
|
||||||
@@ -30,6 +32,7 @@
|
|||||||
normalized.insert(key, (
|
normalized.insert(key, (
|
||||||
supplement: spec.supplement,
|
supplement: spec.supplement,
|
||||||
ref-name: spec.at("ref-name", default: spec.supplement),
|
ref-name: spec.at("ref-name", default: spec.supplement),
|
||||||
|
single-name: spec.at("single-name", default: spec.supplement),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
normalized
|
normalized
|
||||||
@@ -186,11 +189,49 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Single-figure handling
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Figure kinds that are left unnumbered when the document contains only one
|
||||||
|
/// captioned figure of that kind: "Lentelė. Aprašas" and "(žr. lentelė)"
|
||||||
|
/// instead of "1 lentelė. Aprašas" and "(žr. 1 lentelė)". The word used comes
|
||||||
|
/// from the kind's `single-name`.
|
||||||
|
/// Keys are `__figure-key` values.
|
||||||
|
#let __UNNUMBERED_WHEN_SINGLE = ("table", "image")
|
||||||
|
|
||||||
|
/// Whether `fig` is the only captioned figure of its kind in the document and
|
||||||
|
/// its kind is listed in `__UNNUMBERED_WHEN_SINGLE`. Must be called in a context.
|
||||||
|
#let __is-single-unnumbered(fig) = {
|
||||||
|
if __figure-key(fig) not in __UNNUMBERED_WHEN_SINGLE { return false }
|
||||||
|
query(figure.where(kind: fig.kind)).filter(f => f.caption != none).len() == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Capitalizes the first letter of `value` ("lentelė" -> "Lentelė").
|
||||||
|
#let __capitalize(value) = {
|
||||||
|
let first = value.first()
|
||||||
|
upper(first) + value.slice(first.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Caption label of a figure element: "1 lentelė." normally, or
|
||||||
|
/// "Lentelė." for a single unnumbered figure.
|
||||||
|
#let __caption-label(fig) = context {
|
||||||
|
let supplement = __figure-supplement-of(fig)
|
||||||
|
if __is-single-unnumbered(fig) {
|
||||||
|
let name = __all-figure-kinds().at(__figure-key(fig)).single-name
|
||||||
|
[#__capitalize(name).]
|
||||||
|
} else {
|
||||||
|
[#__get-figure-number(fig, fig.location()) #supplement.]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// References
|
// References
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Returns a number for the given reference target.
|
/// Returns a number for the given reference target.
|
||||||
|
/// Panics for a figure that is the only one of its kind,
|
||||||
|
/// since such figures have no number.
|
||||||
/// - target (label): Label to get the reference number for.
|
/// - target (label): Label to get the reference number for.
|
||||||
#let ref-no(target) = context {
|
#let ref-no(target) = context {
|
||||||
if type(target) != label {
|
if type(target) != label {
|
||||||
@@ -202,6 +243,13 @@
|
|||||||
let kind = item.func()
|
let kind = item.func()
|
||||||
|
|
||||||
let number = if kind == figure {
|
let number = if kind == figure {
|
||||||
|
if __is-single-unnumbered(item) {
|
||||||
|
panic(
|
||||||
|
"ref-no: " + str(target) + " is the only " + __figure-key(item)
|
||||||
|
+ " in the document and is therefore unnumbered; "
|
||||||
|
+ "refer to it with @" + str(target) + " (or custom-ref) instead",
|
||||||
|
)
|
||||||
|
}
|
||||||
__get-figure-number(item, loc)
|
__get-figure-number(item, loc)
|
||||||
} else if kind == math.equation {
|
} else if kind == math.equation {
|
||||||
"(" + __get-equation-number(loc) + ")"
|
"(" + __get-equation-number(loc) + ")"
|
||||||
@@ -223,6 +271,7 @@
|
|||||||
/// - targets (label...): Labels to create a custom reference for.
|
/// - targets (label...): Labels to create a custom reference for.
|
||||||
#let custom-ref(..targets) = context {
|
#let custom-ref(..targets) = context {
|
||||||
let group-name = none
|
let group-name = none
|
||||||
|
let single-name = none // set when the target is a lone, unnumbered figure
|
||||||
let entries = () // (location, number) pairs
|
let entries = () // (location, number) pairs
|
||||||
|
|
||||||
for target in targets.pos() {
|
for target in targets.pos() {
|
||||||
@@ -237,6 +286,7 @@
|
|||||||
if kind not in kinds {
|
if kind not in kinds {
|
||||||
panic("unregistered figure kind `" + kind + "`: register it with ktu-paper(figureKinds: ...)")
|
panic("unregistered figure kind `" + kind + "`: register it with ktu-paper(figureKinds: ...)")
|
||||||
}
|
}
|
||||||
|
if __is-single-unnumbered(item) { single-name = kinds.at(kind).single-name }
|
||||||
(kinds.at(kind).ref-name, __get-figure-number(item, loc))
|
(kinds.at(kind).ref-name, __get-figure-number(item, loc))
|
||||||
} else {
|
} else {
|
||||||
panic("referencing unknown type: " + repr(item.func()))
|
panic("referencing unknown type: " + repr(item.func()))
|
||||||
@@ -250,10 +300,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if entries.len() > 0 {
|
if entries.len() > 0 {
|
||||||
|
if single-name != none {
|
||||||
|
// The only figure of its kind: no number, e.g. "(žr. lentelė)"
|
||||||
|
[(žr. #link(entries.first().at(0), single-name))]
|
||||||
|
} else {
|
||||||
let links = __sort-entries(entries).map(e => link(e.at(0), e.at(1)))
|
let links = __sort-entries(entries).map(e => link(e.at(0), e.at(1)))
|
||||||
[(žr. #links.join(", ") #group-name)]
|
[(žr. #links.join(", ") #group-name)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Show rule for `@label` references. Equations render as a bare "(1.2)";
|
/// Show rule for `@label` references. Equations render as a bare "(1.2)";
|
||||||
/// figures delegate to `custom-ref`, so "(žr. 1 pav.)" is built in one place.
|
/// figures delegate to `custom-ref`, so "(žr. 1 pav.)" is built in one place.
|
||||||
@@ -286,10 +341,7 @@
|
|||||||
|
|
||||||
set text(size: 11pt)
|
set text(size: 11pt)
|
||||||
|
|
||||||
let supplement = __figure-supplement-of(it)
|
let caption-line = [*#__caption-label(it)* #caption.body]
|
||||||
let separator = [.]
|
|
||||||
let fig-num = context __get-figure-number(it, here())
|
|
||||||
let caption-line = [*#fig-num #supplement#separator* #caption.body]
|
|
||||||
|
|
||||||
// Tables have captions at the top
|
// Tables have captions at the top
|
||||||
if it.kind == table {
|
if it.kind == table {
|
||||||
|
|||||||
+12
-9
@@ -12,9 +12,7 @@
|
|||||||
#import "figures.typ": (
|
#import "figures.typ": (
|
||||||
ref-no, custom-ref,
|
ref-no, custom-ref,
|
||||||
|
|
||||||
__fig-supplement,
|
__caption-label,
|
||||||
__figure-supplement-of,
|
|
||||||
__get-locatable-element-number,
|
|
||||||
__reset-figure-counters,
|
__reset-figure-counters,
|
||||||
__equation-numbering,
|
__equation-numbering,
|
||||||
__normalize-figure-kinds,
|
__normalize-figure-kinds,
|
||||||
@@ -158,7 +156,7 @@
|
|||||||
show outline.entry: it => link(
|
show outline.entry: it => link(
|
||||||
it.element.location(),
|
it.element.location(),
|
||||||
it.indented(
|
it.indented(
|
||||||
[*#__get-locatable-element-number(it.element) #__fig-supplement(image).*],
|
[*#__caption-label(it.element)*],
|
||||||
[ #it.inner()], gap: 0pt
|
[ #it.inner()], gap: 0pt
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -169,7 +167,7 @@
|
|||||||
show outline.entry: it => link(
|
show outline.entry: it => link(
|
||||||
it.element.location(),
|
it.element.location(),
|
||||||
it.indented(
|
it.indented(
|
||||||
[*#__get-locatable-element-number(it.element) #__fig-supplement(table).*],
|
[*#__caption-label(it.element)*],
|
||||||
[ #it.inner()], gap: 0pt
|
[ #it.inner()], gap: 0pt
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -180,7 +178,7 @@
|
|||||||
show outline.entry: it => link(
|
show outline.entry: it => link(
|
||||||
it.element.location(),
|
it.element.location(),
|
||||||
it.indented(
|
it.indented(
|
||||||
[*#__get-locatable-element-number(it.element) #__fig-supplement(raw).*],
|
[*#__caption-label(it.element)*],
|
||||||
[ #it.inner()], gap: 0pt
|
[ #it.inner()], gap: 0pt
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -202,7 +200,7 @@
|
|||||||
show outline.entry: it => link(
|
show outline.entry: it => link(
|
||||||
it.element.location(),
|
it.element.location(),
|
||||||
it.indented(
|
it.indented(
|
||||||
[*#__get-locatable-element-number(it.element) #__figure-supplement-of(it.element).*],
|
[*#__caption-label(it.element)*],
|
||||||
[ #it.inner()], gap: 0pt
|
[ #it.inner()], gap: 0pt
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -444,8 +442,13 @@
|
|||||||
/// - uppercaseSectionTitles (bool): Whether to uppercase section titles.
|
/// - uppercaseSectionTitles (bool): Whether to uppercase section titles.
|
||||||
/// - unnumberedHeadingAlignment (alignment): Alignment for unnumbered headings.
|
/// - unnumberedHeadingAlignment (alignment): Alignment for unnumbered headings.
|
||||||
/// - figureKinds (dictionary): Extra figure kinds, e.g.
|
/// - figureKinds (dictionary): Extra figure kinds, e.g.
|
||||||
/// `(command: (supplement: "komanda", ref-name: "komanda"))`. `ref-name`
|
/// `(command: (supplement: "komanda", ref-name: "komanda", single-name: "komanda"))`.
|
||||||
/// defaults to `supplement`. Use them with `figure(kind: "command", ...)`.
|
/// Use them with `figure(kind: "command", ...)`. Keys:
|
||||||
|
/// - `supplement` (required): text after the number in captions, e.g. "1 komanda.".
|
||||||
|
/// - `ref-name`: text used in references, e.g. "(žr. 1 komanda)". Defaults to `supplement`.
|
||||||
|
/// - `single-name`: full word used when the figure is the only one of its kind
|
||||||
|
/// and is left unnumbered, e.g. "Komanda." and "(žr. komanda)". Defaults to `supplement`.
|
||||||
|
/// Currently only tables and images are left unnumbered when single, so this only matters for kinds added there.
|
||||||
#let ktu-paper(
|
#let ktu-paper(
|
||||||
font: "Times New Roman",
|
font: "Times New Roman",
|
||||||
figureNumberingPerSection: false,
|
figureNumberingPerSection: false,
|
||||||
|
|||||||
Reference in new issue
Block a user