commit 5407732395f0e9454bb95703da783c5242493f94 Author: Ondřej Mekina Date: Tue Sep 23 14:52:20 2025 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2bd18fa --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/*.pdf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3f94b68 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +.PHONY: example +example: example.pdf + +%.pdf: %.typ + typst compile --font-path template/fonts $< diff --git a/example.typ b/example.typ new file mode 100644 index 0000000..8d86086 --- /dev/null +++ b/example.typ @@ -0,0 +1,7 @@ +#import "template/template.typ": tultemplate + +#tultemplate( + "classic", "fm", "cs", + title: "Návod na použití Typst TUL šablony", + author: "Ondřej Mekina", +) diff --git a/template/assets/tul_logo.svg b/template/assets/tul_logo.svg new file mode 100644 index 0000000..2331857 --- /dev/null +++ b/template/assets/tul_logo.svg @@ -0,0 +1 @@ + diff --git a/template/fonts/cabin/Cabin-Bold.ttf b/template/fonts/cabin/Cabin-Bold.ttf new file mode 100644 index 0000000..212cbf0 Binary files /dev/null and b/template/fonts/cabin/Cabin-Bold.ttf differ diff --git a/template/fonts/cabin/Cabin-Italic.ttf b/template/fonts/cabin/Cabin-Italic.ttf new file mode 100644 index 0000000..1c4223f Binary files /dev/null and b/template/fonts/cabin/Cabin-Italic.ttf differ diff --git a/template/fonts/cabin/Cabin-Regular.ttf b/template/fonts/cabin/Cabin-Regular.ttf new file mode 100644 index 0000000..b56dba9 Binary files /dev/null and b/template/fonts/cabin/Cabin-Regular.ttf differ diff --git a/template/fonts/cabin_license.txt b/template/fonts/cabin_license.txt new file mode 100644 index 0000000..a1023c0 --- /dev/null +++ b/template/fonts/cabin_license.txt @@ -0,0 +1,93 @@ +Copyright 2018 The Cabin Project Authors (https://github.com/impallari/Cabin.git) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/template/fonts/tul_mono_remastered.ttf b/template/fonts/tul_mono_remastered.ttf new file mode 100644 index 0000000..6b285a8 Binary files /dev/null and b/template/fonts/tul_mono_remastered.ttf differ diff --git a/template/lang.typ b/template/lang.typ new file mode 100644 index 0000000..1ceec6d --- /dev/null +++ b/template/lang.typ @@ -0,0 +1,11 @@ +#import "utils.typ": assert_in_dict + +#let lang_ids = ( + cs: 0, + en: 1, +); + +#let lang_id(lang_abbr) = { + assert_in_dict(lang_abbr, lang_ids, "language abbreviation"); + return lang_ids.at(lang_abbr); +}; diff --git a/template/template.typ b/template/template.typ new file mode 100644 index 0000000..a53297c --- /dev/null +++ b/template/template.typ @@ -0,0 +1,20 @@ +#import "template_classic.typ": template_classic +#import "utils.typ": assert_in_dict + +#let templates = ( + classic: template_classic, +); + +#let tultemplate( + template_id, + faculty_abbreviation, + language, + document_type: none, + title: none, author: none, supervisor: none, study_programme: none, +) = { + assert_in_dict(template_id, templates, "template name"); + templates.at(template_id)( + faculty_abbreviation, language, document_type, + title, author, supervisor, study_programme + ); +} diff --git a/template/template_classic.typ b/template/template_classic.typ new file mode 100644 index 0000000..ce1e7a2 --- /dev/null +++ b/template/template_classic.typ @@ -0,0 +1,87 @@ +#import "theme.typ": faculty_logotype, tul_logomark, faculty_color +#import "lang.typ": lang_id +#import "utils.typ": assert_in_dict + +#let base_font = "Cabin"; + +#let classic_header(faculty_id, language) = { + let logotype = faculty_logotype(faculty_id, language); + grid( + logotype, + block(align(right, block(tul_logomark(faculty_id), height: 5em)), width: 100%), + columns: 2 + ); +} + +#let classic_info( + faculty_id, + language, + document_type, + title, author, supervisor, study_programme, +) = { + let lang_id = lang_id(language); + + // document type + if type(document_type) != type(none) { + let document_types = ( + bp: ("Bakalářská práce", "Bachelor thesis"), + dp: ("Diplomová práce", "Diploma thesis"), + 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); + } + + // 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 = ( + (("Studijní program", "Study programme"), study_programme, false), + (("Autor", "Author"), author, true), + (("Vedoucí práce", "Vedoucí práce"), supervisor, false), + ); + context { + let max_field_name_width = calc.max(..info_fields.map((v) => { + if type(v.at(1)) == type(none) { + 0pt + } else { + measure(v.at(0).at(lang_id) + ":").width + } + })); + grid( + columns: 2, + rows: (auto, 1.2em), + ..info_fields.filter((v) => { type(v.at(1)) != type(none) }).map((v) => { + ( + block( + text(v.at(0).at(lang_id) + ":", style: "italic", font: base_font), + width: max_field_name_width + 5em, + ), + text(v.at(1), font: base_font, weight: if v.at(2) { "bold" } else { "regular" }) + ) + }).flatten() + ); + } +} + +#let template_classic( + faculty_id, + language, + document_type, + title, author, supervisor, study_programme +) = { + page({ + classic_header(faculty_id, language); + align({ + classic_info(faculty_id, language, document_type, title, author, supervisor, study_programme); + v(5em); + }, bottom); + }, margin: 2cm); +} diff --git a/template/theme.typ b/template/theme.typ new file mode 100644 index 0000000..e58337d --- /dev/null +++ b/template/theme.typ @@ -0,0 +1,93 @@ +#import "lang.typ": lang_id +#import "utils.typ": assert_in_dict + +#let faculty_themes = ( + + fs: ( + rgb("#000000"), + ( + "FAKULTA STROJNÍ TUL&", + "FACULTY OF MECHANICAL ENGINEERING TUL&" + ), + ), + + ft: ( + rgb("#924c14"), + ( + "FAKULTA TEXTILNÍ TUL&", + "FACULTY OF TEXTILE ENGINEERING TUL&", + ), + ), + + fp: ( + rgb("#3c84e1"), + ( + "FAKULTA\nPŘÍRODOVĚDNĚ-HUMANITNÍ\nA PEDAGOGICKÁ TUL&", + "FACULTY OF SCIENCE,\nHUMANITIES AND\nEDUCATION TUL&", + ), + ), + + ef: ( + rgb("#65a812"), + ( + "EKONOMICKÁ FAKULTA TUL&", + "FACULTY OF ECONOMICS TUL&", + ), + ), + + fua: ( + rgb("#006443"), + ( + "FUA\nTUL&", + "FAA\nTUL&", + ), + ), + + fm: ( + rgb("#ea7603"), + ( + "FAKULTA MECHATRONIKY,\nINFORMATIKY A MEZIOBOROVÝCH\nSTUDIÍ TUL&", + "FACULTY OF MECHATRONICS,\nINFORMATICS AND\nINTERDISCIPLINARY STUDIES TUL&", + ), + ), + + fzs: ( + rgb("#00b0be"), + ( + "FAKULTA ZDRAVOTNICKÝCH STUDIÍ TUL&", + "FACULTY OF HEALTH STUDIES TUL&", + ), + ), + +); + +#let faculty_theme(faculty_id) = { + assert_in_dict(faculty_id, faculty_themes, "faculty abbreviation"); + return faculty_themes.at(faculty_id) +} + +#let faculty_color(faculty_id) = { + let theme = faculty_theme(faculty_id); + let theme_color = theme.at(0); + assert(type(theme_color) == color); + return theme_color; +} + +#let faculty_logotype_text(faculty_id, lang) = { + let theme = faculty_theme(faculty_id); + let logotype_text = theme.at(1).at(lang_id(lang)); + assert(type(logotype_text) == str); + return logotype_text; +} + +#let faculty_logotype(faculty_id, lang) = { + let theme_color = faculty_color(faculty_id); + let logotype_text = faculty_logotype_text(faculty_id, lang); + text(logotype_text, font: "TUL Mono", theme_color, weight: "black"); +} + +#let tul_logomark(faculty_id) = { + let theme_color = faculty_color(faculty_id); + let image_raw = bytes(read("./assets/tul_logo.svg").replace("black", theme_color.to-hex())); + image(image_raw, fit: "contain") +} diff --git a/template/utils.typ b/template/utils.typ new file mode 100644 index 0000000..cb5f068 --- /dev/null +++ b/template/utils.typ @@ -0,0 +1,8 @@ +#let assert_in_dict(needle, dict, item_name) = { + if str(needle) not in dict { + panic( + "unknown " + item_name + " '" + str(needle) + + "', expected one of: " + dict.keys().map((k) => { "'" + str(k) + "'" }).join(", ") + ); + } +}