feat: first draft

This commit is contained in:
Ansgar Lichter 2024-12-30 16:02:49 +01:00
commit fb3b63f05e
24 changed files with 926 additions and 0 deletions

66
README.md Normal file
View file

@ -0,0 +1,66 @@
# Typst Template HKA
This is a thesis template written in [Typst](https://typst.app/),
based on the [template of the TU Munich](https://github.com/ls1intum/thesis-template-typst).
## Usage
You can use this template in the Typst web app by clicking "Start from template"
on the dashboard and searching for `unofficial-hka-thesis`.
Locally, you can use the following command to start with this templates:
```bash
typst init @preview/unofficial-hka-thesis:1.0.0
```
### Features
## Metadata
In the file `settings/metadata.typ` you can enter all metadata (title, author, submission date, ...). The data is automatically referenced in the exposé and the thesis.
## Settings
Some important global settings are located in `settings/settings.typ`. You can adapt them here as you wish and they are automatically changed in the exposé and the thesis.
## Pre-defined Pages
The template supports the following pages out-of-the-box:
- Titlepage
- Declaration of Originality
- Abstract, both in English and German
- Table of Contents
- List of Figures
- List of Tables
- List of Listings
- List of Abbreviations (for instructions refer to [glossarium](https://github.com/typst/packages/tree/main/packages/preview/glossarium/0.2.6))
- Bibliography
# **Usage of official Titlepage**
In the intranet you can download the official titlepage. As Typst is not able to include PDFs, you must manually exchange the current titlepage with the official in the final PDF file. Be aware, that you must adapt the numbering of the PDF itself, so that you view page `5` instead of `V` if you want to jump to page `5`.
## Header
Every header includes the heading of the current chapter, section or subsection.
![Current Subsection](assets/image.png)
If a new section or subsection starts at the current page this one is chosen.
![New Section](assets/image-1.png)
If a new chapter starts at the current page, no header will be shown.
![New Chapter](assets/image-2.png)
The numbering is shown thanks to the inspiration from [hydra](https://github.com/tingerrr/hydra) (Hydra didn't work flawlessly, therefore I had to write my own solution).
## Footer
Every footer is divided by a line from the main body. The footer contains the page numbering in the following format `1 / 3`.
## 💡 Feedback
**Anything Missing?** Please [create an issue](https://github.com/AnsgarLichter/unofficial-hka-thesis/issues/new) or open a Pull Request right away.
**Have Questions?** Please [open a discussion](https://github.com/AnsgarLichter/unofficial-hka-thesis/discussions).

BIN
assets/HKALogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

BIN
assets/company.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

114
assets/company.svg Normal file
View file

@ -0,0 +1,114 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="360.000000pt" height="360.000000pt" viewBox="0 0 360.000000 360.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,360.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1670 2816 c-25 -13 -58 -42 -75 -65 -24 -35 -30 -54 -33 -111 -4
-60 -1 -75 22 -116 25 -44 26 -54 26 -185 0 -126 2 -139 18 -139 15 0 17 11
17 97 0 68 4 98 13 100 9 4 12 -20 12 -96 l0 -101 130 0 130 0 0 136 c0 116 3
140 18 162 78 112 41 261 -79 323 -55 28 -142 26 -199 -5z m199 -55 c35 -25
59 -74 67 -135 6 -38 4 -46 -10 -46 -12 0 -16 10 -16 40 0 70 -46 132 -107
145 -18 3 -33 11 -33 17 0 16 66 2 99 -21z"/>
<path d="M1316 2164 c-9 -8 -16 -24 -16 -35 0 -18 15 -19 470 -21 l470 -3 0
27 c0 17 -8 31 -19 38 -13 6 -174 10 -455 10 -382 0 -436 -2 -450 -16z"/>
<path d="M1670 1995 l0 -85 105 0 105 0 0 85 0 85 -105 0 -105 0 0 -85z"/>
<path d="M1900 1985 c0 -19 13 -40 40 -67 162 -162 4 -442 -220 -388 -70 17
-122 58 -154 121 -45 90 -32 187 36 264 34 39 51 85 30 85 -19 0 -80 -63 -106
-109 -102 -188 35 -414 250 -413 158 1 274 119 274 276 0 105 -37 173 -132
245 -16 12 -18 11 -18 -14z"/>
<path d="M1617 1902 c-25 -27 -57 -104 -57 -137 0 -80 58 -173 127 -202 76
-31 186 -9 240 49 69 73 71 209 4 286 -23 26 -31 28 -31 7 0 -13 -19 -15 -127
-13 -96 2 -127 6 -125 16 3 17 -12 15 -31 -6z"/>
<path d="M1850 1224 c0 -3 9 -22 20 -44 11 -22 20 -51 20 -65 0 -18 5 -25 20
-25 13 0 20 7 20 20 0 12 9 38 20 60 24 48 25 50 2 50 -11 0 -23 -11 -29 -27
l-10 -28 -11 26 c-8 21 -52 49 -52 33z"/>
<path d="M917 1202 c-22 -24 -22 -75 1 -95 20 -18 59 -22 81 -8 20 13 3 32
-23 25 -28 -7 -50 17 -41 46 5 17 13 20 38 18 23 -2 32 1 32 12 0 24 -67 25
-88 2z"/>
<path d="M1067 1202 c-38 -41 -10 -112 44 -112 30 0 43 9 58 37 33 64 -54 128
-102 75z m68 -23 c12 -19 -4 -59 -24 -59 -22 0 -34 25 -26 51 7 20 40 26 50 8z"/>
<path d="M1220 1155 c0 -51 3 -65 15 -65 10 0 15 10 15 33 l0 32 20 -25 c20
-26 21 -26 38 5 10 18 11 17 12 -12 0 -26 4 -33 20 -33 18 0 20 7 20 65 0 62
-1 65 -24 65 -18 0 -27 -8 -35 -32 l-12 -33 -16 33 c-9 19 -23 32 -34 32 -17
0 -19 -8 -19 -65z"/>
<path d="M1410 1155 c0 -51 3 -65 15 -65 8 0 15 9 15 19 0 14 8 21 27 23 19 2
30 11 37 30 13 37 -6 58 -55 58 l-39 0 0 -65z m60 20 c0 -8 -7 -15 -15 -15 -8
0 -15 7 -15 15 0 8 7 15 15 15 8 0 15 -7 15 -15z"/>
<path d="M1556 1168 c-10 -29 -21 -59 -23 -65 -3 -8 3 -13 15 -13 11 0 22 5
24 12 6 17 36 18 42 2 3 -8 14 -14 25 -14 18 0 18 3 -7 65 -32 81 -50 85 -76
13z m40 -25 c-11 -11 -19 6 -11 24 8 17 8 17 12 0 3 -10 2 -21 -1 -24z"/>
<path d="M1690 1155 c0 -58 2 -65 20 -65 16 0 20 7 20 33 l0 32 26 -32 c40
-52 54 -44 54 32 0 51 -3 65 -15 65 -10 0 -15 -10 -15 -30 0 -16 -4 -30 -8
-30 -4 0 -16 14 -25 30 -10 17 -27 30 -38 30 -17 0 -19 -7 -19 -65z"/>
<path d="M2050 1155 c0 -51 3 -65 15 -65 10 0 15 10 15 30 0 38 10 38 35 0 11
-16 28 -30 38 -30 14 0 17 10 17 65 0 58 -2 65 -20 65 -16 0 -20 -7 -20 -32
l0 -33 -26 33 c-40 51 -54 43 -54 -33z"/>
<path d="M2231 1161 c-26 -71 -26 -71 -1 -71 11 0 20 7 20 15 0 8 9 15 20 15
11 0 20 -7 20 -15 0 -8 9 -15 20 -15 25 0 25 0 -1 71 -15 41 -27 59 -39 59
-12 0 -24 -18 -39 -59z m45 -18 c-11 -11 -19 6 -11 24 8 17 8 17 12 0 3 -10 2
-21 -1 -24z"/>
<path d="M2370 1155 c0 -59 2 -65 21 -65 18 0 21 5 17 30 -5 33 7 41 15 10 3
-11 10 -20 17 -20 7 0 14 9 17 20 8 32 26 23 21 -10 -4 -24 -1 -30 14 -30 16
0 18 9 18 65 0 59 -2 65 -20 65 -12 0 -25 -10 -32 -25 -6 -14 -15 -25 -19 -25
-5 0 -11 11 -15 25 -4 18 -13 25 -30 25 -23 0 -24 -3 -24 -65z"/>
<path d="M2560 1155 l0 -65 50 0 c38 0 50 4 50 15 0 10 -10 15 -30 15 -16 0
-30 5 -30 10 0 6 11 10 25 10 16 0 25 6 25 15 0 9 -9 15 -24 15 -14 0 -28 5
-31 10 -4 6 6 10 23 10 17 0 32 6 36 15 4 12 -4 15 -44 15 l-50 0 0 -65z"/>
<path d="M1040 1014 c1 -5 6 -19 13 -31 l13 -23 11 30 c6 17 7 30 2 30 -5 0
-9 -5 -9 -11 0 -8 -5 -8 -15 1 -8 7 -15 9 -15 4z"/>
<path d="M1103 1004 c-3 -8 2 -23 11 -32 15 -15 17 -15 32 0 21 21 11 48 -16
48 -11 0 -23 -7 -27 -16z m37 -9 c0 -8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8
5 15 10 15 6 0 10 -7 10 -15z"/>
<path d="M1183 995 c2 -23 7 -30 22 -30 14 0 21 8 23 28 2 15 -1 27 -7 27 -6
0 -11 -9 -11 -20 0 -27 -17 -25 -23 3 -4 15 -5 12 -4 -8z"/>
<path d="M1250 991 c0 -31 14 -42 23 -18 4 10 6 10 6 0 2 -26 17 -12 16 15 0
20 -6 28 -22 30 -20 3 -23 -1 -23 -27z"/>
<path d="M1338 1013 c6 -2 12 -16 12 -29 0 -34 17 -30 22 6 4 27 2 30 -21 29
-14 0 -20 -3 -13 -6z"/>
<path d="M1402 995 c-15 -33 -16 -32 17 -32 27 0 28 2 19 29 -12 35 -21 35
-36 3z"/>
<path d="M1464 1005 c-4 -8 -4 -22 0 -30 7 -20 46 -19 46 1 0 11 -6 14 -20 9
-28 -9 -26 13 3 25 l22 9 -23 0 c-12 1 -25 -6 -28 -14z"/>
<path d="M1530 990 c0 -23 4 -30 20 -30 11 0 20 5 20 10 0 6 -4 10 -10 10 -5
0 -10 9 -10 20 0 11 -4 20 -10 20 -5 0 -10 -13 -10 -30z"/>
<path d="M1590 990 c0 -16 5 -30 10 -30 6 0 10 14 10 30 0 17 -4 30 -10 30 -5
0 -10 -13 -10 -30z"/>
<path d="M1631 988 c1 -19 3 -25 6 -15 5 18 6 18 24 1 18 -17 19 -16 19 17 0
27 -3 31 -11 19 -8 -11 -12 -12 -16 -2 -9 24 -23 12 -22 -20z"/>
<path d="M1700 990 c0 -26 4 -30 26 -30 14 0 23 4 19 10 -4 6 -11 8 -16 5 -5
-4 -9 -1 -9 4 0 6 6 11 13 11 8 0 8 3 -2 9 -11 7 -10 10 5 14 13 3 11 5 -8 6
-25 1 -28 -3 -28 -29z"/>
<path d="M1785 994 c-24 -37 -11 -41 15 -5 12 17 17 31 12 31 -5 0 -17 -12
-27 -26z"/>
<path d="M1840 1009 c0 -7 8 -18 18 -26 16 -14 16 -14 0 -9 -10 3 -18 1 -18
-4 0 -12 37 -13 44 -1 3 5 -1 14 -10 21 -12 11 -12 15 -2 21 9 6 6 9 -9 9 -13
0 -23 -5 -23 -11z"/>
<path d="M1900 990 c0 -26 4 -30 28 -30 24 1 25 2 10 14 -10 7 -18 21 -18 30
0 9 -4 16 -10 16 -5 0 -10 -13 -10 -30z"/>
<path d="M1964 1005 c-8 -21 2 -45 19 -45 21 0 38 25 31 44 -8 20 -43 21 -50
1z m36 -10 c0 -8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8 5 15 10 15 6 0 10 -7
10 -15z"/>
<path d="M2036 1004 c-4 -9 -1 -23 5 -30 16 -19 49 -18 49 2 0 11 -6 14 -20 9
-15 -5 -20 -2 -20 10 0 11 5 15 15 11 8 -3 15 -1 15 4 0 17 -37 11 -44 -6z"/>
<path d="M2124 1004 c3 -8 2 -13 -3 -10 -5 3 -11 -2 -13 -12 -4 -15 1 -19 22
-19 26 0 27 2 18 29 -6 15 -14 28 -20 28 -6 0 -7 -7 -4 -16z"/>
<path d="M2172 990 c0 -16 4 -30 9 -30 5 0 9 8 9 18 1 16 1 16 11 0 15 -27 29
-21 29 12 0 17 -4 30 -10 30 -5 0 -10 -5 -10 -12 0 -9 -3 -9 -12 0 -19 19 -25
14 -26 -18z"/>
<path d="M2271 990 c0 -30 1 -32 11 -16 11 19 11 19 24 1 13 -17 14 -16 13 16
0 19 -3 28 -6 22 -2 -7 -11 -13 -18 -13 -7 0 -16 6 -18 13 -3 6 -6 -4 -6 -23z"/>
<path d="M2340 990 c0 -26 4 -30 26 -30 14 0 23 4 19 10 -4 6 -11 8 -16 5 -5
-4 -9 -1 -9 4 0 6 6 11 13 11 8 0 8 3 -2 9 -11 7 -10 10 5 14 13 3 11 5 -8 6
-25 1 -28 -3 -28 -29z"/>
<path d="M2400 990 c0 -16 5 -30 10 -30 6 0 10 5 10 11 0 8 5 8 15 -1 13 -11
15 -8 15 19 0 26 -4 31 -25 31 -21 0 -25 -5 -25 -30z m40 16 c0 -3 -4 -8 -10
-11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z"/>
<path d="M2470 990 c0 -26 4 -30 26 -30 14 0 23 4 19 10 -4 6 -11 8 -16 5 -5
-4 -9 -1 -9 4 0 6 6 11 13 11 8 0 8 3 -2 9 -11 7 -10 10 5 14 13 3 11 5 -8 6
-25 1 -28 -3 -28 -29z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
assets/image-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
assets/image-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
assets/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

350
lib.typ Normal file
View file

@ -0,0 +1,350 @@
#import "modules/titlepage.typ": *
#import "@preview/glossarium:0.5.1": print-glossary, register-glossary
#let in-outline = state("in-outline", false)
#let flex-caption(long, short) = context {
if in-outline.at(here()) { short } else { long }
}
#let preface(
settings: (),
degree: "",
program: "",
title: "",
subtitle: "",
author: "",
matriculationNumber: "",
placeOfWork: "",
supervisor: "",
advisor: "",
startDate: none,
submissionDate: none
) = {
set document(title: title, author: author)
titlepage(
settings: settings,
degree: degree,
program: program,
title: title,
subtitle: subtitle,
author: author,
placeOfWork: placeOfWork,
matriculationNumber: matriculationNumber,
supervisor: supervisor,
advisor: advisor,
startDate: startDate,
submissionDate: submissionDate
)
// Page Setup
set page(
margin: (
left: settings.pageMargins.left,
right: settings.pageMargins.right,
top: settings.pageMargins.top,
bottom: settings.pageMargins.bottom
),
numbering: "I",
number-align: center
)
counter(page).update(2)
// Body Font Family
set text(
font: settings.fontBody,
size: settings.fontBodySize,
lang: "en"
)
show math.equation: set text(weight: 400)
// Headings
show heading: set block(
below: settings.headingsSpacing.below,
above: settings.headingsSpacing.above
)
show heading: set text(font: settings.fontBody, size: settings.fontHeadingSize)
set heading(numbering: none)
// Paragraphs
set par(leading: settings.distanceBetweenLines, justify: true)
// Figures
show figure: set text(size: settings.fontFiguresSubtitleSize)
//Indentation of Lists
set list(indent: settings.listIndentation)
set enum(indent: settings.listIndentation)
}
#let listings(
abbreviations: ()
) = {
register-glossary(abbreviations)
// Enable short captions to omit citations
show outline: it => {
in-outline.update(true)
it
in-outline.update(false)
}
// Table of Contents
outline(
title: {
heading(outlined: false, "Table of Contents")
},
target: heading.where(supplement: [Chapter], outlined: true),
indent: true,
depth: 3
)
v(2.4fr)
pagebreak()
// List of Figures
outline(
title: {
heading(outlined: false, "List of Figures")
},
target: figure.where(kind: image),
)
pagebreak()
// List of Tables
outline(
title: {
heading(outlined: false, "List of Tables")
},
target: figure.where(kind: table)
)
pagebreak()
// List of Listings
outline(
title: {
heading(outlined: false, "List of Listings")
},
target: figure.where(kind: raw)
)
pagebreak()
// List of Abbreviations
heading(outlined: false)[List of Abbreviations]
print-glossary(
abbreviations,
show-all: false,
disable-back-references: true,
)
}
#let mainBody(
settings: (),
body
) = {
// Main Body
set heading(numbering: settings.headingsNumberingStyle, supplement: [Chapter])
show heading.where(level: 1): it => {
if it.numbering == none {
[
#it
]
} else {
[
#pagebreak()
#it
]
}
counter(figure.where(kind: table)).update(0);
counter(figure.where(kind: image)).update(0);
counter(figure.where(kind: raw)).update(0);
}
set figure(numbering: it => {
let numberingOfHeading = counter(heading).display();
let topLevelNumber = numberingOfHeading.slice(0, numberingOfHeading.position("."))
[#topLevelNumber.#it]
})
set page(
// Header with current heading
header: context {
let elements = query(
selector(heading.where(depth: 1)).after(here())
)
// Don't show header if a new chapter is starting at the current page
if elements != () and elements.first().location().page() == here().page() and elements.first().depth == 1 {
return;
}
let displayHeading
let displayNumbering
let element
elements = query(selector(heading).after(here()))
if elements != () and elements.first().location().page() == here().page() {
element = elements.first()
if element.has("numbering") and element.numbering != none {
displayNumbering = numbering(element.numbering, ..counter(heading).at(element.location()))
} else {
displayNumbering = numbering(settings.headingsNumberingStyle, ..counter(heading).at(element.location()))
}
displayHeading = element.body
} else {
// Otherwise take the next heading backwards
elements = query(
heading.where().before(here())
)
if elements != () {
element = elements.last()
if element.has("numbering") and element.numbering != none {
displayNumbering = numbering(element.numbering, ..counter(heading).at(element.location()))
} else {
displayNumbering = numbering(settings.headingsNumberingStyle, ..counter(heading).at(element.location()))
}
displayHeading = element.body
}
}
align(center, displayNumbering + " " + displayHeading)
line(length: 100%, stroke: (paint: gray))
},
// Footer with Page Numbering
footer: context {
let currentPage = counter(page).display()
let finalPage = counter(page).final().first()
line(length: 100%, stroke: (paint: gray))
align(center)[#currentPage / #finalPage]
}
)
set page(
numbering: "1/1",
number-align: center,
)
counter(page).update(1)
// Set after header and after all initial pages to just apply it to the acutal content
set par(spacing: settings.spaceBeforeParagraph)
// Actual Content
body
}
// Appendix
#let appendix(body) = {
pagebreak()
outline(
title: {
heading("Appendix", outlined: true, numbering: none)
},
target: heading.where(supplement: [Appendix], outlined: true),
indent: true,
depth: 3
)
counter(heading).update(0)
set heading(numbering: "A.1.", supplement: [Appendix])
show heading: it => {
let prefixedNumbering;
if it.level == 1 and it.numbering != none {
prefixedNumbering = [#it.supplement #counter(heading).display()]
} else if it.numbering != none {
prefixedNumbering = [#counter(heading).display()]
}
block(
below: 0.85em,
above: 1.75em
)[
#prefixedNumbering #it.body
]
}
set figure(numbering: it => {
let alphabet = ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")
let numberingOfHeading = counter(heading).display();
let topLevelNumber = numberingOfHeading.slice(0, numberingOfHeading.position("."))
let index = alphabet.position((el) => { el == topLevelNumber})
if index == none {
let numberingToAlphabet = numbering("A", int(topLevelNumber))
[#numberingToAlphabet.#it]
} else {
[#topLevelNumber.#it]
}
})
show heading.where(level: 1): it => {
if it.numbering == none {
[
#it
]
} else {
[
#pagebreak()
#it
]
}
counter(figure.where(kind: table)).update(0);
counter(figure.where(kind: image)).update(0);
counter(figure.where(kind: raw)).update(0);
}
body
}
// TODOs
#let todo(body) = [
#let rblock = block.with(stroke: red, radius: 0.5em, fill: red.lighten(80%))
#let top-left = place.with(top + left, dx: 1em, dy: -0.35em)
#block(inset: (top: 0.35em), {
rblock(width: 100%, inset: 1em, body)
top-left(rblock(fill: white, outset: 0.25em, text(fill: red)[*TODO*]))
})
<todo>
]
#let outline-todos(title: [TODOS]) = {
heading(numbering: none, outlined: false, title)
context {
let queried-todos = query(<todo>)
let headings = ()
let last-heading
for todo in queried-todos {
let new-last-heading = query(selector(heading).before(todo.location())).last()
if last-heading != new-last-heading {
headings.push((heading: new-last-heading, todos: (todo,)))
last-heading = new-last-heading
} else {
headings.last().todos.push(todo)
}
}
for head in headings {
link(head.heading.location())[
#numbering(head.heading.numbering, ..counter(heading).at(head.heading.location()))
#head.heading.body
]
[ ]
box(width: 1fr, repeat[.])
[ ]
[#head.heading.location().page()]
linebreak()
pad(left: 1em, head.todos.map((todo) => {
list.item(link(todo.location(), todo.body.children.at(0).body))
}).join())
}
}
}

114
modules/titlepage.typ Normal file
View file

@ -0,0 +1,114 @@
#let titlepage(
settings: (),
degree: "",
program: "",
title: "",
subtitle: "",
titleGerman: "",
subtitleGerman: "",
author: "",
matriculationNumber: "",
placeOfWork: "",
supervisor: "",
advisor: "",
startDate: none,
submissionDate: none,
) = {
set document(title: title, author: author)
set page(
paper: "a4",
margin: (left: 30mm, right: 30mm, top: 40mm, bottom: 40mm),
numbering: "I",
number-align: center,
footer: ""
)
set text(
font: settings.fontBody,
size: settings.fontBodySize,
lang: "en"
)
set par(leading: 1em)
// Title Page
//TODO: How to apply company logo?
grid(
columns: (1fr, 1fr),
align(left)[
#image("/assets/company.svg", height: 1.5cm)
],
align(right)[
#image("/assets/HKALogo.png", height: 2cm)
]
)
v(5mm)
align(center, text(font: settings.fontHeading, 1.9em, weight: 700, "University of Applied Sciences Karlsruhe"))
v(15mm)
align(center, text(font: settings.fontHeading, 1.5em, weight: 100, degree + "s Thesis in " + program))
v(8mm)
if titleGerman.len() > 0 {
if subtitle.len() > 0 or subtitleGerman.len() > 0 {
align(center, text(font: settings.fontHeading, 1.2em, weight: 700, title))
align(center, text(font: settings.fontHeading, 1.2em, weight: 500, subtitle))
v(10mm)
align(center, text(font: settings.fontHeading, 1.2em, weight: 700, titleGerman))
align(center, text(font: settings.fontHeading, 1.2em, weight: 500, subtitleGerman))
} else {
align(center, text(font: settings.fontHeading, 1.4em, weight: 700, title))
v(10mm)
align(center, text(font: settings.fontHeading, 1.4em, weight: 700, titleGerman))
}
} else {
if subtitle.len() > 0 {
align(center, text(font: settings.fontHeading, 1.8em, weight: 700, title))
v(5mm)
align(center, text(font: settings.fontHeading, 1.4em, weight: 500, subtitle))
} else {
align(center, text(font: settings.fontHeading, 2.0em, weight: 700, title))
}
}
if advisor.len() > 0 {
pad(
top: 3em,
right: 10%,
left: 10%,
grid(
columns: (3fr, 3fr),
gutter: 1em,
strong("Author: "), author,
strong("Matriculation Number: "), matriculationNumber,
strong("Place of Work: "), placeOfWork,
strong("Supervisor: "), supervisor,
strong("Advisor: "), advisor,
strong("Start Date: "), startDate,
strong("Submission Date: "), submissionDate,
)
)
} else {
pad(
top: 3em,
right: 10%,
left: 10%,
grid(
columns: (3fr, 3fr),
gutter: 1em,
strong("Author: "), author,
strong("Matriculation Number: "), matriculationNumber,
strong("Place of Work: "), placeOfWork,
strong("Supervisor: "), supervisor,
strong("Start Date: "), startDate,
strong("Submission Date: "), submissionDate,
)
)
}
pagebreak()
}

View file

@ -0,0 +1,7 @@
#let abbreviations = (
(
key: "oidc",
short: "OIDC",
long: "Open ID Connect"
),
)

View file

@ -0,0 +1,38 @@
@book{Smith.2020,
author = {John Smith},
title = {A Comprehensive Introduction to C++},
year = {2020},
publisher = {Tech Books Publishing Ltd.},
address = {New York},
}
@book{a,
author = {John Smith},
title = {A Comprehensive Introduction to C++},
year = {2020},
publisher = {Tech Books Publishing Ltd.},
address = {New York},
}
@book{b,
author = {John Smith},
title = {A Comprehensive Introduction to C++},
year = {2020},
publisher = {Tech Books Publishing Ltd.},
address = {New York},
}
@book{c,
author = {John Smith},
title = {A Comprehensive Introduction to C++},
year = {2020},
publisher = {Tech Books Publishing Ltd.},
address = {New York},
}
@book{d,
author = {John Smith},
title = {A Comprehensive Introduction to C++},
year = {2020},
publisher = {Tech Books Publishing Ltd.},
address = {New York},
}

View file

@ -0,0 +1,68 @@
#import "@preview/unofficial-hka-thesis:1.0.0": todo, flex-caption
#import "@preview/glossarium:0.2.6": gls, glspl
= Introduction
#lorem(800)
== Motivation
#lorem(250)
#lorem(36)
#lorem(30)
=== Third Level
#lorem(550)
== Objective
#lorem(300)
This is an example citation @Smith.2020. #gls("oidc") means @oidc. @figure describes @table which is shown in @listing. Test a b c d.
#figure(
image("/figures/tiger.png", width: 80%),
caption: flex-caption(
[This is my long caption text in the document. @a],
[This is short],
)
) <figure>
#figure(
table(
columns: (1fr, auto, auto),
inset: 10pt,
align: horizon,
[], [*Area*], [*Parameters*],
"Text",
$ pi h (D^2 - d^2) / 4 $,
[
$h$: height \
$D$: outer radius \
$d$: inner radius
],
"Text",
$ sqrt(2) / 12 a^3 $,
[$a$: edge length]
),
caption: flex-caption(
[This is my long caption text in the document. @b],
[This is short],
)
) <table>
#figure(
```rust
fn main() {
println!("Hello World!");
}
```,
caption: flex-caption(
[This is my long caption text in the document. @c],
[This is short],
)
) <listing>

View file

@ -0,0 +1,8 @@
#import "@preview/unofficial-hka-thesis:1.0.0": todo, flex-caption
#import "@preview/acrostiche:0.2.0": acr, acrpl
= Foundations
This chapter describes the Foundations.
#lorem(500)

View file

@ -0,0 +1,7 @@
= Additional Material
#lorem(450)
== Subchapter
#lorem(450)

View file

@ -0,0 +1,11 @@
= Transcripts
#lorem(500)
== Interview 1
#lorem(250)
=== Details
#lorem(250)

BIN
template/figures/tiger.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

View file

@ -0,0 +1,15 @@
#let degree = "Master" //Bachelor or Master
#let program = "Computer Science"
#let titleEnglish = "Title English"
#let subtitleEnglish = "Subtitle English"
#let titleGerman = "Title German"
#let subtitleGerman = "Subtitle German"
#let author = "Max Mustermann"
#let matriculationNumber = "12345"
#let placeOfWork = "ABC"
#let supervisor = "Prof Dr. Max Mustermann"
#let advisor = "Prof Dr. John Doe"
#let startDate = "01.03.2024"
#let submissionDate = "31.08.2024"
#let submissionDateExposé = "29.02.2024"
#let place = "Karlsruhe"

View file

@ -0,0 +1,24 @@
#let settings = (
fontBody: "New Computer Modern",
fontBodySize: 12pt,
fontFiguresSubtitleSize: 0.85em,
// At the moment only used on the title page
fontHeading: "New Computer Modern Sans",
fontHeadingSize: 16pt,
headingsNumberingStyle: "1.1.",
headingsSpacing: (
below: 0.85em,
above: 1.75em
),
citationStyle: "ieee",
spaceBeforeParagraph: 24pt,
distanceBetweenLines: 1em,
listIndentation: 2.5em,
pageMargins: (
top: 4cm,
bottom: 2.5cm,
left: 2.5cm,
right: 2.5cm
),
)

View file

@ -0,0 +1,5 @@
#import "@preview/unofficial-hka-thesis:1.0.0": todo, flex-caption
#heading(outlined: false, numbering: none, "Abstract")
#todo("Abstract")

View file

@ -0,0 +1,5 @@
#import "@preview/unofficial-hka-thesis:1.0.0": todo, flex-caption
#heading(outlined: false, numbering: none, "Zusammenfassung")
#todo("Abstract")

View file

@ -0,0 +1,20 @@
#import "../settings/metadata.typ": *
#heading(outlined: false, numbering: none, "Declaration of Originality")
I declare that I have composed the #lower(degree)'s thesis myself and without use of any other than the cited sources and aids. Sentences or parts of sentences quoted literally are marked as such; other references with regard to the statement and scope are indicated by full details of the publications concerned. The thesis in the same or similar form has not been submitted to any examination body and has not been published. This thesis was not yet, even in part, used in another examination or as a course performance. Furthermore I declare that the submitted written (bound) copies of the #lower(degree)'s thesis and the version submitted in digital format are consistent with each other in contents.
#pad(
top: 5em,
table(
columns: (1fr, 1fr),
gutter: 1em,
align: center,
stroke: none,
inset: (
x: 20pt
),
line(length: 100%), line(length: 100%),
[(Place, Date)], author,
)
)

58
template/thesis.typ Normal file
View file

@ -0,0 +1,58 @@
#import "@preview/unofficial-hka-thesis:1.0.0": *
#import "abbreviations.typ": abbreviations
#import "settings/metadata.typ": *
#import "settings/settings.typ": *
#import "@preview/glossarium:0.5.1": make-glossary
#show: make-glossary
#preface(
settings: settings,
degree: degree,
program: program,
title: titleEnglish,
subtitle: subtitleEnglish,
author: author,
matriculationNumber: matriculationNumber,
placeOfWork: placeOfWork,
supervisor: supervisor,
advisor: advisor,
startDate: startDate,
submissionDate: submissionDate,
)
// Citations - applied here so that you are able to use a local CSL file to define the citation style
#set cite(style: settings.citationStyle)
// Statutory Declaration
#include "supplementary/statutoryDeclaration.typ"
#pagebreak()
// Abstract
#include "supplementary/abstract.typ"
#pagebreak()
// Abstract German
#include "supplementary/abstractGerman.typ"
#pagebreak()
#listings(abbreviations: abbreviations)
#show: mainBody.with(
settings: settings
)
#include "chapters/1_introduction.typ"
#include "chapters/2_foundations.typ"
//Bibliography
#pagebreak()
#bibliography("bibliography/thesis.bib")
//Appendix
#appendix()[
#include "chapters/A1_Material.typ"
#include "chapters/A2_Transcripts.typ"
]

BIN
thumbnail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

16
typst.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "unofficial-hka-thesis"
version = "1.0.0"
entrypoint = "lib.typ"
authors = ["Ansgar Lichter <https://www.linkedin.com/in/ansgar-lichter-8532661b1>"]
license = "MIT"
description = "Unofficial thesis template used at the University of Applied Sciences Karlsruhe (Hochschule Karlsruhe / HKA) at the faculty of Computer Science."
repository = "TODO"
keywords = ["Karlsruhe", "University of Applied Sciences Karlsruhe", "HKA", "Hochschule Karlsruhe", "Thesis", "Masterarbeit", "Bachelorarbeit", "Final Thesis", "Bachelor's Thesis", "Master's Thesis"]
categories = ["thesis"]
exclude = []
[template]
path = "template"
entrypoint = "thesis.typ"
thumbnail = "thumbnail.png"