帮助自动创建日历

帮助自动创建日历

我正在为全家人制作日历,但我遇到了一个问题自动化这个过程。我正在使用calendartikz 库。

我需要在日历中加入月相。我可以用以下代码来实现

\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}

首先,我不知道它是如何\newcount工作的(只是从其他网站复制了代码),但我使用它,因为我找不到使用\newcounter或执行它的方法\pgfmathtruncatemacro(我无法让它们在 中工作\calendar)。这就是为什么我有第一个问题:为什么命令在 之外不起作用\calendar?我的意思是。如果我写

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

它没有像我预期的那样工作。我希望它是循环的,但它显示了两个连续的\newmoons。

无论如何,我希望能够输入有月亮的日子,然后让 LaTeX 完成剩下的工作。

我尝试过这个:

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

然后使用

\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}

但它不起作用。它再次无法正确循环(这就是我怀疑的原因\newcount)。

实现此目的的最佳方法是什么? 可能是另一种完全不同的方法?

顺便问一下,有没有关于日历的大型问题/社区 wiki?也许开一个会比较好。

答案1

\ifcase我用一个简单的测试替换了你的 if-if-if-if 结构。\moon现在工作得很好。虽然实际问题是另一个。计数器分配\global\advance\<counter> by 1应该以 结束\relax。这也适用于\ifnum但在这种情况下,它不是必需的,因为数学模式会立即引入。如果没有 TeX\relax可能会找到更多的数字并吞下比它应该吞下的内容更多。有趣的是,\else在下一行放入 也有效。

通过随后恢复原始宏(同一行上没有\relax/ )并输出一整行来测试以下代码。\else\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%
}

无论如何,在这种情况下,我发现一个\ifcase更清晰的结构:

\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%
}

另外,我\moon在 for-each 循环中添加了一个前缀\noexpand,以便在实际排版时首先进行扩展。

代码

\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}

输出

在此处输入图片描述

相关内容