5

I would like to create a calendar like this one : enter image description here And I found a code which was OK for me (once modified) but I don't know how to add the left column withe the letters A-B-C-D to qualify the weeks in this 4-weeks cycle.

\documentclass[french]{standalone}% 
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{tikz}
    \usetikzlibrary{calendar}
\usepackage[active,tightpage]{preview}
\usepackage{babel}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%

\usetikzlibrary{positioning,calendar}
\usetikzlibrary{decorations.markings}

\newcommand{\calrow}[1]{%\node[anchor=base left=of lun](lun){A};
\node[anchor=base east](lun){l};
\node[base right=of lun](mar){m}; \node[base right=of mar](mer){m};
\node[base right=of mer](jeu){j}; \node[base right=of jeu](ven){v};
\node[base right=of ven](sam){s}; \node[base right=of sam](dim){d};
\node[darkgreen,above=of jeu]{\textbf{#1}};}

\newcommand{\calperiod}[1]{\calendar[dates=\the\year-#1-01 to \the\year-#1-last]
    if(Sunday) [black!50] \holidays;}

\newcommand{\holidays}{% holidays
if (equals=01-01) [black!50]%
if (equals=04-13) [black!50]%
if (equals=05-01) [black!50]%
if (equals=05-08) [black!50]%
if (equals=05-21) [black!50]%
if (equals=06-01) [black!50]%
if (equals=08-15) [black!50]%
if (equals=11-01) [black!50]%
if (equals=11-11) [black!50]%
if (equals=12-25) [black!50]%
}

\colorlet{darkgreen}{green!50!black}

\begin{document}
\begin{tikzpicture}[every calendar/.style={week list}]
\sffamily

\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=3ex,%
draw=darkgreen,thick,rounded corners=5pt,%
postaction={decorate,decoration={markings,mark=at position 0.51 with
{\node[fill=white,text=darkgreen,font={\bfseries\Large}] (year) 
{2020};}}}
]{%
\calrow{Janvier} & \calrow{Février} & \calrow{Mars}\\
\calperiod{01} & \calperiod{02} & \calperiod{03}\\
\calrow{Avril} & \calrow{Mai} & \calrow{Juin}\\ 
\calperiod{04} & \calperiod{05} & \calperiod{06}\\
\calrow{Juillet} & \calrow{Août} & \calrow{Septembre}\\
\calperiod{07} & \calperiod{08} & \calperiod{09}\\[1ex]
\calrow{Octobre} & \calrow{Novembre} & \calrow{Décembre}\\
\calperiod{10} & \calperiod{11} & \calperiod{12}\\
};
\end{tikzpicture}
\end{document}

I would like to know how to add the left column, if possible starting from my adapted code.

  • Do you also want \calrow to get fixed that the letters that abbreviate the days are centered above the respective numbers? – Schrödinger's cat Sep 19 '19 at 22:13
  • @Schrödinger's cat Yes, that would be nice too! – DRi Sep 20 '19 at 9:14
6
+50

A counter (and one counter to cheat, which could be removed), a bit of modulo arithmethics, a few ifs and the execute at begin day scope key seem to allow one to get what you want.

\documentclass[french]{standalone}% 
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage[active,tightpage]{preview}
\usepackage{babel}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%
\usetikzlibrary{calendar,babel}

\usetikzlibrary{positioning,calendar}
\usetikzlibrary{decorations.markings}

\newcommand{\calrow}[1]{%\node[anchor=base left=of lun](lun){A};
\node[anchor=base east,xshift=-0.15em](lun){l};
\node[base right=0.3em of lun](mar){m}; \node[base right=0.3em of mar](mer){m};
\node[base right=0.3em of mer](jeu){j}; \node[base right=0.3em of jeu](ven){v};
\node[base right=0.3em of ven](sam){s}; \node[base right=0.3em of sam](dim){d};
\node[darkgreen,above=of jeu]{\textbf{#1}};}

\newcounter{ABCD}
\newcounter{spur}
\newcommand{\calperiod}[2][\currentyear]{\calendar[dates=\currentyear-#2-01 to \currentyear-#2-last,
execute at begin day scope={\ifdate{Monday}{
\pgfmathtruncatemacro{\itest}{\pgfcalendarcurrentday}
\pgfmathtruncatemacro{\iABCD}{Mod(\value{spur},4)+1} 
\setcounter{ABCD}{\iABCD}
\ifnum\itest<8
\ifnum\itest>1
\node at (-2em,1.3em) [anchor=base east,text=darkgreen] {\Alph{ABCD}};
\fi
\fi
\stepcounter{spur}
\pgfmathtruncatemacro{\iABCD}{Mod(\value{spur},4)+1} 
\setcounter{ABCD}{\iABCD}
\node at (-2em,0em) [anchor=base east,text=darkgreen] {\Alph{ABCD}};}}]
    if(Sunday) [black!50] \holidays;}

\newcommand{\holidays}{% holidays
if (equals=01-01) [black!50]%
if (equals=04-13) [black!50]%
if (equals=05-01) [black!50]%
if (equals=05-08) [black!50]%
if (equals=05-21) [black!50]%
if (equals=06-01) [black!50]%
if (equals=08-15) [black!50]%
if (equals=11-01) [black!50]%
if (equals=11-11) [black!50]%
if (equals=12-25) [black!50]%
}

\colorlet{darkgreen}{green!50!black}

\begin{document}
\begin{tikzpicture}[every calendar/.style={week list},current year/.store in=\currentyear,
current year=2020]
\sffamily

\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=3ex,%
draw=darkgreen,thick,rounded corners=5pt,%
postaction={decorate,decoration={markings,mark=at position 0.51 with
{\node[fill=white,text=darkgreen,font={\bfseries\Large}] (year) 
{\currentyear};}}}
]{%
\calrow{Janvier} & \calrow{F\'evrier} & \calrow{Mars}\\
\calperiod{01} & \calperiod{02} & \calperiod{03}\\
\calrow{Avril} & \calrow{Mai} & \calrow{Juin}\\ 
\calperiod{04} & \calperiod{05} & \calperiod{06}\\
\calrow{Juillet} & \calrow{Ao\^ut} & \calrow{Septembre}\\
\calperiod{07} & \calperiod{08} & \calperiod{09}\\[1ex]
\calrow{Octobre} & \calrow{Novembre} & \calrow{D\'ecembre}\\
\calperiod{10} & \calperiod{11} & \calperiod{12}\\
};
\end{tikzpicture}
\end{document}

enter image description here

ADDENDUM. A TikZling calendar.

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikzlings}
\newcounter{Sunday}
\usetikzlibrary{positioning,calendar,backgrounds}
\renewcommand\familydefault\sfdefault
\colorlet{darkgreen}{green!50!black}
\colorlet{holiday}{black!50}
\newcommand{\calrow}[1]{\node[anchor=base east](Mon){M};
\node[base right=of Mon](Tue){T}; \node[base right=of Tue](Wed){W};
\node[base right=of Wed](Thu){T}; \node[base right=of Thu](Fri){F};
\node[base right=of Fri](Sat){S}; \node[base right=of Sat](Sun){S};
\node[darkgreen, above=of Thu]{\textbf{#1}};}

\newcommand{\calperiod}[2][\currentyear]{%
  \calendar[dates=\currentyear-#2-01 to \currentyear-#2-last,
  execute at begin day scope={\ifdate{Sunday}{\stepcounter{Sunday}
   \node[anchor=base east] (SD-\number\value{Sunday}){};}}]
    if (Sunday) [holiday] \holidays;}
\edef\currentyear{\the\year}
\newcommand{\holidays}{% 
if (equals=01-01) [holiday]%
if (equals=01-06) [holiday]%
if (equals=05-01) [holiday]%
if (equals=08-15) [holiday]%
if (equals=11-01) [holiday]%
if (equals=12-06) [holiday]%
if (equals=12-25) [holiday]%
if (equals=12-26) [holiday]%
}
\tikzset{tikzling/.style={execute at begin day scope={\typeout{X}}}}
\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=2019]
\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{January} & \calrow{February} & \calrow{March} \\
\calperiod{01} & \calperiod{02} & \calperiod{03} \\[1ex]

% second row: calendar
\calrow{April} & \calrow{May} & \calrow{June} \\
\calperiod{04} & \calperiod{05} & \calperiod{06} \\[1ex]

% third row: week day and month
\calrow{July} & \calrow{August} & \calrow{September} \\
\calperiod{07} & \calperiod{08} & \calperiod{09} \\[1ex]

% forth row: calendar
\calrow{October} & \calrow{November} & \calrow{December} \\
\calperiod{10} & \calperiod{11} & \calperiod{12} \\[1ex]\\
};
\begin{scope}[on background layer]
\foreach \X in {1,...,\number\value{Sunday}}
{\tikzling[shift={(SD-\X.south west)},scale=0.2]}
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

  • @Shrödinger's cat Thank you, that is exactly what I was looking for. I tried to search for a at begin week scope which does not seem to exist. TikZling are so cuuuutes !!! – DRi Sep 20 '19 at 8:50
  • There is still a problem, the first calendar (with the 2020 label) is indeed a 2019 calendar since it starts (01/01/2019) on m = mardi = Tuesday (the second tikzdingered one is also a 2019 calendar). I don't know how to change this, I tried to introduce a \date in the preamble but it does not change anything. How could on display a calendar for a year different from the current one . – DRi Sep 20 '19 at 12:10
  • @DRi Yes, you are right. I fixed it using tex.stackexchange.com/a/274678. – Schrödinger's cat Sep 20 '19 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.