feat: package definiton with library and template

This commit is contained in:
orangerot 2025-09-09 13:18:10 +02:00
parent c6e566775d
commit 2ed73f8bf4
14 changed files with 185 additions and 76 deletions

View file

@ -17,20 +17,20 @@ Die Vorlage enthält zwei Optionen den Fragebogen zu erstellen. Empfohlen ist da
Erstellen mit Template. Dafür müssen lediglich die Argumente in der Datei
`main.typ` ausgefüllt werden.
```typst
#import "lib.typ": oral-post-exam
#import "lib.typ": exam-report, event
#show: oral-post-exam.with(
#show: exam-report.with(
lecture: "", // Fach
date: datetime(year: 0, month: 1, day: 1), // Prüfungsdatum
examiner: "", // PrüferIn (Prof)
assistant: "", // BeisitzerIn
did_pass: none, // Bestanden? true || false
exam_duration: duration(minutes: 0), // Prüfungsdauer
attendance: (:
/* Veranstaltung, Jahr, regelmäßig besucht? */
"Vorlesung": (year: "", did_attend: ""),
"Übung": (year: "", did_attend: ""),
"Tutorium": (year: "", did_attend: ""),
attendance: (
/* Veranstaltung, Jahr, regelmäßig besucht? */
event(name: "Vorlesung", year: "", did_attend: ""),
event(name: "Übung", year: "", did_attend: ""),
event(name: "Tutorium", year: "", did_attend: ""),
),
preparation_time: [
// Wie lange und wie hast alleine bzw. mit anderen vorbereitet?

View file

@ -2,18 +2,22 @@
//
// SPDX-License-Identifier: MIT
#let oral-post-exam(
#let event(name: "", year: "", did_attend: "") = (
box(height: 1.2em)[*#name*], [#year], [#did_attend]
)
#let exam-report(
lecture: "", // Fach
date: datetime(year: 0, month: 1, day: 1), // Prüfungsdatum
examiner: "", // PrüferIn (Prof)
assistant: "", // BeisitzerIn
did_pass: none, // Bestanden? true || false
exam_duration: duration(minutes: 0), // Prüfungsdauer
attendance: (:
/* Veranstaltung, Jahr, regelmäßig besucht? */
"Vorlesung": (year: "", did_attend: ""),
"Übung": (year: "", did_attend: ""),
"Tutorium": (year: "", did_attend: ""),
attendance: (
/* Veranstaltung, Jahr, regelmäßig besucht? */
event(name: "Vorlesung", year: "", did_attend: ""),
event(name: "Übung", year: "", did_attend: ""),
event(name: "Tutorium", year: "", did_attend: ""),
),
preparation_time: [
// Wie lange und wie hast alleine bzw. mit anderen vorbereitet?
@ -34,13 +38,6 @@
) = [
#let checkbox(checked: false) = if (checked) {$times.square$} else {$square$}
#let events = (
"Vorlesung": (year: "", did_attend: ""),
"Übung": (year: "", did_attend: ""),
"Tutorium": (year: "", did_attend: ""),
..attendance
)
#show <date>: if date.year() > 0 {date.display("[day].[month].[year]")}
#show <examiner>: examiner
#show <assistant>: assistant
@ -64,8 +61,7 @@
let _ = g.remove("label")
table(..g,
..it.fields().children.at(0).children,
..events.pairs().map(((location, (year, did_attend))) =>
(box(height: 1.2em)[*#location*], [#year], [#did_attend])).flatten()
..(attendance + 3*(event(),)).slice(0,3).flatten()
)
}

View file

@ -1,17 +1,17 @@
#import "lib.typ": oral-post-exam
#import "lib.typ": exam-report, event
#show: oral-post-exam.with(
#show: exam-report.with(
lecture: "", // Fach
date: datetime(year: 0, month: 1, day: 1), // Prüfungsdatum
examiner: "", // PrüferIn (Prof)
assistant: "", // BeisitzerIn
did_pass: none, // Bestanden? true || false
exam_duration: duration(minutes: 0), // Prüfungsdauer
attendance: (:
/* Veranstaltung, Jahr, regelmäßig besucht? */
"Vorlesung": (year: "", did_attend: ""),
"Übung": (year: "", did_attend: ""),
"Tutorium": (year: "", did_attend: ""),
attendance: (
/* Veranstaltung, Jahr, regelmäßig besucht? */
event(name: "Vorlesung", year: "", did_attend: ""),
event(name: "Übung", year: "", did_attend: ""),
event(name: "Tutorium", year: "", did_attend: ""),
),
preparation_time: [
// Wie lange und wie hast alleine bzw. mit anderen vorbereitet?

View file

@ -16,9 +16,9 @@ Zum Erstellen des Dokumentes müssen lediglich die Argumente in der Datei
`main.typ` ausgefüllt werden.
```typst
#import "lib.typ": oral-exam, KIND
#import "lib.typ": exam-report, event, KIND
#show: oral-exam.with(
#show: exam-report.with(
study: "", // Studiengang
lecture: "", // Fach
kind: KIND.NONE, // Prüfungsart KIND.{DIPLOM, STAATSEXAM, STUDIENBEGLEITEND, BACHELOR, MASTER}
@ -29,12 +29,12 @@ Zum Erstellen des Dokumentes müssen lediglich die Argumente in der Datei
exam_duration: duration(minutes: 0), // Prüfungsdauer
checked_knowledge_gaps: none, // Wurde Unwissen abgeprüft?
attendance: (
// Titel der Vorlesung, Dozent, Wann gehört, SWS, ECTS, LP
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
/* Titel der Vorlesung, Dozent, Wann gehört, SWS, ECTS, LP */
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
),
attendance_worth: [
// Wie regelmäßig hast du die Lehrveranstaltungen besucht? Hat sich der

View file

@ -7,7 +7,11 @@
"NONE": ""
)
#let oral-exam(
#let event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: "") = (
name, lecturer, year, sws, ects, lp
)
#let exam-report(
study: "", // Studiengang
lecture: "", // Fach
kind: KIND.NONE, // Prüfungsart KIND.{DIPLOM, STAATSEXAM, STUDIENBEGLEITEND, BACHELOR, MASTER}
@ -18,12 +22,12 @@
exam_duration: duration(minutes: 0), // Prüfungsdauer
checked_knowledge_gaps: none, // Wurde Unwissen abgeprüft?
attendance: (
// Titel der Vorlesung, Dozent, Wann gehört, SWS, ECTS, LP
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
/* Titel der Vorlesung, Dozent, Wann gehört, SWS, ECTS, LP */
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
),
attendance_worth: [
// Wie regelmäßig hast du die Lehrveranstaltungen besucht? Hat sich der
@ -92,7 +96,7 @@
)
#show <attendance>: it => table(..grid_arguments(it),
..it.fields().children.at(0).children,
..(attendance.map(lecture => lecture.values()).flatten() + 5*6*([],)).slice(0,count: 5*6)
..(attendance + 5*(event(),)).slice(0,5).flatten()
)
#show <checked_knowledge_gaps>: [
#h(1fr)
@ -106,5 +110,3 @@
#doc
]
#oral-exam()[]

View file

@ -1,6 +1,6 @@
#import "lib.typ": oral-exam, KIND
#import "lib.typ": exam-report, event, KIND
#show: oral-exam.with(
#show: exam-report.with(
study: "", // Studiengang
lecture: "", // Fach
kind: KIND.NONE, // Prüfungsart KIND.{DIPLOM, STAATSEXAM, STUDIENBEGLEITEND, BACHELOR, MASTER}
@ -11,12 +11,12 @@
exam_duration: duration(minutes: 0), // Prüfungsdauer
checked_knowledge_gaps: none, // Wurde Unwissen abgeprüft?
attendance: (
// Titel der Vorlesung, Dozent, Wann gehört, SWS, ECTS, LP
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
(lecture: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
/* Titel der Vorlesung, Dozent, Wann gehört, SWS, ECTS, LP */
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
),
attendance_worth: [
// Wie regelmäßig hast du die Lehrveranstaltungen besucht? Hat sich der

View file

@ -16,9 +16,9 @@ Zum Erstellen des Dokumentes müssen lediglich die Argumente in der Datei
`main.typ` ausgefüllt werden.
```typst
#import "lib.typ": oral-exam, KIND
#import "lib.typ": exam-report, event, KIND
#show: oral-exam.with(
#show: exam-report.with(
study: "", // Studiengang
lecture: "", // Fach
kind: KIND.NONE, // Prüfungsart KIND.{WAHLPFLICHT, VERTIEFUNGSFACH, ERGUENZUNGSFACH}
@ -30,10 +30,10 @@ Zum Erstellen des Dokumentes müssen lediglich die Argumente in der Datei
exam_duration: duration(minutes: 0), // Prüfungsdauer
attendance: (
/* Veranstaltung, Dozent(in), Jahr, regelmäßig besucht? */
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
),
attendance_worth: [
// Hat sich der Besuch / Nichtbesuch der Veranstaltung für dich gelohnt?

View file

@ -9,7 +9,11 @@
"NONE": ""
)
#let oral-exam(
#let event(name: "", lecturer: "", year: "", did_attend: "") = (
name, lecturer, year, did_attend
)
#let exam-report(
study: "", // Studiengang
lecture: "", // Fach
kind: KIND.NONE, // Prüfungsart KIND.{WAHLPFLICHT, VERTIEFUNGSFACH, ERGUENZUNGSFACH}
@ -21,10 +25,10 @@
exam_duration: duration(minutes: 0), // Prüfungsdauer
attendance: (
/* Veranstaltung, Dozent(in), Jahr, regelmäßig besucht? */
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
),
attendance_worth: [
// Hat sich der Besuch / Nichtbesuch der Veranstaltung für dich gelohnt?
@ -81,13 +85,10 @@
let g = it.fields()
let _ = g.remove("children")
let _ = g.remove("label")
let events = attendance.map(((lecture, lecturer, year, did_attend)) =>
(lecture, lecturer, year, did_attend)
).flatten()
table(..g,
..it.fields().children.at(0).children,
..(events + 4*4*([],)).slice(0,4*4)
..(attendance + 4*(event(),)).slice(0,4).flatten()
)
}

View file

@ -1,6 +1,6 @@
#import "lib.typ": oral-exam, KIND
#import "lib.typ": exam-report, event, KIND
#show: oral-exam.with(
#show: exam-report.with(
study: "", // Studiengang
lecture: "", // Fach
kind: KIND.NONE, // Prüfungsart KIND.{WAHLPFLICHT, VERTIEFUNGSFACH, ERGUENZUNGSFACH}
@ -12,10 +12,10 @@
exam_duration: duration(minutes: 0), // Prüfungsdauer
attendance: (
/* Veranstaltung, Dozent(in), Jahr, regelmäßig besucht? */
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
(lecture: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
),
attendance_worth: [
// Hat sich der Besuch / Nichtbesuch der Veranstaltung für dich gelohnt?

3
src/computer-science.typ Normal file
View file

@ -0,0 +1,3 @@
#import "../muendliche-nachpruefung/lib.typ" as oral-post-exam
#import "../muendliche-pruefung/lib.typ" as oral-exam

3
src/lib.typ Normal file
View file

@ -0,0 +1,3 @@
#import "computer-science.typ"
#import "mathmatics.typ"

2
src/mathmatics.typ Normal file
View file

@ -0,0 +1,2 @@
#import "../muendliche-pruefung-mathematik/lib.typ" as oral-exam

79
template/main.typ Normal file
View file

@ -0,0 +1,79 @@
#import "@local/fsmi-exam-report:0.1.0": computer-science, mathmatics
/* Choose accordingly: */
// #import mathmatics.oral-exam: exam-report, event, KIND
// #import computer-science.oral-exam: exam-report, event, KIND
#import computer-science.oral-post-exam: exam-report, event
#show: exam-report.with(
lecture: "", // Fach
date: datetime(year: 0, month: 1, day: 1), // Prüfungsdatum
exam_duration: duration(minutes: 0), // Prüfungsdauer
examiner: "", // PrüferIn (Prof)
..if exam-report in (computer-science.oral-exam.exam-report, computer-science.oral-post-exam.exam-report) {(
assistant: "", // BeisitzerIn
)},
..if computer-science.oral-post-exam.exam-report == exam-report {(
did_pass: none, // Bestanden? true || false
)},
attendance:
if computer-science.oral-post-exam.exam-report == exam-report {(
/* Veranstaltung, Jahr, regelmäßig besucht? */
event(name: "Vorlesung", year: "", did_attend: ""),
event(name: "Übung", year: "", did_attend: ""),
event(name: "Tutorium", year: "", did_attend: ""),
)} else
if computer-science.oral-exam.exam-report == exam-report {(
/* Veranstaltung, Dozent(in), Jahr, regelmäßig besucht? */
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
event(name: "", lecturer: "", year: "", did_attend: ""),
)} else
if mathmatics.oral-exam.exam-report == exam-report {(
/* Titel der Vorlesung, Dozent, Wann gehört, SWS, ECTS, LP */
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
event(name: "", lecturer: "", year: "", sws: "", ects: "", lp: ""),
)},
preparation_time: [
// Wie lange und wie hast alleine bzw. mit anderen vorbereitet?
// Hier ist Platz für deinen Kommentar
],
agreements: [
// Fanden vor der Prüfung Absprachen zu Form oder Inhalt statt? Wurden sie eingehalten?
// Hier ist Platz für deinen Kommentar
],
preparations: [
// Welche Tips zur Vorbereitung kannst Du geben?
// Hier ist Platz für deinen Kommentar
],
examiner_behavior: [
// Wie war der Prüfungsstil des Prüfers / der Prüferin?
// Hier ist Platz für deinen Kommentar
],
examinee_behavior: [
// Kannst Du Ratschläge Verhalten in der Prüfung geben?
// Hier ist Platz für deinen Kommentar
],
..if exam-report in (computer-science.oral-exam.exam-report, mathmatics.oral-exam.exam-report) {(
study: "", // Studiengang
attendance_worth: [
// Hat sich der Besuch / Nichtbesuch der Veranstaltung für dich gelohnt?
],
examiner_recommendation: (none, [ // true, false
// Kannst du ihn / sie weiterempfehlen? Warum?
]),
)},
..if mathmatics.oral-exam.exam-report == exam-report {(
checked_knowledge_gaps: none, // Wurde Unwissen abgeprüft?
literature: [
// Welche Literatur hast du benutzt (Bücher, Skripten, Vorlesungsmitschriften)?
],
)},
)
// Schreibe bitte möglichst viele Fragen und Antworten auf.
// Hier ist Platz für deinen Kommentar

23
typst.toml Normal file
View file

@ -0,0 +1,23 @@
# for a description of available keys, see https://github.com/typst/packages/?tab=readme-ov-file#package-format
[package]
name = "fsmi-exam-report"
version = "0.1.0"
entrypoint = "src/lib.typ"
authors = [
"Gero Beckmann <orangerot@orangerot.dev>"
]
license = "MIT"
description = "Exam Reports for Fachschaft Mathematik/Informatik at the Karlsruhe Institute of Technology"
homepage = ""
repository = ""
keywords = []
categories = []
disciplines = []
# compiler = ""
[template]
path = "template"
entrypoint = "main.typ"
# thumbnail = "thumbnail.png"