commit a8017ffd24114f53fb6e7d63b4ac703299cdbf9e Author: Jannik Meier Date: Tue Jun 9 19:43:18 2026 +0200 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..66ab107 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.claude +abgaben/*.pdf +abgaben/gruppe0.yaml +abgaben/*.md +abgaben/referenzen.bib +abgaben/metadata.yaml +.DS_Store \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..871e317 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,38 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "SM: Aktuelle Abgabe rendern", + "type": "shell", + "command": "make render FILE='${relativeFile}'", + "options": { + "cwd": "${workspaceFolder}" + }, + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "shared", + "clear": true + }, + "problemMatcher": [] + }, + { + "label": "SM: Alle Abgaben rendern", + "type": "shell", + "command": "make all", + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "presentation": { + "reveal": "always", + "panel": "shared", + "clear": true + }, + "problemMatcher": [] + } + ] +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ff8eaa5 --- /dev/null +++ b/Makefile @@ -0,0 +1,67 @@ +export PATH := /Library/TeX/texbin:$(PATH) + +TEMPLATE := templates/sm-template.tex +DEFAULTS := templates/sm-defaults.yaml +FILENAME_TPL := templates/filename.tpl +META_FILE ?= abgaben/metadata.yaml +PANDOC := pandoc + +ABS_TEMPLATE := $(abspath $(TEMPLATE)) +ABS_DEFAULTS := $(abspath $(DEFAULTS)) +ABS_META := $(abspath $(META_FILE)) +ABS_FILENAME_TPL := $(abspath $(FILENAME_TPL)) + +SOURCES := $(shell find abgaben -name "*.md" 2>/dev/null) + +.PHONY: all render clean help + +# -- Alle Abgaben ------------------------------------------------------------- + +all: + @for src in $(SOURCES); do \ + $(MAKE) --no-print-directory render FILE=$$src || exit 1; \ + done + +# -- Einzeldatei (VSCode-Task / manuell) -------------------------------------- +# PDF-Dateiname wird aus den Metadaten ermittelt: Gruppe0_SM-1b_Vorbereitung.pdf +# Aufruf: make render FILE=abgaben/irgendwas.md + +render: +ifndef FILE + $(error Bitte FILE angeben: make render FILE=abgaben/datei.md) +endif + $(eval SRCDIR := $(dir $(abspath $(FILE)))) + $(eval OUTNAME := $(shell $(PANDOC) \ + --template=$(ABS_FILENAME_TPL) \ + --metadata-file=$(ABS_META) \ + -t plain "$(FILE)" 2>/dev/null | tr -d '\n\r')) + @if [ -z "$(OUTNAME)" ]; then \ + echo "FEHLER: PDF-Name konnte nicht aus Metadaten ermittelt werden."; \ + echo " Pflichtfelder in Frontmatter: gruppe, aufgabenkennung"; \ + exit 1; \ + fi + @echo "Baue $(FILE) --> $(SRCDIR)$(OUTNAME)..." + cd "$(SRCDIR)" && $(PANDOC) "$(notdir $(FILE))" \ + --defaults=$(ABS_DEFAULTS) \ + --template=$(ABS_TEMPLATE) \ + --metadata-file=$(ABS_META) \ + -o "$(OUTNAME)" + @echo " => $(SRCDIR)$(OUTNAME)" + +# -- Aufraeumen --------------------------------------------------------------- + +clean: + find abgaben -name "*.pdf" -delete 2>/dev/null; true + @echo "PDFs geloescht." + +# -- Hilfe -------------------------------------------------------------------- + +help: + @echo "Verwendung:" + @echo " make Alle Abgaben bauen" + @echo " make render FILE=abgaben/.md Einzelne Datei rendern" + @echo " make META_FILE=abgaben/x.yaml ... Andere Metadaten-Datei" + @echo " make clean Alle PDFs loeschen" + @echo "" + @echo "PDF-Name aus Metadaten: Gruppe0_SM-1b_Vorbereitung.pdf" + @echo "VSCode: Cmd+Shift+B rendert die aktuell geoeffnete Datei." diff --git a/README.md b/README.md new file mode 100644 index 0000000..5a58e30 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +## Requirements + +OS: Macos +Software: +- Tex Renderer +- pandoc +- make +Tex Packages: +- truncate +- lastpage +- fancyhdr +- lm +- microtype + + +## Installation + +```sh +brew install pandoc basictex + +sudo tlmgr update --self +sudo tlmgr install lastpage fancyhdr lm microtype truncate +``` + +## Usage + +Create markdown Files with frontmatter (see example). Run `make render FILE=abgaben/example.md` + +```sh +make help # see all commands + +make render FILE= # render specific file +make # render all files +``` diff --git a/abgaben/.gitkeep b/abgaben/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/abgaben/metadata.yaml.example b/abgaben/metadata.yaml.example new file mode 100644 index 0000000..b26ea80 --- /dev/null +++ b/abgaben/metadata.yaml.example @@ -0,0 +1,13 @@ +gruppe: 0 +usecase: "USE CASE" + +mitglieder: + - name: "John Doe" + matrikel: "1000001" + +hochschule: "Hochschule / Uni" +fachbereich: "Fachbereich VI" +studiengang: "B.Sc. IT-Sicherheit Online" +modul: "" +dozent: "" +semester: "" diff --git a/templates/filename.tpl b/templates/filename.tpl new file mode 100644 index 0000000..3e75212 --- /dev/null +++ b/templates/filename.tpl @@ -0,0 +1 @@ +Gruppe$gruppe$_SM-$kapitelkennung$$if(aufgabentyp)$_$aufgabentyp$$endif$.pdf \ No newline at end of file diff --git a/templates/sm-defaults.yaml b/templates/sm-defaults.yaml new file mode 100644 index 0000000..77d3067 --- /dev/null +++ b/templates/sm-defaults.yaml @@ -0,0 +1,8 @@ +from: markdown+smart+fenced_code_blocks+inline_code_attributes+bracketed_spans +to: pdf +# template wird im Makefile als absoluter Pfad übergeben (wegen cd-Aufruf) +pdf-engine: pdflatex +citeproc: true +number-sections: true +standalone: true +# reference-section-title: Literaturverzeichnis diff --git a/templates/sm-template.tex b/templates/sm-template.tex new file mode 100644 index 0000000..a87f778 --- /dev/null +++ b/templates/sm-template.tex @@ -0,0 +1,185 @@ +\documentclass[12pt,a4paper]{article} + +% --- Encoding & Language --- +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage[ngerman]{babel} +\usepackage{microtype} +\usepackage{lmodern} + +% --- Page Layout --- +\usepackage[a4paper, + top=2.5cm, bottom=2.5cm, + left=2.5cm, right=2.5cm, + headheight=15pt]{geometry} + +% --- Header / Footer --- +\usepackage{fancyhdr} +\usepackage{lastpage} +\usepackage{truncate} + + +% --- Tables & Figures --- +\usepackage{booktabs} +\usepackage{longtable} +\usepackage{array} +\usepackage{calc} +\usepackage{float} +\usepackage{graphicx} +\usepackage{caption} +\usepackage{subcaption} +\usepackage{xcolor} +\makeatletter +\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} +\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} +\makeatother +\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} + +% --- Math --- +\usepackage{amsmath} +\usepackage{amssymb} + +% --- Code --- +\usepackage{fancyvrb} +\usepackage{listings} +$if(highlighting-macros)$ +$highlighting-macros$ +$endif$ + +% --- Hyperlinks --- +\usepackage{hyperref} +\hypersetup{ + colorlinks=true, + linkcolor=black, + filecolor=black, + citecolor=black, + urlcolor=blue, + pdftitle={$title$}, + pdfauthor={Gruppe $if(gruppe)$$gruppe$$endif$}, +} + +% --- Pandoc compatibility --- +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} + +% --- Absatzformatierung: kein Einzug, sichtbarer Abstand zwischen Absaetzen --- +\setlength{\parindent}{0pt} +\setlength{\parskip}{0.6\baselineskip} + +% --- Section breaks: jede H1 (section) beginnt auf einer neuen Seite --- +\let\oldsection\section +\renewcommand{\section}{\clearpage\oldsection} + +% --- CSL Bibliography (pandoc 3.x --citeproc, kein enumitem nötig) --- +$if(csl-refs)$ +\def\citeproctext{} +\def\citeproc#1#2{\begingroup\def\citeproctext{#2}\cite{#1}\endgroup} +\makeatletter + \let\@cite@ofmt\@firstofone + \def\@biblabel#1{} + \def\@cite#1#2{{#1\if@tempswa , #2\fi}} +\makeatother +\newlength{\cslhangindent} +\setlength{\cslhangindent}{1.5em} +\newlength{\csllabelwidth} +\setlength{\csllabelwidth}{3em} +\newenvironment{CSLReferences}[2] + {\begin{list}{}{% + \setlength{\leftmargin}{\cslhangindent} + \setlength{\itemindent}{-1\cslhangindent} + \setlength{\parsep}{\parskip} + \setlength{\itemsep}{#2\baselineskip}}} + {\end{list}} +\newcommand{\CSLBlock}[1]{\item{}\textnormal{#1}\strut} +\newcommand{\CSLLeftMargin}[1]{\item[\textnormal{#1}]} +\newcommand{\CSLRightInline}[1]{\textnormal{\hangindent0em #1}} +\newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1} +$endif$ + +% ============================================================================= +% Metadata commands (with defaults) +% ============================================================================= +$if(hochschule)$\newcommand{\SMHochschule}{$hochschule$}$else$\newcommand{\SMHochschule}{Hochschule (nicht gesetzt)}$endif$ +$if(fachbereich)$\newcommand{\SMFachbereich}{$fachbereich$}$else$\newcommand{\SMFachbereich}{Fachbereich Informatik}$endif$ +$if(studiengang)$\newcommand{\SMStudiengang}{$studiengang$}$else$\newcommand{\SMStudiengang}{B.Sc. IT-Sicherheit}$endif$ +$if(modul)$\newcommand{\SMModul}{$modul$}$else$\newcommand{\SMModul}{Sicherheitsmanagement (SM 2026)}$endif$ +$if(dozent)$\newcommand{\SMDozent}{$dozent$}$else$\newcommand{\SMDozent}{T. Wa\ss{}mann}$endif$ +$if(aufgabenkennung)$\newcommand{\SMAufgabenkennung}{$aufgabenkennung$}$else$\newcommand{\SMAufgabenkennung}{}$endif$ +$if(aufgabentyp)$\newcommand{\SMAufgabentyp}{$aufgabentyp$}$else$\newcommand{\SMAufgabentyp}{}$endif$ +$if(gruppe)$\newcommand{\SMGruppe}{$gruppe$}$else$\newcommand{\SMGruppe}{X}$endif$ +$if(usecase)$\newcommand{\SMUsecase}{$usecase$}$else$\newcommand{\SMUsecase}{}$endif$ +$if(semester)$\newcommand{\SMSemester}{$semester$}$else$\newcommand{\SMSemester}{}$endif$ +$if(abgabedatum)$\newcommand{\SMAbgabedatum}{$abgabedatum$}$else$\newcommand{\SMAbgabedatum}{\today}$endif$ +$if(kapitel)$\newcommand{\SMKapitel}{$kapitel$}$else$\newcommand{\SMKapitel}{\text{}}$endif$ +$if(kapitelkennung)$\newcommand{\SMKapitelkennung}{$kapitelkennung$}$else$\newcommand{\SMKapitelkennung}{\text{}}$endif$ + +% ============================================================================= +% Header / Footer (every page except title) +% ============================================================================= +\pagestyle{fancy} +\fancyhf{} +\fancyhead[L]{\small\textbf{Gruppe~\SMGruppe{}} - \SMKapitelkennung{}: \truncate{6 0ex}{\SMKapitel{}}} +\fancyhead[R]{\small\SMAufgabenkennung~-~\SMAufgabentyp} +\fancyfoot[C]{\small Seite~\thepage~von~\pageref{LastPage}} +\renewcommand{\headrulewidth}{0.4pt} +\renewcommand{\footrulewidth}{0pt} + +% ============================================================================= +\begin{document} + +% --- Title Page -------------------------------------------------------------- +\begin{titlepage} + \thispagestyle{empty} + \centering + + % uni / studiengang + {\Large\textbf{\SMHochschule}}\par\vspace{0.25cm} + {\large\SMFachbereich}\par\vspace{0.25cm} + {\large\SMStudiengang}\par + + \vspace{0.8cm} + + % modul / dozent + {\normalsize Modul:~\textbf{\SMModul}}\par\vspace{0.4cm} + {\normalsize Dozent:~\SMDozent}\par + + \vspace{0.8cm} + \noindent\rule{\linewidth}{0.6pt}\par + + % aufgabe / thema + \vspace{1.2cm} + {\LARGE\textbf{\SMAufgabentyp{} \SMAufgabenkennung}}\par\vspace{0.35cm} + {\normalsize \textbf{\SMKapitelkennung{}:} \SMKapitel{}}\par + \vspace{0.8cm} + + \noindent\rule{\linewidth}{0.6pt}\par + + % gruppen infos + \vspace{0.8cm} + {\large\textbf{Gruppe~\SMGruppe}}\par\vspace{0.25cm} + $if(usecase)$\vspace{0.35cm}{\normalsize Use-Case:~\SMUsecase}\par$endif$ + + \vspace{0.4cm} + {\normalsize\textbf{Gruppenmitglieder:}}\par + \vspace{0.4cm} + $for(mitglieder)${\normalsize $it.name$$if(it.matrikel)$~~(Matr.-Nr.~$it.matrikel$)$endif$}\par\vspace{0.15cm} + $endfor$ + + % semester + \vfill + {\normalsize Semester:~\SMSemester}\par + {\normalsize Abgabedatum:~\SMAbgabedatum}\par +\end{titlepage} + +\setcounter{page}{1} + +% --- Table of Contents ------------------------------------------------------- +$if(toc)$ +\tableofcontents +\clearpage +$endif$ + +% --- Body -------------------------------------------------------------------- +$body$ + +\end{document}