init Vorlage

This commit is contained in:
2026-03-11 08:07:31 +01:00
commit f9ab6a795d
18 changed files with 1213 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
name: Build Typst PDF
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Typst
run: |
curl -L https://github.com/typst/typst/releases/latest/download/typst-x86_64-unknown-linux-musl.tar.xz \
| tar -xJ --strip-components=1 -C /usr/local/bin typst-x86_64-unknown-linux-musl/typst
- name: Build PDF
run: typst compile main.typ main.pdf
- name: Upload PDF artifact
uses: actions/upload-artifact@v3
with:
name: projektarbeit-pdf
path: main.pdf
retention-days: 30

View File

@@ -0,0 +1,29 @@
name: Release Typst PDF
on:
push:
tags:
- "v*"
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Typst
run: |
curl -L https://github.com/typst/typst/releases/latest/download/typst-x86_64-unknown-linux-musl.tar.xz \
| tar -xJ --strip-components=1 -C /usr/local/bin typst-x86_64-unknown-linux-musl/typst
- name: Build PDF
run: typst compile main.typ projektarbeit-${{ github.ref_name }}.pdf
- name: Create Release and Upload PDF
uses: softprops/action-gh-release@v2
with:
files: projektarbeit-${{ github.ref_name }}.pdf
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

47
.gitignore vendored Normal file
View File

@@ -0,0 +1,47 @@
# Generated .gitignore for Typst project (Windows)
# Output files
*.pdf
*.log
*.aux
*.out
*.toc
*.synctex.gz
*.fls
*.fdb_latexmk
*.bbl
# Build / cache directories
.build/
build/
dist/
.typst-cache/
.cache/
# Editor / IDE
.vscode/
.idea/
*.swp
*~
*.bak
# Python
__pycache__/
*.py[cod]
*.egg-info/
# Environment
.env
.env.local
# OS-specific
.DS_Store
Thumbs.db
desktop.ini
ehthumbs.db
# Misc
*.log
# Keep the .gitignore tracked
!/.gitignore

9
abstract.typ Normal file
View File

@@ -0,0 +1,9 @@
// abstract.typ
#let abstract(meta) = [
#heading(level: 1, outlined: false, numbering: none)[Abstract]
Hier sollte ein kurzer Überblick über die Arbeit gegeben werden, einschließlich der wichtigsten Ergebnisse und Schlussfolgerungen. Es sollte klar und prägnant sein, damit die Leser schnell verstehen können, worum es in der Arbeit geht.
#pagebreak()
]

43
acro.typ Normal file
View File

@@ -0,0 +1,43 @@
#let acronyms = (
XML: "Extensible Markup Language",
)
#let acro(name) = context {
// Prüfen, ob das Akronym vorher schon verwendet wurde
let previous = query(selector(<acro>).before(here()))
.filter(it => it.value == name)
// Marker setzen für diese Verwendung
[#metadata(name)<acro>]
// Beim ersten Mal: volle Form mit Abkürzung, danach: nur Kurzform
if previous.len() == 0 {
link(label("acro-" + name))[
#acronyms.at(name) (#name)
]
} else {
link(label("acro-" + name))[#name]
}
}
#let acro-list() = context {
// Alle verwendeten Akronyme sammeln
let used = query(selector(<acro>))
.map(it => it.value)
.dedup()
// Nur verwendete Akronyme filtern und sortieren
let entries = acronyms.pairs()
.filter(pair => used.contains(pair.at(0)))
.sorted(key: pair => pair.at(0))
table(
columns: (auto, 1fr),
stroke: none,
column-gutter: 1em,
..entries.map(pair => (
[#strong(pair.at(0)) #label("acro-" + pair.at(0))],
[#pair.at(1)]
)).flatten()
)
}

BIN
assets/company-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
assets/dhbw-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

29
code-listing.typ Normal file
View File

@@ -0,0 +1,29 @@
// code-listing.typ
#let code-listing(
body: str,
caption: none,
lang: "text",
label: none,
) = {
show raw: set text(size: 9pt)
let fig = figure(
block(
width: 100%,
inset: (x: 14pt, y: 12pt),
radius: 5pt,
stroke: 0.5pt,
raw(lang: lang, block: true, body.trim()),
),
supplement: "Listing",
kind: "code",
caption: caption
)
if label != none {
[#fig #label]
} else {
fig
}
}

17
declaration.typ Normal file
View File

@@ -0,0 +1,17 @@
// declaration.typ
#let declaration(meta) = [
#heading(level: 1, outlined: false, numbering: none)[Erklärung]
Ich versichere hiermit, dass ich meine Bachelorarbeit mit dem Thema: #emph[#meta.title] selbstständig verfasst und keine anderen als die angegebenen Quellen und Hilfsmittel benutzt habe. Ich versichere zudem, dass die eingereichte elektronische Fassung mit der gedruckten Fassung übereinstimmt.
#v(20mm)
#let months = ("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember")
#text()[#meta.submission_place, #months.at(meta.submission_date.month() - 1) #meta.submission_date.year()]
#v(16mm)
#line(length: 30%)
#meta.author
#pagebreak()
]

361
din-1505-2-alphanumeric.csl Normal file
View File

@@ -0,0 +1,361 @@
<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only" default-locale="de-DE">
<info>
<title>DIN 1505-2 (alphanumeric, Deutsch) - standard superseded by ISO-690</title>
<id>http://www.zotero.org/styles/din-1505-2-alphanumeric</id>
<link href="http://www.zotero.org/styles/din-1505-2-alphanumeric" rel="self"/>
<link href="http://www.angst-vor-dem-leeren-blatt.de/docs/download/zitierrichtlinie_din_1505.pdf" rel="documentation"/>
<link href="http://www.bui.haw-hamburg.de/fileadmin/redaktion/diplom/Lorenzen__litverz.pdf" rel="documentation"/>
<link href="http://de.wikipedia.org/wiki/DIN_1505-2" rel="documentation"/>
<link href="http://forums.zotero.org/discussion/5239/1/first-letter-of-author-as-citation/" rel="documentation"/>
<author>
<name>Sven Rothe</name>
<email>mmoole@googlemail.com</email>
</author>
<contributor>
<name>Julian Onions</name>
<email>julian.onions@gmail.com</email>
</contributor>
<contributor>
<name>Sebastian Karcher</name>
</contributor>
<category citation-format="label"/>
<category field="generic-base"/>
<summary>Style following DIN 1505-2, using the alphanumeric citation keys, for other media types on additional standards
Hinweise zur Benutzung:
* Zitieren von Gesetzen:
- hier müssen manuell §, Abs und S. zur Seitenangabe beim Zitieren eingetragen werden
- im Kurzbeleg wird der Kurztitel verwendet, dafür keine Autoren eintragen!
- als Jahresangabe wird 'Datum des Inkrafttretens' herangezogen, Verwenden nur bei Verweis auf nicht z.Z. gültige Gesetze, z.B. (idF. v. 12.12.1972)
* Zitieren von Normen und Standards - nicht vollständig nach DIN 1505
- Nutzen Sie den Typ 'Bericht' - als Abhilfe, da es keinen Typ 'Standard' gibt.
- als Autor die Kurzbezeichnung inkl. Nummer und Jahr eingeben (z.B. VDI 2222-1997), Vorname leer, Jahr leer
- als Titel den ausführlichen Titel bei Bedarf (z.B. VDI Richtlinie 2222 Blatt 1 - Konstruktionsmethodik - Methodisches Entwickeln von Lösungsprinzipien)</summary>
<!-- This is just a beginning to try to have a DIN 1505 citation style,
Feel free to send me any comments, suggestions etc...
todo:
* basic media types (book, journal article, etc..)
* more media types (according DINxxx) audio video etc...
* fine tuning
* correcting errors
known bugs, help appreciated
* Abbreviations (Mitarb.) & (Hrsg. der Reihe) are missing (contributor, seriesEditor labels)
* "contributor" is not valid as a name variable , nevertheless it works but doesnt validate!
* author etc. first names should not be abbreviated
* reviewed author seems to be not available as variable (newspaper article)
* thesis type does notoffer a PLACE or FACULTY as variable!
how to show the place if it is not included in the University title!?!?
* thesis type: publisher (university), genre (type) dont seem to get through!?
-->
<!-- useful things:
non breaking space: &#160;
narrow no break space: uni202F / &#8239; - but this is not supported widely!
em dash: &#8212;
space: &#032;
tab: &#009;
-->
<updated>2012-09-27T22:06:38+00:00</updated>
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
</info>
<locale xml:lang="de">
<terms>
<term name="anonymous" form="short">o.&#160;A.</term>
<term name="no date" form="short">o.&#160;J.</term>
<term name="collection-editor" form="short">Hrsg.</term>
<term name="retrieved">abgerufen am</term>
<term name="composer" form="short">Komp.</term>
<term name="composer" form="long">Komponist</term>
</terms>
</locale>
<macro name="author">
<names variable="author" delimiter=" ; ">
<name name-as-sort-order="all" sort-separator=", " delimiter=" ; " delimiter-precedes-last="always" font-variant="small-caps"/>
<label form="short" prefix=" (" suffix=")"/>
</names>
</macro>
<macro name="author-container">
<names variable="container-author" delimiter=" ; ">
<name name-as-sort-order="all" sort-separator=", " initialize-with=". " delimiter=" ; " delimiter-precedes-last="always" font-variant="small-caps"/>
<label form="short" prefix=" (" suffix=")"/>
</names>
</macro>
<macro name="editor">
<names variable="editor" delimiter=" ; ">
<name name-as-sort-order="all" sort-separator=", " initialize-with=". " delimiter=" ; " delimiter-precedes-last="always" font-variant="small-caps"/>
<label form="short" prefix=" (" suffix=")"/>
<!-- needed: Label should appear as suffix to EVERY name...!-->
</names>
</macro>
<macro name="editor-collection">
<names variable="collection-editor" delimiter=" ; ">
<name name-as-sort-order="all" sort-separator=", " initialize-with=". " delimiter=" ; " delimiter-precedes-last="always" font-variant="small-caps"/>
<label form="short" prefix=" (" suffix=")"/>
<!-- needed: Label should appear as suffix to EVERY name...!-->
</names>
</macro>
<macro name="composer">
<names variable="composer" delimiter=" ; ">
<name name-as-sort-order="all" sort-separator=", " delimiter=" ; " delimiter-precedes-last="always" font-variant="small-caps"/>
<label form="long" prefix=" (" suffix=")"/>
<!-- needed: Label should appear as suffix to EVERY name...!-->
</names>
</macro>
<!-- <macro name="contributor">
<names variable=" " delimiter=" ; ">
<name name-as-sort-order="all" sort-separator=", " initialize-with=". " delimiter=" ; "
delimiter-precedes-last="always" font-variant="small-caps"/>
<label form="short" prefix=" (" suffix=")"/>
</names>
</macro>-->
<macro name="translator">
<names variable="translator" delimiter=" ; ">
<name name-as-sort-order="all" sort-separator=", " initialize-with=". " delimiter=" ; " delimiter-precedes-last="always" font-variant="small-caps"/>
<label form="short" prefix=" (" suffix=")"/>
<!-- needed: Label should appear as suffix to EVERY name...!-->
</names>
</macro>
<macro name="recipient">
<names variable="recipient" delimiter=" ; ">
<name name-as-sort-order="all" sort-separator=", " initialize-with=". " delimiter=" ; " delimiter-precedes-last="always" font-variant="small-caps"/>
<!--<label form="long" prefix=" (" suffix=")"/>-->
<!-- needed: Label should appear as suffix to EVERY name...!-->
</names>
</macro>
<macro name="access">
<group>
<text term="retrieved" suffix=" "/>
<date variable="accessed">
<date-part name="year" form="long" suffix="-"/>
<date-part name="month" form="numeric-leading-zeros" suffix="-"/>
<date-part name="day" form="numeric-leading-zeros"/>
</date>
<!--<date variable="accessed" form="numeric" date-parts="year-month-day"/> // dd.mm.yyy -->
</group>
</macro>
<macro name="title">
<choose>
<if type="bill legislation" match="any">
<group delimiter=" &#8212; ">
<text variable="title-short" font-style="normal"/>
<text variable="title"/>
</group>
</if>
<else-if type="book graphic legal_case motion_picture report song" match="any">
<text variable="title" font-style="italic"/>
</else-if>
<else>
<text variable="title"/>
</else>
</choose>
</macro>
<macro name="genre">
<choose>
<if type="report thesis manuscript map" match="any">
<group>
<text variable="genre"/>
<!--<text term="number" form="short" suffix=" "/>-->
<text variable="number" prefix=" Nr. "/>
</group>
</if>
</choose>
</macro>
<macro name="volumes">
<group delimiter=" ">
<text term="volume" form="short" plural="false"/>
<number variable="volume" form="numeric"/>
<number variable="number-of-volumes" form="numeric" prefix="v. "/>
</group>
</macro>
<macro name="edition">
<choose>
<if is-numeric="edition">
<group delimiter=" ">
<number variable="edition" form="numeric" suffix=". "/>
<text term="edition" form="short" plural="false"/>
</group>
</if>
<else>
<text variable="edition" suffix="."/>
</else>
</choose>
</macro>
<macro name="pages">
<choose>
<if type="chapter paper-conference article-journal" match="any">
<label variable="page" form="short" suffix="&#160;"/>
<text variable="page"/>
</if>
</choose>
</macro>
<macro name="dimensions">
<group>
<text variable="dimensions"/>
</group>
</macro>
<macro name="medium">
<group>
<text variable="medium"/>
</group>
</macro>
<macro name="scale">
<group>
<text term="scale"/>
<text prefix=" " variable="scale"/>
</group>
</macro>
<macro name="recipient-show">
<choose>
<if type="personal_communication">
<choose>
<if variable="genre">
<text variable="genre" text-case="capitalize-first"/>
</if>
<else>
<text term="letter" text-case="capitalize-first"/>
</else>
</choose>
</if>
</choose>
<text macro="recipient" prefix=", "/>
</macro>
<citation et-al-min="3" et-al-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="false" disambiguate-add-givenname="false" collapse="year">
<sort>
<key variable="citation-label"/>
</sort>
<layout prefix="[" suffix="]" delimiter="; ">
<group delimiter=", ">
<text variable="citation-label"/>
<group>
<label variable="locator" form="short"/>
<text variable="locator"/>
</group>
</group>
</layout>
</citation>
<bibliography et-al-min="9" et-al-use-first="8" second-field-align="flush">
<sort>
<key variable="citation-label"/>
</sort>
<layout>
<text variable="citation-label" prefix="[" suffix="] "/>
<group delimiter=" ; " suffix=":">
<text macro="author"/>
<choose>
<if type="bill book graphic legal_case legislation manuscript map motion_picture report song thesis webpage" match="any">
<!-- except type="chapter article " etc.... -->
<text macro="editor"/>
<text macro="editor-collection"/>
<text macro="composer"/>
</if>
</choose>
<!-- <text macro="contributor"/> -->
<text macro="translator"/>
</group>
<choose>
<!-- Tabelle 1 aus litverz.ps -->
<if type="bill book broadcast graphic legal_case legislation manuscript map motion_picture report song" match="any">
<text prefix=" " macro="title"/>
<text prefix=", " variable="collection-title" font-style="italic"/>
<!--Reihe-->
<text prefix=" (" macro="genre" suffix=")"/>
<text prefix=". " macro="volumes"/>
<text prefix=". " macro="edition"/>
<text prefix=". " macro="medium"/>
<text prefix=". " macro="dimensions"/>
<text prefix=". " variable="publisher-place"/>
<text prefix="&#160;: " variable="publisher"/>
<date prefix=", " variable="issued" form="numeric" date-parts="year"/>
<!-- " (1. Gesamttitel mit Zählung)"
" (2. Gesamttitel mit Zählung)" -->
<text prefix=" &#8211;&#160;" macro="scale"/>
<text prefix=". &#8212;&#160;" variable="note"/>
<text prefix=" &#8212;&#160;ISBN&#160;" variable="ISBN"/>
</if>
<!-- Tabelle 3 aus litverz.ps -->
<else-if type="chapter paper-conference" match="any">
<text prefix=" " macro="title" suffix="."/>
<text prefix=". " term="in" text-case="capitalize-all" suffix=": "/>
<!-- verfahre nach Tabelle 1... -->
<group delimiter=" ; " suffix=": ">
<text macro="author-container"/>
<text macro="editor"/>
<text macro="editor-collection"/>
</group>
<text variable="container-title" font-style="italic"/>
<text prefix=", " variable="collection-title" font-style="italic"/>
<!-- Reihe -->
<text prefix=". " macro="volumes"/>
<!-- <text prefix=" : " variable="title of volumes"/> what is this? -->
<text prefix=". " macro="edition"/>
<text prefix=". " variable="publisher-place"/>
<text prefix="&#160;: " variable="publisher"/>
<date prefix=", " variable="issued" form="numeric" date-parts="year"/>
<!-- " (1. Gesamttitel mit Zählung)"
" (2. Gesamttitel mit Zählung)" -->
<text prefix=". &#8212;&#160;" variable="note"/>
<text prefix=" &#8212;&#160;ISBN&#160;" variable="ISBN"/>
<text prefix=", " macro="pages"/>
</else-if>
<!-- Tabelle 5 aus litverz.ps - Hochschulschriften
(Diplomarbeiten, Dissertationen, Master-A., unverö. Studienarbeiten -->
<else-if type="thesis" match="any">
<text prefix=" " macro="title" font-style="italic"/>
<text prefix=". " macro="edition"/>
<text prefix=". " variable="publisher-place"/>
<text prefix=", " variable="publisher" form="long"/>
<!-- <text prefix=", " variable="faculty"/> -->
<text prefix=", " macro="genre"/>
<date prefix=", " variable="issued" form="numeric" date-parts="year"/>
<text prefix=". &#8212;&#160;" variable="note"/>
</else-if>
<else-if type="webpage post post-weblog" match="any">
<text prefix=" " macro="title" suffix=". " font-style="italic"/>
<text prefix="URL " variable="URL"/>
<text prefix=". - " macro="access"/>
<text prefix=". &#8212;&#160;" variable="container-title"/>
<text prefix=". &#8212;&#160;" variable="note"/>
</else-if>
<!-- Tabelle 2 aus litverz.ps UND -->
<!-- Tabelle 4 aus litverz.ps - Schriften von Tagungen, Konferenzen, Symposien, ...-->
<else-if type="article article-journal article-magazine article-newspaper" match="any">
<text prefix=" " variable="title"/>
<!-- " : Zusatz zum Sachtitel"
". Angabe des Teils"
" (Gesamttitelangabe)" -->
<group>
<text prefix=". " term="in" text-case="capitalize-first" suffix=": "/>
<text macro="editor" suffix=" "/>
<text variable="container-title" font-style="italic"/>
<text prefix=", " variable="collection-title" font-style="italic" suffix="."/>
<!--", unterreihe der zeitschrift/zeitung" -->
</group>
<text prefix=" " macro="volumes"/>
<text prefix=". " variable="publisher-place"/>
<text prefix=", " variable="publisher" form="long"/>
<date prefix=" (" suffix=")" variable="issued" form="numeric" date-parts="year"/>
<text prefix=", Nr.&#160;" variable="issue"/>
<text prefix=", " macro="pages"/>
<text prefix=". &#8212;&#160;" variable="note"/>
<text prefix=" &#8212;&#160;ISBN&#160;" variable="ISBN"/>
</else-if>
<!-- keiner der oben genannten fälle -->
<else>
<group suffix=".">
<text prefix=" " macro="title"/>
<text prefix=", " macro="editor"/>
<text prefix=". " macro="recipient-show"/>
</group>
<group prefix=" " suffix=".">
<text variable="container-title" font-style="italic"/>
<group prefix=", ">
<text variable="volume" font-style="italic"/>
<text variable="issue" prefix="(" suffix=")"/>
</group>
<text prefix=", " macro="pages"/>
</group>
</else>
</choose>
</layout>
</bibliography>
</style>

98
frontpage.typ Normal file
View File

@@ -0,0 +1,98 @@
// Standard-Font (anpassbar)
#let base-font = "Libertinus Serif" // oder "Times New Roman", "TeX Gyre Pagella", ...
// Ein dünner grauer Trenner
#let rule() = line(length: 100%, stroke: 1pt + gray.darken(10%))
// ---- Exportierte API -------------------------------------------------------
/// Erzeugt eine Titelseite.
/// Parameter sind bewusst sprechend und optional, damit du flexibel bleibst.
#let cover-page = (
// Logos
uni-logo: none, // Pfad zur Uni/HS-Logo-Datei (PNG/SVG/PDF)
company-logo: none, // Pfad Firmenlogo (optional)
// Titel / Art / Abschluss
title: "",
subtitle: none, // z.B. "Bachelorarbeit"
degree: none, // z.B. "für die Prüfung zum"
// Studiengang / Hochschule / Standort
program: none, // z.B. "des Studiengangs Informatik"
institution: none, // z.B. "an der Dualen Hochschule BadenWürttemberg Heidenheim"
// Autor/Datum
author: "",
date: datetime,
processing_time: none,
matrikelnummer: none,
kurs: none,
ausbildungsbetrieb: none,
firmenort: none,
erstgutachter: none,
zweitgutachter: none,
// Layout-Parameter
page-size: "a4",
top-gap: 18%, // Abstand nach oben bis zum Logo-Block
logo-width: 110pt, // Zielbreite Logos
gap: 12pt, // Standard-Vertikalabstände
title-size: 16pt,
section-size: 11pt,
author-size: 12pt,
date-size: 12pt,
meta-label-style: text.with(weight: "bold"),
meta-value-style: text,
) => {
// Ganze Seite ohne Kopf/Fuß
page(
paper: page-size,
margin: 2.5cm,
header: none,
footer: none,
)[
#box(width: 100%, height: 15%)[
#columns(2, gutter: 8pt)[
#align(left, if (uni-logo != none and uni-logo != "" and uni-logo != ()) { image(uni-logo, width: logo-width) } else { [] })
#colbreak()
#v(6mm)
#align(right, if (company-logo != none and company-logo != "" and company-logo != ()) { image(company-logo, width: logo-width) } else { [] })
]
]
#align(center)[
#set text(size: 12pt)
//#v(10mm)
#text(size: 20pt, weight: 700)[#title]
#v(6mm)
#text(size: 16pt, weight: 700)[#subtitle]
#v(10mm)
für die Prüfung zum
#v(3mm)
#text(size: 14pt, weight: "bold")[#degree]
#v(10mm)
des #program
#v(0mm)
an der #institution
#v(16mm)
von
#v(2mm)
#text(size: 18pt, weight: "bold")[#author]
#v(8mm)
#let months = ("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember")
#text(size: date-size)[#months.at(date.month() - 1) #date.year()]
]
#place(bottom)[
#set text(size: 11pt)
#table(rows: 5, align: left, stroke: none, columns: (55%, 45%),
[*Bearbeitungszeitraum*], [#processing_time],
[*Matrikelnummer, Kurs*], [#matrikelnummer, #kurs],
[*Ausbildungsbetrieb, Firmenort*], [#ausbildungsbetrieb, #firmenort],
[*Erstgutachter*], [#erstgutachter],
[*Zweitgutachter*], [#zweitgutachter],
)
]
]
}

BIN
images/großes-bild.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

234
main.typ Normal file
View File

@@ -0,0 +1,234 @@
#import "frontpage.typ": cover-page
#import "sperrvermerk.typ": sperrvermerk
#import "declaration.typ" : declaration
#import "abstract.typ" : abstract
#import "code-listing.typ" : code-listing
#import "verzeichnise.typ" : verzeichnise
#import "acro.typ" : acro
#import "@preview/fletcher:0.5.8" as fletcher: diagram, node, edge
#let meta = (
title: "Dies ist der Titel der Bachelorarbeit und bitte ohne Rechtschreibfehler",
degree: "Bachelor of Science",
study_program: "Informatik",
university: "Duale Hochschule Baden-Württemberg Heidenheim",
author: "Max Mustermann",
submission_place: "Abgabeort",
submission_date: datetime(month: 4, year: 2026, day: 1),
processing_time: "12 Wochen",
matrikelnummer: "123456",
kurs: "TINF2023",
ausbildungsbetrieb: "Firma XYZ GmbH",
firmenort: "Heidenheim",
erstgutachter: "Dipl.-Inf. Tester Trester",
zweitgutachter: "Prof. Dr. Rolf Assfalg",
)
#set text(lang: "de", size: 12pt)
#set par(justify: true, leading: 0.65em * 1.25)
#set heading(numbering: "1.")
#show figure: set block(below: 15pt)
#show table: set block(below: 6pt)
#show heading.where(level: 1): it => [
// Schriftgröße der Überschrift
#set text(size: 20pt)
// Abstand NACH der Überschrift
#set block(below: 2.2em)
// Seitenumbruch vor jeder H1 (außer wenn sie die erste Überschrift auf der Seite ist)
#pagebreak(weak: true)
// eigentliche Überschrift wieder ausgeben
#it
]
#show heading.where(level: 2): it => [
// Abstand VOR und NACH der H2-Überschrift
#set block(above: 2.5em, below: 1.5em)
#it
]
// ---------- Titelseite ----------
#cover-page(
uni-logo: "assets/dhbw-logo.png",
company-logo: "assets/company-logo.png",
title: meta.title,
subtitle: "T3000 - Projektarbeit",
degree: meta.degree,
program: meta.study_program,
institution: meta.university,
author: meta.author,
date: meta.submission_date,
processing_time: meta.processing_time,
matrikelnummer: meta.matrikelnummer,
kurs: meta.kurs,
ausbildungsbetrieb: meta.ausbildungsbetrieb,
firmenort: meta.firmenort,
erstgutachter: meta.erstgutachter,
zweitgutachter: meta.zweitgutachter,
// Feintuning (optional)
logo-width: 115pt,
title-size: 18pt,
section-size: 11pt,
author-size: 12pt,
date-size: 10pt,
)
// ---------- Sperrvermerk ----------
#sperrvermerk(meta)
// ---------- Erklärung ----------
#declaration(meta)
// ---------- Abstract ----------
#abstract(meta)
// ---------- Inhaltsverzeichnis ----------
#set page(
numbering: "I",
header: context {
let headings = query(heading.where(level: 1))
let on_this_page = headings.filter(h => h.location().page() == here().page())
if on_this_page.len() == 0 {
let before = headings.filter(h => h.location().page() < here().page())
if before.len() > 0 {
let current = before.last()
align(center, block[
#set text(size: 12pt)
#if current.numbering != none [
#numbering(current.numbering, ..counter(heading).at(current.location()))
#h(0.3em)
]
#current.body
])
line(length: 100%, stroke: 0.5pt)
}
}
},
footer: context {
line(length: 100%, stroke: 0.5pt)
align(center)[#counter(page).display()]
},
)
#counter(page).update(1)
#outline(depth: 2)
#pagebreak()
// ---------- Verzeichnisse ----------
#verzeichnise()
// ---------- Hauptteil ----------
#set page(numbering: "1")
#counter(page).update(1)
// ---------- Kapitel 1 ----------
= Einleitung
== Problemstellung
Seit Jahrzehnten gilt LaTeX als Standardwerkzeug für wissenschaftliches Schreiben, insbesondere wenn präzise Typografie, mathematische Formeln oder technische Dokumentation gefragt sind. Doch trotz seiner Leistungsfähigkeit wirkt LaTeX für viele Anwender veraltet, schwer zugänglich und nur mit viel Einarbeitung effizient nutzbar. In den letzten Jahren ist mit Typst jedoch ein moderner Ansatz entstanden, der die Stärken von LaTeX aufgreift, sie aber mit einer deutlich intuitiveren Syntax, zeitgemäßer Technologie und höherer Produktivität verbindet. Typst bietet eine unmittelbare Vorschau, ein konsistentes Layout-System, eingebaute Features wie Referenzen oder Formeln und eine schnelle Lernkurve. Damit wird es für Studierende, Forschende und Entwickler zunehmend zur attraktiven Alternative. Im Folgenden wird dargestellt, warum Typst in vielen Bereichen als moderner und pragmatischer Ersatz für LaTeX betrachtet werden kann.
== Zielsetzung und Abgrenzung
Die Diskussion um eine mögliche Ersetzung von LaTeX durch Typst gewinnt zunehmend Aufmerksamkeit. LaTeX hat sich über Jahrzehnte als Standard für wissenschaftliche Publikationen etabliert, ist jedoch in vielerlei Hinsicht nicht mehr zeitgemäß. Viele seiner Konzepte stammen aus den 1980er-Jahren und führen heute zu einer hohen Einstiegshürde, komplexen Toolchains sowie einem oft mühsamen Schreibprozess. Typst setzt genau dort an: Es verfolgt das Ziel, die Stärken von LaTeX zu erhalten, gleichzeitig aber ein modernes, benutzerfreundliches und deutlich effizienteres Werkzeug bereitzustellen.
Typst kombiniert eine intuitive, leicht erlernbare Syntax mit einer sofortigen Live-Vorschau, sodass Formatierungen ohne Kompilationsschritte direkt sichtbar sind. Funktionen wie mathematische Formeln, Referenzen, Zitationen oder Layout-Regeln sind integriert, statt über externe Pakete ergänzt werden zu müssen. Damit entfällt ein Großteil der Konfigurationsarbeit, die LaTeX traditionell verlangt. Zudem arbeitet Typst mit einer modernen Rendering-Engine, die konsistente Ergebnisse über verschiedene Plattformen hinweg sicherstellt.
Durch diese Eigenschaften bietet Typst einen Ansatz, der sowohl Einsteigerinnen als auch erfahrenen Nutzerinnen einen produktiveren Schreibfluss ermöglicht. Während LaTeX zweifellos weiterhin für bestimmte Spezialanwendungen relevant bleibt, zeigt sich zunehmend, dass Typst für viele akademische und technische Dokumente eine praktikable, zeitgemäße Alternative darstellt. In zahlreichen Anwendungsfällen kann Typst LaTeX deshalb nicht nur ergänzen, sondern vollständig ersetzen.
// ---------- Kapitel 2 ----------
= Grundlagen
Einfacher Text, Absätze und Überschriften
Die grundlegende Struktur eines Dokuments in Typst wird durch einfachen Text, Absätze und Überschriften definiert. Absätze werden durch eine Leerzeile getrennt, während Überschriften mit dem `=`-Symbol gefolgt von der Überschriftsebene und dem Text erstellt werden. Zum Beispiel erzeugt `= Heading 1` eine Überschrift der ersten Ebene, während `== Heading 2` eine Überschrift der zweiten Ebene erstellt. Diese Struktur ermöglicht eine klare Gliederung des Dokuments und erleichtert die Navigation für den Leser.
Typst bietet auch die Möglichkeit, die Formatierung von Text und Absätzen anzupassen. So können beispielsweise Schriftgröße, Zeilenabstand und Einzüge individuell festgelegt werden. Dies ermöglicht es, das Layout des Dokuments an die spezifischen Anforderungen anzupassen und eine ansprechende Präsentation der Inhalte zu gewährleisten.
== Listen und Aufzählungen
Typst unterstützt verschiedene Arten von Listen#footnote[das ist eine Fußnote], darunter ungeordnete Listen, geordnete Listen und verschachtelte Listen. Ungeordnete Listen werden mit einem Bindestrich `-` erstellt, während geordnete Listen mit einer Zahl gefolgt von einem Punkt `1.` beginnen. Verschachtelte Listen können durch Einrücken erstellt werden, wobei die Einrückungstiefe die Hierarchie der Liste bestimmt. Listen sind ein wichtiges Werkzeug, um Informationen übersichtlich und strukturiert darzustellen, und Typst bietet eine flexible Möglichkeit, diese zu erstellen und anzupassen.
1. Erster Punkt
2. Zweiter Punkt
- Unterpunkt 1
- Unterpunkt 2
3. Dritter Punkt
== Formeln und mathematische Ausdrücke
Typst ermöglicht die einfache Erstellung von mathematischen Formeln und Ausdrücken. Inline-Formeln können durch die Verwendung von Dollarzeichen `$...$` erstellt werden.
$E = "mc"^2$
== Tabellen und Abbildungen
Typst bietet umfangreiche Möglichkeiten zur Erstellung von Tabellen und Abbildungen. Tabellen können mit der `table`-Umgebung erstellt werden, die es ermöglicht, Spalten, Zeilen und Zellen zu definieren. Abbildungen können mit der `figure`-Umgebung erstellt werden, die es ermöglicht, Bilder einzufügen und zu beschriften. Beide Umgebungen bieten zahlreiche Optionen zur Anpassung des Layouts und der Formatierung, um eine ansprechende Präsentation der Inhalte zu gewährleisten. @tab:test-table
#figure(
table(
columns: (auto, auto),
inset: 10pt,
align: (x, y) => (
if x > 0 { center }
else { left }
),
stroke: (x ,y) => if y == 0 { (bottom: 0.5pt + black) },
table.header(
[*Medium (Gas)*], [*ECF [kJ/m³]*]
),
[#acro("XML")], [529],
[N₂ (Stickstoff)], [529],
[Vacuum (Vakuum)], [216],
),
caption: [Test Table]
) <tab:test-table>
== Referenzen und Zitate
Typst bietet eine integrierte Unterstützung für Referenzen und Zitate, die es ermöglicht,Querverweise innerhalb des Dokuments zu erstellen und Literaturangaben zu verwalten. Referenzen können mit der `#label`-Funktion erstellt werden, die es ermöglicht, bestimmte Elemente im Dokument zu kennzeichnen und später darauf zu verweisen. Zitate können mit der `#bibliography`-Funktion erstellt werden, die es ermöglicht, Literaturangaben aus einer BibTeX-Datei zu importieren und im Dokument zu zitieren. Diese Funktionen erleichtern die Erstellung von wissenschaftlichen Arbeiten und ermöglichen eine konsistente und professionelle Präsentation der Inhalte. @DD80
== Code-Listings
Typst unterstützt die Einbindung von Code-Listings, um Quellcode oder andere vorformatierte Texte darzustellen. Code-Listings können mit der `code-listing`-Umgebung erstellt werden, was ich dazu gebastelt habe das Code-Listing-Feature zu ermöglichen. Innerhalb dieser Umgebung kann der Quellcode in verschiedenen Programmiersprachen formatiert und mit Syntax-Highlighting versehen werden, um die Lesbarkeit zu verbessern. Code-Listings sind besonders nützlich, um technische Details oder Beispiele in einem Dokument klar und übersichtlich darzustellen.
#code-listing(
body: "
def hello_world():
print('Hello, World!')
",
caption: [Python-Beispiel],
lang: "python",
label: <lst:python-beispiel>
)
Auch hier gibt es links zu diesem Code-Listing, z.B. in der Einleitung: siehe @lst:python-beispiel.
== Blider
Typst ermöglicht die einfache Einbindung von Bildern in Dokumente. Bilder können mit der `figure`-Umgebung erstellt werden, die es ermöglicht, Bilder einzufügen und zu beschriften. Die `image`-Funktion innerhalb der `figure`-Umgebung ermöglicht die Angabe des Bildpfads sowie optionaler Parameter wie Breite, Höhe und Skalierung. Bilder können auch mit Beschriftungen versehen werden, um sie im Text zu referenzieren. Die Einbindung von Bildern ist ein wichtiger Aspekt bei der Erstellung von ansprechenden und informativen Dokumenten, und Typst bietet eine flexible Möglichkeit, dies zu tun.
#figure(caption: [Großers Bild])[
#image("images/großes-bild.png", width: 100%)
]
// ---------- Kapitel 3 ----------
= Diagramme mit fletcher
// Beispiel eines Diagramms mit fletcher
#figure(
block(width: 80%)[
#scale(x: 100%, y: 100%)[
#diagram(
spacing: (15mm, 10mm),
node-stroke: 1pt,
edge-stroke: 1.5pt,
node((0, 0), [#acro("XML") \ (auch acronyme)], shape: rect, fill: blue.lighten(80%)),
edge("-|>"),
node((1, 0), [Node], shape: rect, fill: green.lighten(80%)),
)
]
],
caption: [Beispiel eines Diagramms mit fletcher]
) <fig:diagramm-fletcher>
Ein einfaches Beispiel für die Erstellung eines Diagramms mit fletcher zeigt Abbildung @fig:diagramm-fletcher. Hier werden zwei Knoten definiert, von denen einer ein Akronym enthält, und durch eine gerichtete Kante verbunden. Die Syntax ist dabei klar strukturiert und ermöglicht eine schnelle Umsetzung von Diagrammen direkt im Dokument.
// ---------- Literatur ----------
#bibliography("refs.bib", title: "Literatur", style: "din-1505-2-alphanumeric.csl")

172
plain.csl Normal file
View File

@@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" version="1.0" class="in-text" default-locale="en-US">
<!-- This style was edited with the Visual CSL Editor (https://editor.citationstyles.org/visualEditor/#) -->
<info>
<title>Plain (BibTeX)</title>
<title-short>Plain</title-short>
<id>http://www.zotero.org/styles/plain</id>
<link rel="self" href="http://www.zotero.org/styles/plain"/>
<author>
<name>Howard Trickey</name>
</author>
<author>
<name>Oren Patashnik</name>
</author>
<author>
<name>Timothé Albouy</name>
<email>timothe.albouy@gmail.com</email>
</author>
<category citation-format="numeric"/>
<summary>Faithful CSL conversion of the standard BibTeX plain.bst style.</summary>
<updated>2025-10-08T17:28:31+00:00</updated>
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under the MIT License</rights>
</info>
<macro name="author">
<group suffix=".">
<names variable="author">
<name delimiter=", " and="text" sort-separator=", "/>
<label prefix=", " form="long"/>
<substitute>
<names variable="editor"/>
<text variable="publisher"/>
<text variable="authority"/>
</substitute>
</names>
</group>
</macro>
<macro name="editor">
<names variable="editor">
<name delimiter=", " and="text" delimiter-precedes-last="never"/>
<label prefix=", "/>
</names>
</macro>
<macro name="title">
<choose>
<if type="book thesis" match="any">
<text variable="title" font-style="italic"/>
</if>
<else>
<text variable="title" text-case="capitalize-first"/>
</else>
</choose>
</macro>
<macro name="year">
<date variable="issued">
<date-part name="year"/>
</date>
</macro>
<macro name="edition">
<group delimiter=" ">
<number variable="edition" form="ordinal"/>
<text term="edition"/>
</group>
</macro>
<macro name="publisher">
<group delimiter=", ">
<text variable="publisher"/>
<text variable="publisher-place"/>
</group>
</macro>
<macro name="sort-key">
<choose>
<if variable="author">
<names variable="author">
<name sort-separator=" " name-as-sort-order="all"/>
</names>
</if>
<else-if variable="editor">
<names variable="editor">
<name sort-separator=" " name-as-sort-order="all"/>
</names>
</else-if>
<else-if variable="authority">
<text variable="authority"/>
</else-if>
<else-if variable="publisher">
<text variable="publisher"/>
</else-if>
<else>
<text variable="title"/>
</else>
</choose>
</macro>
<macro name="container-title">
<text variable="container-title" font-style="italic"/>
</macro>
<macro name="vol-page">
<choose>
<if type="article-journal" match="any">
<text variable="volume"/>
<text variable="issue" prefix="(" suffix=")"/>
<text value=":"/>
<text variable="page"/>
</if>
<else>
<group delimiter=", ">
<group delimiter=" ">
<label variable="volume"/>
<text variable="volume"/>
</group>
<group delimiter=" ">
<label variable="page"/>
<text variable="page"/>
</group>
</group>
</else>
</choose>
</macro>
<citation>
<layout prefix="[" suffix="]" delimiter=", ">
<text variable="citation-number"/>
<text variable="locator"/>
</layout>
</citation>
<bibliography entry-spacing="0" second-field-align="flush">
<sort>
<key macro="sort-key"/>
<key variable="issued" sort="descending"/>
<key variable="title"/>
</sort>
<layout>
<text variable="citation-number" prefix="[" suffix="] "/>
<group delimiter=". " suffix=". ">
<text macro="author"/>
<text macro="title"/>
</group>
<choose>
<if type="article-journal" match="any">
<group delimiter=", " suffix=".">
<text macro="container-title"/>
<text macro="vol-page"/>
<text macro="year"/>
</group>
</if>
<else>
<group delimiter=" " suffix=". ">
<text term="in" text-case="capitalize-first" suffix=" "/>
<group font-style="normal" delimiter=", ">
<text macro="editor"/>
<text macro="container-title"/>
<text macro="vol-page"/>
</group>
</group>
<group delimiter=", " suffix=". ">
<choose>
<if type="report" match="any">
<text value="Technical report"/>
</if>
</choose>
<group delimiter=" ">
<text variable="genre"/>
<text variable="number"/>
</group>
<text macro="publisher"/>
<text macro="edition"/>
<text macro="year" prefix=" "/>
</group>
</else>
</choose>
<text variable="note"/>
</layout>
</bibliography>
</style>

46
readme.md Normal file
View File

@@ -0,0 +1,46 @@
# Projektarbeit Typst Vorlage
## Dokument bauen
```bash
typst compile main.typ
```
Erzeugt `main.pdf` im gleichen Verzeichnis.
## Watch-Modus (automatische Aktualisierung)
```bash
typst watch main.typ
```
Das PDF wird bei jeder Dateiänderung automatisch neu gebaut. Ideal in Kombination mit einem PDF-Viewer, der Hot-Reload unterstützt.
## Zitationsstil
Der Zitationsstil folgt **DIN 1505-2 (alphanumerisch)**.
- Stildatei: `din-1505-2-alphanumeric.csl`
- Eingebunden in `main.typ` via:
```typst
#bibliography("refs.bib", title: "Literatur", style: "din-1505-2-alphanumeric.csl")
```
- Referenz/Editor: https://editor.citationstyles.org/styleInfo/?styleId=http%3A%2F%2Fwww.zotero.org%2Fstyles%2Fdin-1505-2-alphanumeric
### Literatur hinzufügen
1. Eintrag in `refs.bib` ergänzen (BibTeX-Format)
2. Im Text zitieren mit `@schluessel` oder `@schluessel[S. 12ff.]`
3. Nur tatsächlich zitierte Quellen erscheinen im Literaturverzeichnis
### BibTeX-Beispiel
```bibtex
@book{MeinBuch23,
author = {Max Mustermann},
title = {Titel des Buches},
year = {2023},
publisher = {Verlag},
address = {Stadt},
}
```

32
refs.bib Normal file
View File

@@ -0,0 +1,32 @@
@book{BHMH02,
author = {Peter Baumgartner and Hartmut Häfele and Kornelia Maier-Häfele},
title = {E-Learning Praxishandbuch : Auswahl von Lernplattformen; Marktübersicht, Funktionen, Fachbegriffe},
year = {2002},
address = {Innsbruck},
publisher = {StudienVerlag},
isbn = {3-7065-1771-X}
}
@techreport{DD80,
author = {Stuard E. Dreyfus and Hubert L. Dreyfus},
title = {A Five-Stage Model Of The Mental Activities Involved In Directed Skill Acquisition},
institution = {University of California, Berkley},
year = {1980},
url = {http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADA084551&Location=U2&doc=GetTRDoc.pdf}
}
@misc{Fre07,
author = {{Free Software Foundation}},
title = {GNU AFFERO GENERAL PUBLIC LICENSE},
year = {2007},
url = {http://www.gnu.org/licenses/agpl-3.0.de.html}
}
@unpublished{Mus12,
author = {Max Mustermann},
title = {tolles Musterthema},
note = {Studienarbeit},
year = {2012},
address= {Musterstadt}
}

31
sperrvermerk.typ Normal file
View File

@@ -0,0 +1,31 @@
// sperrvermerk.typ
#let sperrvermerk(meta) = [
#heading(level: 1, outlined: false, numbering: none)[Sperrvermerk]
Die vorliegende Bachelorarbeit mit dem Titel #emph[#meta.title] enthält
unternehmensinterne bzw. vertrauliche Informationen der #meta.ausbildungsbetrieb,
ist deshalb mit einem Sperrvermerk versehen und wird ausschließlich
zu Prüfungszwecken am Studiengang #meta.study_program der #meta.university
vorgelegt. Sie ist ausschließlich zur Einsicht durch den zugeteilten
Gutachter, die Leitung des Studiengangs und ggf. den Prüfungsausschuss
des Studiengangs bestimmt.
Es ist untersagt,
- den Inhalt dieser Arbeit als Ganzes oder auszugsweise weiterzugeben,
- Kopien oder Abschriften anzufertigen,
- diese Arbeit zu veröffentlichen oder digital zur Verfügung zu stellen.
Jede anderweitige Einsichtnahme und Veröffentlichung - auch von Teilen -
bedarf der vorherigen Zustimmung durch den Verfasser und #meta.ausbildungsbetrieb.
#v(20mm)
#let months = ("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember")
#text()[#meta.submission_place, #months.at(meta.submission_date.month() - 1) #meta.submission_date.year()]
#v(16mm)
#line(length: 30%)
#meta.author
#pagebreak()
]

35
verzeichnise.typ Normal file
View File

@@ -0,0 +1,35 @@
#import "acro.typ" : acro-list
#let verzeichnise() = [
// ---------- Abkürzungsverzeichnis ----------
#heading(level: 1, numbering: none)[Abkürzungsverzeichnis]
#acro-list()
#pagebreak()
// ---------- Abbildungsverzeichnis ----------
#heading(level: 1, numbering: none)[Abbildungsverzeichnis]
#outline(
title: none,
target: figure.where(kind: image),
)
#pagebreak()
// ---------- Listingsverzeichnis ----------
#heading(level: 1, numbering: none)[Listings]
#outline(
title: none,
target: figure.where(kind: "code"),
)
#pagebreak()
// ---------- Tabellenverzeichnis ----------
#heading(level: 1, numbering: none)[Tabellenverzeichnis]
#outline(
title: none,
target: figure.where(kind: table),
)
#pagebreak()
]