German calendar with tikz
The spacing between days can be controlled using the day xshift
option of \calendar
. Note that this spacing is measured between the east
anchors of consecutive days.
\calendar[dates=\currentyear-#2-01 to \currentyear-#2-last, day xshift=1.8em]
We can then set the space between east
anchors of consecutive day labels to be the same:
\newcommand{\calrow}[1]{\node[anchor=east] (Mon){Mo};
\node[right=1.8em of Mon.east, anchor=east](Tue){Di};
...
}
Edit: If you want the day labels to left-align with the day numbers, one solution is to use a phantom node that has the width of a day number (i.e., 24), and then place the day labels based on their west
anchor:
\newcommand{\calrow}[1]{
% phantom node
\node[anchor=east, draw=none] (start) {\phantom{24}};
% left-aligned nodes
\node[anchor=west] at (start.west) (Mon){Mo};
\node[right=1.8em of Mon.west, anchor=west](Tue){Di};
...
}
Full code with left-aligned day labels:
\documentclass[tikz,border=5]{standalone}
\renewcommand\familydefault\sfdefault
\usetikzlibrary{positioning,calendar}
\colorlet{darkgreen}{green!50!black}
\colorlet{holiday}{black!50}
\newcommand{\calrow}[1]{
% phantom node
\node[anchor=east, draw=none] (start) {\phantom{24}};
% left-aligned nodes
\node[anchor=west] at (start.west) (Mon){Mo};
\node[right=1.8em of Mon.west, anchor=west](Tue){Di}; \node[right=1.8em of Tue.west, anchor=west](Wed){Mi};
\node[right=1.8em of Wed.west, anchor=west](Thu){Do}; \node[right=1.8em of Thu.west, anchor=west](Fri){Fr};
\node[right=1.8em of Fri.west, anchor=west](Sat){Sa}; \node[right=1.8em of Sat.west, anchor=west](Sun){So};
\node[darkgreen, above=of Thu]{\textbf{#1}};
}
\newcommand{\calperiod}[2][\currentyear]{%
\calendar[dates=\currentyear-#2-01 to \currentyear-#2-last, day xshift=1.8em]
if (Sunday) [holiday] \holidays;}
\edef\currentyear{\the\year}
\newcommand{\holidays}{% holidays in Italy
if (equals=01-01) [holiday]%
if (equals=01-06) [holiday]%
if (equals=04-04) [holiday]%
if (equals=04-05) [holiday]%
if (equals=04-25) [holiday]%
if (equals=05-01) [holiday]%
if (equals=05-01) [holiday]%
if (equals=06-02) [holiday]%
if (equals=08-15) [holiday]%
if (equals=11-01) [holiday]%
if (equals=12-08) [holiday]%
if (equals=12-25) [holiday]%
if (equals=12-26) [holiday]%
}
\begin{document}
\begin{tikzpicture}[every calendar/.style={week list},
year label/.style={
fill=white,text=darkgreen,font=\bfseries\Large
}, current year/.store in=\currentyear,
current year=2017]
\matrix[%
row 1/.style={darkgreen,node distance=.3ex},%
row 3/.style={darkgreen,node distance=.3ex},
row 5/.style={darkgreen,node distance=.3ex},
row 7/.style={darkgreen,node distance=.3ex},
column sep=1ex,%
draw=darkgreen,thick,rounded corners=5pt,%
append after command={
\pgfextra{\edef\matrixname{\tikzlastnode}}
node [year label/.try, right=1ex of \matrixname.south west] {\currentyear}
node [year label/.try, right=1ex of \matrixname.north west] {\currentyear}
node [year label/.try, left=1ex of \matrixname.south east] {\currentyear}
node [year label/.try, left=1ex of \matrixname.north east] {\currentyear}
}
]{%
% first row: week day and month
\calrow{Januar} & \calrow{Februar} & \calrow{M\"arz} \\
\calperiod{01} & \calperiod{02} & \calperiod{03} \\[1ex]
% second row: calendar
\calrow{April} & \calrow{Mai} & \calrow{Juni} \\
\calperiod{04} & \calperiod{05} & \calperiod{06} \\[1ex]
% third row: week day and month
\calrow{Juli} & \calrow{August} & \calrow{September} \\
\calperiod{07} & \calperiod{08} & \calperiod{09} \\[1ex]
% forth row: calendar
\calrow{Oktober} & \calrow{November} & \calrow{Dezember} \\
\calperiod{10} & \calperiod{11} & \calperiod{12} \\[1ex]\\
};
\end{tikzpicture}
\end{document}
I wanted to see if I could make the process a bit smarter and avoid having to manually tinker with too many lengths. I take one weekday ("Mo") as a reference, measure its width, and then use that to set various things in the code. Additionally, there is a parameter \padding
which can be adjusted as needed. It can now cope with three-letter weekdays as well (whether or not that is a good idea in the first place shall be left as an exercise to the reader -- it can start looking a bit cramped, though again, \padding
).
Some slight manual fiddling was still required by setting every day/.append style={inner xsep=0.2ex}
, though now that it's set up, it doesn't seem to require changing anymore (at least not in the few different configurations I've tried out). Maybe somebody can a nice way of automating that too.
\documentclass[tikz,border=5]{standalone}
\usepackage[utf8]{inputenc}
\renewcommand\familydefault\sfdefault
\usetikzlibrary{positioning,calendar}
\colorlet{darkgreen}{green!50!black}
% Adjust formatting here
\newcommand*\refday{Mo}
\newlength\padding
\setlength\padding{0.25ex} % Set as needed
\newcommand{\calrow}[1]{%
\begin{scope}[every node/.style={
anchor=east,
align=right,% or left, depending on preference
inner sep=0,
outer sep=\padding,
minimum width={width("\refday")},
text width={width("\refday")}
}
]
\node[anchor=base east](Mon){Mo};
\node[base right=0mm of Mon](Tue){Di};
\node[base right=0mm of Tue](Wed){Mi};
\node[base right=0mm of Wed](Thu){Do};
\node[base right=0mm of Thu](Fri){Fr};
\node[base right=0mm of Fri](Sat){Sa};
\node[base right=0mm of Sat](Sun){So};
\end{scope}%
\node[darkgreen, above=of Thu]{\textbf{#1}};
}
\newcommand{\calperiod}[2][\currentyear]{%
\calendar[dates=\currentyear-#2-01 to \currentyear-#2-last]
if (Sunday) [black!50];}
\edef\currentyear{\the\year}
\begin{document}
\begin{tikzpicture}[
day xshift={width("\refday") + 2 * \padding},% Double the outer sep of the \calrow scope
every day/.append style={inner xsep=0.2ex},
every calendar/.style={week list},
year label/.style={
fill=white,text=darkgreen,font=\bfseries\Large
},
current year/.store in=\currentyear,
current year=2017]
\matrix[%
row 1/.style={darkgreen,node distance=.3ex},%
row 3/.style={darkgreen,node distance=.3ex},
row 5/.style={darkgreen,node distance=.3ex},
row 7/.style={darkgreen,node distance=.3ex},
column sep=1ex,%
draw=darkgreen,thick,rounded corners=5pt
]{%
% first row: week day and month
\calrow{Januar} & \calrow{Februar} & \calrow{März} \\
\calperiod{01} & \calperiod{02} & \calperiod{03} \\[1ex]
% second row: calendar
\calrow{April} & \calrow{Mai} & \calrow{Juni} \\
\calperiod{04} & \calperiod{05} & \calperiod{06} \\[1ex]
% third row: week day and month
\calrow{Juli} & \calrow{August} & \calrow{September} \\
\calperiod{07} & \calperiod{08} & \calperiod{09} \\[1ex]
% forth row: calendar
\calrow{Oktober} & \calrow{November} & \calrow{Dezember} \\
\calperiod{10} & \calperiod{11} & \calperiod{12} \\[1ex]\\
};
\end{tikzpicture}
\end{document}