4

I want do define a set with dates chemistryclasses={2021-05-25,2021-06-01,2021-06-08,2021-06-15,2021-06-22,2021-06-29,2021-07-06,2021-07-13} and then I want the code to paint the corresponding dates in tikz-calendar. In the MWE below I could do that. However, I would like to automatize the routine. It is tedious to write all those if (equals=2021-05-25). At the moment I use Python to write the .tex file. It reads a CSV file with the dates and the generate the .tex file. But I was thinking about an all-LaTeX solution. I tried something like

\foreach \x in {2021-05-25,2021-06-01,2021-06-08,2021-06-15,2021-06-22,2021-06-29,2021-07-06,2021-07-13} {%
  if (equals=\x) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};}
}

but it didn't work. So how can I automatize these things inside LaTeX? A good workflow would be:

1)Write the dates in a file

2)LaTeX reads the dates and save to a variable

3)LaTeX generates the calendar.

MWE:

\documentclass[12pt]{article}
\usepackage{hyperref}
\hypersetup{bookmarks=true,colorlinks=true,citecolor=blue}
\usepackage{tikz}
\usetikzlibrary{positioning,calc,calendar,shapes.geometric}

% ============= % = TColorBox = % ============= \usepackage[most]{tcolorbox} \tcbuselibrary{breakable} \tcbset{left=4mm,sharpish corners,colback=white}

% ============ % = Calendar = % ============ \newcommand{\calrow}[1]{ \nodeanchor=base,xshift=0.5ex{M}; % Shift first weekday \nodebase right=0.1em of mon{T}; \nodebase right=0.0em of tue{W}; \nodebase right=0.0em of wed{T}; \nodebase right=0.1em of thu{F}; \nodebase right=0.2em of fri{S}; \nodebase right=0.2em of sat{S}; \node[black,above=0.1em of thu]{\textbf{#1}};} \newcommand{\calperiod}[1]{% \calendar (month-#1)[dates=2021-#1-01 to 2021-#1-last, every day/.style={anchor=base}, % Center days day text={%d=},rounded corners=0, anchor=base,text height=1ex,text depth=-0.5ex] % Make node placement easier if(Sunday) [red] \teachingdays; } \newcommand{\teachingdays}{ if (equals=2021-05-11) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-05-18) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-05-25) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-06-01) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-06-08) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-06-15) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-06-22) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-06-29) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-07-06) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-07-13) {\node [fill=yellow,draw,regular polygon,regular polygon sides=4] {};} if (equals=2021-05-11) [blue] if (equals=2021-05-18) [blue] if (equals=2021-05-25) [blue] if (equals=2021-06-01) [blue] if (equals=2021-06-08) [blue] if (equals=2021-06-15) [blue] if (equals=2021-06-22) [blue] if (equals=2021-06-29) [blue] if (equals=2021-07-06) [blue] if (equals=2021-07-13) [blue] } \newcommand{\generatehyperlinks}{ \node [hyperlink node=data01,draw=none,regular polygon,regular polygon sides=4] at (month-05-2021-05-11) {}; \node [hyperlink node=data02,draw=none,regular polygon,regular polygon sides=4] at (month-05-2021-05-18) {}; \node [hyperlink node=data03,draw=none,regular polygon,regular polygon sides=4] at (month-05-2021-05-25) {}; \node [hyperlink node=data04,draw=none,regular polygon,regular polygon sides=4] at (month-06-2021-06-01) {}; \node [hyperlink node=data05,draw=none,regular polygon,regular polygon sides=4] at (month-06-2021-06-08) {}; \node [hyperlink node=data06,draw=none,regular polygon,regular polygon sides=4] at (month-06-2021-06-15) {}; \node [hyperlink node=data07,draw=none,regular polygon,regular polygon sides=4] at (month-06-2021-06-22) {}; \node [hyperlink node=data08,draw=none,regular polygon,regular polygon sides=4] at (month-06-2021-06-29) {}; \node [hyperlink node=data09,draw=none,regular polygon,regular polygon sides=4] at (month-07-2021-07-06) {}; \node [hyperlink node=data10,draw=none,regular polygon,regular polygon sides=4] at (month-07-2021-07-13) {}; } \tikzset{ hyperlink node/.style={ alias=sourcenode, append after command={ let \p1 = (sourcenode.north west), \p2=(sourcenode.south east), \n1={\x2-\x1}, \n2={\y1-\y2} in node [inner sep=0pt, outer sep=0pt,anchor=north west,at=(\p1)] {\hyperlink{#1}{\XeTeXLinkBox{\phantom{\rule{\n1}{\n2}}}}} %xelatex needs \XeTeXLinkBox, won't create a link unless it %finds text --- rules don't work without \XeTeXLinkBox. %Still builds correctly with pdflatex and lualatex } } } \linespread{1.3}

\begin{document}

% ============ % = Calendar = % ============

\begin{tikzpicture}[every calendar/.style={week list}] \matrix[% row 1/.style={black,node distance=.3ex},% row 3/.style={black,node distance=.3ex}, column sep=1ex,draw=none]{% % first row: week day and month \calrow{May} & \calrow{June} & \calrow{July} \ % second row: calendar \calperiod{05} & \calperiod{06} & \calperiod{07} \ }; \generatehyperlinks \end{tikzpicture}

\newpage \begin{itemize} \item \hypertarget{data01}{01} \item \hypertarget{data02}{02} \item \hypertarget{data03}{03} \item \hypertarget{data04}{04} \item \hypertarget{data05}{05} \item \hypertarget{data06}{06} \item \hypertarget{data07}{07} \item \hypertarget{data08}{08} \item \hypertarget{data09}{09} \item \hypertarget{data10}{10} \end{itemize} \end{document}

S.V.
  • 499

1 Answers1

3

It is tedious to write all those if (equals=2021-05-25).

Then don't. Take a look at the /pgf/calendar/equals-strip key that takes an argment as #1/#2 and forwards #1 to equals. The second part after / is only used to place the \items later.

We can use the list inside \teachingdays once expanded and fed as a list to equals-strip:

if (equals-strip/.list/.expand once=\teachingdays) [teaching day]

The \teachingdays macro can then simply be:

\newcommand*\teachingdays{%
  2021-05-11/Intro,
  2021-05-18/Basics I,
  2021-05-25/Basics II,
  …
}

This should make it much easier to use the calendar libraries by TikZ/PGF.

Code

\documentclass[12pt]{article}
\usepackage{hyperref}
\hypersetup{colorlinks=true, citecolor=blue}
\usepackage{tikz}
\usetikzlibrary{calc,calendar}

%%% Shorthand w- for Weekday \expandafter\def\csname pgfcalendar@shorthand@w-\endcsname{\ifcase\pgfcalendarcurrentweekday M\or T\or W \or T\or F\else S\fi}

%%% equal key that strips /<text> \pgfqkeys{/pgf/calendar}{equals-strip/.style args={#1/#2}{equals={#1}}}

%%% A simple parser for <year>-<month>-<day> so we can use shorthands outside of a calendar \def\pgfcalendarsimpleparse#1-#2-#3\relax{% \def\pgfcalendarcurrentyear{#1}% \def\pgfcalendarcurrentmonth{#2}% \def\pgfcalendarcurrentday{#3}}

%%% hyperling node \tikzset{ hyperlink node/.style={ alias=@hyper, append after command={ let \p1 = (@hyper.north west), \p2 = (@hyper.south east), \n1 = {\x2-\x1}, \n2 = {\y1-\y2} in node [inner sep=+0pt, outer sep=+0pt, anchor=center, at=(@hyper)] {\hyperlink{ref-#1}{\XeTeXLinkBox{\phantom{\rule{\n1}{\n2}}}}}}}}

\newcommand{\calrow}[1]{\node[draw,black, minimum width=7\csname tikz@lib@cal@xshift\endcsname]{\textbf{#1}};}

\newcommand{\calperiod}[1]{% \calendar [ dates=2021-#1-01 to 2021-#1-last, day text={%d=}, % % we name every weekday node (even though we only need the Thursday) weekday node/.style={ black, name=weekday-\pgfcalendarcurrentmonth-\pgfcalendarcurrentweekday}, % % teaching day, include hyperlink node based on the date teaching day/.style={ days={text=blue, fill=yellow, hyperlink node=\pgfcalendarcurrentyear-\pgfcalendarcurrentmonth-\pgfcalendarcurrentday}}] % % standard stuff % if (Saturday) [red!50!black] if (Sunday) [red] % % the first day of the month is in the upmost row, % let's place the weekday above it and align it properly % the name @firstweekday can be referenced later % if (day of month=1) [days={append after command={ node [anchor=base east, at={(\tikzlastnode.base east)}, alias=@firstweekday, yshift=\csname tikz@lib@cal@yshift\endcsname, weekday node/.try] {%w-}}}] % % for all other days 2 to 7 we place the weekday text similar but we use the % the first placed weekday text to make sure we align it at the same height % if (day of month=2, day of month=3, day of month=4, day of month=5, day of month=6, day of month=7) [days={append after command={ node [anchor=base east, at={(@firstweekday.base east-|\tikzlastnode.base east)}, weekday node/.try] {%w-}}}] % % and go % if (equals-strip/.list/.expand once=\teachingdays) [teaching day] ; } \newcommand*\teachingdays{% 2021-05-11/Intro, 2021-05-18/Basics I, 2021-05-25/Basics II, 2021-06-01/And, 2021-06-08/Much, 2021-06-15/More, 2021-06-22/Stuff, 2021-06-29/To Do, 2021-07-06/In, 2021-07-13/Class}

\linespread{1.3} \begin{document}\noindent \begin{tikzpicture}[every calendar/.style={week list}] \matrix[column sep=1.5ex]{% \calperiod{05} & \calperiod{06} & \calperiod{07} \ }; \foreach \mon/\t in {05/May, 06/Jun, 07/Jul} \node[anchor=south, yshift=2ex, at=(weekday-\mon-3)] {\textbf{\t}}; \end{tikzpicture}

\pagebreak \setlength{\labelwidth}{4em} \begin{itemize} \foreach \target/\name[/utils/exec=\let%\pgfcalendarshorthand] in \teachingdays { \expandafter\pgfcalendarsimpleparse\target\relax \item[%m. %d= %y-] \hypertarget{ref-\target}{\name}} \end{itemize} \end{document}

Output

three months side by side list of teachings

Qrrbrbirlbel
  • 119,821