Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I've been searching for a while how to make a calendar with LaTeX and I've found some templates, however none of them fitted my needs. What I want is just a basic monthly calendar with some space for each day in order to add some reminders, tasks, birthdays, etc. I would like to plan my activities monthly in an easy way and print them then in a page.

I've seen this template surfing the internet, which I think is pretty neat, clear and not too old-styled, however I've been unable to find the code, so I would like to know if some of you could give me a hint in how to make it.

Latex Calendar

share|improve this question
    
Some years ago I created calendar sheets for my filofax. I wasn't able to implement a pure LaTeX solution so I used PHP to generate the code. I guess, I'd use Excel or Python now to calculate the weekdays and TikZ for the layout. –  Uwe Ziegenhagen Apr 9 at 5:52
3  
It looks like this example on texample.net –  esdd Apr 9 at 6:59
    
Yes, it is pretty much the same, I'm currently figuring out how to use it. Thanks. –  Giovanni Cásares Apr 9 at 7:17
    
@esdd, maybe you paste the code here as answer, otherwise I wonder how this question can be closed. –  math Apr 9 at 7:31
    
I have typeset this yearly calendar, striz7.fame.utb.cz/tex-sx/2014-calendar.pdf Each cell is one node in TikZ, but I doubt it would help you with your monthly calendar. –  Malipivo Apr 9 at 10:23
add comment

1 Answer 1

Here is a copy of the code from texample.net (Author: Hakon Malmedal):

% Birthday calendar
% Author: Hakon Malmedal
\documentclass[fontsize=20pt]{scrartcl}
\usepackage[norsk]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[margin=1cm,a4paper,landscape]{geometry}
\pagestyle{empty}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{calendar,fit}
\usepackage{expl3,xparse}

%% Adapted from http://tex.stackexchange.com/a/10199/4771
\makeatletter%
\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}%
      \pgftransformyshift{-\pgf@ya}
      \foreach \d/\l in {0/Mandag,1/Tirsdag,2/Onsdag,3/Torsdag,%
                         4/Fredag,5/Lørdag,6/Søndag} {
        \pgf@xa=\d\pgf@xa%
        \pgftransformxshift{\pgf@xa-\cellwidth/2}%
        \pgftransformyshift{\pgf@ya}%
        \node[above=-0.5ex,day heading]{\l};%
      }
    }{}%
  }%
]
\makeatother%
%% End

%% Adapted from pgf source
\def\pgfcalendarmonthname#1{%
  \translate{\ifcase#1\or Januar\or Februar\or Mars\or April\or
    Mai\or Juni\or Juli\or August\or September\or Oktober\or
    November\or Desember\fi}%
}

\makeatletter
\tikzstyle{month label above centered}=[%
  execute before day scope={%
    \ifdate{day of month=1}{%
      {
        \pgfmathsetlength{\pgf@xa}{\tikz@lib@cal@xshift}%
        \pgf@xb=\tikz@lib@cal@width\pgf@xa%
        \advance\pgf@xb by-\pgf@xa%
        \pgf@xb=.5\pgf@xb%
        \pgftransformxshift{\pgf@xb}%
        \pgftransformxshift{-\cellwidth/2}%
        \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
        \pgftransformyshift{0.333\pgf@y}
        \tikzmonthcode%
      }
    }{}},
  every month/.append style={anchor=base}
]
\makeatother
%% End

\ExplSyntaxOn

%% Adapted from http://tex.stackexchange.com/a/56214/4771
%%
% first of all we define the user level commands
\NewDocumentCommand{\addtext}{ m }{ \bdaycal_input_add:n { #1 } }
\NewDocumentCommand{\addtextyear}{ mm }{ \bdaycal_input_add_y:nn { #1 } { #2 } }
\NewDocumentCommand{\showtext}{ }{ \bdaycal_output_direct: }

% allocate variable:
% a sequence for global storage of the inputs;
\seq_new:N \g_bdaycal_input_seq

% store globally an input in the sequence
\cs_new:Npn \bdaycal_input_add:n #1
 {
  \seq_gput_right:Nn \g_bdaycal_input_seq { #1 }
 }

\cs_new:Npn \bdaycal_input_add_y:nn #1 #2
 {
  \seq_gput_right:Nn \g_bdaycal_input_seq { #1 ~ ( \int_to_arabic:n
    { \pgfcalendarifdateyear - #2 } ) }
 }

% how to output in direct order; we simply do a mapping function calling
% \bdaycal_print:n after incrementing the counter
\cs_new_protected:Npn \bdaycal_output_direct:
 {
  \seq_map_inline:Nn \g_bdaycal_input_seq
   {
    \bdaycal_print:n { ##1 }
   }
  \seq_gclear:N \g_bdaycal_input_seq
 }

% the printing macro; change here for adapting to your wishes
\cs_new:Npn \bdaycal_print:n #1
 {
  #1 \par
 }
%% End

%% Knuth's AoCP, vol 1, 2nd ed, pp 155--156
\int_new:N \l_easter_Y_int
\int_new:N \l_easter_G_int
\int_new:N \l_easter_C_int
\int_new:N \l_easter_X_int
\int_new:N \l_easter_Z_int
\int_new:N \l_easter_D_int
\int_new:N \l_easter_E_int
\int_new:N \l_easter_N_int
\int_new:N \l_easter_M_int
\int_new:N \l_easter_julian_day_int

\cs_new:Nn \easter_sunday:n {

  \int_set:Nn \l_easter_Y_int { #1 }

  \int_set:Nn \l_easter_G_int {
    \int_mod:nn { \l_easter_Y_int } { 19 } + 1
  }

  \int_set:Nn \l_easter_C_int {
    \int_div_truncate:nn { \l_easter_Y_int } { 100 } + 1
  }

  \int_set:Nn \l_easter_X_int {
    \int_div_truncate:nn { 3 * \l_easter_C_int } { 4 } - 12
  }

  \int_set:Nn \l_easter_Z_int {
    \int_div_truncate:nn { 8 * \l_easter_C_int + 5 } { 25 } - 5
  }

  \int_set:Nn \l_easter_D_int {
    \int_div_truncate:nn { 5 * \l_easter_Y_int } { 4 } - \l_easter_X_int - 10
  }

  \int_set:Nn \l_easter_E_int {
    \int_mod:nn { 11 * \l_easter_G_int + 20 + \l_easter_Z_int
      - \l_easter_X_int } { 30 }
  }

  % \int_mod:nn behaves strangely.
  \int_compare:nNnT { \l_easter_E_int } < { 0 }
  {
    \int_add:Nn \l_easter_E_int { 30 }
  }

  \int_compare:nNnTF { \l_easter_E_int } = { 25 }
  { % true
    \int_compare:nNnT { \l_easter_G_int } > { 11 }
    { % true
      \int_incr:N \l_easter_E_int
    }
  }
  { % false
    \int_compare:nNnT { \l_easter_E_int } = { 24 }
    { % true
      \int_incr:N \l_easter_E_int
    }
  }

  \int_set:Nn \l_easter_N_int { 44 - \l_easter_E_int }

  \int_compare:nNnT { \l_easter_N_int } < { 21 }
  { % true
    \int_add:Nn \l_easter_N_int { 30 }
  }

  \int_add:Nn \l_easter_N_int {
    7 - \int_mod:nn { \l_easter_D_int + \l_easter_N_int } { 7 }
  }

  \int_compare:nNnTF { \l_easter_N_int } > { 31 }
  { % true
    \int_sub:Nn \l_easter_N_int { 31 }
    \int_set:Nn \l_easter_M_int { 4 } % April
  }
  { % false
    \int_set:Nn \l_easter_M_int { 3 } % March
  }

  \pgfcalendardatetojulian { \l_easter_Y_int -
     \l_easter_M_int - \l_easter_N_int
  } { \l_easter_julian_day_int }

}

\pgfkeys{/pgf/calendar/Easter/.default = 0}
\pgfkeys{/pgf/calendar/Easter/.code =
  {
    \easter_sunday:n { \pgfcalendarifdateyear }
    \int_compare:nNnT { \pgfcalendarifdatejulian }
    =  {\l_easter_julian_day_int + #1}
    { \pgfcalendarmatchestrue }
  }
}

\int_new:N \l_advent_Y_int
\int_new:N \l_advent_xmas_julian_day_int
\int_new:N \l_advent_xmas_week_day_int
\int_new:N \l_advent_julian_day_int

\cs_new:Nn \advent_sunday:n {

  \int_set:Nn \l_advent_Y_int { #1 }

  \pgfcalendardatetojulian { \l_advent_Y_int - 12 - 25 } {
    \l_advent_xmas_julian_day_int }

  \pgfcalendarjuliantoweekday { \l_advent_xmas_julian_day_int } {
    \l_advent_xmas_week_day_int }

  \int_set:Nn \l_advent_julian_day_int {
    \l_advent_xmas_julian_day_int - \l_advent_xmas_week_day_int - 22 }

}

\pgfkeys{/pgf/calendar/Advent/.default = 0}
\pgfkeys{/pgf/calendar/Advent/.code =
  {
    \advent_sunday:n { \pgfcalendarifdateyear }
    \int_compare:nNnT { \pgfcalendarifdatejulian }
    =  {\l_advent_julian_day_int + #1}
    { \pgfcalendarmatchestrue }
  }
}

%% http://www.tondering.dk/claus/cal/week.php#calcweekno
\int_new:N \l_week_number_year_int
\int_new:N \l_week_number_month_int
\int_new:N \l_week_number_day_int
\int_new:N \l_week_number_a_int
\int_new:N \l_week_number_b_int
\int_new:N \l_week_number_c_int
\int_new:N \l_week_number_s_int
\int_new:N \l_week_number_e_int
\int_new:N \l_week_number_f_int
\int_new:N \l_week_number_g_int
\int_new:N \l_week_number_d_int
\int_new:N \l_week_number_n_int
\int_new:N \l_week_number_W_int

\cs_new:Nn \week_number:nnn {

  \int_set:Nn \l_week_number_year_int { #1 }
  \int_set:Nn \l_week_number_month_int { #2 }
  \int_set:Nn \l_week_number_day_int { #3 }

  \int_compare:nNnTF { \l_week_number_month_int } < { 3 } % jan or feb
  { % true

    \int_set:Nn \l_week_number_a_int { \l_week_number_year_int - 1 }

    \int_set:Nn \l_week_number_b_int {
      \int_div_truncate:nn { \l_week_number_a_int } { 4 }
      - \int_div_truncate:nn { \l_week_number_a_int } { 100 }
      + \int_div_truncate:nn { \l_week_number_a_int } { 400 }
    }

    \int_set:Nn \l_week_number_c_int {
      \int_div_truncate:nn { \l_week_number_a_int - 1 } { 4 }
      - \int_div_truncate:nn { \l_week_number_a_int - 1 } { 100 }
      + \int_div_truncate:nn { \l_week_number_a_int - 1 } { 400 }
    }

    \int_set:Nn \l_week_number_s_int {
      \l_week_number_b_int - \l_week_number_c_int }

    \int_zero:N \l_week_number_e_int

    \int_set:Nn \l_week_number_f_int { \l_week_number_day_int - 1
      + 31 * ( \l_week_number_month_int - 1 ) }

  } % end true
  { % false

    \int_set_eq:NN \l_week_number_a_int \l_week_number_year_int

    \int_set:Nn \l_week_number_b_int {
      \int_div_truncate:nn { \l_week_number_a_int } { 4 }
      - \int_div_truncate:nn { \l_week_number_a_int } { 100 }
      + \int_div_truncate:nn { \l_week_number_a_int } { 400 }
    }

    \int_set:Nn \l_week_number_c_int {
      \int_div_truncate:nn { \l_week_number_a_int - 1 } { 4 }
      - \int_div_truncate:nn { \l_week_number_a_int - 1 } { 100 }
      + \int_div_truncate:nn { \l_week_number_a_int - 1 } { 400 }
    }

    \int_set:Nn \l_week_number_s_int {
      \l_week_number_b_int - \l_week_number_c_int }

    \int_set:Nn \l_week_number_e_int { \l_week_number_s_int + 1 }

    \int_set:Nn \l_week_number_f_int { \l_week_number_day_int
      + \int_div_truncate:nn {
        153 * ( \l_week_number_month_int - 3 ) + 2 } { 5 }
      + 58 + \l_week_number_s_int }

  } % end false

  \int_set:Nn \l_week_number_g_int {
    \int_mod:nn { \l_week_number_a_int + \l_week_number_b_int } { 7 }  }

  \int_set:Nn \l_week_number_d_int {
    \int_mod:nn { \l_week_number_f_int + \l_week_number_g_int
      - \l_week_number_e_int } { 7 }  }

  \int_set:Nn \l_week_number_n_int {
    \l_week_number_f_int + 3 - \l_week_number_d_int }

  \int_compare:nNnTF { \l_week_number_n_int } < { 0 }
  { %true

    \int_set:Nn \l_week_number_W_int { 53
      - \int_div_truncate:nn { \l_week_number_g_int
        - \l_week_number_s_int } { 5 } }

  } % end true
  { % false

    \int_compare:nNnTF { \l_week_number_n_int } > { 364
      + \l_week_number_s_int }
    { % true

      \int_set:Nn \l_week_number_W_int { 1 }

    } % end true
    { % false

      \int_set:Nn \l_week_number_W_int { \int_div_truncate:nn {
          \l_week_number_n_int } { 7 } + 1 }

    } % end false

  } % end false

}

\definecolor{roed}{rgb}{0.937254901961,0.16862745098,0.176470588235}
\definecolor{blaa}{rgb}{0,0.156862745098,0.407843137255}

\newsavebox{\flagNO}
\savebox{\flagNO}{
\begin{tikzpicture}
  \fill[roed] rectangle (6pt,6pt);
  \fill[roed,yshift=10pt] rectangle (6pt,6pt);
  \fill[roed,xshift=10pt] rectangle (12pt,6pt);
  \fill[roed,xshift=10pt,yshift=10pt] rectangle (12pt,6pt);
  \fill[blaa,yshift=7pt] rectangle (22pt,2pt);
  \fill[blaa,xshift=7pt] rectangle (2pt,16pt);
\end{tikzpicture}
}

\pgfkeys{/tikz/week~number/.code =
  {
    \week_number:nnn { 
      \pgfcalendarifdateyear } { 
      \pgfcalendarifdatemonth } { 
      \pgfcalendarifdateday }
    \addtext{ Uke ~ \int_to_arabic:n { \l_week_number_W_int } }
  }
}

\ExplSyntaxOff

\pgfkeys{/tikz/flag-flying day/.code =
  {
    \draw (-\cellwidth,0) node [above right,font=\Huge]
    {\resizebox{!}{0.8ex}{\usebox{\flagNO}}};
  }
}

\pgfkeys{/tikz/observance/.code =
  {
    \addtext{#1}
  }
}

\pgfkeys{/tikz/anniversary/.code 2 args=\addtextyear{#1}{#2}}

\pgfkeys{/tikz/day code =
  {
    \node (lower right) at (0,0) [above left,font=\Huge] {\tikzdaytext};
    \node (upper left) at (-\cellwidth,\cellheight)
    [below right,align=left,text width=\cellwidth-\pgflinewidth,
    font=\tiny,black] {\showtext};
    \node (lower left) at (-\cellwidth,0) {};
    \node[rounded corners, draw,
          fit=(lower right) (upper left) (lower left),
          inner sep=1mm] {};
  }
}

\pgfkeys{/tikz/inner sep = 0pt}

\pgfkeys{/tikz/day xshift=\cellwidth+2mm+2mm}

\pgfkeys{/tikz/day yshift=\cellheight+2mm+2mm}

\newlength{\cellheight}
\setlength{\cellheight}{25mm}
\newlength{\cellwidth}
\setlength{\cellwidth}{35mm}

\begin{document}

\centering

\begin{tikzpicture}[thick]
  \calendar[dates=2012-05-01 to 2012-05-last,
            week list,
            month label above centered,
            month text=\textsc{\%mt \%y0},
            day headings={font=\footnotesize},
            day letter headings]
  if (Monday,
      equals=01-01,
      equals=02-01,
      equals=03-01,
      equals=04-01,
      equals=05-01,
      equals=06-01,
      equals=07-01,
      equals=08-01,
      equals=09-01,
      equals=10-01,
      equals=11-01,
      equals=12-01) [week number]
  if (Sunday,
      Easter=-3, % Maundy Thursday
      Easter=-2, % Good Friday
      Easter,    % Easter Sunday
      Easter=1,  % Easter Monday
      Easter=39, % Feast of the Ascension
      Easter=49, % Pentecost
      Easter=50, % Whit Monday
      equals=01-01,
      equals=05-01,
      equals=05-17,
      equals=12-25,
      equals=12-26) [red]
  if (equals=01-01,
      equals=01-21,
      equals=02-06,
      equals=02-21,
      equals=05-01,
      equals=05-08,
      equals=05-17,
      equals=06-07,
      equals=07-04,
      equals=07-20,
      equals=07-29,
      equals=08-19,
      equals=12-25,
      Easter,
      Easter=49) [flag-flying day]
  if (equals=01-01) [observance=Første nyttårsdag]
  if (equals=01-21) [observance=Prinsesse Ingrid Alexandra]
  if (equals=02-06) [observance=Samefolkets dag]
  if (equals=02-21) [observance=Kong Harald~V]
  if (equals=05-01) [observance=Offentlig høytidsdag]
  if (equals=05-08) [observance=Frigjøringsdagen]
  if (equals=05-17) [observance=Grunnlovsdag]
  if (equals=06-07) [observance=Unionsoppløsningen]
  if (equals=06-23) [observance=Sankthansaften]
  if (equals=07-04) [observance=Dronning Sonja]
  if (equals=07-20) [observance=Kronprins Haakon]
  if (equals=07-29) [observance=Olsok]
  if (equals=08-19) [observance=Kronprinsesse Mette-Marit]
  if (equals=10-24) [observance=FN-dagen]
  if (equals=12-25) [observance=Første juledag]
  if (equals=12-26) [observance=Andre juledag]
  if (Easter=-49) [observance=Fastelavnssøndag]
  if (Easter=-7) [observance=Palmesøndag]
  if (Easter=-3) [observance=Skjærtorsdag]
  if (Easter=-2) [observance=Langfredag]
  if (Easter) [observance=Første påskedag]
  if (Easter=1) [observance=Andre påskedag]
  if (Easter=39) [observance=Kristi himmelfartsdag]
  if (Easter=49) [observance=Første pinsedag]
  if (Easter=50) [observance=Andre pinsedag]
  if (Advent) [observance=Advent]
  if (equals=05-07) [anniversary={Brahms}{1833}]
;
\end{tikzpicture}

\end{document}

enter image description here

share|improve this answer
    
You have any ideas about how to change the font color for the observances? Just like in the image I provided? For example, to make them look tan or brown. –  Giovanni Cásares Apr 9 at 8:46
    
You can define a new color like \definecolor{obse}{rgb}{0.847,0.380,0.024} and then change the pgfkey /tikz/observance/.code in \pgfkeys{/tikz/observance/.code ={\addtext{\textcolor{obse}{#1}}}} –  esdd Apr 9 at 9:50
    
That is perfect, it worked like a charm, thanks again! –  Giovanni Cásares Apr 10 at 23:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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