Wir machen es uns erstmal einfach.
Es gibt pro *y*-Höhe nur einen Eintrag pro Tag, es überlappen sich also keine Termine.
Anstatt CSV-Einlese-Spielerein zu machen, habe ich die Liste kurzerhand umformatiert, aus den `,` wurde ein `;` und aus den Zeilenumbrüchen wurde ein `,` und schon ist die „CSV“ `\foreach`-kompatibel. (Achtung, die letzte Zeile darf nicht mit eine `,` enden!)
Der `scan and store`-Style wird nun mit dieser Liste gefüttert, und für jeden Tag schreibt er nur in ein Value-Key (also letztlich einfach ein Makro/eine Token List) eine weitere Liste, die `\foreach`-kompatibel ist.
Dabei wird der Tag vom `MM/DD/YY`- ins `JJJJ-MM-TT`-Format umformatiert, sowie die Uhrzeit in ein Dezimalbruch umgerechnet. Da der Tag erst um acht Uhr anfängt (und da auch *y* = 0) ist, ziehe ich erst noch acht Stunden von der Uhrzeit ab.
Das Makro `\stripFirstZero` ist notwendig, damit führende Nullen von PGFMath nicht als Oktalzahl interpretiert werden (was bei `00` bis `07` kein Problem ist, aber natürlich bei `08` und `09` ein Fehler erzeugt).
Die `\expandafter`-Kette innerhalb des `day code`s ist notwendig, um das führende Komma `,` aus der Liste zu entfernen. Direkt darüber, wird mit `\ifx\DAY\relax` getestet, ob es für den Tag überhaupt Einträge gibt, falls nein, bekommen wir nämlich von PGFKeys nur ein `\relax` zurück.
Die `chains`-Library wird nur für die Stundenspalte verwendet, wirklich notwendig ist die nicht, da sie nur immer `below=of <vorherige Node auf dieser Chain>` macht, aber sie macht einem das Leben einfacher. Die obere rechte Ecke der ersten Stunde bekommt ein Dummy-Alias `@`, sodass ich sie im Kalendar dann einfach referenzieren kann.
Apropos Kalendar. Der TikZ-Kalendar nutzt – unüberraschend – die `\pgfcalendar`-Funktion, die nichts anderes macht, über die angegebenen Tage zu iterieren. TikZ führt dabei in jeder Iteration folgendes aus:
* Vor dem Tag
* *(Gruppe)* Anfang des Tages
* *(Gruppe)* Ifs
* *(Gruppe)* Tag
* *(Gruppe)* Ende des Tages
* Nach dem Tag
Diese „Hooks“ sind mit
* `execute before day scope`
* *(Gruppe)* `execute at begin day scope`
* *(Gruppe)* `if`
* *(Gruppe)* `day code`
* *(Gruppe)* `execute at end day scope`
* `execute after day scope`
anpassbar.
Die Hooks innerhalb der *(Gruppe)* werden in einer TeX-Group ausgeführt.
Die mitgelieferten Styles von TikZ (zum Beispiel `week list`) versetzt ständig das Koordinatensystem, um den `day code` (normalerweise einfach eine Node) an unterschiedlichen Stellen zu platzieren.
Dieses Vorgehen umgehe ich komplett, und nutze einfach nur relatives Positionieren zum `weekday node`, die alle `@` als Alias bekommen (und ihre Vorgänge damit dauernd überschreiben). Außerdem nutze ich aus, dass die *y* = 0 eben genau bei 8 Uhr ist.
## Code
\documentclass[a4paper,11pt,ngerman]{article}
%\documentclass[a4paper, 11pt, ngerman, multi=tikzpicture]{standalone}
\documentclass[a4paper, 11pt, ngerman]{article}
\usepackage{fourier}
\usepackage{babel, translator}
\usepackage{tikz}
\usetikzlibrary{calendar, chains}
\usetikzlibrary{calendar}
\newcommand*\bscalset{\pgfqkeys{/tikz/bscal}}
\newcommand*\bsvo[1]{\pgfkeysvalueof{/tikz/bscal/#1}}
\bscalset{
.code=\bscalset{#1},
day width/.initial=2.2cm,
hour height/.initial=1cm,
height/.initial=1.0cm,
hour width/.initial=1.5cm,
weekday height/.initial=.8cm,
hour node/.style args={#1-#2}{
fill=yellow!30,
minimum width=\bsvo{hour width},
minimum height=\bsvo{hour height},
draw,
outer sep=+0pt,
node contents={%
\ifnum#1<10 \hphantom{0}\fi#1--\ifnum#2<10 \hphantom{0}\fi#2},
},
day node/.style={
draw,
outer sep=+0pt,
text width={\bsvo{day width}-2*(\pgfkeysvalueof{/pgf/inner xsep})},
align=center,
},
weekday node/.style={
bscal/day node,
at=(@.south east),
name=@,
anchor=south west,
minimum height=\bsvo{weekday height},
node contents={\%w., \%d-.\,\%m-.},
text depth=+0pt,
},
month node/.style={
bscal/hour node={0-0},
fill=blue!20,
node contents=\%m.,
anchor=south east,
at=(@),
text depth=+0pt,
minimum height=\bsvo{weekday height},
},
calendar/.style={
execute before day scope={
\ifdate{equals=\pgfcalendarbeginiso}{
\node[bscal/month node];
}{}
\node[bscal/weekday node];
},
day code={
\pgfkeysgetvalue{/tikz/bscal/storage/%
\pgfcalendarcurrentyear-\pgfcalendarcurrentmonth-\pgfcalendarcurrentday}\DAY
\unless\ifx\DAY\relax
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\DAY
\expandafter\expandafter\expandafter{\expandafter\stripFirstAnything\DAY}
\foreach \TIMES/\TIMEE/\TEXT/\ROOM in \DAY {
\node[bscal/day node, anchor=north west]
west,
minimum height=(\TIMEE-\TIMES)*\bsvo{hour height}]
at (@.south west|--\TIMES*\bsvo{hour height},0)
west|-0,-\TIMES*\bsvo{hour height})
{\tiny\TEXT\par\tiny\ROOM\par};
}
\fi
}
},
scanner/day/.code args={#1/#2/#3:#4}{\def#4{20#3-#1-#2}},
scanner/time/.code args={#1:#2:#3/#4}{%
\pgfmathsetmacro#4{(\stripFirstZero{#1}-8)
+(\stripFirstZero{#2}/60)
+(\stripFirstZero{#3}/3600)}},
scan and store/.style args={#1 [#2];#3;#4;#5;#6}{
scanner/day={#3:\DAY},
scanner/time={#4/\TIMES},
scanner/time={#6/\TIMEE},
storage/\DAY/.append/.expanded={%
,\TIMES/\TIMEE/{\unexpanded{#1}}/{\unexpanded{#2}}}
}
}
\newcommand*\stripFirstAnything[1]{}
\newcommand*\stripFirstZero[1]{\if0#1\else#1\fi}
\bscalset{
scan and store/.list={
Lineare Algebra TÜ [Übungsraum (3322-316)];01/28/15;08:15:00;01/28/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];02/04/15;08:15:00;02/04/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];02/11/15;08:15:00;02/11/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];02/18/15;08:15:00;02/18/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];02/25/15;08:15:00;02/25/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];03/04/15;08:15:00;03/04/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];03/11/15;08:15:00;03/11/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];04/15/15;08:15:00;04/15/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];04/22/15;08:15:00;04/22/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];04/29/15;08:15:00;04/29/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];05/06/15;08:15:00;05/06/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];05/13/15;08:15:00;05/13/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];05/20/15;08:15:00;05/20/15;10:00:00,
Lineare Algebra TÜ [Übungsraum (3322-316)];05/27/15;08:15:00;05/27/15;10:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];01/26/15;14:15:00;01/26/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];02/02/15;14:15:00;02/02/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];02/09/15;14:15:00;02/09/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];02/16/15;14:15:00;02/16/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];02/23/15;14:15:00;02/23/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];03/02/15;14:15:00;03/02/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];03/09/15;14:15:00;03/09/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];04/13/15;14:15:00;04/13/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];04/20/15;14:15:00;04/20/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];04/27/15;14:15:00;04/27/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];05/04/15;14:15:00;05/04/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];05/11/15;14:15:00;05/11/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];05/18/15;14:15:00;05/18/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];05/25/15;14:15:00;05/25/15;17:00:00,
Lineare Algebra Lab. [Übungsraum (2226-114)];06/01/15;14:15:00;06/01/15;17:00:00%
}
}
\begin{document}
\foreach \weekoffset in {0, 7, ..., 126}{%
\noindent
\begin{tikzpicture}[
node distance=+0cm,
start chain=hours going below,
start chain=weekdays going right,
]
\begin{tikzpicture}
\coordinate (@);
\foreach [count=\e from 9] \s in {8, ..., 18}
\node[on chain=hours, \node[name=@, at=(@.south), anchor=north, bscal/hour node=\s-\e];
\coordinate (@) at (hours-begin.north east);
(0,0-|@.east);
\calendar[
dates=2015-01-26+\weekoffset to 2015-01-26+\pgfinteval{\weekoffset+4},
bscal/calendar
];
\end{tikzpicture}
\par
\pagebreak}
\end{document}
## Ergebnis
[![alt text][1]][1]
[1]: https://texwelt.de/upfiles/de12523_1.gifhttps://texwelt.de/upfiles/de12523_2.gif