If you modify the placement of the days slightly, you can easily add shapes without having to place the shapes using trial and error to find the right coordinates.
By adding
every day/.style={anchor=base},
day text={\%d=},rounded corners=0,anchor=base,text height=1ex,text depth=-0.5ex
to the calendar options
you align the days in such a way that you can then just add \node
s to the days you want to highlight, without any fiddling around. day text={\%d=}
takes care of making single digit days as wide as two digit ones.
By using \node[anchor=base,xshift=0.5ex](seg){S};
to print the first weekday letter, all the weekdays will align nicely with the days.
After these adjustments, you can highlight individual days using things like
if (equals=01-10) {\node [fill=yellow,draw,star] {};}
in the \holidays
macro.
Here's the full adjusted code:
\documentclass[12pt]{article}
\usepackage{lscape,tikz}
\usepackage[brazil]{babel}
\usepackage[latin1]{inputenc}
\usepackage[margin=1in, paperwidth=15.8in, paperheight=8.5in]{geometry}
\usepackage{geometry}
\usepackage{amsmath,color,graphicx}
\usepackage{amsfonts}
\usepackage{amssymb}
\definecolor{Red}{cmyk}{0,1,1,0}
\def\red{\color{Red}}
\definecolor{Blue}{cmyk}{1,1,0,0}
\def\blue{\color{Blue}}
%%in preamble:
%
\Huge
\usetikzlibrary{arrows,shapes}
\usetikzlibrary{positioning,calendar,er}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes.geometric}
\newcommand{\calrow}[1]{\node[anchor=base,xshift=0.5ex](seg){S}; % Shift first weekday
\node[base right=of seg](ter){T}; \node[base right=of ter](qua){Q};
\node[base right=of qua](qui){Q}; \node[base right=of qui](sex){\ \!S};
\node[base right=of sex](sab){\ \!S}; \node[base right=of sab](dom){D};
\node[black,above=of qui]{\textbf{#1}};}
\newcommand{\calperiod}[1]{\calendar[dates=\the\year-#1-01 to \the\year-#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] \holidays;}
\newcommand{\holidays}{
if (equals=01-15) {\node [draw,regular polygon,regular polygon sides=3] {};}
if (equals=01-20) {\node [draw,cloud] {};}
if (equals=01-10) {\node [fill=yellow,draw,star] {};}
if (equals=01-06) [black!50]%
if (equals=04-04) [black!50]%
if (equals=04-05) [black!50]%
if (equals=04-25) [black!50]%
if (equals=05-01) [black!50]%
if (equals=05-01) [black!50]%
if (equals=06-02) {\draw (-0.25,0.135) circle (9.0pt);}%
if (equals=08-15) [black!50]%
if (equals=11-01) [black!50]%
if (equals=12-08) [black!50]%
if (equals=12-25) [black!50]%
if (equals=12-26) [black!50]%
}
\colorlet{darkgreen}{green!50!black}
\begin{document}
\begin{tikzpicture}
[every calendar/.style={week list}]
%\node[star,draw,minimum size=.4cm,star point ratio=1.0,thick] at (calendar-\the\year-08-29){};
\sffamily
\matrix[%
row 1/.style={black,node distance=.3ex},%
row 3/.style={black,node distance=.3ex},
column sep=1ex,%
draw=black,thick,rounded corners=30pt,%
postaction={decorate,decoration={markings,mark=at position 0.51 with
{\node[fill=white,text=black,font={\bfseries\Large}] (year) {\the\year};}}}
% year on frame: decorations.markings library
]{%
% first row: week day and month
\calrow{Janeiro} & \calrow{Fevereiro} & \calrow{Março} &
\calrow{Abril} & \calrow{Maio} & \calrow{Junho} \\
% second row: calendar
\calperiod{01} & \calperiod{02} & \calperiod{03} &
\calperiod{04} & \calperiod{05} & \calperiod{06} \\[0.4cm]
% third row: week day and month
\calrow{Julho} & \calrow{Agosto} & \calrow{Setembro} &
\calrow{Outubro} & \calrow{Novembro} & \calrow{Dezembro} \\
% forth row: calendar
\calperiod{07} & \calperiod{08} & \calperiod{09} &
\calperiod{10} & \calperiod{11} & \calperiod{12} \\
};
\end{tikzpicture}
\end{document}
Here's a new style vertical week list
, which is adapted from the week list
style found in the TikZ source code. The day labels are adapted from the answer to Weekday captions with the TikZ library "calendar".
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calendar}
\makeatletter
\tikzstyle{week list}=[%
execute before day scope={%
\ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}
{%
% On first of month, except when first date in calendar.
\pgfmathsetlength{\pgf@x}{\tikz@lib@cal@month@xshift}%
\pgftransformxshift{\pgf@x}
}%
}{}%
},
execute at begin day scope={%
\pgfmathsetlength\pgf@y{\tikz@lib@cal@yshift}%
\pgf@y=\pgfcalendarcurrentweekday\pgf@y%
\pgftransformyshift{-\pgf@y}%
},
execute after day scope={%
\ifdate{Sunday}{%
\pgfmathsetlength{\pgf@x}{\tikz@lib@cal@xshift}%
\pgftransformxshift{\pgf@x}
}{}%
}
]
\tikzoption{day headings}{\tikzstyle{day heading}=[#1]}
\tikzstyle{day heading}=[]
\tikzstyle{day letter headings}=[
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength\pgf@ya{\tikz@lib@cal@yshift}%
\pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
\pgftransformxshift{\pgf@xa}
\foreach \d/\l in {0/M,1/T,2/W,3/T,4/F,5/S,6/S} {
\pgf@ya=\d\pgf@ya%
\pgftransformxshift{-\pgf@xa}%
\pgftransformyshift{-\pgf@ya}%
\node[every day,day heading, anchor=base]{\l};%
}
}{}%
}%
]
\makeatother
\begin{document}
\begin{tikzpicture}
\calendar[
dates=1997-06-01 to 1997-06-last,
week list,
day letter headings,
day heading/.style={gray, xshift=-1em},
month label above left,
month text=\%mt \%y0
];
\end{tikzpicture}
\end{document}
Best Answer
The trick was to use the command
\pgfkeys
.Here is the full code:
Here is the result:
Here is an expanded version: http://pastebin.com/KYngbPGQ
There is also a version here: http://www.texample.net/tikz/examples/birthday-calendar/
Please note that this solution requires an up-to-date TeX distro. It won’t work with the distro that comes with Ubuntu 12.04 and older.