About
Shop
LaTeX
Software
Books
Gallery
News
Contact
Blog
Settings
Latest news 2019-12-05: new blog post "RSS Feeds and Other Notifications."

Exercise 23: Calendar for 2014 (Solution)

This is a solution to Exercise 23. I suggest you use a better colour scheme.
\documentclass[a4paper,landscape,12pt]{article}

\usepackage[margin=1cm]{geometry}

\usepackage{etoolbox}
\usepackage{tikz}
\usepackage{pgfcalendar}

\usetikzlibrary{shapes.multipart}

\pagestyle{empty}

\newcount\rowcount
\newcount\julianday

\newcommand*{\addevent}[2]{%
  \ifcsdef{cal-#1}
  {% already defined so append info
    \csappto{cal-#1}{\newline #2}%
  }%
  {% not defined
    \csdef{cal-#1}{#2}%
  }
}

\newlength\dayinnersep
\setlength\dayinnersep{4pt}

\newcommand*{\daynode}[2]{%
  #1\nodepart{two}\parbox[t][\dayheight]{\daywidth}{\raggedright\mbox{}#2}}

\newlength\daywidth
\newlength\dayheight
\newlength\dayyunit

\newcommand*{\calendarmonth}[2]{%
  \setlength{\daywidth}{0.12\textwidth}%
  \edef\dayxunit{\the\daywidth}%
  \addtolength{\daywidth}{-2\dayinnersep}%
  \setlength{\dayheight}{0.1\textheight}%
  \settoheight{\dayyunit}{%
     \tikz{\node[rectangle split,rectangle split parts=2]
     {\daynode{0}{}};}}%
  \addtolength{\dayyunit}{2pt}%
  \fbox{%
  \rowcount=1\relax
  \let\%\pgfcalendarshorthand
  \begin{tikzpicture}[x=\dayxunit,y=\dayyunit,every node/.style={inner sep=\dayinnersep}]
    % display the month name at the top
    \path (3,0.25) node {\Huge\bfseries\itshape \pgfcalendarmonthname{#2}};
    \begin{scope}[every node/.style={rectangle,fill=green!5,minimum
width=\dayxunit,outer sep=0pt}]
    \foreach \x in {0,...,6}
    {
      \path (\x,-0.25) node {\pgfcalendarweekdayshortname{\x}};
    }
    \end{scope}
    \pgfcalendar{cal}{#1-#2-01}{#1-#2-last}
    {%
      % Is this the first day of the month?
      \ifnum\pgfcalendarcurrentday=1\relax
      % Fill in days from previous month if this isn't a Monday
      \ifdate{Monday}{}
      {
        % Get last day of previous month
        \julianday = \pgfcalendarcurrentjulian\relax
        \advance\julianday by -\pgfcalendarcurrentweekday\relax
        \foreach \x in {0,...,\numexpr\pgfcalendarcurrentweekday-1}
        {
          \pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
          \path (\x,-1)
           node
           [
             rectangle split,
             rectangle split parts=2,
             draw=gray,
             text=gray]
          {%
            \daynode{\number\theday}{}%
          };
          \global\advance\julianday by 1\relax
        }
      }
      \fi
      \def\thebackground{magenta!4}%
      \ifcsdef{\pgfcalendarsuggestedname}%
      {%
        \def\thecontents{\csuse{\pgfcalendarsuggestedname}}%
        \def\thebackground{black!4}%
      }%
      {%
        \def\thecontents{\mbox{}}%
        \ifdate{weekend}{\def\thebackground{black!4}}{}%
      }%
      \path (\pgfcalendarcurrentweekday,-\rowcount)
       node
       [
         rectangle split,
         rectangle split parts=2,
         rectangle split part fill={cyan!20,\thebackground},
         draw] 
      {%
        \daynode{\%d-}{\small\thecontents}%
      };
      \ifdate{Sunday}{\global\advance\rowcount by 1}{}%
      \xdef\lastjulianday{\number\pgfcalendarcurrentjulian}
      \xdef\lastweekday{\number\pgfcalendarcurrentweekday}
    }%
    \ifnum\lastweekday < 6\relax
     \julianday = \lastjulianday\relax
     \edef\lastweekday{\number\numexpr\lastweekday+1}
     \foreach \x in {\lastweekday,...,6}
     {
       \global\advance\julianday by 1\relax
       \pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
       \path (\x,-\rowcount)
        node
        [
          rectangle split,
          rectangle split parts=2,
          draw=gray,
          text=gray]
       {%
        \daynode{\number\theday}{}%
       };
     }
    \fi
  \end{tikzpicture}%
  }
}

\addevent{2014-01-01}{New Year's Day}
\addevent{2014-05-05}{Early May BH}
\addevent{2014-05-26}{Spring BH}
\addevent{2014-04-21}{Easter Monday BH}
\addevent{2014-08-25}{Summer BH}
\addevent{2014-12-25}{Christmas Day}
\addevent{2014-12-26}{Boxing Day}

\begin{document}
\centering

\foreach \thismonth in {1,...,12}
{
  \calendarmonth{2014}{\thismonth}
  \newpage
}

\end{document}

Download calendar2014.tex or calendar2014.pdf.

© 2015 Dickimaw Books. "Dickimaw", "Dickimaw Books" and the Dickimaw parrot logo are trademarks. The Dickimaw parrot was painted by Magdalene Pritchett.

Terms of Use Privacy Policy Cookies Site Map FAQs