improve title page layout and extract natural language to separate file

This commit is contained in:
2025-09-26 08:25:12 +02:00
parent 1faa0c6c93
commit 5347a16cf1
6 changed files with 118 additions and 38 deletions

25
template/lang.json Normal file
View File

@@ -0,0 +1,25 @@
{
"cs": {
"author": "Autor",
"supervisor": "Vedoucí práce",
"study_programme": "Studijní program",
"bp": "Bakalářská práce",
"dp": "Diplomová práce",
"dis": "Disertační práce",
"city": "Liberec"
},
"en": {
"author": "Autor",
"supervisor": "Supervisor",
"study_programme": "Study programme",
"bp": "Bachelor thesis",
"dp": "Diploma thesis",
"dis": "Dissertation thesis",
"city": "Liberec"
}
}

View File

@@ -9,3 +9,14 @@
assert_in_dict(lang_abbr, lang_ids, "language abbreviation"); assert_in_dict(lang_abbr, lang_ids, "language abbreviation");
return lang_ids.at(lang_abbr); return lang_ids.at(lang_abbr);
}; };
// Typst will usually cache this - so we don't have to re-read the file each time
#let fetch_lang_items() = {
return json("lang.json");
}
#let get_lang_item(lang_abbr, item_name) = {
assert_in_dict(lang_abbr, lang_ids, "language abbreviation");
let lang_items = fetch_lang_items();
return lang_items.at(lang_abbr).at(item_name);
}

View File

@@ -19,7 +19,7 @@
// ) // )
// ``` // ```
// //
// - style (str): Visual style to use. This can be "latex". // - 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", "dp", "ds".
@@ -32,7 +32,7 @@
// //
//-> none //-> none
#let tultemplate2( #let tultemplate2(
style: "latex", style: "classic",
faculty: "tul", faculty: "tul",
lang: "cs", lang: "cs",
document: none, document: none,
@@ -40,10 +40,10 @@
citations: "citations.bib", citations: "citations.bib",
content, content,
) = { ) = {
import "template_latex.typ": template_latex import "template_classic.typ": template_classic
import "utils.typ": assert_in_dict import "utils.typ": assert_in_dict
let templates = ( let templates = (
latex: template_latex, classic: template_classic,
); );
assert_in_dict(style, templates, "template name"); assert_in_dict(style, templates, "template name");

View File

@@ -1,15 +1,17 @@
#import "theme.typ": faculty_logotype, tul_logomark, faculty_color #import "theme.typ": faculty_logotype, tul_logomark, faculty_color
#import "lang.typ": lang_id #import "lang.typ": lang_id, get_lang_item
#import "utils.typ": assert_in_dict #import "utils.typ": assert_in_dict, assert_in_arr
#let base_font = "Inter"; #let base_font = "Inter";
#let mono_font = "Noto Sans Mono"; #let mono_font = "Noto Sans Mono";
#let serif_font = "Merriweather";
#let tul_logomark_size = 6.5em;
#let classic_header(faculty_id, language) = { #let classic_header(faculty_id, language) = {
let logotype = faculty_logotype(faculty_id, language); let logotype = faculty_logotype(faculty_id, language);
grid( grid(
block(logotype, width: 100%), block(logotype, width: 100%),
block(align(right, block(tul_logomark(faculty_id), height: 5em))), block(align(right, block(tul_logomark(faculty_id), height: tul_logomark_size))),
columns: 2 columns: 2
); );
} }
@@ -20,17 +22,14 @@
document_type, document_type,
title, author, supervisor, study_programme, title, author, supervisor, study_programme,
) = { ) = {
let lang_id = lang_id(language); let info_name_value_padding = 5em;
let info_name_min_width = 10em;
// document type // document type
if type(document_type) != type(none) { if type(document_type) != type(none) {
let document_types = ( let document_types = ("bp", "dp", "ds");
bp: ("Bakalářská práce", "Bachelor thesis"), assert_in_arr(document_type, document_types, "document type abbreviation");
dp: ("Diplomová práce", "Diploma thesis"), text(get_lang_item(language, document_type), weight: "bold", font: base_font);
ds: ("Disertační práce", "Dissertation thesis"),
);
assert_in_dict(document_type, document_types, "document type abbreviation");
text(document_types.at(document_type).at(lang_id), weight: "bold", font: base_font);
v(0em); v(0em);
} }
@@ -44,34 +43,62 @@
// other info // other info
// [field_name, field_value, bold] // [field_name, field_value, bold]
let info_fields = ( let info_fields = (
(("Studijní program", "Study programme"), study_programme, false), ("study_programme", study_programme, false),
(("Autor", "Author"), author, true), ("author", author, true),
(("Vedoucí práce", "Supervisor"), supervisor, false), ("supervisor", supervisor, false),
); )
context { context {
let max_field_name_width = calc.max(..info_fields.map((v) => { let max_field_name_width = calc.max(..info_fields.map((v) => {
if type(v.at(1)) == type(none) { if type(v.at(1)) == type(none) {
0pt 0pt
} else { } else {
measure(v.at(0).at(lang_id) + ":").width measure(get_lang_item(language, v.at(0)) + ":").width
} }
})); }), info_name_min_width.to-absolute());
grid( grid(
columns: 2, columns: 2,
rows: (auto, 1.2em), rows: (auto, 1.2em),
..info_fields.filter((v) => { type(v.at(1)) != type(none) }).map((v) => { ..info_fields.filter((v) => { type(v.at(1)) != type(none) }).map((v) => {
( (
block( block(
text(v.at(0).at(lang_id) + ":", style: "italic", font: base_font), text(get_lang_item(language, v.at(0)) + ":", style: "italic", font: base_font),
width: max_field_name_width + 5em, width: max_field_name_width + info_name_value_padding,
), ),
text(v.at(1), font: base_font, weight: if v.at(2) { "bold" } else { "regular" }) text(v.at(1), font: base_font, weight: if v.at(2) { "bold" } else { "regular" })
) )
}).flatten() }).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, author, supervisor, study_programme
);
v(5em);
}, bottom);
}
}, margin: 2cm);
}
#let abbrlist(language) = { #let abbrlist(language) = {
import "abbreviations.typ": abbrlist import "abbreviations.typ": abbrlist
context { context {
@@ -90,7 +117,7 @@
} }
} }
#let template_latex( #let template_classic(
faculty_id, faculty_id,
language, language,
document_type, document_type,
@@ -98,14 +125,8 @@
citation_file, citation_file,
content, content,
) = { ) = {
// intro page // main page
page({ classic_mainpage(faculty_id, language, document_type, title, author, supervisor, study_programme);
classic_header(faculty_id, language);
align({
classic_info(faculty_id, language, document_type, title, author, supervisor, study_programme);
v(5em);
}, bottom);
}, margin: 2cm);
// styling // styling
let faculty_color = faculty_color(faculty_id); let faculty_color = faculty_color(faculty_id);
@@ -117,6 +138,7 @@
align(str(page), if calc.rem(page, 2) == 0 { right } else { left }) align(str(page), if calc.rem(page, 2) == 0 { right } else { left })
} }
}); });
set text(font: serif_font);
show heading: it => { show heading: it => {
set par(justify: false); set par(justify: false);
block( block(
@@ -134,6 +156,7 @@
show raw.where(block: true): it => { show raw.where(block: true): it => {
block(it, fill: rgb("#eee"), inset: 1em) block(it, fill: rgb("#eee"), inset: 1em)
}; };
set highlight(fill: faculty_color.lighten(90%));
set image(width: 80%); set image(width: 80%);
let language = lang_id(language); let language = lang_id(language);

View File

@@ -46,8 +46,8 @@
fua: ( fua: (
cmyk(96%, 2%, 80%, 47%), cmyk(96%, 2%, 80%, 47%),
( (
"FUA\nTUL&", "FAKULTA UMĚNÍ A ARCHITEKTURY TUL&",
"FAA\nTUL&", "FACULTY OF ARTS AND ARCHITECTURE TUL&",
), ),
), ),

View File

@@ -1,8 +1,29 @@
#let assert_in_dict(needle, dict, item_name) = { #let assert_in_arr(needle, arr, item_name) = {
if str(needle) not in dict { if str(needle) not in arr {
panic( panic(
"unknown " + item_name + " '" + str(needle) + "unknown " + item_name + " '" + str(needle) +
"', expected one of: " + dict.keys().map((k) => { "'" + str(k) + "'" }).join(", ") "', expected one of: " + arr.map((k) => { "'" + str(k) + "'" }).join(", ")
); );
} }
} }
#let assert_in_dict(needle, dict, item_name) = {
assert_in_arr(needle, dict.keys(), item_name);
}
#let is_none(thing) = {
if type(thing) == type(none) {
true
} else {
false
}
}
#let has_all_none(arr) = {
for item in arr {
if not is_none(item) {
return false;
}
}
true
}