8 Commits

16 changed files with 429 additions and 259 deletions

View File

@@ -21,8 +21,8 @@ PACKDIR := pack/tultemplate2
BUNDLEDIR := pack/bundle
TO_PACK := $(shell find template -type f) template/LICENSE
BUNDLE_TARGETS := $(TO_PACK:%=$(BUNDLEDIR)/%) $(BUNDLEDIR)/citations.bib $(BUNDLEDIR)/bp.typ \
$(BUNDLEDIR)/dp.typ $(BUNDLEDIR)/Makefile
BUNDLE_TARGETS := $(TO_PACK:%=$(BUNDLEDIR)/%) $(BUNDLEDIR)/citations.bib $(BUNDLEDIR)/bp_cs.typ \
$(BUNDLEDIR)/bp_en.typ $(BUNDLEDIR)/dp_cs.typ $(BUNDLEDIR)/Makefile
PACK_TARGETS := $(TO_PACK:%=$(PACKDIR)/%) $(PACKDIR)/documentation.typ \
$(PACKDIR)/documentation.pdf $(PACKDIR)/citations.bib
@@ -51,11 +51,7 @@ $(BUNDLEDIR)/citations.bib: citations.bib
@mkdir -p $(@D)
ln -f $< $@
$(BUNDLEDIR)/bp.typ: theses/bp.typ
@mkdir -p $(@D)
awk 'BEGIN{RS=""; ORS="\n\n"} NR>2{print}' $< | sed 's/\.\.\/template\//template\//' > $@
$(BUNDLEDIR)/dp.typ: theses/dp.typ
$(BUNDLEDIR)/%.typ: theses/%.typ
@mkdir -p $(@D)
awk 'BEGIN{RS=""; ORS="\n\n"} NR>2{print}' $< | sed 's/\.\.\/template\//template\//' > $@

View File

@@ -222,6 +222,19 @@ zrakovým postižením).
Tabulky se zobrazí na začátku dokumentu v seznamu (pokud to daný typ dokumentu vyžaduje).
== Poznámky pod čarou
Poznámky pod čarou jsou způsob sdělení dodatečných informácí, které pro čtenáře běžně nebudou velmi
podstatné. Mohou sloužit například k upřesnění informací. #footnote[Nebo k doplnění technikálií]
Poznámka pod čarou se vytvoří následovně:
```typst
#footnote[Moje poznámka]
```
Šablona automaticky vytvoří čáru s barvou vaší fakulty a pod vloží poznámky na dané straně.
== Citace
Šablona podporuje správu citací pomocí standardního BibTeX @bibtex souboru, stejně jako

View File

@@ -18,10 +18,11 @@
}
"(" + abbrs.pairs().map((v) => { v.at(0) + ":\"" + v.at(1) + "\"" }).join(",") + ")"
});
let target_label = label("abbr_" + abbreviation);
if type(text) != type(none) {
text + " (" + abbreviation + ")";
link(target_label, text + " (" + abbreviation + ")");
} else {
abbreviation;
link(target_label, abbreviation)
}
}

174
template/arguments.typ Normal file
View File

@@ -0,0 +1,174 @@
#import "utils.typ": assert_type_signature, is_none, map_none, deref
#let arguments_structure = (
document: (
visual_style: "string",
faculty: "string",
language: "string",
type: "string",
),
title_pages: "string | boolean | none",
title: "dictionary[string : string] | none",
author: (
name: "string | none",
pronouns: "string | none",
programme: "dictionary[string : string] | none",
specialization: "dictionary[string : string] | none",
year_of_study: "integer | none",
),
project: (
supervisor: "string | dictionary[string : string] | none",
consultant: "string | dictionary[string : string] | none",
),
abstract: (
content: "dictionary[string : string | content] | none",
keywords: "dictionary[string : array[string]] | none",
),
acknowledgement: "dictionary[string : string | content] | none",
assignment: "string | none",
citations: "string",
);
#let check_arguments(args) = {
let check_arguments_dict(structure, args, argument_path) = {
for (key, value) in structure.pairs() {
argument_path.push(str(key).replace("_", " "));
if not key in args {
panic("invalid arguments definition");
}
let arg = args.at(key);
if type(value) == dictionary {
check_arguments_dict(value, arg, argument_path);
} else if type(value) == str {
assert_type_signature(arg, value, argument_path.join(" "));
} else {
panic("invalid arguments definition");
}
let _ = argument_path.pop();
}
}
check_arguments_dict(arguments_structure, args, ());
}
#let get_arg_single(args, path) = {
let args = args;
for segment in path.split(".") {
if segment not in args {
panic("invalid argument query path: " + str(path));
}
args = args.at(segment);
}
args
}
#let get_arg(args, path) = {
if type(path) == array {
let res = ();
for path in path {
res.push(get_arg_single(args, path));
}
res
} else if type(path) == str {
get_arg_single(args, path)
} else {
panic("invalid argument path");
}
}
#let req_arg_single(args, path) = {
let arg = get_arg_single(args, path);
if is_none(arg) {
let panic_message = path.split(".").join(" ").replace("_", " ") + " is missing";
panic(panic_message);
}
arg
}
#let req_arg(args, path) = {
if type(path) == array {
let res = ();
for path in path {
res.push(req_arg_single(args, path));
}
res
} else if type(path) == str {
req_arg_single(args, path)
} else {
panic("invalid argument path");
}
}
#let map_arg_single(args, path, mapper) = {
let arg = get_arg(args, path);
map_none(arg, mapper)
}
#let map_arg(args, path, mapper) = {
if type(path) == array {
let res = ();
for path in path {
res.push(map_arg_single(args, path, mapper));
}
res
} else if type(path) == str {
map_arg_single(args, path, mapper)
} else {
panic("invalid argument path");
}
}
#let arguments(
document_info,
title_pages,
title,
author_info,
project_info,
abstract_info,
acknowledgement,
assignment,
citations,
) = {
(
document: document_info,
title_pages: title_pages,
title: title,
author: author_info,
project: project_info,
abstract: abstract_info,
acknowledgement: acknowledgement,
assignment: assignment,
citations: citations,
)
}
#let document_info(visual_style, faculty_abbreviation, language_abbreviation, document_type) = {
(
visual_style: visual_style,
faculty: faculty_abbreviation,
language: language_abbreviation,
type: document_type,
)
}
#let author_info(name, pronouns, programme, specialization, year_of_study) = {
(
name: name,
pronouns: pronouns,
programme: programme,
specialization: specialization,
year_of_study: year_of_study,
)
}
#let project_info(supervisor, consultant) = {
(supervisor: supervisor, consultant: consultant)
}
#let abstract_info(abstract, keywords) = {
(content: abstract, keywords: keywords)
}

View File

@@ -1,74 +1,19 @@
#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
#import "../arguments.typ": req_arg, get_arg
#import "../utils.typ": assert_dict_has, is_none
#import "common.typ": mainpage, assignment, external_title_pages
#import "thesis_base.typ": thesis_base
#let bp(
// general settings
faculty_id, faculty_color, language, assignment_document, citation_file,
// document info
title, author, author_pronouns, supervisor, consultant, study_programme, study_specialization,
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_specialization, "study specialization");
assert_dict_has((language,), study_specialization, "study specialization");
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");
}
#let bp(args, content) = {
let language = req_arg(args, "document.language");
let programme = req_arg(args, "author.programme");
assert_dict_has((language,), programme, "study programme");
let specialization = req_arg(args, "author.specialization");
assert_dict_has((language,), specialization, "study specialization");
if language == "cs" {
assert_not_none(author_pronouns, "author gender");
let _ = req_arg(args, "author.pronouns");
}
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_specialization, year_of_study,
);
assignment(language, assignment_document);
default_styling(false, faculty_color, {
disclaimer(language, faculty_id, "bp", author, author_pronouns);
if language == "cs" {
abstract("cs", title, abstract_content, keywords);
abstract("en", title, abstract_content, keywords);
}
if language == "en" {
abstract("en", title, abstract_content, keywords);
abstract("cs", 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);
});
mainpage(args);
assignment(args);
thesis_base(args, content);
}

View File

@@ -1,53 +1,43 @@
// 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
#import "../utils.typ": assert_in_dict, assert_in_arr, map_none, assert_dict_has, is_none
#import "../arguments.typ": req_arg, map_arg, get_arg
#import "common.typ": default_styling, external_title_pages
// thesis types
#import "bp.typ": bp
#import "dp.typ": dp
#import "other.typ": other
#import "thesis_base.typ": thesis_base
#let template_classic(
// general settings
language, faculty_id, document_type, citation_file, assignment_document,
#let template_classic(args, content) = {
let language = req_arg(args, "document.language");
// document info
title, author, author_pronouns, supervisor, consultant, study_programme, study_specialization,
year_of_study, abstract, acknowledgement, keywords,
// content
content,
) = {
// argument pre-checking
let document_types = (
"bp": bp,
"dp": dp,
"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_specialization, (v) => assert_dict_has((language,), v, "study specialization"));
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_specialization,
year_of_study,
abstract,
acknowledgement,
keywords,
content,
assert_in_dict(req_arg(args, "document.type"), document_types, "document type");
map_arg(args, "title", (v) => assert_dict_has((language,), v, "title"));
map_arg(args, "author.programme", (v) => assert_dict_has((language,), v, "study programme"));
map_arg(
args, "author.specialization", (v) => assert_dict_has((language,), v, "study specialization")
);
map_arg(
args, "acknowledgement", (v) => assert_dict_has((language,), v, "acknowledgement content")
);
args.assignment = map_arg(args, "assignment", (v) => "../../" + v);
args.citations = map_arg(args, "citations", (v) => "../../" + v);
args.title_pages = map_arg(args, "title_pages", (v) => "../../" + v);
if not is_none(get_arg(args, "title_pages")) and not req_arg(args, "document.type") == "other" {
external_title_pages(req_arg(args, "title_pages"));
thesis_base(args, content);
} else {
document_types.at(req_arg(args, "document.type"))(args, content);
}
}

View File

@@ -1,6 +1,7 @@
#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
#import "../lang.typ": get_lang_item, set_czech_nonbreakable_terms
#import "../utils.typ": is_none, assert_dict_has, has_all_none, map_none
#import "../arguments.typ": req_arg, get_arg
#let base_font = "Inter";
#let mono_font = "Noto Sans Mono";
@@ -15,7 +16,7 @@
// TYPST ELEMENT STYLING
#let default_styling(flip_bonding, faculty_color, content) = {
#let default_styling(flip_bonding, faculty_color, content, language) = {
// page
set page(
margin: if flip_bonding {
@@ -37,6 +38,9 @@
// text
set text(font: serif_font);
set par(justify: true, first-line-indent: 0.63cm);
if language == "cs" {
content = set_czech_nonbreakable_terms(content);
}
// figures
let figure_numbering(realcount, c) = {
@@ -142,7 +146,7 @@
let gutter = .7em;
// document type
if type(document_type) != type(none) {
if document_type != "other" {
text(get_lang_item(language, document_type), weight: "bold", font: base_font);
v(0em);
}
@@ -193,24 +197,32 @@
// MAINPAGE
#let mainpage(
faculty_id,
language,
document_type,
title, author, supervisor, consultant, study_programme, study_specialization, year_of_study,
) = {
import "../utils.typ": has_all_none, map_none
let nonetype = type(none);
#let mainpage(args) = {
let (
language, document_type, faculty,
title, author, supervisor, consultant, study_programme, study_specialization, year_of_study,
) = get_arg(args, (
"document.language",
"document.type",
"document.faculty",
"title",
"author.name",
"project.supervisor",
"project.consultant",
"author.programme",
"author.specialization",
"author.year_of_study",
));
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);
header(faculty, language);
align({
info(
faculty_id, language, document_type, map_none(title, (v) => v.at(language)),
faculty, language, document_type, map_none(title, (v) => v.at(language)),
author, supervisor, consultant, map_none(study_programme, (v) => v.at(language)),
map_none(study_specialization, (v) => v.at(language)), year_of_study,
);
@@ -220,13 +232,21 @@
}, margin: 2cm);
}
// _ EMBEDDED
#let pdfembed(path) = {
import "@preview/muchpdf:0.1.1": muchpdf
set page(margin: 0em);
muchpdf(read(path, encoding: none));
}
// ASSIGNMENT PAGE
#let assignment(language, document) = {
if type(document) == type(none) {
#let assignment(args) = {
if is_none(get_arg(args, "assignment")) {
page(
place(center + horizon, text(
get_lang_item(language, "place_assignment"),
get_lang_item(req_arg(args, "document.language"), "place_assignment"),
fill: red,
size: 3em,
font: base_font,
@@ -237,15 +257,26 @@
);
return;
}
import "@preview/muchpdf:0.1.1": muchpdf
set page(margin: 0em);
muchpdf(read(document, encoding: none));
pdfembed(req_arg(args, "assignment"))
}
// EXTERNAL TITLE PAGES
#let external_title_pages(path) = {
pdfembed(path);
}
// DISCLAIMER PAGE
#let disclaimer(language, faculty_id, disclaimer_type, author, author_pronouns) = {
#let disclaimer(args) = {
import "../lang.typ": disclaimer
let (language, faculty, disclaimer_type, author, author_pronouns) = req_arg(args, (
"document.language",
"document.faculty",
"document.type",
"author.name",
"author.pronouns",
));
heading(get_lang_item(language, "disclaimer"), numbering: none, outlined: false);
par(
text(disclaimer(language, disclaimer_type, author_pronouns))
@@ -263,7 +294,9 @@
// ACKNOWLEDGEMENT PAGE
#let acknowledgement(language, author, content) = {
#let acknowledgement(args) = {
let content = get_arg(args, "acknowledgement");
let (language, author) = req_arg(args, ("document.language", "author.name"));
if is_none(content) {
return;
}
@@ -275,8 +308,10 @@
// ABSTRACT
#let abstract(language, title, content, keywords) = {
heading(text(title.at(language), font: base_font), numbering: none, outlined: false);
#let abstract(language, args) = {
heading(
text(req_arg(args, "title").at(language), font: base_font), numbering: none, outlined: false
);
v(2em);
heading(
level: 2,
@@ -284,7 +319,8 @@
numbering: none,
outlined: false,
);
text(content.at(language));
text(req_arg(args, "abstract.content").at(language));
let keywords = get_arg(args, "abstract.keywords");
if not is_none(keywords) and type(keywords.at(language)) != type(none) {
linebreak();
linebreak();
@@ -364,7 +400,12 @@
gutter: 1em,
..abbrs.pairs().map((a) => {
(
align(left, block(text(a.at(0), weight: "bold"), width: max_abbr_width + 1em)),
align(left, {
[
#block(text(a.at(0), weight: "bold"), width: max_abbr_width + 1em)
#label("abbr_" + a.at(0))
]
}),
text(a.at(1))
)
}).flatten()
@@ -384,7 +425,8 @@
// BIBLIOGRAPHY
#let bibliogr(language, citations_file) = {
#let bibliogr(args) = {
let (language, citations_file) = req_arg(args, ("document.language", "citations"));
if language == "cs" {
bibliography(
citations_file, style: "../tul_citace.csl", title: get_lang_item(language, "bibliography"),

View File

@@ -1,67 +1,20 @@
#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, map_none
#import "../arguments.typ": req_arg, get_arg, map_arg
#import "../utils.typ": assert_dict_has, is_none
#import "common.typ": mainpage, assignment, external_title_pages
#import "thesis_base.typ": thesis_base
#let dp(
// general settings
faculty_id, faculty_color, language, assignment_document, citation_file,
// document info
title, author, author_pronouns, supervisor, consultant, study_programme, study_specialization,
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");
map_none(study_specialization, (v) => assert_dict_has((language,), v, "study specialization"));
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");
}
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, "dp", title, author, supervisor, consultant, study_programme,
study_specialization, year_of_study,
);
assignment(language, assignment_document);
default_styling(false, faculty_color, {
disclaimer(language, faculty_id, "dp", 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);
#let dp(args, content) = {
let language = req_arg(args, "document.language");
let programme = req_arg(args, "author.programme");
assert_dict_has((language,), programme, "study programme");
map_arg(args, "author.specialization", (v) => {
assert_dict_has((language,), v, "study specialization");
});
if language == "cs" {
let _ = req_arg(args, "author.pronouns");
}
mainpage(args);
assignment(args);
thesis_base(args, content);
}

View File

@@ -13,32 +13,22 @@
)
#import "../attachments.typ": attachment_list
#import "../utils.typ": is_none, assert_not_none, assert_dict_has, assert_in_arr
#import "../arguments.typ": req_arg
#import "../theme.typ": faculty_color
#let other(
// general settings
faculty_id, faculty_color, language, assignment_document, citation_file,
// document info
title, author, _, supervisor, consultant, study_programme, study_specialization, year_of_study,
abstract_content, _, keywords,
content
) = {
assert_not_none(title, "title");
#let other(args, content) = {
let (language, title) = req_arg(args, ("document.language", "title"));
assert_dict_has((language,), title, "title");
mainpage(
faculty_id, language, none, title, author, supervisor, consultant, study_programme,
study_specialization, year_of_study,
);
default_styling(true, faculty_color, {
mainpage(args);
default_styling(true, faculty_color(req_arg(args, "document.faculty")), {
toc(language);
tablelist(language);
imagelist(language);
abbrlist(language);
pagebreak(to: "even", weak: true);
content;
bibliogr(language, citation_file);
bibliogr(args);
attachment_list(language);
});
}, language);
}

View File

@@ -0,0 +1,40 @@
#import "../theme.typ": faculty_color
#import "../arguments.typ": get_arg, req_arg
#import "../utils.typ": is_none, assert_dict_has
#import "common.typ": (
default_styling,
disclaimer,
abstract,
acknowledgement,
toc,
tablelist,
imagelist,
abbrlist,
bibliogr,
)
#import "../attachments.typ": attachment_list
#let thesis_base(args, content) = {
let force_langs = ("cs", "en");
assert_dict_has(force_langs, req_arg(args, "title"), "title");
assert_dict_has(force_langs, req_arg(args, "abstract.content"), "abstract");
assert_dict_has(force_langs, req_arg(args, "abstract.keywords"), "keywords");
let language = req_arg(args, "document.language");
default_styling(false, faculty_color(req_arg(args, "document.faculty")), {
if is_none(get_arg(args, "title_pages")) {
disclaimer(args);
}
abstract("cs", args);
abstract("en", args);
acknowledgement(args);
toc(language);
tablelist(language);
imagelist(language);
abbrlist(language);
pagebreak(weak: true);
content;
bibliogr(args);
attachment_list(language);
}, language);
}

View File

@@ -45,6 +45,34 @@
});
}
#let set_czech_nonbreakable_terms(content) = {
let space_after = (
"[kosuvzai]",
"(tj|tzv|tzn)\.",
);
show regex("\b((?i)(" + space_after.join("|") + ") )+\w+\b"): match => {
box(match);
}
let nonbreaking_abbreviations = (
"a. s",
"s. r. o",
"v. o. s",
"k. s",
"n. p",
"p. o",
"č. ([pe]|ev)",
"ev?. č",
);
show regex(
"(?i)\b(" + nonbreaking_abbreviations.map((v) => { v.replace(".", "\\.") }).join("|") + ")\."
): match => {
box(match);
}
content
}
#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);

View File

@@ -26,6 +26,7 @@
// - faculty (str): Factulty abbreviation. One of "fs", "ft", "fp", "ef", "fua", "fm", "fzs", "cxi".
// - lang (str): Language code. This can be "cs" or "en".
// - document (str): Type of document. This can be "bp" or "other".
// - title_pages (str): The title pages exported from STAG (supported for some document types)
// - title (dictionary): The title of the document.
// - 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.
@@ -45,6 +46,7 @@
style: "classic", faculty: "tul", lang: "cs", document: "other",
// document info
title_pages: none,
title: none, keywords: none, abstract: none, acknowledgement: none, author: none,
author_pronouns: none, supervisor: none, consultant: none, programme: none,
specialization: none, year_of_study: none,
@@ -55,38 +57,30 @@
// content
content,
) = {
import "utils.typ": assert_in_dict, assert_type_signature
import "arguments.typ": (
arguments,
document_info,
author_info,
project_info,
abstract_info,
check_arguments,
req_arg,
)
// 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"
let args = arguments(
document_info(style, faculty, lang, document),
title_pages,
title,
author_info(author, author_pronouns, programme, specialization, year_of_study),
project_info(supervisor, consultant),
abstract_info(abstract, keywords),
acknowledgement,
assignment,
citations,
);
assert_type_signature(
acknowledgement, "dictionary[string : string | content] | 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(
specialization, "dictionary[string : string] | none", "study specialization 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");
check_arguments(args);
import "utils.typ": assert_in_dict, assert_type_signature
// templates
import "classic/classic.typ": template_classic
@@ -101,11 +95,7 @@
set text(lang: lang);
// template call
templates.at(style)(
lang, faculty, document, citations, assignment,
title, author, author_pronouns, supervisor, consultant,
programme, specialization, year_of_study, abstract, acknowledgement, keywords, content
);
templates.at(style)(args, content);
import "prototyping.typ": assert_release_ready
assert_release_ready();

View File

@@ -297,7 +297,7 @@
<sort>
<key variable="citation-number"/>
</sort>
<layout prefix="(" suffix=")" delimiter=", ">
<layout prefix="[" suffix="]" delimiter=", ">
<group delimiter=", ">
<text variable="citation-number"/>
<group>
@@ -312,7 +312,7 @@
<key variable="citation-number"/>
</sort>
<layout>
<text variable="citation-number" display="left-margin" suffix=". "/>
<text variable="citation-number" display="left-margin" prefix="[" suffix="] "/>
<choose>
<if type="book map" match="any">
<group display="right-inline">

View File

@@ -309,3 +309,11 @@
}
mapper(value)
}
#let deref(arr) = {
if arr.len() == 0 {
arr.at(0)
} else {
arr
}
}