312 lines
7.9 KiB
Typst
312 lines
7.9 KiB
Typst
#import "./util/title.typ": title as titlepage
|
|
#import "./util/versionhistory.typ": parseCurrentVersion, versionhistoryTable
|
|
#import "./util/cover.typ": cover
|
|
#import "./util/code.typ": code
|
|
#import "./util/glossary.typ"
|
|
#import "./util/acronyms.typ"
|
|
#import "./pallete.typ": palette
|
|
|
|
#let std-bibliography = bibliography
|
|
#import "./util/persons.typ"
|
|
|
|
|
|
#let ipa(
|
|
// The title for your work.
|
|
title: [Your Title],
|
|
peoples: (
|
|
(
|
|
name: "Axel Schweiss",
|
|
email: "axel.schweiss@bit.admin.ch",
|
|
shorthand: "AS",
|
|
role: "Kandidat",
|
|
git: "xxxxxxxxx",
|
|
),
|
|
),
|
|
company: [Bundesamt für Informatik und Telekommunikation BIT],
|
|
departement: [Entwicklung 5 - BS-BSC-EN5],
|
|
metadata: (
|
|
specialisation: "Applikationsentwicklung",
|
|
managementMethod: "HERMES",
|
|
// year as in "Jahrgang"
|
|
year: "IPA 2025",
|
|
place: "Kanton Bern",
|
|
dateOfSubmission: datetime(day: 1, month: 12, year: 2024),
|
|
commits: (),
|
|
final-version: false,
|
|
),
|
|
// The result of a call to the `bibliography` function or `none`.
|
|
// Example: bibliography("refs.bib")
|
|
// More info: https://typst.app/docs/reference/model/bibliography/
|
|
bibliography: none,
|
|
abbreviations: none,
|
|
part1: (
|
|
cover: read("./assets/cover1.jpg", encoding: none),
|
|
content: content,
|
|
),
|
|
part2: (
|
|
cover: read("./assets/cover2.jpg", encoding: none),
|
|
content: content,
|
|
),
|
|
// Display an appendix after the body but before the bibliography.
|
|
appendix: (
|
|
files: (),
|
|
// default acronyms fir the "Abkürzungs Verzeichniss"
|
|
acronyms: (:),
|
|
// default terns fir the "Glossar"
|
|
terms: (:),
|
|
body: none,
|
|
),
|
|
// The content of your work.
|
|
body,
|
|
) = {
|
|
context {
|
|
persons._persons.update(_ => return peoples)
|
|
|
|
let author = persons.byFunction("Kandidat")
|
|
|
|
|
|
let persons-dict = (:)
|
|
for person in peoples {
|
|
if person.keys().contains("git") {
|
|
persons-dict.insert(person.git, person.name)
|
|
}
|
|
}
|
|
|
|
let currentversion = parseCurrentVersion(
|
|
commits: metadata.commits,
|
|
persons: persons-dict,
|
|
final: datetime.today() == metadata.dateOfSubmission,
|
|
)
|
|
// Set the document's metadata.
|
|
set document(title: title, author: author.name)
|
|
|
|
set text(
|
|
lang: "de",
|
|
region: "ch",
|
|
font: (
|
|
"Helvetica",
|
|
),
|
|
size: 11pt,
|
|
fill: palette.ui.text,
|
|
)
|
|
|
|
// Set raw text font.
|
|
// Default is Fira Mono at 8.8pt
|
|
show raw: set text(font: ("Fira Mono", "PT Mono"), size: 9pt, fill: palette.ui.text)
|
|
|
|
// Configure page size and margins.
|
|
set page(
|
|
paper: "a4",
|
|
number-align: bottom + right,
|
|
margin: 2.5cm,
|
|
footer: [
|
|
#set text(size: 8pt)
|
|
#title | #author.name | #datetime.today().display("[day].[month].[year]")
|
|
#h(1fr)
|
|
Version #currentversion | #context counter(page).display("1 / 1", both: true)
|
|
],
|
|
)
|
|
|
|
|
|
// Cover page.
|
|
titlepage(
|
|
title: title,
|
|
author: author.name,
|
|
company: company,
|
|
departement: departement,
|
|
metadata: (..metadata, currentversion: currentversion),
|
|
)
|
|
|
|
|
|
// Configure paragraph properties.
|
|
// Default leading is 0.65em.
|
|
// Default spacing is 1.2em.
|
|
set par(leading: 0.7em, spacing: 1.35em, justify: true, linebreaks: "optimized")
|
|
|
|
// Add vertical space after headings.
|
|
show heading: it => {
|
|
it
|
|
v(2%, weak: true)
|
|
}
|
|
// Do not hyphenate headings.
|
|
show heading: set text(hyphenate: false)
|
|
|
|
|
|
// Display inline code in a small box that retains the correct baseline.
|
|
show raw.where(block: false): box.with(
|
|
fill: palette.gray.at("200"),
|
|
inset: (x: 3pt, y: 0pt),
|
|
outset: (y: 3pt),
|
|
radius: 2pt,
|
|
)
|
|
|
|
// Display block code with padding.
|
|
show raw.where(block: true): block.with(inset: 5pt)
|
|
|
|
// figure settings
|
|
show figure.where(kind: raw): set figure(supplement: [Codeblock])
|
|
|
|
show figure.where(kind: code): set block(breakable: true)
|
|
show figure.where(kind: table): set block(breakable: true)
|
|
|
|
set table(
|
|
// Increase the table cell's padding
|
|
inset: 7pt, // default is 5pt
|
|
stroke: (0.5pt + palette.ui.border),
|
|
)
|
|
|
|
|
|
let frame(stroke) = (
|
|
(
|
|
x,
|
|
y,
|
|
) => (
|
|
left: none,
|
|
right: none,
|
|
top: if y == 0 { 0pt } else { stroke },
|
|
bottom: if y == 0 { 2pt } else { stroke },
|
|
)
|
|
)
|
|
set table(
|
|
fill: (_, y) => if calc.odd(y) {
|
|
rgb(palette.ui.bg-dark)
|
|
},
|
|
stroke: frame(rgb(palette.ui.border)),
|
|
)
|
|
|
|
set table.cell(align: left)
|
|
show table.cell.where(y: 0): strong
|
|
show figure.caption: emph
|
|
|
|
// Show all headings by default in outline
|
|
show outline: set heading(outlined: true)
|
|
|
|
// Allow figures to break across multiple pages, except code blocks
|
|
// Add some padding at the bottom to every figure
|
|
show figure: it => pad(bottom: 10pt, it)
|
|
|
|
|
|
// Declare versionhistoryTable after table settings
|
|
pagebreak(weak: true)
|
|
versionhistoryTable(
|
|
commits: metadata.commits,
|
|
persons: persons-dict,
|
|
final: datetime.today() == metadata.dateOfSubmission,
|
|
)
|
|
|
|
|
|
// Wrap `body` in curly braces so that it has its own context. This way show/set rules
|
|
// will only apply to body.
|
|
{
|
|
show "ß": "ss"
|
|
|
|
|
|
// Configure heading numbering.
|
|
set heading(numbering: (..n) => {
|
|
if n.pos().len() < 4 {
|
|
numbering("1.1", ..n)
|
|
} else {
|
|
numbering(() => h(-0.3em))
|
|
}
|
|
})
|
|
|
|
|
|
// pagebreak before lvl 1 headings
|
|
show heading.where(level: 1): it => {
|
|
if it.numbering != none and it.body != [Zeitplan] {
|
|
pagebreak(weak: true)
|
|
}
|
|
it
|
|
}
|
|
// pagebreak if heading would start at last 20% of page for lvl 2 headings, but this fucks page margins so it is commented out
|
|
// show heading.where(level: 2): it => {
|
|
// let threshold = 20%
|
|
// block(breakable: false, height: threshold, spacing: 0pt)
|
|
// v(-threshold)
|
|
// // set block(spacing: 1em)
|
|
// it
|
|
// }
|
|
//
|
|
show ref: it => if it.element == none or it.element.func() != heading {
|
|
it
|
|
} else {
|
|
let h = it.element // heading
|
|
let c = context {
|
|
let n = numbering("1.1", ..counter(heading).at(h.location())) // numbering
|
|
return h.supplement + " " + n + " (" + h.body + ")"
|
|
}
|
|
link(it.target, c)
|
|
}
|
|
|
|
|
|
cover(
|
|
part: [TEIL 1],
|
|
img: if part1.keys().contains("cover") { part1.cover } else { read("./assets/cover1.jpg", encoding: none) },
|
|
description: [Ablauf - Organisation - Umfeld],
|
|
)
|
|
|
|
outline(
|
|
depth: 3,
|
|
indent: auto,
|
|
)
|
|
pagebreak(weak: true)
|
|
|
|
part1.content
|
|
cover(
|
|
part: [TEIL 2],
|
|
img: if part2.keys().contains("cover") { part2.cover } else { read("./assets/cover2.jpg", encoding: none) },
|
|
description: [Individueller, praktischer Teil],
|
|
)
|
|
|
|
part2.content
|
|
show outline: set heading(numbering: "1.1")
|
|
|
|
outline(
|
|
title: [Abbildungsverzeichnis],
|
|
target: figure.where(kind: image),
|
|
)
|
|
outline(
|
|
title: [Tabellenverzeichnis],
|
|
target: figure.where(kind: table),
|
|
)
|
|
|
|
if bibliography != none {
|
|
show std-bibliography: set heading(numbering: "1.1")
|
|
|
|
set par(justify: false)
|
|
// pagebreak()
|
|
{
|
|
set std-bibliography(
|
|
title: "Quellenverzeichnis",
|
|
style: "ieee",
|
|
)
|
|
bibliography
|
|
}
|
|
}
|
|
|
|
acronyms.setDefaults(appendix.at("acronyms", default: (:)))
|
|
acronyms.acronymList()
|
|
|
|
glossary.setDefaults(appendix.at("terms", default: (:)))
|
|
glossary.glossary()
|
|
|
|
|
|
[
|
|
= Anhang
|
|
#if appendix.body != none {
|
|
appendix.body
|
|
}
|
|
== Quellcode
|
|
#{
|
|
outline(
|
|
title: none,
|
|
target: figure.where(kind: raw),
|
|
)
|
|
code(files: appendix.files)
|
|
}
|
|
|
|
]
|
|
}
|
|
}
|
|
}
|