From 23134f98867da201f748e9e139976ff358612d6a Mon Sep 17 00:00:00 2001 From: Simon Bruder Date: Sat, 11 Dec 2021 16:14:26 +0100 Subject: [PATCH] Init --- .drone.yml | 18 +++++++ .envrc | 1 + .gitattributes | 1 + .gitignore | 13 +++++ LICENSE | 19 +++++++ Makefile | 17 +++++++ README.md | 13 +++++ flake.lock | 43 ++++++++++++++++ flake.nix | 42 ++++++++++++++++ lint.sh | 30 +++++++++++ podcastproto.cls | 127 +++++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 324 insertions(+) create mode 100644 .drone.yml create mode 100644 .envrc create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100755 lint.sh create mode 100644 podcastproto.cls diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..bf2625d --- /dev/null +++ b/.drone.yml @@ -0,0 +1,18 @@ +kind: pipeline +name: default +type: exec + +steps: + - name: lfs + commands: + - git lfs install + - git lfs pull + + - name: lint + commands: + - ./lint.sh + + - name: build + commands: + - nix build -L + - readlink -f result diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ce96537 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +attachments/*.pdf filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9448001 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.aux +*.fdb_latexmk +*.fls +*.log +*.out +*.pdf +*.synctex.gz +*.toc +*.xdv + +!/attachments/*.pdf + +/result diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fff17bb --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright 2020-2021 Simon Bruder + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..de99379 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +.PHONY: all +all: $(patsubst %.tex,%.pdf,$(wildcard *.tex)) + +%-sitzung.pdf: %-sitzung.tex podcastproto.cls + latexmk -xelatex $< + +clean: + rm -f \ + *.aux \ + *.fdb_latexmk \ + *.fls \ + *.log \ + *.out \ + *.pdf \ + *.synctex.gz \ + *.toc \ + *.xdv diff --git a/README.md b/README.md new file mode 100644 index 0000000..6d3aba8 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Redacted version of protocol template + +Since the production repository for the protocols includes personal data, +it can’t be published. +This repository includes a snapshot of the templates used to generate the protocols. + +## How to get dates of all meetings + + grep 'date=\\DTMdisplaydate' -ri *.tex | sort -n | sed -r 's/([0-9]*)-sitzung.tex: date=\\DTMdisplaydate\{([0-9][0-9][0-9][0-9])\}\{([0-9]*)\}\{([0-9]*)\}\{-1\},/\4.\3.\2: \1. Sitzung/' | sed -r 's/(^|\.)([0-9])(\.|:)/\10\2\3/g' + +## License + +The MIT License, see [LICENSE](./LICENSE) for the full text. diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..8312ede --- /dev/null +++ b/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1619345332, + "narHash": "sha256-qHnQkEp1uklKTpx3MvKtY6xzgcqXDsz5nLilbbuL+3A=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "2ebf2558e5bf978c7fb8ea927dfaed8fefab2e28", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1619796933, + "narHash": "sha256-Tw9QyuOL8ROhMKkpYBmj8r8h9ehEn9JKhZ+VyK4OfMI=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "c8dff328e51f62760bf646bc345e3aabcfd82046", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..cbe353e --- /dev/null +++ b/flake.nix @@ -0,0 +1,42 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, flake-utils, nixpkgs }: flake-utils.lib.eachDefaultSystem (system: rec { + packages.p-seminar-protocols = nixpkgs.legacyPackages.${system}.callPackage ({ stdenv, texlive }: + let + texlive' = texlive.combine { + inherit (texlive) scheme-small + datetime2 + datetime2-german + latexmk + tracklang + xkeyval; + }; + in + stdenv.mkDerivation { + name = "p-seminar-protocols"; + + nativeBuildInputs = [ + texlive' + ]; + + src = self; + + enableParallelBuilding = true; + + # We only build a PDF + dontFixup = true; + + installPhase = '' + mkdir $out + cp *-sitzung.pdf $out + ''; + }) { }; + + defaultPackage = packages.p-seminar-protocols; + }); +} diff --git a/lint.sh b/lint.sh new file mode 100755 index 0000000..166859b --- /dev/null +++ b/lint.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -o pipefail + +fail=0 + +for file in *.tex *.cls; do + basename="$(basename -- "$file")" + filefail=0 + + (grep -n $'\t' "$file" | sed 's/\t/↹/g') && echo -e "$file: Found tab (expected only spaces)\n" && filefail=1 + (grep -n '\s$' "$file" | sed 's/\s/·/g') && echo -e "$file: Trailing whitespace\n" && filefail=1 + [ "${basename##*.}" = "tex" ] && (grep -nE '^ [^&]*\\\\' "$file") && echo -e "$file: Forced linebreak outside of table\n" && filefail=1 + [[ -x "$file" ]] && echo -e "$file: Executable bit is set (but filetype does not need to be executable)\n" && filefail=1 + + if [ "$filefail" = "1" ]; then + fail=1 + echo # additional newline after each failed file + fi +done + +if [ "$CI" = "true" ]; then + pdfs=$(find . -iname "*.pdf" -not -path "./attachments/*") + [ -n "$pdfs" ] && echo -e "Found PDF files not in ./attachments/:\n$pdfs" && fail=1 +fi + +if [ "$fail" = "1" ]; then + exit 1 +else + echo "Linting passed" +fi diff --git a/podcastproto.cls b/podcastproto.cls new file mode 100644 index 0000000..56e361a --- /dev/null +++ b/podcastproto.cls @@ -0,0 +1,127 @@ +% vim: set ft=tex +\ProvidesClass{podcastproto} + +\LoadClass[ + DIV=20, + parskip=half, +]{scrartcl} + +% hyphenation +\RequirePackage[ngerman]{babel} + +% cretion of nice dates from numbers +\RequirePackage[useregional]{datetime2} + +% if conditions for commands +\RequirePackage{etoolbox} + +% key-value pairs for command options +\RequirePackage{xkeyval} + +% attachments +\RequirePackage{pdfpages} + +% links/pdf toc +\RequirePackage[unicode, hidelinks]{hyperref} + +% roman font for title +\addtokomafont{disposition}{\rmfamily} + +% No dots in TOC +% https://tex.stackexchange.com/a/53899 +\makeatletter +\renewcommand\@dotsep{1000} +\makeatother + +% no page numbers +\pagenumbering{gobble} + +% only subsection in agenda +\setcounter{tocdepth}{\sectiontocdepth} + +\makeatletter +\define@key{meta}{number}{\def\Number{#1}} +\define@key{meta}{date}{\def\Date{#1}} +\define@key{meta}{present}{\def\PeoplePresent{#1}} +\define@key{meta}{absent}{\def\PeopleAbsent{#1}} +\define@key{meta}{duration}{\def\Duration{#1}} +\define@key{meta}{location}{\def\Location{#1}} +\define@key{meta}{chairperson}{\def\Chairperson{#1}} +\define@key{meta}{secretary}{\def\Secretary{#1}} +\define@key{meta}{secretaryAddress}{\def\SecretaryAddress{#1}} +\define@key{meta}{attachments}{\def\Attachments{#1}} +\setkeys{meta}{ + duration=15:55 bis 17:25, + location=Raum 126 der Christian-von-Bomhard-Schule Uffenheim, + chairperson=redigiert +} +\makeatother + +% header +\newcommand*{\header}[1][]{ + \begingroup + \setkeys{meta}{#1} + + {\DTMsetstyle{pdf} + \hypersetup{ + pdftitle={P-Seminar „Einen Podcast erstellen“ -- Niederschrift über die \Number. Sitzung}, + pdfauthor={\Secretary}, + pdfinfo={ + CreationDate={\Date} + } + }} + + \begin{center} + {\bfseries + {\Large + Christian-von-Bomhard Schule \\ + P-Seminar „Einen Podcast erstellen“ + } + + \vspace{2em} + + Niederschrift \\ + über die \\ + \Number. Sitzung \\ + am \Date + } + \end{center} + + \vspace{2em} + + \begin{tabular}{l l} + Anwesend: & \PeoplePresent\ Seminarteilnehmende \\ + \ifdef{\PeopleAbsent}{Abwesend: & \PeopleAbsent \\}{} + Zeit: & \Duration\\ + Ort: & \Location \\ + Vorsitzende: & \Chairperson \\ + \SecretaryAddress: & \Secretary \\ + \ifdef{\Attachments}{Anlagen: & \Attachments \\}{} + \end{tabular} + \endgroup + + % End (needs to access variables from header) + \newcommand*\protoend{ + \begingroup + \setkeys{meta}{#1} + \filbreak % rather break here than somewhere we don’t need it + + \vspace{5mm} + Uffenheim, \Date + \vspace{5mm} + + \makebox[6cm][c]{\textbf{\SecretaryAddress:}}\hfill + \makebox[6cm][c]{\textbf{Vorsitzende:}} + \vspace{1.5cm}\par + \makebox[6cm]{\hrulefill} \hfill\makebox[6cm]{\hrulefill} \\ + \makebox[6cm][c]{(\Secretary)} \hfill\makebox[6cm][c]{(\Chairperson)} + \endgroup + } +} + +% Agenda +\newcommand*{\agenda}{ + \DeclareTOCStyleEntry[]{undottedtocline}{section} + \renewcommand*{\contentsname}{Tagesordnung} + \tableofcontents +}