commit cd80eedd54d0b9c3610076e7bf5f0c88bd5a0c26 Author: C0ffeeCode Date: Wed Dec 13 17:58:37 2023 +0100 initial version of template diff --git a/README.md b/README.md new file mode 100644 index 0000000..37afe77 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ + +# Typst template for faculty Technik at DHBW + +As an example and guide how to use this template, +check out [this PDF document](./Template-Example-guide.pdf). + +As you can see, it is obviously in english, +but feel free to translate it ;). + +This is a adapted version of a template by [@satoqz](https://github.com/satoqz/). diff --git a/Template-Example-guide.pdf b/Template-Example-guide.pdf new file mode 100644 index 0000000..0cc7b64 Binary files /dev/null and b/Template-Example-guide.pdf differ diff --git a/abstract.typ b/abstract.typ new file mode 100644 index 0000000..2eb8adc --- /dev/null +++ b/abstract.typ @@ -0,0 +1,2 @@ + +This is quite abstract... diff --git a/acronyms.yml b/acronyms.yml new file mode 100644 index 0000000..24305ed --- /dev/null +++ b/acronyms.yml @@ -0,0 +1,2 @@ +HPE: Hewlett Packard Enterprise +JSON: JavaScript Object Notation diff --git a/assets/dhbw.png b/assets/dhbw.png new file mode 100755 index 0000000..a8fdba3 Binary files /dev/null and b/assets/dhbw.png differ diff --git a/assets/hpe.png b/assets/hpe.png new file mode 100755 index 0000000..4f4f3c3 Binary files /dev/null and b/assets/hpe.png differ diff --git a/assets/hpe.svg b/assets/hpe.svg new file mode 100644 index 0000000..2445ada --- /dev/null +++ b/assets/hpe.svg @@ -0,0 +1,88 @@ + + +Hewlett Packard Enterprise logo + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/chapters/01-Introduction.typ b/chapters/01-Introduction.typ new file mode 100644 index 0000000..6f80d2a --- /dev/null +++ b/chapters/01-Introduction.typ @@ -0,0 +1,96 @@ +#import "../template.typ": * + +Fist, in the `thesis.typ` file, adapt the configuration to match your requirements. +For further configuration, look in the upper part of the `template.typ` file, +e.g. to learn how to change the company name and logo. +Of cause, you may change other parts of the template to adapt it to your preferences. + +Also, make sure to read the #link("https://typst.app/docs/")[Typst documentation]. + +This template is for english documents only (for now), +but one could translate it... + +*Note* that the template needs to know your first chapter, +you can supply it if it is not "Introduction" using the `first_chapter_title` parameter. + +#figure(```typ + #show: thesis.with( + ... + first_chapter_title = "Introduction but with another title", + ) + ```, kind: "code", supplement: "Code example", + caption: [Code example explaining how to configure a different first chapter] +) + +== Bibliography + +As for bibliography / reference listing, +you may decide whether to use Hayagriva, a yaml-based format format designed for Typst +or BibTeX (`.bib`) format, which is well supported by other platforms since it is commonly used by LaTeX. +To switch between bibliography formats, change the above to the following: + +#figure(```typ + #show: thesis.with( + ... + bibliography_path = "literature.bib", // or literature.yml for Hayagriva + ) + ```, kind: "code", supplement: "Code example", + caption: [Code example on how to use different bibliography formats with this template] +) + +== Proposed Structure + +But of cause, you can do it as you like. + +Put each chapter in the `chapter/` directory, +prefixed i.e. with `01-` if it is the first chapter. +I'd recommend using CamelCase or snake_case but not spaces. +Also, I would recommend deciding if to put the heading `= Introduction` +in these files or to the parent file. + +You can include files using the following e.g: +```typ +#include ./chapters/01-example.typ +``` + +If your chapter gets too large for one file, create a subdirectory +in `chapters` with the chapters name, +and create files for the different sections. + +== Acronyms + +These are implemented provided by this template, not typst itself. + +You can use them like: + +```typ +#acro("HPE") +#acro("HPE", pref: true) // To prefer the long version +#acro("JSON", append: "-schemata") +``` + ++ #acro("HPE") ++ #acro("HPE", pref: true) // To prefer the long version ++ #acro("JSON", append: "-schemata") + +== TODO marker + +Well, if you are too lazy to write now, +just add a todo-marker. + +```typ +#todo([Your #strike[excuse] notes on what change here]) +``` + +For example: +#todo([I could probably write more on how to use this template and Typst in general, if I wouldn't be too lazy...]) + +And the template makes sure it is well readable in the PDF and not forgotten. + +== Once you are done + +Add a signature to your thesis. +Use the `signature` property. +Set it to `hide`, to leave some blank space for you to sign manually, +e.g. in a printed version. +Or put in the path to your signature image or svg. diff --git a/literature.yml b/literature.yml new file mode 100644 index 0000000..db249af --- /dev/null +++ b/literature.yml @@ -0,0 +1,2 @@ +# format: https://github.com/typst/hayagriva/blob/main/docs/file-format.md + diff --git a/template.typ b/template.typ new file mode 100755 index 0000000..4f192c8 --- /dev/null +++ b/template.typ @@ -0,0 +1,463 @@ + +#let acronyms = yaml("acronyms.yml"); +#let acroStates = state("acronymStates", ()); + +#let thesis( + // the title of your thesis + title: none, + // your name + author: none, + // your student id / matriculation number + student_id: none, + // the name of your course, such as "TINF21A" + course: none, + signature: none, + + // the name of your supervisor + supervisor: none, + + // the due date of your thesis + date: none, + // the time period that the work described in your thesis took place in + time_period: none, + + // the type of your thesis, such as T1000, T2000, etc. + type: none, + // your degree, such as "Bachelor of Science" + degree: "Bachelor of Science", + // your major, such as "Computer Science" + major: "Computer Science", + + // Details on your university + university: ( + name: "Cooperative State University Baden-Württemberg", + location: "Stuttgart", + image: "assets/dhbw.png", + ), + + // Details on your company + company: ( + name: "Hewlett Packard Enterprise", + image: "assets/hpe.png", + ), + + // Does the document require a Confidentiality Clause? + confidentiality_clause: false, + + // Path to your bibliography file + // You may use `.yml` for Hayagriva format + // or `.bib` for BibLaTeX format + bibliography_path: "literature.yml", + + // The contents of your abstract + abstract: include "./abstract.typ", + + // First chapter of your thesis + // This is required to generate the content section correctly + first_chapter_title: "Introduction", + + // set automatically by using the template via `#show: thesis.with(...) + body, +) = [ + // Assert all parameters are set + #assert.ne(title, none) + #assert.ne(author, none) + #assert.ne(student_id, none) + #assert.ne(type, none) + #assert.ne(course, none) + #assert.ne(date, none) + #assert.ne(time_period, none) + #assert.ne(supervisor, none) + + #set document( + title: title, + author: author, + ) + + #set page( + paper: "a4", + margin: 2.5cm, + numbering: none, // don't number the first pages, i.e. titlepage and abstract + ) + + // suggested font and font size by the DHBW style guide + #set text( + font: "Linux Libertine", + size: 12pt, + hyphenate: false, + lang: "en", + ligatures: true, + ) + + #set par( + leading: 8pt, // 1.5x line spacing + justify: true, + linebreaks: "optimized", + ) + + #set figure( + numbering: "I" + ) + + // don't outline or number the first headings + #set heading( + numbering: none, + outlined: false, + ) + + // modify the spacing between various headings and the content below them + #show heading: it => { + let sizes = if it.level == 1 { + (64pt, 24pt, 24pt) + } else if it.level == 2 { + (32pt, 20pt, 18pt) + } else { + (24pt, 16pt, 14pt) + } + + [ + #set text(size: sizes.at(2)) + #v(sizes.at(0)) + #if it.numbering != none [ + #counter(heading).display(it.numbering) #h(4pt) #it.body + ] else [#it.body] + #v(sizes.at(1)) + ] + } + // Alternative formating for headdings + // #show heading: it => { + // v(1em) + // if it.numbering != none { + // grid( + // columns: (auto, auto), + // { + // numbering(it.numbering, ..counter(heading).at(it.location())) + // h(24pt / it.level) + // }, + // it.body, + // ) + // } else { + // it.body + // } + // v(0.5em) + // } + // #show heading.where(level: 1): set text(size: 24pt) + // #show heading.where(level: 2): set text(size: 20pt) + // #show heading.where(level: 3): set text(size: 16pt) + + // Style figure captions + #show figure : it => block(breakable: false)[ + #v(15pt, weak: true) + #it.body + #align(center)[ + // #v(.5em) + #block(width: 80%, text(size: .9em)[ + #it.supplement #it.counter.display(it.numbering): + #emph(it.caption) + ]) + #v(15pt) + ] + ] + + // rename level 1 headings to "Chapter", otherwise "Section" + #set ref(supplement: it => { + if it.func() == heading and it.level == 1 { + "Chapter" + } else { + "Section" + } + }) + + // beginning of the document, render the title page + + #set align(center) + + // nice + #grid( + columns: (1fr, 1fr), + align(center)[ + #image(company.image, width: 69%) + ], + align(center)[ + #image(university.image, width: 69%) + ], + ) + #v(64pt) + + #set par(justify: false) + #text(20pt)[*#title*] + #v(32pt) + #set par(justify: true) + + #text(16pt)[*#type*] + #v(16pt) + + #text(14pt)[for the] + + #text(14pt)[*#degree*] + + #text(14pt)[from the Course of Studies #major] + #v(32pt) + + #text(14pt)[by] + + #text(16pt)[*#author*] + #v(16pt) + + #text(14pt)[#date] + + #set align(bottom) + + #grid( + columns: (1fr, 0.5fr, 1fr), + align(left)[ + *Time Period* \ + *Student ID, Course* \ + *Company* \ + *Supervisor in the Company* + ], + none, + align(left)[ + #time_period \ + #student_id, #course \ + #company.name \ + #supervisor + ], + ) + + #pagebreak() + #set align(top) + #set align(left) + + // initially set the page numbering to roman + #set page(numbering: "I") + #counter(page).update(1) + + // https://www.dhbw.de/fileadmin/user_upload/Dokumente/Broschueren_Handbuch_Betriebe/Infoblatt_Vertraulichkeit.pdf + #if confidentiality_clause [ + == Confidentiality Clause + + The content of this work may not be made accessible to people outside of the + testing process and the evaluation process neither as a whole nor as excerpts, + unless an authorization stating otherwise is presented by the training facility. + + // #text(lang: "de")[ + // Der Inhalt dieser Arbeit darf weder als Ganzes noch in Auszügen Personen außerhalb des + // Prüfungs- und des Evaluationsverfahrens zugänglich gemacht werden, sofern keine anders + // lautende Genehmigung des Dualen Partners vorliegt. + // ] + + #pagebreak() + ] + + // render the abstract aligned to the center of the page + #set align(horizon) + #set align(center) + + == Abstract + + #block(width: 70%)[#abstract] + + #pagebreak() + + #set align(top) + #set align(start) + + = Author's Declaration + + Hereby I solemnly declare: + + + that this #type, titled #text(style: "italic")[#title] is entirely the product of my + own scholarly work, unless otherwise indicated in the text or references, or acknowledged below; + + + I have indicated the thoughts adopted directly or indirectly from other sources at the appropriate + places within the document; + + + this #type has not been submitted either in whole or part, for a degree at this or + any other university or institution; + + + I have not published this #type in the past; + + // - the printed version is equivalent to the submitted one. + + I am aware that a dishonest declaration will entail legal consequences. + #v(48pt) + + #university.location, #date + // #v(48pt) + + #box(width: 196pt, height: 40pt)[ + #if signature == "hide" { + box(height: 50pt) + } else if signature == none { + [ + Set your signature by setting the `signature` argument + to an image or set it to `hide`, to leave place for signing otherwise + #v(2pt) + ] + } else { + image(signature) + } + #v(0pt, weak: true) + #line(length: 100%) + #author + ] + + #pagebreak() + + = Contents + + #locate(loc => { + let headings = query(heading, loc) + let before_content = true + let after_content = false + + for elem in headings { + // kind of hacky, we track whether the main document has started by looking for a chapter by name + if elem.body == [#first_chapter_title] { + before_content = false + } + + // similarly, track the end of the main content by the position of the "Bibliography" chapter + if elem.body == [Bibliography] { + after_content = true + } + + // page numbers of the main document are arabic, the first pages are roman + let index_fmt = if before_content { + "I" + } else { + "1" + } + + let location = elem.location() + let page_index = counter(page).at(location).at(0) + + let formatted_index = numbering(index_fmt, page_index) + + // only the main content should be numbered + let formatted_name = if before_content or after_content { + elem.body + } else [ + #numbering("1.1", ..counter(heading).at(location)) + #h(4pt) + #elem.body + ] + + let is_chapter = elem.level == 1 + + // indent headings in the table of contents based on their level + let indent = if is_chapter { + 0pt + } else if elem.level == 2 { + 2em + } else { + 4em + } + + // non-chapter headings have their line filled with dots + let spacer = if is_chapter { " " } else { " . " } + + if elem.body != [Abstract] and elem.body != [Confidentiality Clause] { + link( + location, + [ + #h(indent) + // add extra spacing between chapters + #if is_chapter {v(1pt)} + // chapters are bold, sections are not + #if is_chapter [*#formatted_name*] else [#formatted_name] + #box(width: 1fr, repeat(spacer)) + #h(8pt) + #if is_chapter [*#formatted_index*] else [#formatted_index] \ + ], + ) + } + } + }) + + // #outline(target: heading.) + + // #show outline.entry.where( + // level: 1 + // ): it => { + // v(12pt, weak: true) + // strong(it) + // } + + // #outline(target: heading, depth: 3, indent: 2em, fill: repeat(" . ")) + + #pagebreak() + + // start adding headings to the outline after the table of contents + #set heading(outlined: true) + + // = List of Figures + + #show outline.entry: it => [ + #v(12pt, weak: true) #it + ] + + #outline(target: figure, title: "List of Figures", fill: repeat(" . ")) + + #pagebreak() + + = Acronyms + + #let acroArr = (); + #for (k, v) in acronyms.pairs().sorted(key: s => lower(s.at(0))) { + acroArr.push([*#k* #label(k)]); + acroArr.push([#v]); + } + + #table( + columns: (1fr, 6fr), + align: horizon, + stroke: none, + ..acroArr, + ) + + #pagebreak() + + // update heading and page numberings to begin the main part of the document + #set heading(numbering: "1.1") + #set page(numbering: "1 / 1") + #counter(page).update(1) + + // the actual chapters + #body + + // finally, include the bibliography chapter at the end of the document + #pagebreak() + // #bibliography(bibliography_path, style: "ieee") + #bibliography(bibliography_path, style: "ieee") +] + +#let acro(short, pref: false, append: "") = { + let item = acronyms.at(short) + + locate(loc => { + let entries = acroStates.at(loc).filter(e => e == short); + + if entries.len() > 0 { + if pref { + link(label(short))[#item#append] + } else { + link(label(short))[#short#append] + } + } else { + acroStates.update(e => {e.push(short); e;}); + if pref { + link(label(short))[#item#append (#short)] + } else { + link(label(short))[#short#append (#item)] + } + } + }); +} + +#let acroOnce(main, inside) = [#main (#inside)] + +#let todo(content) = par(emph([ + #h(5pt) #text(weight: "bold")[To-do/WIP:] #content +])) diff --git a/thesis.typ b/thesis.typ new file mode 100755 index 0000000..cdec0b2 --- /dev/null +++ b/thesis.typ @@ -0,0 +1,41 @@ +#import "template.typ" : * + +#show: thesis.with( + title: "Creating a Typst template", + author: "Your name", + type: "TX000", + student_id: "change-me", + course: "TINF2XA", + date: "00.00.2024", + time_period: "01.01.2023 - 00.00.2024", + supervisor: "Someone", + signature: none, // TODO +) + +// NOTE: https://www.dhbw.de/fileadmin/user_upload/Dokumente/Dokumente_fuer_Studierende/191212_Leitlinien_Praxismodule_Studien_Bachelorarbeiten.pdf + +// Requirements: +// - 25-35 pages without directories und attachments +// incl. graphics and tables +// - must document: task, process of implementation, solutions and results +// - proof that a connection between theoretical and practical was made +// and that the holy theory taught by the DHBW is of relevance +// - No + += Introduction + +#include "./chapters/01-Introduction.typ" + +#pagebreak() + += Technical Background + +== Spell checking + +You can use #link("https://github.com/crate-ci/typos")[Typos], +but I am too lazy to explain. + +#pagebreak() += Summary and Conclusion + +#lorem(100) diff --git a/typos.toml b/typos.toml new file mode 100644 index 0000000..e5b8a95 --- /dev/null +++ b/typos.toml @@ -0,0 +1,10 @@ + +[default.extend-words] +Mosquitto = "Mosquitto" +Hashi = "Hashi" # HashiCorp Vault + +[files] +extend-exclude = [ + "/template.typ", + "/images/" +]