2 Commits
6 changed files with 228 additions and 23 deletions

No files matched your search

+2 -2
View File
@@ -4,9 +4,9 @@ This repository contains a Typst template for academic papers at the Kaunas Univ
## Initiating the template ## Initiating the template
Install the downloaded template under the following directory: Install the downloaded template under the following directory:
- Linux: `~/.local/share/typst/packages/local/ktu-paper/0.4.0/` - Linux: `~/.local/share/typst/packages/local/ktu-paper/0.4.1/`
And then initiate a new project: And then initiate a new project:
```sh ```sh
typst init @local/ktu-paper:0.4.0 typst init @local/ktu-paper:0.4.1
``` ```
+62 -10
View File
@@ -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,8 +300,13 @@
} }
if entries.len() > 0 { if entries.len() > 0 {
let links = __sort-entries(entries).map(e => link(e.at(0), e.at(1))) if single-name != none {
[(žr. #links.join(", ") #group-name)] // 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)))
[(žr. #links.join(", ") #group-name)]
}
} }
} }
@@ -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
View File
@@ -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,
+150
View File
@@ -0,0 +1,150 @@
#import "../src/lib.typ": (
ktu-paper, setup-code,
ktu-table-of-contents, ktu-picture-list, ktu-table-list, ktu-code-list,
ktu-heading-page-normal,
ktu-table,
unnumbered-heading,
custom-ref, ref-no
)
#show: ktu-paper.with(
font: "Times New Roman", // or Arial
figureNumberingPerSection: true,
figureKinds: (
veryCustomKind: (supplement: "komanda", ref-name: "komanda"),
),
)
#show: setup-code.with()
#show math.equation: it => {
show regex("\d+\.\d+"): it => {show ".": {","+h(0pt)}
it}
it
}
#ktu-heading-page-normal(
faculty: highlight[Informatikos fakultetas],
title: highlight[Laboratorinio darbo ataskaitos pavadinimas],
subtitles: (
"Laboratorinio darbo ataskaita",
highlight[Studijų modulio pavadinimas (kodas)]
),
authors: (
(highlight[Vardenis Pavardenis], "Ataskaitą parengė"),
(highlight[Pareigų ir mokslo laipsnio sutrumpinimas Vardenis Pavardenis], "Laboratoriniam darbui vadovavo"),
),
authorNamesFirst: false,
place: "Kaunas",
year: datetime.today().year(),
)
#pagebreak()
#set page(numbering: "1")
#ktu-table-of-contents()
#pagebreak()
#ktu-picture-list()
#pagebreak()
#ktu-table-list()
#pagebreak()
#ktu-code-list()
#pagebreak()
#unnumbered-heading[= Įvadas]
#lorem(50)
#pagebreak()
= Skyrius
#lorem(50)
== Poskyrius
#lorem(50)
=== Dalis
#lorem(50)
#pagebreak()
= Komponentai
== Paveikslai
Galima gauti paveikslo numerį #ref-no(<image-label>) arba visą paveikslo nuorodą #custom-ref(<image-label>).
#figure(
image("images/santaka.png", width: 70%),
caption: [
Paveikslo pavadinimas
],
) <image-label>
== Paveikslų "grid" išdėstymas
Paveikslus taip pat galima sudėti į "grid" išdėstymą, į jį kreiptis kaip numerį #ref-no(<image-grid-label>) arba visą nuorodą #custom-ref(<image-grid-label>).
#figure(grid(
columns: 2,
gutter: 2mm,
image("images/santaka.png", width: 100%),
image("images/santaka.png", width: 100%),
), caption: [
Paveikslėliai "grid'e"
]) <image-grid-label>
== Lentelės
Galima gauti lentelės numerį /*#ref-no(<table-label>)*/ arba visą lentelės nuorodą #custom-ref(<table-label>).
#figure(
ktu-table(
columns: (auto, 1fr, 1fr, 1fr),
align: (x, y) => { horizon + left },
table.header([*Stulpelio pavadinimas*], [*Stulpelio pavadinimas*], [*Stulpelio pavadinimas*], [*Stulpelio pavadinimas*]),
[Eilutė 1], [...], [...], [...],
[Eilutė 2], [...], [...], [...],
[Eilutė 3], [...], [...], [...],
[Eilutė 4], [...], [...], [...],
),
caption: [Lentelės pavadinimas],
) <table-label>
== Formulės
Formules galima išreikšti eilutėje, pavyzdžiui $E = m c^2$ arba atskiroje eilutėje, pavyzdžiui:
$
E = m c^2
$ <formula-label>
// TODO: fix
Formulės atskiroje eilutėje numeruojamos besąlygiškai, galima gauti formulės numerį #ref-no(<formula-label>) arba visą formulės nuorodą #custom-ref(<formula-label>).
== Kodo fragmentai
Kodo fragmentus galima išreikšti eilutėje, pavyzdžiui `print("Hello, world!")` arba atskiroje eilutėje, pavyzdžiui:
#figure(```python
def main():
print("Hello, world!")
if __name__ == "__main__":
main()
```, caption: [
Python kodas
]) <code-label>
Galima gauti kodo fragmento numerį #ref-no(<code-label>) arba visą kodo fragmento nuorodą #custom-ref(<code-label>).
== Naudotojo apibrėžtos figūros
Naudotojai tai pat gali apibrėžti savo figūras, pavyzdžiui, komandų fragmentus. Pavyzdžiui, galima apibrėžti komandų fragmentą su papildoma informacija ir naudoti jį dokumente. Galima gauti kodo fragmento numerį #ref-no(<custom-figure-label>) arba visą kodo fragmento nuorodą #custom-ref(<custom-figure-label>).
#figure(
```sh
npm install foo
```,
kind: "veryCustomKind",
supplement: "...",
caption: [Diegimo komanda],
) <custom-figure-label>
#pagebreak()
= Išvados
#lorem(50)
+1 -1
View File
@@ -1,4 +1,4 @@
#import "@local/ktu-paper:0.4.0": ( #import "@local/ktu-paper:0.4.1": (
ktu-paper, setup-code, ktu-paper, setup-code,
ktu-table-of-contents, ktu-picture-list, ktu-table-list, ktu-table-of-contents, ktu-picture-list, ktu-table-list,
ktu-heading-page-normal, ktu-heading-page-normal,
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "ktu-paper" name = "ktu-paper"
version = "0.4.0" version = "0.4.1"
compiler = "0.15.0" compiler = "0.15.0"
entrypoint = "src/lib.typ" entrypoint = "src/lib.typ"
repository = "https://github.com/svetikas/ktu-paper" repository = "https://github.com/svetikas/ktu-paper"