1

I am looking for a simple way to generate calendar pages in LaTeX, something like this: http://www.latextemplates.com/template/monthly-calendar - however without me having to think about the "correct" week-days to calendar alignments. It should be possible to automatically layout the pages correctly by specifying the date (e.g. February 2017).

Furthermore, it must be possible to edit the text in the calendar easily in LaTeX, so this not just for print out and filling in with ink. I guess the best would a two step process, one that generates the LaTeX file with entries for every day, and then one can edit the agenda of particular days. Another possibility is to have the calendar entries in some simpler text format (it should be possible to have this in git version control) and parse and insert them correctly from the latex file.

Emit Taste
  • 4,404
  • is this helpful: Typeset calendar but with the ability to write notes and todos? (it's one of the suggestions in the "related" column on the sidebar here.) – barbara beeton Jan 29 '17 at 14:09
  • @barbarabeeton thanks, this was indeed the same template I had at hand; the problem is you have to manually construct all the months. I'm looking for something procedural that basically creates this template with parametric input for month and year – Emit Taste Jan 29 '17 at 14:13
  • 1
    this answer (which probably isn't helpful otherwise -- http://tex.stackexchange.com/a/1227/579) mentions that it's necessary to use python to access the relevant dates. maybe a request for enhancement regarding the cited calendar at latextemplates would be worth trying. – barbara beeton Jan 29 '17 at 14:24

1 Answers1

1

Taking my answer from another question and adjusting it with:

\newcommand*\events{%
  \month-\day / Today,
  2023-04-10 / A very long text with math $e = mc^2$ and so much text that the whole box and its five lines are needed,
  12-31 / New Year's Eve,
  2023-04-11 / A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y
}
\tikzset{
  day event/.style={
    node contents={%
      \parshape 5 0pt \dimexpr\textwidth-1.9em 0pt \dimexpr\textwidth-1.9em
      0pt \textwidth 0pt \textwidth 0pt \textwidth #1\par},
    text height=+1em,
    text depth=\pgfkeysvalueof{/pgf/minimum height}-2*(\pgfkeysvalueof{/pgf/inner ysep})-1em,
    text width=\pgfkeysvalueof{/pgf/minimum width}-2*(\pgfkeysvalueof{/pgf/inner xsep}),
    align=left,
  },
  events/.style args={#1/#2}{
    if = {(equals=#1) [every day/.append style={day event={#2}}]}
  }
}

where \events holds a list of things you want to typeset inside the nodes boxes that is given to events which adds the text part to the day node where I'm using a \parshape solution to cut out an area on the right side (where the day number sits).

All you need now, is to fill the \events macros.

You can combine this with zjr approach taken in another answer where I'm using multiple macros and allow different styles so that you can use various type of events to be added to your calendar.

Though, try to make sure you only have one event per day, otherwise you will need something like [1] or [2].

There's also a solution where the calendar stretches so that it always fills the page.


The \parshape implentation is rather rudimentary because it just uses 1.9em as the extra padding at the right, it would be smarter to measure the width of the day text in the corner and use that.

I've also adjusted the main loop and added trim left and trim right to suppress overful hbox warnings.

Code

\documentclass[a4paper,landscape]{article}
\usepackage[margin={1cm},noheadfoot]{geometry}
\renewcommand*\thepage{}
\usepackage{libertine}
\usepackage{tikz}
\usetikzlibrary{calendar}
\tikzset{
  every weekday/.style={
    anchor=south west, black,
    name=weekday-\pgfcalendarcurrentmonth-\pgfcalendarcurrentweekday,
    node contents=\%wt},
  weekday above/.style={
    if = {(day of month=1) [days={append after command={
          node [at={(\tikzlastnode.north west)},
                alias=@firstweekday,
                every weekday]}}]},
    if = {(day of month=2, day of month=3, day of month=4, day of month=5, day of month=6, day of month=7) [
          days={append after command={
          node [at={(@firstweekday.south west-|\tikzlastnode.south west)}, every weekday]}}]}},
  wall calendar/.style={
    week list, weekday above, day text=,
    day and weekday/.style={
      draw, outer sep=+0pt,
      minimum width=\linewidth/7,
      minimum height=+.125\textheight},
    day xshift=\linewidth/7,
    day yshift=\textheight/8,
    every day label/.style={
      anchor=north east,
      font=\Large\itshape,
      node contents={\%d=},
      inner sep=+.7em},
    every day/.append style={
      day and weekday,
      anchor=center,
      label={[every day label]north east:}},
    every weekday/.append style={
      day and weekday,
      minimum height=+2em}}}
\newcommand*\Year{2023}
\newcommand*\events{%
  \month-\day / Today,
  2023-04-10 / A very long text with math $e = mc^2$ and so much text that the whole box and its five lines are needed,
  12-31 / New Year's Eve,
  2023-04-11 / A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y
}
\tikzset{
  day event/.style={
    node contents={%
      \parshape 5 0pt \dimexpr\textwidth-1.9em 0pt \dimexpr\textwidth-1.9em
      0pt \textwidth 0pt \textwidth 0pt \textwidth #1\par},
    text height=+1em,
    text depth=\pgfkeysvalueof{/pgf/minimum height}-2*(\pgfkeysvalueof{/pgf/inner ysep})-1em,
    text width=\pgfkeysvalueof{/pgf/minimum width}-2*(\pgfkeysvalueof{/pgf/inner xsep}),
    align=left,
  },
  events/.style args={#1/#2}{
    if = {(equals=#1) [every day/.append style={day event={#2}}]}
  }
}
\begin{document}\sffamily
\centering
\foreach \mon in {01,0...,09,10,11,12}{% leading zero for trim left/right
  {\Huge \pgfcalendarmonthname{\mon}\par}
  {\huge \Year\par}
  \vspace{2em}
  \tikz[trim left=(weekday-\mon-0.west), trim right=(weekday-\mon-6.east)]
    \calendar[
      dates=\Year-\mon-01 to \Year-\mon-last,
      wall calendar,
      events/.list/.expand once=\events,
    ];

\pagebreak} \end{document}

Output

enter image description here

Qrrbrbirlbel
  • 119,821