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.

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

1 Answer 1

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

3
  • @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
    Commented Sep 20, 2019 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
    Commented Sep 20, 2019 at 12:10
  • @DRi Yes, you are right. I fixed it using tex.stackexchange.com/a/274678.
    – user194703
    Commented Sep 20, 2019 at 14:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .