Compare commits
35 Commits
9657f4b75b
...
v0.7
Author | SHA1 | Date | |
---|---|---|---|
3f53ed89ba
|
|||
da11cd88fa
|
|||
d915b8cf27
|
|||
afc1ee372f
|
|||
d478d63812
|
|||
527534f885
|
|||
5c35389dca
|
|||
f22b16a803
|
|||
![]() |
f66f36d560 | ||
011ef2c950
|
|||
2787bed48d
|
|||
a691d84e1b
|
|||
![]() |
a0c75deba0 | ||
![]() |
1a7418d2cd | ||
2e300ded3c
|
|||
0e9fbcdc93
|
|||
bfe08ac9b4
|
|||
8a76ee9e1e
|
|||
d954a0e687
|
|||
eba0ec7826
|
|||
768ba54856
|
|||
85a6ed8d44
|
|||
afe325da0a
|
|||
cc079dd87d
|
|||
08c7123041
|
|||
c786ec2a4a
|
|||
5773e9785b
|
|||
f31bcaddec
|
|||
26d861b72a
|
|||
6bebe41d6e
|
|||
4e634e6ff9
|
|||
b03978a2c0
|
|||
c41ac4bc77
|
|||
1f75a74f61
|
|||
5d17fa8fe3
|
13
Makefile
13
Makefile
@@ -10,7 +10,8 @@ watch_example:
|
|||||||
example: example.pdf
|
example: example.pdf
|
||||||
|
|
||||||
TO_PACK := $(shell find template -type f) template/LICENSE
|
TO_PACK := $(shell find template -type f) template/LICENSE
|
||||||
PACK_TARGETS := $(TO_PACK:%=pack/tultemplate2/%) pack/tultemplate2/example.typ
|
PACK_TARGETS := $(TO_PACK:%=pack/tultemplate2/%) pack/tultemplate2/example.typ \
|
||||||
|
pack/tultemplate2/citations.bib
|
||||||
|
|
||||||
.PHONY: pack
|
.PHONY: pack
|
||||||
pack: pack/tultemplate2.zip
|
pack: pack/tultemplate2.zip
|
||||||
@@ -25,13 +26,21 @@ pack/tultemplate2.zip: $(PACK_TARGETS)
|
|||||||
rm -f $@
|
rm -f $@
|
||||||
cd pack && zip -r tultemplate2.zip tultemplate2
|
cd pack && zip -r tultemplate2.zip tultemplate2
|
||||||
|
|
||||||
pack/tultemplate2/example.typ: example.typ
|
pack/tultemplate2/%: %
|
||||||
ln -f $< $@
|
ln -f $< $@
|
||||||
|
|
||||||
pack/tultemplate2/template/LICENSE: LICENSE
|
pack/tultemplate2/template/LICENSE: LICENSE
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
ln -f $< $@
|
ln -f $< $@
|
||||||
|
|
||||||
|
pack/tultemplate2/template/tul_citace.csl: template/tul_citace.csl
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
cat $< | sed 's/^\s*\(.*\)$$/\1/' | tr -d '\n' > $@
|
||||||
|
|
||||||
|
pack/tultemplate2/template/lang.json: template/lang.json
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
cat $< | jq -c > $@
|
||||||
|
|
||||||
pack/tultemplate2/template/%: template/%
|
pack/tultemplate2/template/%: template/%
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
ln -f $< $@
|
ln -f $< $@
|
||||||
|
@@ -6,6 +6,7 @@ Easy Typst template for TUL documents. Begin by compiling `example.typ` and read
|
|||||||
|
|
||||||
It is recommended to use either:
|
It is recommended to use either:
|
||||||
- The on-line Typst editor (https://typst.app/play/) - use some zip build from releases
|
- The on-line Typst editor (https://typst.app/play/) - use some zip build from releases
|
||||||
|
(https://git.zumepro.cz/tul/tultemplate2/releases).
|
||||||
- The `typst` CLI tool (available in Arch repos and Snap)
|
- The `typst` CLI tool (available in Arch repos and Snap)
|
||||||
|
|
||||||
On Linux, with the `typst` command available, you can just run:
|
On Linux, with the `typst` command available, you can just run:
|
||||||
|
159
example.typ
159
example.typ
@@ -1,18 +1,7 @@
|
|||||||
#import "template/template.typ": *
|
#import "template/template.typ": *
|
||||||
|
|
||||||
#show: tultemplate2.with(
|
#show: tultemplate2.with(
|
||||||
title_cs: "Návod na použití Typst TUL šablony",
|
title: (cs: "Návod na použití Typst TUL šablony"),
|
||||||
abstract_cs: [
|
|
||||||
V tomto dokumentu se naučíte základy použití TUL Typst šablony a i nějaké lehké základy Typstu.
|
|
||||||
Šablonu vyvíjíme pro *všechny fakulty* TUL a snažíme se postupně přidávat všechny typy
|
|
||||||
vysokoškolských prací.
|
|
||||||
|
|
||||||
Tento dokument by měl být vhodný pro všechny čtenáře
|
|
||||||
(ze všech fakult a s různými úrovněmi dovedností). Pokud je něco popsáno nejasně
|
|
||||||
(nebo něco chybí), prosíme, dejte nám vědět. Snažíme se šablonu i dokumentaci průběžně
|
|
||||||
zlepšovat.
|
|
||||||
],
|
|
||||||
keywords_cs: ("šablona", "TUL", "Typst"),
|
|
||||||
author: "Ondřej Mekina, Matěj Žucha",
|
author: "Ondřej Mekina, Matěj Žucha",
|
||||||
supervisor: "Ondřej Mekina",
|
supervisor: "Ondřej Mekina",
|
||||||
)
|
)
|
||||||
@@ -93,7 +82,7 @@ hlášek (nebo se můžete podívat do zdrojového souboru pro toto PDF `example
|
|||||||
Nyní pojďme přidat nějaký obsah na titulní stránku. Jednoduše do volání šablony přidáme další
|
Nyní pojďme přidat nějaký obsah na titulní stránku. Jednoduše do volání šablony přidáme další
|
||||||
parametry.
|
parametry.
|
||||||
```typst
|
```typst
|
||||||
#show: tultemplate.with(..., title: "Můj úžasný dokument", author: "Já")
|
#show: tultemplate.with(..., title: (cs: "Můj úžasný dokument"), author: "Já")
|
||||||
```
|
```
|
||||||
Všechny možné parametry by vám měl našeptávat váš editor (nebo LSP) -- poslouchejte takové nápovědy,
|
Všechny možné parametry by vám měl našeptávat váš editor (nebo LSP) -- poslouchejte takové nápovědy,
|
||||||
opravdu hodně vám to usnadní práci.
|
opravdu hodně vám to usnadní práci.
|
||||||
@@ -202,6 +191,34 @@ Tady je praktická ukázka jednoduchého vložení obrázku s popiskem:
|
|||||||
Logo *TUL*
|
Logo *TUL*
|
||||||
])
|
])
|
||||||
|
|
||||||
|
Obrázky se zobrazí na začátku dokumentu v seznamu (pokud to daný typ dokumentu vyžaduje).
|
||||||
|
|
||||||
|
== Tabulky
|
||||||
|
|
||||||
|
Tabulky lze vytvářet takto:
|
||||||
|
|
||||||
|
```typst
|
||||||
|
#figure(table(
|
||||||
|
columns: 3,
|
||||||
|
table.header([], [*Sloupec 1*], [*Sloupec 2*]),
|
||||||
|
[*Řádek 1*], [a], [b],
|
||||||
|
[*Řádek 2*], [c], [d],
|
||||||
|
), caption: "Moje krásná tabulka")
|
||||||
|
```
|
||||||
|
|
||||||
|
#highlight[Hlavičku tabulky (první řádek) je dobré zabalit do funkce header (viz. výše)], to je
|
||||||
|
kvůli tomu, že Typst do vygenerovaného PDF souboru poté přidá metadata (například pro osoby se
|
||||||
|
zrakovým postižením).
|
||||||
|
|
||||||
|
#figure(table(
|
||||||
|
columns: 3,
|
||||||
|
table.header([], [*Sloupec 1*], [*Sloupec 2*]),
|
||||||
|
[*Řádek 1*], [a], [b],
|
||||||
|
[*Řádek 2*], [c], [d],
|
||||||
|
), caption: "Moje krásná tabulka")
|
||||||
|
|
||||||
|
Tabulky se zobrazí na začátku dokumentu v seznamu (pokud to daný typ dokumentu vyžaduje).
|
||||||
|
|
||||||
== Citace
|
== Citace
|
||||||
|
|
||||||
Šablona podporuje správu citací pomocí standardního BibTeX @bibtex souboru, stejně jako
|
Šablona podporuje správu citací pomocí standardního BibTeX @bibtex souboru, stejně jako
|
||||||
@@ -268,6 +285,93 @@ co nejvíce využívala základních funkcí Typstu -- například:
|
|||||||
|
|
||||||
V této kapitole se naučíme vymaxovat využití této šablony za pomocí dalších funkcí a syntaxe.
|
V této kapitole se naučíme vymaxovat využití této šablony za pomocí dalších funkcí a syntaxe.
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
|
== Parametry této šablony
|
||||||
|
|
||||||
|
Šablonu standardně použijete takto:
|
||||||
|
```typst
|
||||||
|
#show: tultemplate2.with(
|
||||||
|
<název_parametru>: <hodnota_parametru>,
|
||||||
|
<nazev_dalšího_parametru>: "<hodnota_dalšího_parametru>",
|
||||||
|
...
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Funkce `tultemplate2` přijímá následující parametry.
|
||||||
|
Zvýrazněné hodnoty jsou základní -- pokud vynecháte parametr, pak bude použita tato hodnota.
|
||||||
|
|
||||||
|
#line()
|
||||||
|
- `style` (vizuální styl dokumentu)
|
||||||
|
- *`"classic"`* - Klasický vizuální styl. Tento styl je neblíže klasické formální
|
||||||
|
podobě dokumentů. _(doporučeno pro nováčky této šablony)_
|
||||||
|
#line()
|
||||||
|
- `faculty` (zkratka fakulty)
|
||||||
|
- *`"tul"`* - barvy a logomarky univerzity
|
||||||
|
- `"fs"` - fakulta strojní
|
||||||
|
- `"ft"` - fakulta textilní
|
||||||
|
- `"fp"` - fakulta přírodovědně-humanitní a pedagogická
|
||||||
|
- `"ef"` - ekonomická fakulta
|
||||||
|
- `"fua"` - fakulta umění a architektury
|
||||||
|
- `"fm"` - fakulta mechatroniky, informatiky a mezioborových studií
|
||||||
|
- `"fzs"` - fakulta zdravotnických studií
|
||||||
|
- `"cxi"` - ústav pro nanomateriály, pokročilé technologie a inovace
|
||||||
|
#line()
|
||||||
|
- `lang` (základní jazyk dokumentu)
|
||||||
|
- *`"cs"`* - čeština
|
||||||
|
- `"en"`
|
||||||
|
#line()
|
||||||
|
- `document` (typ dokumentu)
|
||||||
|
- *`"other"`* - nespecifikovaný (neformální) typ dokumentu
|
||||||
|
- `bp` - Bakalářská práce
|
||||||
|
#line()
|
||||||
|
- `title` (nadpis dokumentu)
|
||||||
|
- Ve formátu `(<zkratka_jazyka>: "<nadpis>")`, například `(cs: "Můj nadpis")`
|
||||||
|
- Pro většinu dokumentů (kromě `other`) jsou vyžadovány verze _cs_ a _en_ (kvůli abstraktu).
|
||||||
|
#line()
|
||||||
|
- `author` (autor/autoři dokumentu)
|
||||||
|
- Příklad: `"Pavel Novák"` nebo `"Petra Velká, Jindřich Peterka"`
|
||||||
|
#line()
|
||||||
|
- `author_pronouns` (jazykový rod autora - není potřeba pro angličtinu, která má základní hodnotu)
|
||||||
|
- Pro vybraný jazyk _cs_:
|
||||||
|
- `"masculine"` - Mužský rod
|
||||||
|
- `"feminine"` - Ženský rod
|
||||||
|
- `"we"` - Množné číslo
|
||||||
|
- Pro vybraný jazyk _en_:
|
||||||
|
- *`"me"`* - První osoba jednotného čísla
|
||||||
|
- `"we"` - První osoba množného čísla
|
||||||
|
#line()
|
||||||
|
- `supervisor` (vedoucí práce) <arg_supervisor>
|
||||||
|
- V podobě textového řetězce, příklad: `"prof. Jindřich Jindřich"`
|
||||||
|
- Ve formátu `(name: "<jméno>", institute: "<institut>")` (toto lze využít například při DP)
|
||||||
|
#line()
|
||||||
|
- `consultant` (konzultant práce)
|
||||||
|
- Stejně jako u #link(<arg_supervisor>, [`supervisor`])
|
||||||
|
#line()
|
||||||
|
- `programme` (studijní program) <arg_programme>
|
||||||
|
- Ve formátu `(<zkratka_jazyka>: "<název_programu>")`
|
||||||
|
- Je vyžadován jazyk, který je vybrán pro celou šablonu -- tohle je pojistka, aby uživatel šablony
|
||||||
|
nevynechal vybraný jazyk
|
||||||
|
#line()
|
||||||
|
- `branch` (studijní obor)
|
||||||
|
- Stejně jako #link(<arg_programme>, [`programme`])
|
||||||
|
#line()
|
||||||
|
- `abstract` (abstrakt)
|
||||||
|
- Ve formátu `(<zkratka_jazyka>: [<abstrakt>])`, například `(cs: [Můj *krásný* abstrakt.])`
|
||||||
|
- Dokumenty vyžadují _cs_ i _en_ abstrakt (kromě typu dokumentu `other`).
|
||||||
|
#line()
|
||||||
|
- `keywords` (klíčová slova zobrazovaná pod abstraktem)
|
||||||
|
- Ve formátu `(<zkratka_jazyka>: ("slovo1", "slovo2", ...))`
|
||||||
|
#line()
|
||||||
|
- `assignment` (PDF soubor se zadáním)
|
||||||
|
- Ve formě cesty k souboru, například: `"zadani.pdf"`. Pokud je tento argument vynechán, bude
|
||||||
|
vložena hláška "vložte zadání" na příslušné místo v dokumentu -- tu stranu můžete pak nahradit
|
||||||
|
originálem zadání.
|
||||||
|
#line()
|
||||||
|
- `citations` (BibTex soubor s citacemi)
|
||||||
|
- Ve formě cesty k souboru, například: `"citace.bib"`. Pokud není specifikován, bude použit
|
||||||
|
výchozí (`"citations.bib"`).
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
== Zkratky
|
== Zkratky
|
||||||
|
|
||||||
LaTeX TUL šablona má k začátku dokumentu seznam zkratek. Proto jsme ho přidali i do této šablony.
|
LaTeX TUL šablona má k začátku dokumentu seznam zkratek. Proto jsme ho přidali i do této šablony.
|
||||||
@@ -299,6 +403,30 @@ Při dalších použití bude vypadat takto: #abbr("ZK").
|
|||||||
Tedy zkratku _nepřidáváte_ přímo do seznamu zkratek, ale elegantně jí používáte přímo v textu.
|
Tedy zkratku _nepřidáváte_ přímo do seznamu zkratek, ale elegantně jí používáte přímo v textu.
|
||||||
]
|
]
|
||||||
|
|
||||||
|
== Přílohy
|
||||||
|
|
||||||
|
V některých typech dokumentů budete chtít přidat přílohy. Přílohy se přikládají v různých podobách:
|
||||||
|
|
||||||
|
- Jako odkaz (URL/URI adresa)
|
||||||
|
- Zmínka externího souboru (například další soubor nahraný do systému)
|
||||||
|
- Přiložený obsah (vygenerovaný Typstem v tomto dokumentu -- je tedy součástí tohoto kódu)
|
||||||
|
- Externí PDF soubor přiložený jako obsah (jiný PDF dokument, vložený do příloh v kompletní
|
||||||
|
podobě -- to je dobré například do tisku, kde můžete přílohy vytisknout s dokumentem)
|
||||||
|
|
||||||
|
#highlight[
|
||||||
|
Přílohy lze definovat *pouze na jednom* místě v dokumentu, aby se zabránilo omylnému opakování
|
||||||
|
příloh. Přílohy doporučujeme definovat *na konci* souboru pro přehlednost.
|
||||||
|
]
|
||||||
|
|
||||||
|
Zde je ukázka definice příloh (je také použita na konci tohoto ukázkového souboru):
|
||||||
|
|
||||||
|
```typst
|
||||||
|
#attachments(
|
||||||
|
attach_link("Zdrojový kód této šablony", "https://git.zumepro.cz/tul/tultemplate2"),
|
||||||
|
attach_content("Testovací obsah vygenerovaný Typstem", [Sem lze psát _stylovaný_ obsah.]),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
= Workflow a jak si zjednoduššit práci
|
= Workflow a jak si zjednoduššit práci
|
||||||
|
|
||||||
Tyhle věci používat _nemusíte_, aby vám šablona fungovala. Nicméně často jsou poměrně fajn.
|
Tyhle věci používat _nemusíte_, aby vám šablona fungovala. Nicméně často jsou poměrně fajn.
|
||||||
@@ -361,3 +489,8 @@ Takhle si můžete předpřipravit délku odstavců a vyzkoušet si, jestli se r
|
|||||||
do požadavků. Pak můžete postupně přepisovat/vyplňovat.
|
do požadavků. Pak můžete postupně přepisovat/vyplňovat.
|
||||||
|
|
||||||
Funkce `todo` vám zároveň zabrání v tom, aby se text Lorem Ipsum vyskytl ve výsledném dokumentu.
|
Funkce `todo` vám zároveň zabrání v tom, aby se text Lorem Ipsum vyskytl ve výsledném dokumentu.
|
||||||
|
|
||||||
|
#attachments(
|
||||||
|
attach_link("Zdrojový kód této šablony", "https://git.zumepro.cz/tul/tultemplate2"),
|
||||||
|
attach_content("Testovací obsah vygenerovaný Typstem", [Sem lze psát _stylovaný_ obsah.]),
|
||||||
|
)
|
||||||
|
171
template/attachments.typ
Normal file
171
template/attachments.typ
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
#import "utils.typ": assert_type_signature, is_none
|
||||||
|
#import "lang.typ": get_lang_item
|
||||||
|
|
||||||
|
#let attachment_data = state("attachment_data");
|
||||||
|
|
||||||
|
#let attach_link(name, link) = {
|
||||||
|
assert_type_signature(link, "string", "attach link argument");
|
||||||
|
assert_type_signature(name, "string", "attach link name argument");
|
||||||
|
("link", link, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let attach_content(name, inner_content) = {
|
||||||
|
assert_type_signature(inner_content, "content", "attach content argument");
|
||||||
|
assert_type_signature(name, "string", "attach content name argument");
|
||||||
|
("content", inner_content, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let attach_pdf(name, filepath) = {
|
||||||
|
assert_type_signature(filepath, "string", "attach pdf argument");
|
||||||
|
assert_type_signature(name, "string", "attach pdf name argument");
|
||||||
|
("pdf", filepath, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let attach_file_reference(name, filename) = {
|
||||||
|
assert_type_signature(filename, "string", "attach file reference filename argument");
|
||||||
|
assert_type_signature(name, "string", "attach file reference name argument");
|
||||||
|
("ref", filename, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let make_content_anchor(idx) = {
|
||||||
|
"attachment_" + str(idx + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let generate_attachment_content(attachment, idx) = {
|
||||||
|
let attachment_type = attachment.at(0);
|
||||||
|
if attachment_type == "content" {
|
||||||
|
let anchor = make_content_anchor(idx);
|
||||||
|
[#metadata(attachment.at(1)) #label(anchor)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let generate_attachment_info(attachment, idx) = {
|
||||||
|
let attachment_type = attachment.at(0);
|
||||||
|
if type(attachment_type) != str {
|
||||||
|
panic("invalid attachment - wrap the attach using: attach_content, attach_pdf, ...");
|
||||||
|
}
|
||||||
|
if attachment_type == "content" {
|
||||||
|
let anchor = make_content_anchor(idx);
|
||||||
|
"(\"content\",\"" + anchor + "\",\"" + attachment.at(2) + "\")"
|
||||||
|
} else if attachment_type == "pdf" {
|
||||||
|
"(\"pdf\",\"" + attachment.at(1) + "\",\"" + attachment.at(2) + "\")"
|
||||||
|
} else if (
|
||||||
|
attachment_type == "pdf" or
|
||||||
|
attachment_type == "link" or
|
||||||
|
attachment_type == "ref"
|
||||||
|
) {
|
||||||
|
"(" + attachment.map((v) => { "\"" + v + "\"" }).join(",") + ",)"
|
||||||
|
} else {
|
||||||
|
panic("unknown attachment type '" + attachment_type + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let attachments(..attachments) = {
|
||||||
|
let attachments = attachments.pos();
|
||||||
|
assert_type_signature(
|
||||||
|
attachments, "array[array[string | content]] | array[string | content]", "attachments"
|
||||||
|
);
|
||||||
|
context {
|
||||||
|
if not is_none(attachment_data.get()) {
|
||||||
|
panic("re-definition of attachments - attachments must only be defined once");
|
||||||
|
}
|
||||||
|
if attachments.len() == 0 {
|
||||||
|
attachment_data.update("false");
|
||||||
|
} else {
|
||||||
|
attachment_data.update({
|
||||||
|
"(" + if type(attachments) == array and type(attachments.at(0)) == array {
|
||||||
|
for (idx, attachment) in attachments.enumerate() {
|
||||||
|
(generate_attachment_info(attachment, idx),)
|
||||||
|
}.join(", ")
|
||||||
|
} else {
|
||||||
|
generate_attachment_info(attachments, 0)
|
||||||
|
} + ",)"
|
||||||
|
})
|
||||||
|
if type(attachments) == array and type(attachments.at(0)) == array {
|
||||||
|
for (idx, attachment) in attachments.enumerate() {
|
||||||
|
generate_attachment_content(attachment, idx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
generate_attachment_content(attachments, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let list_entry(language, entry, is_embedded) = {
|
||||||
|
let entry_type = entry.at(0);
|
||||||
|
entry.at(2);
|
||||||
|
if entry_type == "link" {
|
||||||
|
": ";
|
||||||
|
link(entry.at(1));
|
||||||
|
} else if entry_type == "ref" {
|
||||||
|
": soubor ";
|
||||||
|
raw(entry.at(1));
|
||||||
|
}
|
||||||
|
if is_embedded {
|
||||||
|
text(
|
||||||
|
" (" + get_lang_item(language, "attached_bellow") + ")",
|
||||||
|
style: "italic",
|
||||||
|
fill: black.lighten(50%),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let attachment_list(language) = {
|
||||||
|
context {
|
||||||
|
let data = attachment_data.get();
|
||||||
|
if is_none(data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = eval(data);
|
||||||
|
if data == false {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
heading(get_lang_item(language, "attachments"), numbering: none);
|
||||||
|
|
||||||
|
// listing
|
||||||
|
let has_embedded = false;
|
||||||
|
let enum_items = ();
|
||||||
|
for attachment in data {
|
||||||
|
let attachment_type = attachment.at(0);
|
||||||
|
let is_embedded = false;
|
||||||
|
if attachment_type == "content" or attachment_type == "pdf" {
|
||||||
|
has_embedded = true;
|
||||||
|
is_embedded = true;
|
||||||
|
}
|
||||||
|
enum_items.push(list_entry(language, attachment, is_embedded));
|
||||||
|
}
|
||||||
|
enum(..enum_items.map((v) => { enum.item(v) }), spacing: 1em);
|
||||||
|
|
||||||
|
if has_embedded {
|
||||||
|
pagebreak(weak: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// embedded
|
||||||
|
set page(footer: none);
|
||||||
|
for (idx, attachment) in data.enumerate() {
|
||||||
|
let attachment_type = attachment.at(0);
|
||||||
|
if attachment_type == "content" {
|
||||||
|
heading(
|
||||||
|
level: 2,
|
||||||
|
get_lang_item(language, "attachment") + " " + str(idx + 1),
|
||||||
|
numbering: none,
|
||||||
|
outlined: false,
|
||||||
|
);
|
||||||
|
query(label(attachment.at(1))).at(0).value;
|
||||||
|
} else if attachment_type == "pdf" {
|
||||||
|
import "@preview/muchpdf:0.1.1": muchpdf
|
||||||
|
page(place(center + horizon, heading(
|
||||||
|
level: 2,
|
||||||
|
get_lang_item(language, "attachment") + " " +
|
||||||
|
str(idx + 1) + " " +
|
||||||
|
get_lang_item(language, "next_page_attachment"),
|
||||||
|
numbering: none,
|
||||||
|
outlined: false,
|
||||||
|
)), margin: 0em);
|
||||||
|
set page(margin: 0em);
|
||||||
|
muchpdf(read("../" + attachment.at(1), encoding: none), width: 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
template/classic/bp.typ
Normal file
69
template/classic/bp.typ
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#import "../lang.typ": get_lang_item
|
||||||
|
#import "common.typ": (
|
||||||
|
mainpage,
|
||||||
|
default_styling,
|
||||||
|
assignment,
|
||||||
|
disclaimer,
|
||||||
|
abstract,
|
||||||
|
acknowledgement,
|
||||||
|
toc,
|
||||||
|
abbrlist,
|
||||||
|
imagelist,
|
||||||
|
tablelist,
|
||||||
|
bibliogr
|
||||||
|
)
|
||||||
|
#import "../attachments.typ": attachment_list
|
||||||
|
#import "../utils.typ": is_none, assert_dict_has, assert_not_none, assert_type_signature
|
||||||
|
|
||||||
|
#let bp(
|
||||||
|
// general settings
|
||||||
|
faculty_id, faculty_color, language, assignment_document, citation_file,
|
||||||
|
|
||||||
|
// document info
|
||||||
|
title, author, author_pronouns, supervisor, consultant, study_programme, study_branch,
|
||||||
|
year_of_study, abstract_content, acknowledgement_content, keywords,
|
||||||
|
|
||||||
|
content
|
||||||
|
) = {
|
||||||
|
let force_langs = ("cs", "en");
|
||||||
|
assert_not_none(title, "title");
|
||||||
|
assert_dict_has(force_langs, title, "title");
|
||||||
|
|
||||||
|
assert_not_none(study_programme, "study programme");
|
||||||
|
assert_dict_has((language,), study_programme, "study programme");
|
||||||
|
assert_not_none(study_branch, "study branch");
|
||||||
|
assert_dict_has((language,), study_branch, "study branch");
|
||||||
|
|
||||||
|
assert_not_none(abstract_content, "abstract");
|
||||||
|
assert_dict_has(force_langs, abstract_content, "abstract");
|
||||||
|
if not is_none(keywords) {
|
||||||
|
assert_dict_has(force_langs, keywords, "keywords");
|
||||||
|
}
|
||||||
|
assert_not_none(acknowledgement_content, "acknowledgement content");
|
||||||
|
if language == "cs" {
|
||||||
|
assert_not_none(author_pronouns, "author gender");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_type_signature(supervisor, "string | none", "supervisor");
|
||||||
|
assert_type_signature(consultant, "string | none", "consultant");
|
||||||
|
|
||||||
|
mainpage(
|
||||||
|
faculty_id, language, "bp", title, author, supervisor, consultant, study_programme,
|
||||||
|
study_branch, year_of_study,
|
||||||
|
);
|
||||||
|
assignment(language, assignment_document);
|
||||||
|
default_styling(false, faculty_color, {
|
||||||
|
disclaimer(language, faculty_id, "bp", author, author_pronouns);
|
||||||
|
abstract("cs", title, abstract_content, keywords);
|
||||||
|
abstract("en", title, abstract_content, keywords);
|
||||||
|
acknowledgement(language, author, acknowledgement_content);
|
||||||
|
toc(language);
|
||||||
|
tablelist(language);
|
||||||
|
imagelist(language);
|
||||||
|
abbrlist(language);
|
||||||
|
pagebreak(weak: true);
|
||||||
|
content;
|
||||||
|
bibliogr(language, citation_file);
|
||||||
|
attachment_list(language);
|
||||||
|
});
|
||||||
|
}
|
51
template/classic/classic.typ
Normal file
51
template/classic/classic.typ
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// tools & utils
|
||||||
|
#import "../theme.typ": faculty_logotype, tul_logomark, faculty_color
|
||||||
|
#import "../lang.typ": lang_id, get_lang_item
|
||||||
|
#import "../utils.typ": assert_in_dict, assert_in_arr, map_none, assert_dict_has
|
||||||
|
|
||||||
|
// thesis types
|
||||||
|
#import "bp.typ": bp
|
||||||
|
#import "other.typ": other
|
||||||
|
|
||||||
|
#let template_classic(
|
||||||
|
// general settings
|
||||||
|
language, faculty_id, document_type, citation_file, assignment_document,
|
||||||
|
|
||||||
|
// document info
|
||||||
|
title, author, author_pronouns, supervisor, consultant, study_programme, study_branch,
|
||||||
|
year_of_study, abstract, acknowledgement, keywords,
|
||||||
|
|
||||||
|
// content
|
||||||
|
content,
|
||||||
|
) = {
|
||||||
|
// argument pre-checking
|
||||||
|
let document_types = (
|
||||||
|
"bp": bp,
|
||||||
|
"other": other,
|
||||||
|
)
|
||||||
|
assert_in_dict(document_type, document_types, "document type");
|
||||||
|
map_none(title, (v) => assert_dict_has((language,), v, "title"));
|
||||||
|
map_none(study_programme, (v) => assert_dict_has((language,), v, "study programme"));
|
||||||
|
map_none(study_branch, (v) => assert_dict_has((language,), v, "study branch"));
|
||||||
|
map_none(acknowledgement, (v) => assert_dict_has((language,), v, "acknowledgement content"));
|
||||||
|
|
||||||
|
document_types.at(document_type)(
|
||||||
|
faculty_id,
|
||||||
|
faculty_color(faculty_id),
|
||||||
|
language,
|
||||||
|
map_none(assignment_document, (v) => "../../" + v),
|
||||||
|
map_none(citation_file, (v) => "../../" + v),
|
||||||
|
title,
|
||||||
|
author,
|
||||||
|
author_pronouns,
|
||||||
|
supervisor,
|
||||||
|
consultant,
|
||||||
|
study_programme,
|
||||||
|
study_branch,
|
||||||
|
year_of_study,
|
||||||
|
abstract,
|
||||||
|
acknowledgement,
|
||||||
|
keywords,
|
||||||
|
content,
|
||||||
|
);
|
||||||
|
}
|
379
template/classic/common.typ
Normal file
379
template/classic/common.typ
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
#import "../theme.typ": faculty_logotype, tul_logomark, faculty_color
|
||||||
|
#import "../lang.typ": get_lang_item
|
||||||
|
#import "../utils.typ": is_none, assert_dict_has, map_none
|
||||||
|
|
||||||
|
#let base_font = "Inter";
|
||||||
|
#let mono_font = "Noto Sans Mono";
|
||||||
|
#let serif_font = "Merriweather";
|
||||||
|
#let tul_logomark_size = 6.5em;
|
||||||
|
|
||||||
|
// COUNTERS
|
||||||
|
|
||||||
|
#let image_count = counter("image_count");
|
||||||
|
#let table_count = counter("table_count");
|
||||||
|
|
||||||
|
// TYPST ELEMENT STYLING
|
||||||
|
|
||||||
|
#let default_styling(flip_bonding, faculty_color, content) = {
|
||||||
|
// page
|
||||||
|
set page(
|
||||||
|
margin: if flip_bonding {
|
||||||
|
(inside: 4cm, top: 3cm, bottom: 3cm)
|
||||||
|
} else {
|
||||||
|
(left: 4cm, top: 3cm, bottom: 3cm)
|
||||||
|
},
|
||||||
|
numbering: "1", footer: {
|
||||||
|
context {
|
||||||
|
let page = counter(page).get().at(0);
|
||||||
|
if flip_bonding {
|
||||||
|
align(str(page), if calc.rem(page, 2) == 1 { right } else { left });
|
||||||
|
} else {
|
||||||
|
align(str(page), right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// text
|
||||||
|
set text(font: serif_font);
|
||||||
|
set par(justify: true);
|
||||||
|
|
||||||
|
// figures
|
||||||
|
let figure_numbering(realcount, c) = {
|
||||||
|
context realcount.step();
|
||||||
|
context numbering("1. 1", counter(heading).get().at(0), c)
|
||||||
|
};
|
||||||
|
show figure.where(kind: image): set figure(numbering: figure_numbering.with(image_count));
|
||||||
|
show figure.where(kind: table): set figure(numbering: figure_numbering.with(table_count));
|
||||||
|
show figure.where(kind: table): set figure.caption(position: top);
|
||||||
|
show figure: it => {
|
||||||
|
block(it, above: 2em, below: 2em);
|
||||||
|
}
|
||||||
|
set image(width: 80%);
|
||||||
|
|
||||||
|
// heading
|
||||||
|
set heading(numbering: "1.1.1 ");
|
||||||
|
show heading: it => {
|
||||||
|
set par(justify: false);
|
||||||
|
block(
|
||||||
|
above: 2em,
|
||||||
|
below: 2em,
|
||||||
|
text(it, faculty_color, font: "TUL Mono", size: 1.2em)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
show heading.where(level: 1): it => {
|
||||||
|
// reset figure counters
|
||||||
|
context counter(figure.where(kind: image)).update(0);
|
||||||
|
context counter(figure.where(kind: table)).update(0);
|
||||||
|
|
||||||
|
pagebreak(weak: true);
|
||||||
|
v(2cm);
|
||||||
|
it
|
||||||
|
};
|
||||||
|
|
||||||
|
// other
|
||||||
|
show raw: set text(font: mono_font);
|
||||||
|
show raw.where(block: true): it => {
|
||||||
|
block(it, fill: rgb("#eee"), inset: 1em)
|
||||||
|
};
|
||||||
|
set highlight(fill: faculty_color.lighten(90%));
|
||||||
|
|
||||||
|
content
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#let header(faculty_id, language) = {
|
||||||
|
let logotype = faculty_logotype(faculty_id, language);
|
||||||
|
grid(
|
||||||
|
block(logotype, width: 100%),
|
||||||
|
block(align(right, block(tul_logomark(faculty_id), height: tul_logomark_size))),
|
||||||
|
columns: 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOCUMENT INFO
|
||||||
|
|
||||||
|
#let person_info(record, item_name) = {
|
||||||
|
if is_none(record) {
|
||||||
|
none
|
||||||
|
} else if type(record) == str {
|
||||||
|
record
|
||||||
|
} else if type(record) == dictionary {
|
||||||
|
if "name" in record {
|
||||||
|
record.at("name");
|
||||||
|
if "institute" in record {
|
||||||
|
text("\n " + record.at("institute"), style: "italic")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let panic_message = (
|
||||||
|
item_name + " name is required (or try not specifying " + item_name + " at all)"
|
||||||
|
);
|
||||||
|
panic(panic_message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let panic_message = "invalid " + item_name + " - expected a string or a dictionary";
|
||||||
|
panic(panic_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let info(
|
||||||
|
faculty_id,
|
||||||
|
language,
|
||||||
|
document_type,
|
||||||
|
title, author, supervisor, consultant, study_programme, study_branch, year_of_study,
|
||||||
|
) = {
|
||||||
|
let info_name_value_padding = 5em;
|
||||||
|
let info_name_min_width = 10em;
|
||||||
|
let gutter = .7em;
|
||||||
|
|
||||||
|
// document type
|
||||||
|
if type(document_type) != type(none) {
|
||||||
|
text(get_lang_item(language, document_type), weight: "bold", font: base_font);
|
||||||
|
v(0em);
|
||||||
|
}
|
||||||
|
|
||||||
|
// title
|
||||||
|
text(
|
||||||
|
title, weight: "bold", size: 2em,
|
||||||
|
faculty_color(faculty_id), font: base_font,
|
||||||
|
);
|
||||||
|
v(0em);
|
||||||
|
|
||||||
|
// other info
|
||||||
|
// [field_name, field_value, bold]
|
||||||
|
let info_fields = (
|
||||||
|
("author", author, true),
|
||||||
|
("supervisor", person_info(supervisor, "supervisor"), false),
|
||||||
|
("consultant", person_info(consultant, "consultant"), false),
|
||||||
|
("study_programme", study_programme, false),
|
||||||
|
("study_branch", study_branch, false),
|
||||||
|
("year_of_study", map_none(year_of_study, (v) => str(v) + "."), false),
|
||||||
|
)
|
||||||
|
context {
|
||||||
|
let max_field_name_width = calc.max(..info_fields.map((v) => {
|
||||||
|
if type(v.at(1)) == type(none) {
|
||||||
|
0pt
|
||||||
|
} else {
|
||||||
|
measure(get_lang_item(language, v.at(0)) + ":").width
|
||||||
|
}
|
||||||
|
}), info_name_min_width.to-absolute());
|
||||||
|
grid(
|
||||||
|
columns: 2,
|
||||||
|
gutter: gutter,
|
||||||
|
..info_fields.filter((v) => { type(v.at(1)) != type(none) }).map((v) => {
|
||||||
|
(
|
||||||
|
align(top, block(
|
||||||
|
text(get_lang_item(language, v.at(0)) + ":", style: "italic", font: base_font),
|
||||||
|
width: max_field_name_width + info_name_value_padding
|
||||||
|
)),
|
||||||
|
text(v.at(1), font: base_font, weight: if v.at(2) { "bold" } else { "regular" })
|
||||||
|
)
|
||||||
|
}).flatten(),
|
||||||
|
);
|
||||||
|
v(1em);
|
||||||
|
h(max_field_name_width + info_name_value_padding + gutter);
|
||||||
|
text(get_lang_item(language, "city") + " " + str(datetime.today().year()), font: base_font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MAINPAGE
|
||||||
|
|
||||||
|
#let mainpage(
|
||||||
|
faculty_id,
|
||||||
|
language,
|
||||||
|
document_type,
|
||||||
|
title, author, supervisor, consultant, study_programme, study_branch, year_of_study,
|
||||||
|
) = {
|
||||||
|
import "../utils.typ": has_all_none, map_none
|
||||||
|
let nonetype = type(none);
|
||||||
|
page({
|
||||||
|
if has_all_none((
|
||||||
|
document_type, title, author, supervisor, consultant, study_programme,
|
||||||
|
)) {
|
||||||
|
place(center + horizon, align(left, faculty_logotype(faculty_id, language)));
|
||||||
|
} else {
|
||||||
|
header(faculty_id, language);
|
||||||
|
align({
|
||||||
|
info(
|
||||||
|
faculty_id, language, document_type, map_none(title, (v) => v.at(language)),
|
||||||
|
author, supervisor, consultant, map_none(study_programme, (v) => v.at(language)),
|
||||||
|
map_none(study_branch, (v) => v.at(language)), year_of_study,
|
||||||
|
);
|
||||||
|
v(5em);
|
||||||
|
}, bottom);
|
||||||
|
}
|
||||||
|
}, margin: 2cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ASSIGNMENT PAGE
|
||||||
|
|
||||||
|
#let assignment(language, document) = {
|
||||||
|
if type(document) == type(none) {
|
||||||
|
page(
|
||||||
|
place(center + horizon, text(
|
||||||
|
get_lang_item(language, "place_assignment"),
|
||||||
|
fill: red,
|
||||||
|
size: 3em,
|
||||||
|
font: base_font,
|
||||||
|
weight: "bold",
|
||||||
|
)),
|
||||||
|
margin: 0em,
|
||||||
|
footer: none,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
import "@preview/muchpdf:0.1.1": muchpdf
|
||||||
|
set page(margin: 0em);
|
||||||
|
muchpdf(read(document, encoding: none));
|
||||||
|
}
|
||||||
|
|
||||||
|
// DISCLAIMER PAGE
|
||||||
|
|
||||||
|
#let disclaimer(language, faculty_id, disclaimer_type, author, author_pronouns) = {
|
||||||
|
import "../lang.typ": disclaimer
|
||||||
|
heading(get_lang_item(language, "disclaimer"), numbering: none, outlined: false);
|
||||||
|
par(
|
||||||
|
text(disclaimer(language, disclaimer_type, author_pronouns))
|
||||||
|
);
|
||||||
|
v(5em);
|
||||||
|
grid(
|
||||||
|
columns: 2,
|
||||||
|
gutter: 1em,
|
||||||
|
block(
|
||||||
|
text(datetime.today().display(get_lang_item(language, "date")), lang: "cs"), width: 100%
|
||||||
|
),
|
||||||
|
text(author),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ACKNOWLEDGEMENT PAGE
|
||||||
|
|
||||||
|
#let acknowledgement(language, author, content) = {
|
||||||
|
if is_none(content) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
heading(get_lang_item(language, "acknowledgement"), numbering: none, outlined: false);
|
||||||
|
par(content.at(language));
|
||||||
|
v(2em);
|
||||||
|
align(right, author);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSTRACT
|
||||||
|
|
||||||
|
#let abstract(language, title, content, keywords) = {
|
||||||
|
heading(text(title.at(language), font: base_font), numbering: none, outlined: false);
|
||||||
|
v(2em);
|
||||||
|
heading(
|
||||||
|
level: 2,
|
||||||
|
get_lang_item(language, "abstract"),
|
||||||
|
numbering: none,
|
||||||
|
outlined: false,
|
||||||
|
);
|
||||||
|
text(content.at(language));
|
||||||
|
if not is_none(keywords) and type(keywords.at(language)) != type(none) {
|
||||||
|
linebreak();
|
||||||
|
linebreak();
|
||||||
|
text(get_lang_item(language, "keywords") + ": ", weight: "bold", font: base_font);
|
||||||
|
text(keywords.at(language).join(", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _ OUTLINE FIGURE INNER
|
||||||
|
#let _outline_figure_inner(selector, title, body_mapper) = {
|
||||||
|
let entry(selector, element) = {
|
||||||
|
link(
|
||||||
|
element.location(),
|
||||||
|
grid(
|
||||||
|
columns: 3,
|
||||||
|
gutter: .5em,
|
||||||
|
stack(
|
||||||
|
dir: ltr,
|
||||||
|
text(numbering(
|
||||||
|
"1.1",
|
||||||
|
counter(heading).at(element.location()).at(0),
|
||||||
|
counter(selector).at(element.location()).at(0),
|
||||||
|
)),
|
||||||
|
h(.5em),
|
||||||
|
text(body_mapper(element)),
|
||||||
|
),
|
||||||
|
box(repeat([.], gap: 0.15em)),
|
||||||
|
str(element.location().page()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
heading(title, numbering: none);
|
||||||
|
for el in query(figure.where(kind: selector)) {
|
||||||
|
if is_none(el.caption) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entry(figure.where(kind: selector), el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _ FIGURE OUTLINE
|
||||||
|
|
||||||
|
#let _figure_outline(realcount, target, title) = {
|
||||||
|
context {
|
||||||
|
if realcount.final().at(0) == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_outline_figure_inner(target, title, (it) => it.caption.body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMAGE LIST
|
||||||
|
|
||||||
|
#let imagelist(language) = {
|
||||||
|
_figure_outline(image_count, image, get_lang_item(language, "image_list"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TABLE LIST
|
||||||
|
|
||||||
|
#let tablelist(language) = {
|
||||||
|
_figure_outline(table_count, table, get_lang_item(language, "table_list"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABBREVIATION LIST
|
||||||
|
|
||||||
|
#let abbrlist(language) = {
|
||||||
|
import "../abbreviations.typ": abbrlist
|
||||||
|
context {
|
||||||
|
let abbrs = abbrlist();
|
||||||
|
let max_abbr_width = if abbrs.len() > 0 {
|
||||||
|
calc.max(abbrs.keys().map((v) => measure(v).width)).at(0)
|
||||||
|
} else { return };
|
||||||
|
pagebreak(weak: true);
|
||||||
|
heading(get_lang_item(language, "abbrs"), numbering: none);
|
||||||
|
align(center, grid(
|
||||||
|
columns: 2,
|
||||||
|
gutter: 1em,
|
||||||
|
..abbrs.pairs().map((a) => {
|
||||||
|
(
|
||||||
|
align(left, block(text(a.at(0), weight: "bold"), width: max_abbr_width + 1em)),
|
||||||
|
text(a.at(1))
|
||||||
|
)
|
||||||
|
}).flatten()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TABLE OF CONTENTS
|
||||||
|
|
||||||
|
#let toc(language) = {
|
||||||
|
show outline.entry.where(level: 1): it => {
|
||||||
|
show repeat: none;
|
||||||
|
block(text(it, weight: "bold", size: 1.2em), above: 1.5em);
|
||||||
|
};
|
||||||
|
outline(title: get_lang_item(language, "toc"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// BIBLIOGRAPHY
|
||||||
|
|
||||||
|
#let bibliogr(language, citations_file) = {
|
||||||
|
if language == "cs" {
|
||||||
|
bibliography(citations_file, style: "../tul_citace.csl");
|
||||||
|
} else if language == "en" {
|
||||||
|
bibliography(citations_file, style: "iso-690-numeric");
|
||||||
|
} else {
|
||||||
|
panic("unknown language for bibliography '" + language + "'");
|
||||||
|
}
|
||||||
|
}
|
43
template/classic/other.typ
Normal file
43
template/classic/other.typ
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#import "../lang.typ": get_lang_item
|
||||||
|
#import "common.typ": (
|
||||||
|
mainpage,
|
||||||
|
default_styling,
|
||||||
|
assignment,
|
||||||
|
disclaimer,
|
||||||
|
abstract,
|
||||||
|
toc,
|
||||||
|
abbrlist,
|
||||||
|
imagelist,
|
||||||
|
tablelist,
|
||||||
|
)
|
||||||
|
#import "../attachments.typ": attachment_list
|
||||||
|
#import "../utils.typ": is_none, assert_not_none, assert_dict_has, assert_in_arr
|
||||||
|
|
||||||
|
#let other(
|
||||||
|
// general settings
|
||||||
|
faculty_id, faculty_color, language, assignment_document, citation_file,
|
||||||
|
|
||||||
|
// document info
|
||||||
|
title, author, _, supervisor, consultant, study_programme, study_branch, year_of_study,
|
||||||
|
abstract_content, _, keywords,
|
||||||
|
|
||||||
|
content
|
||||||
|
) = {
|
||||||
|
assert_not_none(title, "title");
|
||||||
|
assert_dict_has((language,), title, "title");
|
||||||
|
|
||||||
|
mainpage(
|
||||||
|
faculty_id, language, none, title, author, supervisor, consultant, study_programme,
|
||||||
|
study_branch, year_of_study,
|
||||||
|
);
|
||||||
|
default_styling(true, faculty_color, {
|
||||||
|
toc(language);
|
||||||
|
tablelist(language);
|
||||||
|
imagelist(language);
|
||||||
|
abbrlist(language);
|
||||||
|
pagebreak(to: "even", weak: true);
|
||||||
|
content;
|
||||||
|
bibliography(citation_file, style: "../tul_citace.csl");
|
||||||
|
attachment_list(language);
|
||||||
|
});
|
||||||
|
}
|
@@ -1,41 +1,92 @@
|
|||||||
{
|
{
|
||||||
"cs": {
|
"cs": {
|
||||||
"author": "Autor",
|
"author": "Autor",
|
||||||
|
"authors": "Autoři",
|
||||||
"supervisor": "Vedoucí práce",
|
"supervisor": "Vedoucí práce",
|
||||||
|
"consultant": "Konzultant práce",
|
||||||
"study_programme": "Studijní program",
|
"study_programme": "Studijní program",
|
||||||
|
"study_branch": "Studijní obor",
|
||||||
|
"year_of_study": "Ročník",
|
||||||
|
|
||||||
"bp": "Bakalářská práce",
|
"bp": "Bakalářská práce",
|
||||||
"dp": "Diplomová práce",
|
|
||||||
"dis": "Disertační práce",
|
|
||||||
|
|
||||||
"city": "Liberec",
|
"city": "Liberec",
|
||||||
|
|
||||||
|
"toc": "Obsah",
|
||||||
|
|
||||||
"disclaimer": "Prohlášení",
|
"disclaimer": "Prohlášení",
|
||||||
"disclaimer_bp": "Prohlašuji, že svou bakalářskou práci jsem vypracoval samostatně jako původní dílo s použitím uvedené literatury a na základě konzultací s vedoucím mé bakalářské práce a konzultantem.\n\nJsem si vědom toho, že na mou bakalářskou práci se plně vztahuje zákon č. 121/2000 Sb., o právu autorském, zejména § 60 – školní dílo.\n\nBeru na vědomí, že Technická univerzita v Liberci nezasahuje do mých autorských práv užitím mé bakalářské práce pro vnitřní potřebu Technické univerzity v Liberci.\n\nUžiji-li bakalářskou práci nebo poskytnu-li licenci k jejímu využití, jsem si vědom povinnosti informovat o této skutečnosti Technic-kou univerzitu v Liberci; v tomto případě má Technická univerzita v Liberci právo ode mne požadovat úhradu nákladů, které vynaložila na vytvoření díla, až do jejich skutečné výše.\n\nSoučasně čestně prohlašuji, že text elektronické podoby práce vložený do IS/STAG se shoduje s textem tištěné podoby práce.\n\nBeru na vědomí, že má bakalářská práce bude zveřejněna Tech- nickou univerzitou v Liberci v souladu s § 47b zákona č. 111/1998 Sb., o vysokých školách a o změně a doplnění dalších zákonů (zá- kon o vysokých školách), ve znění pozdějších předpisů.\n\nJsem si vědom následků, které podle zákona o vysokých školách mohou vyplývat z porušení tohoto prohlášení.",
|
"disclaimer_content": "Prohlašuj{g:i|i|eme}, že {svůj} {práce:tu} js{g:em|em|me} vypracoval{g:|a|i} samostatně jako původní dílo s použitím uvedené literatury a na základě konzultací s vedoucím {{g:mé|mé|naší}} bakalářské práce a konzultantem.\n\nJs{g:em|em|me} si vědom{g:|a|i} toho, že na {{g:moji|moji|naši}} {práce:tu} se plně vztahuje zákon č. 121/2000 Sb., o právu autorském, zejména § 60 – školní dílo.\n\nBer{g:u|u|eme} na vědomí, že Technická univerzita v Liberci nezasahuje do {g:mých|mých|našich} autorských práv užitím {{g:mé|mé|naší}} {práce:té} pro vnitřní potřebu Technické univerzity v Liberci.\n\nUžij{g:i|i|eme}-li {práce:tu} nebo poskytn{g:u|u|eme}-li licenci k {jejímu} využití, js{g:em|em|me} si vědom{g:|a|i} povinnosti informovat o této skutečnosti Technickou univerzitu v Liberci; v tomto případě má Technická univerzita v Liberci právo od{g:e|e|} {g:mne|mne|nás} požadovat úhradu nákladů, které vynaložila na vytvoření díla, až do jejich skutečné výše.\n\nSoučasně čestně prohlašuj{g:i|i|eme}, že text elektronické podoby práce vložený do IS/STAG se shoduje s textem tištěné podoby práce.\n\nBer{g:u|u|eme} na vědomí, že {{g:můj|můj|naše}} {práce:ta} bude {zveřejněn} Technickou univerzitou v Liberci v souladu s § 47b zákona č. 111/1998 Sb., o vysokých školách a o změně a doplnění dalších zákonů (zákon o vysokých školách), ve znění pozdějších předpisů.\n\nJs{g:em|em|me} si vědom{g:|a|i} následků, které podle zákona o vysokých školách mohou vyplývat z porušení tohoto prohlášení.",
|
||||||
|
|
||||||
|
"disclaimer_replace": {
|
||||||
|
"bp": {
|
||||||
|
"práce:ta": "bakalářská práce",
|
||||||
|
"práce:tu": "bakalářskou práci",
|
||||||
|
"práce:té": "bakalářské práce",
|
||||||
|
"moji": "moji",
|
||||||
|
"naše": "naše",
|
||||||
|
"naši": "naši",
|
||||||
|
"naší": "naší",
|
||||||
|
"mé": "mé",
|
||||||
|
"můj": "moje",
|
||||||
|
"svůj": "svoji",
|
||||||
|
"jejímu": "jejímu",
|
||||||
|
"zveřejněn": "zveřejněna"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"date": "[day]. [month]. [year]",
|
"date": "[day]. [month]. [year]",
|
||||||
|
|
||||||
"abstract": "Abstrakt",
|
"abstract": "Abstrakt",
|
||||||
"keywords": "Klíčová slova"
|
"acknowledgement": "Poděkování",
|
||||||
|
"keywords": "Klíčová slova",
|
||||||
|
"abbrs": "Seznam zkratek",
|
||||||
|
"image_list": "Seznam obrázků",
|
||||||
|
"table_list": "Seznam tabulek",
|
||||||
|
"attachments": "Přílohy",
|
||||||
|
"attachment": "Příloha",
|
||||||
|
"next_page_attachment": "začíná na další straně",
|
||||||
|
"attached_bellow": "dále přiloženo",
|
||||||
|
|
||||||
|
"place_assignment": "Sem vložte zadání"
|
||||||
},
|
},
|
||||||
|
|
||||||
"en": {
|
"en": {
|
||||||
"author": "Author",
|
"author": "Author",
|
||||||
|
"authors": "Authors",
|
||||||
"supervisor": "Supervisor",
|
"supervisor": "Supervisor",
|
||||||
|
"consultant": "Consultant",
|
||||||
"study_programme": "Study programme",
|
"study_programme": "Study programme",
|
||||||
|
"study_branch": "Study branch",
|
||||||
|
"year_of_study": "Year of study",
|
||||||
|
|
||||||
"bp": "Bachelor thesis",
|
"bp": "Bachelor thesis",
|
||||||
"dp": "Diploma thesis",
|
|
||||||
"dis": "Dissertation thesis",
|
|
||||||
|
|
||||||
"city": "Liberec",
|
"city": "Liberec",
|
||||||
|
|
||||||
|
"toc": "Contents",
|
||||||
|
|
||||||
"disclaimer": "Declaration",
|
"disclaimer": "Declaration",
|
||||||
"disclaimer_bp": "I hereby certify, I, myself, have written my bachelor thesis as an original and primary work using the literature listed below and consulting it with my thesis supervisor and my thesis counsellor.\n\nI acknowledge that my bachelor thesis is fully governed by Act No. 121/2000 Coll., the Copyright Act, in particular Article 60 – School Work.\n\nI acknowledge that the Technical University of Liberec does not infringe my copyrights by using my bachelor thesis for internal purposes of the Technical University of Liberec.\n\nI am aware of my obligation to inform the Technical University of Liberec on having used or granted license to use the results of my bachelor thesis; in such a case the Technical University of Liberec may require reimbursement of the costs incurred for creating the result up to their actual amount.\n\nAt the same time, I honestly declare that the text of the printed version of my bachelor thesis is identical with the text of the electronic version uploaded into the IS STAG.\n\nI acknowledge that the Technical University of Liberec will make my bachelor thesis public in accordance with paragraph 47b of Act No. 111/1998 Coll., on Higher Education Institutions and on Amendment to Other Acts (the Higher Education Act), as amended.\n\nI am aware of the consequences which may under the Higher Education Act result from a breach of this declaration.",
|
"disclaimer_content": "{g:I|We} hereby certify, {g:I|we}, {g:myself|ourselves}, have written {g:my|our} {thesis} as an original and primary work using the literature listed below and consulting it with {g:my|our} thesis supervisor and {g:my|our} thesis counsellor.\n\n{g:I|We} acknowledge that {g:my|our} {thesis} is fully governed by Act No. 121/2000 Coll., the Copyright Act, in particular Article 60 – School Work.\n\n{g:I|We} acknowledge that the Technical University of Liberec does not infringe {g:my|our} copyrights by using {g:my|our} {thesis} for internal purposes of the Technical University of Liberec.\n\n{g:I|We} {g:am|are} aware of {g:my|our} obligation to inform the Technical University of Liberec on having used or granted license to use the results of {g:my|our} {thesis}; in such a case the Technical University of Liberec may require reimbursement of the costs incurred for creating the result up to their actual amount.\n\nAt the same time, {g:I|we} honestly declare that the text of the printed version of {g:my|our} {thesis} is identical with the text of the electronic version uploaded into the IS STAG.\n\n{g:I|We} acknowledge that the Technical University of Liberec will make {g:my|our} {thesis} public in accordance with paragraph 47b of Act No. 111/1998 Coll., on Higher Education Institutions and on Amendment to Other Acts (the Higher Education Act), as amended.\n\n{g:I|We} {g:am|are} aware of the consequences which may under the Higher Education Act result from a breach of this declaration.",
|
||||||
|
|
||||||
|
"disclaimer_replace": {
|
||||||
|
"bp": {
|
||||||
|
"thesis": "bachelor thesis"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"date": "[year]-[month]-[day]",
|
"date": "[year]-[month]-[day]",
|
||||||
|
|
||||||
"abstract": "Abstract",
|
"abstract": "Abstract",
|
||||||
"keywords": "Keywords"
|
"acknowledgement": "Acknowledgement",
|
||||||
|
"keywords": "Keywords",
|
||||||
|
"abbrs": "List of abbreviations",
|
||||||
|
"image_list": "List of images",
|
||||||
|
"table_list": "List of tables",
|
||||||
|
"attachments": "Attachments",
|
||||||
|
"attachment": "Attachment",
|
||||||
|
"next_page_attachment": "begins on the next page",
|
||||||
|
"attached_bellow": "attached bellow",
|
||||||
|
|
||||||
|
"place_assignment": "Insert your assignment here"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#import "utils.typ": assert_in_dict
|
#import "utils.typ": assert_in_dict, assert_in_arr, map_none, ok_or
|
||||||
|
|
||||||
#let lang_ids = (
|
#let lang_ids = (
|
||||||
cs: 0,
|
cs: 0,
|
||||||
@@ -20,3 +20,44 @@
|
|||||||
let lang_items = fetch_lang_items();
|
let lang_items = fetch_lang_items();
|
||||||
return lang_items.at(lang_abbr).at(item_name);
|
return lang_items.at(lang_abbr).at(item_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#let replace_czech_gender(raw, gender) = {
|
||||||
|
let genders = (
|
||||||
|
feminine: 1,
|
||||||
|
masculine: 0,
|
||||||
|
we: 2,
|
||||||
|
);
|
||||||
|
assert_in_dict(gender, genders, "author gender");
|
||||||
|
raw.replace(regex("\{g:([^|]*)\|([^|]*)\|([^}]*)\}"), (match) => {
|
||||||
|
match.captures.at(genders.at(gender))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#let replace_english_pronounce(raw, pronounce) = {
|
||||||
|
let pronounce = ok_or(pronounce, "me");
|
||||||
|
let pronouns = (
|
||||||
|
me: 0,
|
||||||
|
we: 1,
|
||||||
|
);
|
||||||
|
assert_in_dict(pronounce, pronouns, "author gender");
|
||||||
|
raw.replace(regex("\{g:([^|]*)\|([^}]*)\}"), (match) => {
|
||||||
|
match.captures.at(pronouns.at(pronounce))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#let disclaimer(language, document_type, author_pronouns) = {
|
||||||
|
let disclaimer = get_lang_item(language, "disclaimer_content");
|
||||||
|
let replacements = get_lang_item(language, "disclaimer_replace").at(document_type);
|
||||||
|
if language == "cs" {
|
||||||
|
disclaimer = replace_czech_gender(disclaimer, author_pronouns);
|
||||||
|
} else if language == "en" {
|
||||||
|
disclaimer = replace_english_pronounce(disclaimer, author_pronouns);
|
||||||
|
}
|
||||||
|
for (key, value) in replacements.pairs() {
|
||||||
|
disclaimer = disclaimer.replace("{" + key + "}", value);
|
||||||
|
}
|
||||||
|
if disclaimer.contains("{") or disclaimer.contains("}") {
|
||||||
|
panic("invalid language file");
|
||||||
|
}
|
||||||
|
disclaimer
|
||||||
|
}
|
||||||
|
@@ -7,6 +7,9 @@
|
|||||||
// Git: https://git.zumepro.cz/tul/tultemplate2
|
// Git: https://git.zumepro.cz/tul/tultemplate2
|
||||||
|
|
||||||
#import "prototyping.typ": todo, profile
|
#import "prototyping.typ": todo, profile
|
||||||
|
#import "attachments.typ": (
|
||||||
|
attachments, attach_content, attach_pdf, attach_link, attach_file_reference
|
||||||
|
)
|
||||||
|
|
||||||
// TUL Template 2
|
// TUL Template 2
|
||||||
//
|
//
|
||||||
@@ -22,43 +25,84 @@
|
|||||||
// - style (str): Visual style to use. This can be "classic".
|
// - style (str): Visual style to use. This can be "classic".
|
||||||
// - faculty (str): Factulty abbreviation. One of "fs", "ft", "fp", "ef", "fua", "fm", "fzs", "cxi".
|
// - faculty (str): Factulty abbreviation. One of "fs", "ft", "fp", "ef", "fua", "fm", "fzs", "cxi".
|
||||||
// - lang (str): Language code. This can be "cs" or "en".
|
// - lang (str): Language code. This can be "cs" or "en".
|
||||||
// - document (str): Type of document. This can be "bp", "dp", "ds".
|
// - document (str): Type of document. This can be "bp" or "other".
|
||||||
// - title (str): The title of the document.
|
// - title (dictionary): The title of the document.
|
||||||
// - author (str): The name of the document's author.
|
// - author (str): The name of the document's author.
|
||||||
|
// - author_pronouns (str): The gender of the document's author. Needed only for the `cs` language.
|
||||||
// - supervisor (str): The name of the document's supervisor.
|
// - supervisor (str): The name of the document's supervisor.
|
||||||
// - programme (str): Study programme.
|
// - consultant (str): The name of the document's consultant.
|
||||||
|
// - programme (dictionary): Study programme.
|
||||||
|
// - branch (disctionary): Study branch
|
||||||
|
// - abstract (dictionary): The abstract.
|
||||||
|
// - keywords (dictionary): The abstract keywords.
|
||||||
|
// - assignment (str): Filepath of the assignment document/page.
|
||||||
// - citations (str): The location of the citation file.
|
// - citations (str): The location of the citation file.
|
||||||
// - content (content): The content of the document
|
// - content (content): The content of the document
|
||||||
//
|
//
|
||||||
//-> none
|
//-> none
|
||||||
#let tultemplate2(
|
#let tultemplate2(
|
||||||
style: "classic",
|
// general settings
|
||||||
faculty: "tul",
|
style: "classic", faculty: "tul", lang: "cs", document: "other",
|
||||||
lang: "cs",
|
|
||||||
document: none,
|
// document info
|
||||||
title_cs: none, author: none, supervisor: none, programme: none, abstract_cs: none,
|
title: none, keywords: none, abstract: none, acknowledgement: none, author: none,
|
||||||
keywords_cs: none,
|
author_pronouns: none, supervisor: none, consultant: none, programme: none,
|
||||||
title_en: none, abstract_en: none, keywords_en: none,
|
branch: none, year_of_study: none,
|
||||||
citations: "citations.bib",
|
|
||||||
|
// links
|
||||||
|
assignment: none, citations: "citations.bib",
|
||||||
|
|
||||||
|
// content
|
||||||
content,
|
content,
|
||||||
) = {
|
) = {
|
||||||
import "template_classic.typ": template_classic
|
import "utils.typ": assert_in_dict, assert_type_signature
|
||||||
import "utils.typ": assert_in_dict
|
|
||||||
|
// argument checking
|
||||||
|
assert_type_signature(style, "string", "visual style argument");
|
||||||
|
assert_type_signature(faculty, "string", "faculty id argument");
|
||||||
|
assert_type_signature(lang, "string", "language abbreviation argument");
|
||||||
|
assert_type_signature(document, "string | none", "document kind argument");
|
||||||
|
assert_type_signature(title, "dictionary[string : string] | none", "title argument");
|
||||||
|
assert_type_signature(keywords, "dictionary[string : array[string]] | none", "keywords argument");
|
||||||
|
assert_type_signature(
|
||||||
|
abstract, "dictionary[string : string | content] | none", "abstract argument"
|
||||||
|
);
|
||||||
|
assert_type_signature(
|
||||||
|
acknowledgement, "dictionary[string : string] | none", "acknowledgement content"
|
||||||
|
);
|
||||||
|
assert_type_signature(author, "string | none", "author argument");
|
||||||
|
assert_type_signature(author_pronouns, "string | none", "author gender argument");
|
||||||
|
assert_type_signature(
|
||||||
|
supervisor, "string | dictionary[string : string] | none", "supervisor argument"
|
||||||
|
);
|
||||||
|
assert_type_signature(
|
||||||
|
consultant, "string | dictionary[string : string] | none", "consultant argument"
|
||||||
|
);
|
||||||
|
assert_type_signature(
|
||||||
|
programme, "dictionary[string : string] | none", "study programme argument"
|
||||||
|
);
|
||||||
|
assert_type_signature(branch, "dictionary[string : string] | none", "study branch argument");
|
||||||
|
assert_type_signature(year_of_study, "integer | none", "year of study");
|
||||||
|
assert_type_signature(assignment, "string | none", "assignment document argument");
|
||||||
|
assert_type_signature(citations, "string", "citations file argument");
|
||||||
|
|
||||||
|
// templates
|
||||||
|
import "classic/classic.typ": template_classic
|
||||||
let templates = (
|
let templates = (
|
||||||
classic: template_classic,
|
classic: template_classic,
|
||||||
);
|
);
|
||||||
assert_in_dict(style, templates, "template name");
|
assert_in_dict(style, templates, "template name");
|
||||||
|
|
||||||
// global set-up
|
// language set-up
|
||||||
import "lang.typ": lang_ids
|
import "lang.typ": lang_ids
|
||||||
assert_in_dict(lang, lang_ids, "language abbreviation");
|
assert_in_dict(lang, lang_ids, "language abbreviation");
|
||||||
set text(lang: lang);
|
set text(lang: lang);
|
||||||
|
|
||||||
|
// template call
|
||||||
templates.at(style)(
|
templates.at(style)(
|
||||||
faculty, lang, document,
|
lang, faculty, document, citations, assignment,
|
||||||
title_cs, author, supervisor, programme, abstract_cs, keywords_cs,
|
title, author, author_pronouns, supervisor, consultant,
|
||||||
title_en, abstract_en, keywords_en,
|
programme, branch, year_of_study, abstract, acknowledgement, keywords, content
|
||||||
"../" + citations,
|
|
||||||
content
|
|
||||||
);
|
);
|
||||||
|
|
||||||
import "prototyping.typ": assert_release_ready
|
import "prototyping.typ": assert_release_ready
|
||||||
|
@@ -1,270 +0,0 @@
|
|||||||
#import "theme.typ": faculty_logotype, tul_logomark, faculty_color
|
|
||||||
#import "lang.typ": lang_id, get_lang_item
|
|
||||||
#import "utils.typ": assert_in_dict, assert_in_arr
|
|
||||||
|
|
||||||
#let base_font = "Inter";
|
|
||||||
#let mono_font = "Noto Sans Mono";
|
|
||||||
#let serif_font = "Merriweather";
|
|
||||||
#let tul_logomark_size = 6.5em;
|
|
||||||
|
|
||||||
#let classic_header(faculty_id, language) = {
|
|
||||||
let logotype = faculty_logotype(faculty_id, language);
|
|
||||||
grid(
|
|
||||||
block(logotype, width: 100%),
|
|
||||||
block(align(right, block(tul_logomark(faculty_id), height: tul_logomark_size))),
|
|
||||||
columns: 2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#let classic_info(
|
|
||||||
faculty_id,
|
|
||||||
language,
|
|
||||||
document_type,
|
|
||||||
title, author, supervisor, study_programme,
|
|
||||||
) = {
|
|
||||||
let info_name_value_padding = 5em;
|
|
||||||
let info_name_min_width = 10em;
|
|
||||||
|
|
||||||
// document type
|
|
||||||
if type(document_type) != type(none) {
|
|
||||||
let document_types = ("bp", "dp", "dis", "hab", "teze", "autoref", "proj", "sp");
|
|
||||||
assert_in_arr(document_type, document_types, "document type abbreviation");
|
|
||||||
text(get_lang_item(language, document_type), weight: "bold", font: base_font);
|
|
||||||
v(0em);
|
|
||||||
}
|
|
||||||
|
|
||||||
// title
|
|
||||||
text(
|
|
||||||
title, weight: "bold", size: 2em,
|
|
||||||
faculty_color(faculty_id), font: base_font,
|
|
||||||
);
|
|
||||||
v(0em);
|
|
||||||
|
|
||||||
// other info
|
|
||||||
// [field_name, field_value, bold]
|
|
||||||
let info_fields = (
|
|
||||||
("study_programme", study_programme, false),
|
|
||||||
("author", author, true),
|
|
||||||
("supervisor", supervisor, false),
|
|
||||||
)
|
|
||||||
context {
|
|
||||||
let max_field_name_width = calc.max(..info_fields.map((v) => {
|
|
||||||
if type(v.at(1)) == type(none) {
|
|
||||||
0pt
|
|
||||||
} else {
|
|
||||||
measure(get_lang_item(language, v.at(0)) + ":").width
|
|
||||||
}
|
|
||||||
}), info_name_min_width.to-absolute());
|
|
||||||
grid(
|
|
||||||
columns: 2,
|
|
||||||
rows: (auto, 1.2em),
|
|
||||||
..info_fields.filter((v) => { type(v.at(1)) != type(none) }).map((v) => {
|
|
||||||
(
|
|
||||||
block(
|
|
||||||
text(get_lang_item(language, v.at(0)) + ":", style: "italic", font: base_font),
|
|
||||||
width: max_field_name_width + info_name_value_padding,
|
|
||||||
),
|
|
||||||
text(v.at(1), font: base_font, weight: if v.at(2) { "bold" } else { "regular" })
|
|
||||||
)
|
|
||||||
}).flatten(),
|
|
||||||
);
|
|
||||||
v(1em);
|
|
||||||
h(max_field_name_width + info_name_value_padding);
|
|
||||||
text(get_lang_item(language, "city") + " " + str(datetime.today().year()), font: base_font);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#let classic_mainpage(
|
|
||||||
faculty_id,
|
|
||||||
language,
|
|
||||||
document_type,
|
|
||||||
title, author, supervisor, study_programme,
|
|
||||||
) = {
|
|
||||||
import "utils.typ": has_all_none
|
|
||||||
let nonetype = type(none);
|
|
||||||
page({
|
|
||||||
if has_all_none((
|
|
||||||
document_type, title, author, supervisor, study_programme,
|
|
||||||
)) {
|
|
||||||
place(center + horizon, align(left, faculty_logotype(faculty_id, language)));
|
|
||||||
} else {
|
|
||||||
classic_header(faculty_id, language);
|
|
||||||
align({
|
|
||||||
classic_info(
|
|
||||||
faculty_id, language, document_type, title.at(language),
|
|
||||||
author, supervisor, study_programme,
|
|
||||||
);
|
|
||||||
v(5em);
|
|
||||||
}, bottom);
|
|
||||||
}
|
|
||||||
}, margin: 2cm);
|
|
||||||
}
|
|
||||||
|
|
||||||
#let disclaimer(language, faculty_id, disclaimer_type, author) = {
|
|
||||||
let disclaimers_for = ("bp");
|
|
||||||
if type(disclaimer_type) == type(none) or disclaimer_type not in disclaimers_for {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
heading(get_lang_item(language, "disclaimer"), numbering: none, outlined: false);
|
|
||||||
par(
|
|
||||||
text(get_lang_item(language, "disclaimer_" + disclaimer_type))
|
|
||||||
);
|
|
||||||
v(5em);
|
|
||||||
grid(
|
|
||||||
columns: 2,
|
|
||||||
gutter: 1em,
|
|
||||||
block(text(datetime.today().display(get_lang_item(language, "date")), lang: "cs"), width: 100%),
|
|
||||||
text(author),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#let abstract(language, title, content, keywords) = {
|
|
||||||
if type(content.at(language)) == type(none) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if type(title.at(language)) == type(none) {
|
|
||||||
panic("no title found for language `" + language + "` (required for abstract)");
|
|
||||||
}
|
|
||||||
heading(text(title.at(language), font: base_font), numbering: none, outlined: false);
|
|
||||||
v(2em);
|
|
||||||
heading(
|
|
||||||
level: 2,
|
|
||||||
get_lang_item(language, "abstract"),
|
|
||||||
numbering: none,
|
|
||||||
outlined: false,
|
|
||||||
);
|
|
||||||
text(content.at(language));
|
|
||||||
if type(keywords.at(language)) != type(none) {
|
|
||||||
linebreak();
|
|
||||||
linebreak();
|
|
||||||
text(get_lang_item(language, "keywords") + ": ", weight: "bold", font: base_font);
|
|
||||||
text(keywords.at(language).join(", "));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#let abbrlist(language) = {
|
|
||||||
import "abbreviations.typ": abbrlist
|
|
||||||
context {
|
|
||||||
let abbrs = abbrlist();
|
|
||||||
let max_abbr_width = if abbrs.len() > 0 {
|
|
||||||
calc.max(abbrs.keys().map((v) => measure(v).width)).at(0)
|
|
||||||
} else { return };
|
|
||||||
pagebreak(weak: true);
|
|
||||||
heading(("Seznam zkratek", "List of abbreviations").at(language), numbering: none);
|
|
||||||
align(center, grid(
|
|
||||||
columns: 2,
|
|
||||||
gutter: 1em,
|
|
||||||
..abbrs.pairs().map((a) => {
|
|
||||||
(
|
|
||||||
align(left, block(text(a.at(0), weight: "bold"), width: max_abbr_width + 1em)),
|
|
||||||
text(a.at(1))
|
|
||||||
)
|
|
||||||
}).flatten()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#let template_classic(
|
|
||||||
faculty_id,
|
|
||||||
language,
|
|
||||||
document_type,
|
|
||||||
title_cs, author, supervisor, study_programme, abstract_cs, keywords_cs,
|
|
||||||
title_en, abstract_en, keywords_en,
|
|
||||||
citation_file,
|
|
||||||
content,
|
|
||||||
) = {
|
|
||||||
let flip_bonding = if document_type == "bp" {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
let title = (
|
|
||||||
"cs": title_cs,
|
|
||||||
"en": title_en,
|
|
||||||
);
|
|
||||||
|
|
||||||
// main page
|
|
||||||
classic_mainpage(faculty_id, language, document_type, title, author, supervisor, study_programme);
|
|
||||||
|
|
||||||
// styling
|
|
||||||
let faculty_color = faculty_color(faculty_id);
|
|
||||||
set par(justify: true);
|
|
||||||
set heading(numbering: "1.1.1 ");
|
|
||||||
set page(
|
|
||||||
margin: if flip_bonding {
|
|
||||||
(inside: 4cm, top: 3cm, bottom: 3cm)
|
|
||||||
} else {
|
|
||||||
(left: 4cm, top: 3cm, bottom: 3cm)
|
|
||||||
},
|
|
||||||
numbering: "1", footer: {
|
|
||||||
context {
|
|
||||||
let page = counter(page).get().at(0);
|
|
||||||
if flip_bonding {
|
|
||||||
align(str(page), if calc.rem(page, 2) == 1 { right } else { left });
|
|
||||||
} else {
|
|
||||||
align(str(page), right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
set text(font: serif_font);
|
|
||||||
show heading: it => {
|
|
||||||
set par(justify: false);
|
|
||||||
block(
|
|
||||||
above: 2em,
|
|
||||||
below: 2em,
|
|
||||||
text(it, faculty_color, font: "TUL Mono", size: 1.2em)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
show heading.where(level: 1): it => {
|
|
||||||
pagebreak();
|
|
||||||
v(2cm);
|
|
||||||
it
|
|
||||||
};
|
|
||||||
show raw: set text(font: mono_font);
|
|
||||||
show raw.where(block: true): it => {
|
|
||||||
block(it, fill: rgb("#eee"), inset: 1em)
|
|
||||||
};
|
|
||||||
set highlight(fill: faculty_color.lighten(90%));
|
|
||||||
set image(width: 80%);
|
|
||||||
|
|
||||||
// disclaimer
|
|
||||||
disclaimer(language, faculty_id, document_type, author);
|
|
||||||
|
|
||||||
// abstract
|
|
||||||
let abstract_content = (
|
|
||||||
"cs": abstract_cs,
|
|
||||||
"en": abstract_en,
|
|
||||||
);
|
|
||||||
let keywords = (
|
|
||||||
"cs": keywords_cs,
|
|
||||||
"en": keywords_en,
|
|
||||||
);
|
|
||||||
if language == "cs" {
|
|
||||||
abstract("cs", title, abstract_content, keywords);
|
|
||||||
abstract("en", title, abstract_content, keywords);
|
|
||||||
} else {
|
|
||||||
abstract(language, title, abstract_content, keywords);
|
|
||||||
}
|
|
||||||
|
|
||||||
let language = lang_id(language);
|
|
||||||
|
|
||||||
// toc
|
|
||||||
show outline.entry.where(level: 1): it => {
|
|
||||||
show repeat: none;
|
|
||||||
block(text(it, weight: "bold", size: 1.2em), above: 1.5em);
|
|
||||||
};
|
|
||||||
outline(title: ("Obsah", "Contents").at(language));
|
|
||||||
|
|
||||||
// abbreviation list
|
|
||||||
abbrlist(language);
|
|
||||||
|
|
||||||
// content
|
|
||||||
if flip_bonding {
|
|
||||||
pagebreak(to: "even", weak: true);
|
|
||||||
}
|
|
||||||
content
|
|
||||||
|
|
||||||
// bibliography
|
|
||||||
bibliography(citation_file, style: "./tul_citace.csl")
|
|
||||||
}
|
|
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="never" default-locale="en-US">
|
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="never" default-locale="en-US">
|
||||||
<info>
|
<info>
|
||||||
<title>ISO-690 (numeric, Czech)</title>
|
<title>TUL ISO-690</title>
|
||||||
<id>-----</id>
|
<id>-----</id>
|
||||||
<link href="" rel="self"/>
|
<link href="" rel="self"/>
|
||||||
<link href="" rel="documentation"/>
|
<link href="" rel="documentation"/>
|
||||||
@@ -264,7 +264,7 @@
|
|||||||
<group>
|
<group>
|
||||||
<text term="retrieved" suffix=" " text-case="capitalize-first"/>
|
<text term="retrieved" suffix=" " text-case="capitalize-first"/>
|
||||||
<text term="from" suffix=": "/>
|
<text term="from" suffix=": "/>
|
||||||
<text variable="URL"/>
|
<text variable="URL" suffix=" "/>
|
||||||
</group>
|
</group>
|
||||||
</if>
|
</if>
|
||||||
</choose>
|
</choose>
|
||||||
|
@@ -1,9 +1,198 @@
|
|||||||
|
#let join(a, b) = {
|
||||||
|
let res = ();
|
||||||
|
if type(a) == array {
|
||||||
|
for a in a {
|
||||||
|
res.push(a);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.push(a);
|
||||||
|
}
|
||||||
|
if type(b) == array {
|
||||||
|
for b in b {
|
||||||
|
res.push(b);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.push(b);
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
#let serialize_array(arr) = {
|
||||||
|
arr.map((v) => { "'" + str(v) + "'" }).join(", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assumes a valid type signature
|
||||||
|
#let decompose_type_signature(signature) = {
|
||||||
|
let parse_variants(raw) = {
|
||||||
|
let tmp = "";
|
||||||
|
let res = ();
|
||||||
|
for char in raw {
|
||||||
|
if char == ":" {
|
||||||
|
let trimmed = tmp.trim();
|
||||||
|
tmp = "";
|
||||||
|
if trimmed.len() != 0 {
|
||||||
|
res.push(trimmed);
|
||||||
|
}
|
||||||
|
res.push(":");
|
||||||
|
} else if char == "|" {
|
||||||
|
let trimmed = tmp.trim();
|
||||||
|
tmp = "";
|
||||||
|
if trimmed.len() != 0 {
|
||||||
|
res.push(trimmed);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmp += char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tmp.len() != 0 {
|
||||||
|
res.push(tmp.trim());
|
||||||
|
}
|
||||||
|
res
|
||||||
|
};
|
||||||
|
let parse_groups(raw) = {
|
||||||
|
let tmp = "";
|
||||||
|
let groups = ();
|
||||||
|
let found_nested = false;
|
||||||
|
let nested = 0;
|
||||||
|
for char in raw {
|
||||||
|
if nested == 2 {
|
||||||
|
found_nested = true;
|
||||||
|
}
|
||||||
|
if char == "[" {
|
||||||
|
if nested > 0 {
|
||||||
|
tmp += char;
|
||||||
|
} else {
|
||||||
|
groups = join(groups, parse_variants(tmp));
|
||||||
|
tmp = "";
|
||||||
|
found_nested = false;
|
||||||
|
}
|
||||||
|
nested += 1;
|
||||||
|
} else if char == "]" {
|
||||||
|
if nested > 1 {
|
||||||
|
tmp += char;
|
||||||
|
} else {
|
||||||
|
groups.push(if found_nested { parse_groups(tmp) } else { parse_variants(tmp) });
|
||||||
|
tmp = "";
|
||||||
|
found_nested = false;
|
||||||
|
}
|
||||||
|
nested -= 1;
|
||||||
|
} else {
|
||||||
|
tmp += char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tmp.len() != 0 {
|
||||||
|
groups = join(groups, parse_variants(tmp));
|
||||||
|
}
|
||||||
|
groups
|
||||||
|
};
|
||||||
|
let parse_nested(grouped) = {
|
||||||
|
if type(grouped) != array or grouped.len() == 0 {
|
||||||
|
return grouped;
|
||||||
|
}
|
||||||
|
let first = grouped.at(0);
|
||||||
|
if type(first) == str and first == "dictionary" {
|
||||||
|
let body = grouped.at(1);
|
||||||
|
let key = ();
|
||||||
|
for group in body {
|
||||||
|
if group == ":" {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
key.push(group);
|
||||||
|
}
|
||||||
|
let val = body.slice(key.len() + 1);
|
||||||
|
join((("dictionary", parse_nested(key), parse_nested(val)),), parse_nested(grouped.slice(2)))
|
||||||
|
} else if type(first) == str and first == "array" {
|
||||||
|
join((("array", parse_nested(grouped.at(1))),), parse_nested(grouped.slice(2)))
|
||||||
|
} else {
|
||||||
|
join(parse_nested(first), parse_nested(grouped.slice(1)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let grouped = parse_groups(signature);
|
||||||
|
parse_nested(grouped)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let serialize_type_signature(value) = {
|
||||||
|
let serialize_type(value, array_serializer, dict_serializer) = {
|
||||||
|
if type(value) == dictionary {
|
||||||
|
dict_serializer(value, array_serializer)
|
||||||
|
} else if type(value) == array {
|
||||||
|
array_serializer(value)
|
||||||
|
} else {
|
||||||
|
str(type(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let serialize_multi_type(values, array_serializer, dict_serializer) = {
|
||||||
|
let signatures = ().to-dict();
|
||||||
|
for value in values {
|
||||||
|
signatures.insert(serialize_type(value, array_serializer, dict_serializer), none);
|
||||||
|
}
|
||||||
|
signatures.keys().join(" | ")
|
||||||
|
}
|
||||||
|
|
||||||
|
let serialize_dict_type(dict, array_serializer) = {
|
||||||
|
(
|
||||||
|
"dictionary[" +
|
||||||
|
serialize_multi_type(dict.keys(), array_serializer, serialize_dict_type) +
|
||||||
|
" : " +
|
||||||
|
serialize_multi_type(dict.values(), array_serializer, serialize_dict_type) +
|
||||||
|
"]"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let serialize_array_type(arr) = {
|
||||||
|
"array[" + serialize_multi_type(arr, serialize_array_type, serialize_dict_type) + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
serialize_type(value, serialize_array_type, serialize_dict_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
#let is_subset_of(subset, of) = {
|
||||||
|
let has_value(value, target, matcher) = {
|
||||||
|
for target in target {
|
||||||
|
if matcher(value, target) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
};
|
||||||
|
let is_subset(subset, of, matcher) = {
|
||||||
|
for item in subset {
|
||||||
|
if not has_value(item, of, matcher) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
};
|
||||||
|
let matches(a, b) = {
|
||||||
|
if type(a) == array {
|
||||||
|
if a.at(0) != b.at(0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let a_type = a.at(0);
|
||||||
|
if a_type == "dictionary" {
|
||||||
|
is_subset(a.at(1), b.at(1), matches) and is_subset(a.at(2), b.at(2), matches)
|
||||||
|
} else if a_type == "array" {
|
||||||
|
is_subset(a.at(1), b.at(1), matches)
|
||||||
|
} else {
|
||||||
|
panic("invalid signature");
|
||||||
|
}
|
||||||
|
} else if type(a) != array and type(b) != array {
|
||||||
|
a == b
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
is_subset(subset, of, matches)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#let assert_in_arr(needle, arr, item_name) = {
|
#let assert_in_arr(needle, arr, item_name) = {
|
||||||
if str(needle) not in arr {
|
if str(needle) not in arr {
|
||||||
panic(
|
let panic_message = (
|
||||||
"unknown " + item_name + " '" + str(needle) +
|
"unknown " + item_name + " '" + str(needle) + "', expected one of: " + serialize_array(arr)
|
||||||
"', expected one of: " + arr.map((k) => { "'" + str(k) + "'" }).join(", ")
|
|
||||||
);
|
);
|
||||||
|
panic(panic_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,6 +200,77 @@
|
|||||||
assert_in_arr(needle, dict.keys(), item_name);
|
assert_in_arr(needle, dict.keys(), item_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#let assert_dict_has(needles, dict, item_name) = {
|
||||||
|
for needle in needles {
|
||||||
|
if not needle in dict {
|
||||||
|
let panic_message = item_name + " does not contain an entry for '" + needle + "'";
|
||||||
|
panic(panic_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let matches_type(value, expected_types) = {
|
||||||
|
return type(value) in expected_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
#let assert_type(value, expected_types, value_name) = {
|
||||||
|
if not matches_type(value, expected_types) {
|
||||||
|
let panic_message = (
|
||||||
|
"unexpected type for " + value_name + " '" + str(type(value)) + "', expected one of: " +
|
||||||
|
serialize_array(expected_types)
|
||||||
|
);
|
||||||
|
panic(panic_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let matches_array_type(arr, expected_item_types) = {
|
||||||
|
for item in arr {
|
||||||
|
if not matches_type(item, expected_item_types) { return false; }
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
#let assert_array_type(arr, expected_types, array_name) = {
|
||||||
|
assert_type(arr, (array), array_name);
|
||||||
|
for item in arr {
|
||||||
|
assert_type(item, expected_types, array_name + " item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let matches_dict_type(dict, expected_key_types, expected_value_types) = {
|
||||||
|
if type(dict) != dictionary {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (key, value) in dict.pairs() {
|
||||||
|
if not (matches_type(key, expected_key_types) and matches_type(value, expected_value_types)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
#let assert_dict_type(dict, expected_key_types, expected_value_types, dict_name) = {
|
||||||
|
assert_type(dict, (dictionary), dict_name);
|
||||||
|
for (key, value) in dict.items() {
|
||||||
|
assert_type(key, expected_key_types, dict_name + " key");
|
||||||
|
assert_type(value, expected_value_types, dict_name + " value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let assert_type_signature(value, expected_type_signature, value_name) = {
|
||||||
|
let type_signature = serialize_type_signature(value);
|
||||||
|
if not is_subset_of(
|
||||||
|
decompose_type_signature(type_signature),
|
||||||
|
decompose_type_signature(expected_type_signature)
|
||||||
|
) {
|
||||||
|
let panic_message = (
|
||||||
|
"unexpected " + value_name + " type '" + type_signature +
|
||||||
|
"' expected at least a subset of '" + expected_type_signature + "'"
|
||||||
|
);
|
||||||
|
panic(panic_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#let is_none(thing) = {
|
#let is_none(thing) = {
|
||||||
if type(thing) == type(none) {
|
if type(thing) == type(none) {
|
||||||
true
|
true
|
||||||
@@ -19,6 +279,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#let assert_not_none(thing, item_name) = {
|
||||||
|
if is_none(thing) {
|
||||||
|
let panic_message = "missing " + item_name;
|
||||||
|
panic(panic_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let ok_or(thing, fallback) = {
|
||||||
|
if is_none(thing) {
|
||||||
|
fallback
|
||||||
|
} else {
|
||||||
|
thing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#let has_all_none(arr) = {
|
#let has_all_none(arr) = {
|
||||||
for item in arr {
|
for item in arr {
|
||||||
if not is_none(item) {
|
if not is_none(item) {
|
||||||
@@ -27,3 +302,10 @@
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#let map_none(value, mapper) = {
|
||||||
|
if is_none(value) {
|
||||||
|
return none;
|
||||||
|
}
|
||||||
|
mapper(value)
|
||||||
|
}
|
||||||
|
@@ -0,0 +1,40 @@
|
|||||||
|
@article{Wang2025,
|
||||||
|
author = {Wang, Erming and Yu, Kaiwen and Cao, Jiqing and Wang, Minghui and Katsel, Pavel and Song, Won-min and Wang, Zhen and Li, Yuxin and Wang, Xusheng and Wang, Qian and Xu, Peng and Yu, Gefei and Zhu, Li and Geng, Jia and Habibi, Parnian and Qian, Lu and Tuck, Tony and Li, Aiqun and TCW, Julia and Roussos, Panos and Brennand, Kristen J. and Haroutunian, Vahram and Johnson, Erik C.B. and Seyfried, Nicholas T. and Levey, Allan I. and Bennett, David A. and Peng, Junmin and Cai, Dongming and Zhang, Bin},
|
||||||
|
title = {Multiscale proteomic modeling reveals protein networks driving Alzheimer’s disease pathogenesis},
|
||||||
|
journal = {Cell},
|
||||||
|
year = {2025},
|
||||||
|
volume = {},
|
||||||
|
number = {},
|
||||||
|
pages = {},
|
||||||
|
publisher = {Elsevier},
|
||||||
|
doi = {10.1016/j.cell.2025.08.038},
|
||||||
|
url = {https://doi.org/10.1016/j.cell.2025.08.038},
|
||||||
|
issn = {0092-8674}
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{csl,
|
||||||
|
title = {Citation Style Language},
|
||||||
|
year = {2025},
|
||||||
|
medium = {online},
|
||||||
|
accessed = {2025-06-10},
|
||||||
|
URL = {https://citationstyles.org/},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{linux,
|
||||||
|
journal = {Blog | Linux Foundation},
|
||||||
|
title = {Classic SysAdmin: Vim 101: A Beginner’s Guide to Vim},
|
||||||
|
year = {2025},
|
||||||
|
medium = {online},
|
||||||
|
accessed = {2025-06-10},
|
||||||
|
URL = {https://www.linuxfoundation.org/blog/blog/classic-sysadmin-vim-101-a-beginners-guide-to-vim},
|
||||||
|
}
|
||||||
|
|
||||||
|
@book{Satrapa2011,
|
||||||
|
author = {Pavel Satrapa},
|
||||||
|
title = {IPv6},
|
||||||
|
publisher = {Edice CZ.NIC},
|
||||||
|
year = {2011},
|
||||||
|
edition = {3. vydání},
|
||||||
|
ISBN = {978-80-904248-4-9},
|
||||||
|
URL = {https://www.bookport.cz/kniha/ipv6-treti-vydani-5999/},
|
||||||
|
}
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
// todo: add citations
|
@Wang2025
|
||||||
|
@csl
|
||||||
|
@linux
|
||||||
|
@Satrapa2011
|
||||||
|
|
||||||
#pagebreak(weak: true)
|
#set text(lang: "cs")
|
||||||
#bibliography("citations.bib", title: "Bibliography - CZ", style: "../template/tul_citace.csl")
|
#bibliography("citations.bib", title: "Bibliography - CZ", style: "../template/tul_citace.csl")
|
6
tests/citations_en.typ
Normal file
6
tests/citations_en.typ
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@Wang2025
|
||||||
|
@csl
|
||||||
|
@linux
|
||||||
|
@Satrapa2011
|
||||||
|
|
||||||
|
#bibliography("citations.bib", title: "Bibliography - EN", style: "iso-690-numeric")
|
Reference in New Issue
Block a user