14

I'm doing calendars for all the family, and I have a problem automating the process. I'm using the calendar tikz library.

I need to include the moon phase in the calendar. I can do it with this code

\documentclass{scrartcl}
\usepackage{mathabx}
\usepackage{tikz}
\usetikzlibrary{calendar}
\usepackage{etoolbox}

\newcount\mooncounter
\mooncounter=1

\def\moon{%
\ifnum\mooncounter=1%
    $\newmoon$\global\advance\mooncounter by 1\else
    \ifnum\mooncounter=2% 
        $\rightmoon$\global\advance\mooncounter by 1\else
        \ifnum\mooncounter=3% 
            $\fullmoon$\global\advance\mooncounter by 1\else
            \ifnum\mooncounter=4% 
                $\leftmoon$\global\mooncounter=1
            \fi%
        \fi%
    \fi%
\fi%
}

\begin{document}
\begin{tikzpicture}
    \calendar [
        dates = 2012-12-1 to 2012-12-last,
        week list,
        day xshift = 3em
        ] if (equals = 2012-12-27,
            equals = 2012-12-2,
            equals = 2012-12-7,
            equals = 2012-12-6,
            equals = 2012-12-8,
            equals = 2012-12-9,
            equals = 2012-12-12) [day text = \moon\%d-];
\end{tikzpicture}
\end{document}

First of all, I don't know how \newcount works (just copied the code from other site), but I use it because I can't find the way of doing it with \newcounter or \pgfmathtruncatemacro (I can't make them work in the \calendar). That's why I have this first question: Why the command doesn't work out of the \calendar? I mean. If I write

\begin{document}
    \moon \moon
\end{document}

it doesn't work as I expected. I want it to be cyclic but it shows me two consecutive \newmoons.

Anyway, I want to be able to input the days which have a moon, and then let LaTeX do the rest.

I tried with this:

\newcommand*{\listofmoons}[1]{%
    \edef\listmoons{#1}%
    \def\moons{}%
    \foreach \l in \listmoons {%
        \xappto\moons{if (equals = 2012-12-\l) [day text=\moon\%d-]}
    }%
}

and then use

\begin{tikzpicture}
    \listofmoons{2,6,7,8,9,12,27}
    \calendar [
        dates = 2012-12-1 to 2012-12-last,
        week list,
        day xshift = 3em
        ] \moons;
\end{tikzpicture}

but it doesn't work. Again it doesn't cycle correctly (that's why I'm suspicious about \newcount).

Which is the best way to achieve this? May be another completely different method?

By the way, is there any big question/community wiki about calendars? May be it would be good to open one.

1 Answer 1

14

I replaced your if-if-if-if construct with a simple \ifcase test. \moon works just fine now. Though the actual problem was another one. The counter assignments \global\advance\<counter> by 1 should be finished with a \relax. This also applies to the \ifnum but in this instance, it is not needed as math-mode is introduces right away. Without the \relax TeX might find more digits and swallows more than it should. Interestingly, putting \else on the next line does work, too.

Test the following code by subsequently restoring your original macro (no \relax/\else on the same line) and output a full line of \moon \moon \moon \moon \moon \moon.

\def\moon{%
\ifnum\mooncounter=1%
    $\newmoon$\global\advance\mooncounter by 1
  \else
    \ifnum\mooncounter=2% 
        $\rightmoon$\global\advance\mooncounter by 1\relax\else
        \ifnum\mooncounter=3% 
            $\fullmoon$\global\advance\mooncounter by 1
          \else
            \ifnum\mooncounter=4% 
                $\leftmoon$\global\mooncounter=1
            \fi%
        \fi%
    \fi%
\fi%
}

Anyhow, in this case I find a \ifcase construct much clearer:

\def\moon{%
    \global\advance\mooncounter by 1\relax% needs \mooncounter to start with -1
    \ifcase\mooncounter   $\newmoon$%                             = 0
        \or             $\rightmoon$%                             = 1
        \or              $\fullmoon$%                             = 2
        \or              $\leftmoon$\global\mooncounter=-1\relax% = 3
    \fi%
}

Also, I prepended \moon in the for-each loop with a \noexpand so that is firstly expanded when it is actually typeset.

Code

\documentclass{scrartcl}
\usepackage{mathabx}
\usepackage{tikz}
\usetikzlibrary{calendar}
\usepackage{etoolbox}

\newcount\mooncounter
\def\moonreset{\global\mooncounter=-1\relax}
\moonreset

\def\moon{%
    \global\advance\mooncounter by 1\relax%
    \ifcase\mooncounter $\newmoon$%
        \or             $\rightmoon$%
        \or             $\fullmoon$%
        \or             $\leftmoon$\global\mooncounter=-1\relax%
    \fi%
}

\newcommand*{\listofmoons}[1]{%
    \edef\listmoons{#1}%
    \def\moons{}%
    \foreach \l in \listmoons {%
        \xappto\moons{if (equals = 2012-12-\l) [day text=\noexpand\moon\%d-]}
    }%
}
\begin{document}
\moon \moon
\moonreset

\begin{tikzpicture}
    \calendar [
        dates = 2012-12-1 to 2012-12-last,
        week list,
        day xshift = 3em
        ] if (equals = 2012-12-27,
            equals = 2012-12-2,
            equals = 2012-12-7,
            equals = 2012-12-6,
            equals = 2012-12-8,
            equals = 2012-12-9,
            equals = 2012-12-12) [day text = \moon\%d-];
\end{tikzpicture}

\moonreset
\begin{tikzpicture}
    \listofmoons{2,6,7,8,9,12,27}
    \calendar [
        dates = 2012-12-1 to 2012-12-last,
        week list,
        day xshift = 3em
        ] \moons;
\end{tikzpicture}
\end{document}

Output

enter image description here

5
  • Okey. Perfect answer. By the way, is there any big question/community wiki about calendars? May be it would be good to open one.
    – Manuel
    Dec 27, 2012 at 13:58
  • @Manuel: You might also want to have a look at http://www.ctan.org/topic/calendar.
    – Stephen
    Dec 27, 2012 at 18:42
  • @Stephen Do they really add spectacular functionalities? Because I don't have most of them installed (I tried to compile most of their examples and doesn't work because my system doesn't find the package), and the calendar library of TikZ is useful for me.
    – Manuel
    Dec 27, 2012 at 20:26
  • @Manuel: I thought you could have wanted to look into the code of the packages to see how they create calendars. It was not my intention to suggest the use of one of those. My comment was too short to express this, sorry for being unclear!
    – Stephen
    Dec 28, 2012 at 17:17
  • +1. If I could I'd give +100 because you saved my day with \xappto. Thanks so much.
    – Sigur
    Feb 27, 2016 at 17:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .