# Misaligned month label in TikZ calendar

I'm putting together a multi-month calendar in TikZ and am seeing some awkward and undesired alignment in the month labels despite using the month label above centered style. In particular, the month label appears to be centered only over the first six columns, rather than over all seven:

I've reproduced my code below in a minimal context. Two questions: What's going on here, and how can I correct this alignment?

\documentclass[letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calendar,shapes}

\makeatletter%
\tikzstyle{week list sunday}=[
% Note that we cannot extend from week list,
% the execute before day scope is cumulative
execute before day scope={%
\ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}{
% On first of month, except when first date in calendar.
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
\pgftransformyshift{-\pgf@y}
}}{}%
},
execute at begin day scope={%
% Because for TikZ Monday is 0 and Sunday is 6,
% we can't directly use \pgfcalendarcurrentweekday,
% but instead we define \c@pgf@counta (basically) as:
% (\pgfcalendarcurrentweekday + 1) % 7
\pgfmathsetlength\pgf@x{\tikz@lib@cal@xshift}%
\ifnum\pgfcalendarcurrentweekday=6
\c@pgf@counta=0
\else
\c@pgf@counta=\pgfcalendarcurrentweekday
\fi
\pgf@x=\c@pgf@counta\pgf@x
% Shift to the right position for the day.
\pgftransformxshift{\pgf@x}
},
execute after day scope={
% Week is done, shift to the next line.
\ifdate{Saturday}{
% But not if it's already the last day of the month.
\ifdate{end of month=1}{}{
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
\pgftransformyshift{-\pgf@y}
}%
}{}%
},
% This should be defined, glancing from the source code.
tikz@lib@cal@width=7
]

\tikzstyle{every calendar}=[week list sunday,
month label above centered,
month text=\textbf{\%mt~\%y-},
day xshift = 0.5cm,
\tikzstyle{every day}=[anchor=base]
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength{\pgf@ya}{\tikz@lib@cal@yshift}%
\pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
\pgftransformyshift{-\pgf@ya}
\foreach \d/\l in {0/S,1/M,2/T,3/W,4/T,5/F,6/S} {
\pgf@xa=\d\pgf@xa%
\pgftransformxshift{\pgf@xa}%
\pgftransformyshift{\pgf@ya}%
}
}{}%
}%
]

\makeatother%

% ==================================================

\begin{document}

\begin{tikzpicture}
\calendar (K) [dates=2013-01-01 to 2013-03-last]
if (weekend) [black!40];
\draw[black](K-2013-01-21) circle (0.6em);
\draw[black](K-2013-02-13) circle (0.6em);
\draw[black](K-2013-03-10) circle (0.6em);
\draw[black](K-2013-03-31) circle (0.6em);
\end{tikzpicture}

\end{document}


-

You can increase the value for tikz@lib@cal@width for example, to 7.8:

\documentclass[letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calendar,shapes}

\makeatletter%
\tikzstyle{week list sunday}=[
% Note that we cannot extend from week list,
% the execute before day scope is cumulative
execute before day scope={%
\ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}{
% On first of month, except when first date in calendar.
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
\pgftransformyshift{-\pgf@y}
}}{}%
},
execute at begin day scope={%
% Because for TikZ Monday is 0 and Sunday is 6,
% we can't directly use \pgfcalendarcurrentweekday,
% but instead we define \c@pgf@counta (basically) as:
% (\pgfcalendarcurrentweekday + 1) % 7
\pgfmathsetlength\pgf@x{\tikz@lib@cal@xshift}%
\ifnum\pgfcalendarcurrentweekday=6
\c@pgf@counta=0
\else
\c@pgf@counta=\pgfcalendarcurrentweekday
\fi
\pgf@x=\c@pgf@counta\pgf@x
% Shift to the right position for the day.
\pgftransformxshift{\pgf@x}
},
execute after day scope={
% Week is done, shift to the next line.
\ifdate{Saturday}{
% But not if it's already the last day of the month.
\ifdate{end of month=1}{}{
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
\pgftransformyshift{-\pgf@y}
}%
}{}%
},
% This should be defined, glancing from the source code.
tikz@lib@cal@width=7.8
]

\tikzstyle{every calendar}=[week list sunday,
month label above centered,
month text=\textbf{\%mt~\%y-},
day xshift = 0.5cm,
\tikzstyle{every day}=[anchor=base]
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength{\pgf@ya}{\tikz@lib@cal@yshift}%
\pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
\pgftransformyshift{-\pgf@ya}
\foreach \d/\l in {0/S,1/M,2/T,3/W,4/T,5/F,6/S} {
\pgf@xa=\d\pgf@xa%
\pgftransformxshift{\pgf@xa}%
\pgftransformyshift{\pgf@ya}%
}
}{}%
}%
]

\makeatother%

% ==================================================

\begin{document}

\begin{tikzpicture}
\calendar (K) [dates=2013-01-01 to 2013-03-last]
if (weekend) [black!40];
\draw[black](K-2013-01-21) circle (0.6em);
\draw[black](K-2013-02-13) circle (0.6em);
\draw[black](K-2013-03-10) circle (0.6em);
\draw[black](K-2013-03-31) circle (0.6em);
\end{tikzpicture}

\end{document}


-
Looks pretty good, but why 7.8, specifically? Is tikz@lib@cal@width effectively a multiple of day xshift? If so, why doesn't 7 work in this example? I'm trying to understand the root cause of the problem... –  Tim Parenti Nov 26 '12 at 2:53
After some experimentation, it seems the value which "correctly" centers the label in this example is 7.9, but I still don't have any additional insight into what that value actually represents and why 7 doesn't work as it should. –  Tim Parenti Nov 26 '12 at 3:41
@TimParenti I really don't know; I've never used the calendar library, so I am not familiar with how it works; I found the "dirty fix" by detecting which part of your code had to do with the horizontal alignment of the month label and that's how tikz@lib@cal@width appeared. The value 7.8 was found by trial/error. –  Gonzalo Medina Nov 26 '12 at 14:42
I suppose a "dirty fix" is better than no fix at all. Still leaves me with a bad taste, but hey... at least it works. I'm going to hold off on accepting this for another day or so in case anyone else can offer a more insightful solution. (But congrats on 100k!) –  Tim Parenti Nov 26 '12 at 22:13
@TimParenti sure, I would also like to know if someone offers a "proper" calculation ("manual" guessing are by no means my favorite either). Thanks for the congratulations. –  Gonzalo Medina Nov 26 '12 at 22:31