如何定义 tikz 日历的日期列表

如何定义 tikz 日历的日期列表

我正在尝试使用 pgf 键将日期列表传递给日历,以便可以在代码的不同部分使用它。

按照 PGF 和 TIKZ 手册,我得到了它mybirthday(见下面的代码)。但是,类似的想法在 中不起作用myholidays。我该如何修复它?顺便问一下,有没有更好的解决方案来定义一个日期“列表”(或数组等)来实现它?

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calendar}

\newcommand\myweekdayname[1]{\ifcase#1M\or T\or W\or T\or F\or S\or S\fi}

\pgfkeys{/pgf/calendar/mybirthday/.code={
    \ifnum\pgfcalendarifdatemonth=1\relax
        \ifnum\pgfcalendarifdateday=20\relax
            \pgfcalendarmatchestrue
        \fi\fi}}

\pgfkeys{/pgf/calendar/myholidays/.code={
    \foreach \m / \d in {1/4, 1/5, 1/6, 1/7, 1/8}{
        \ifnum\pgfcalendarifdatemonth=\m\relax
            \ifnum\pgfcalendarifdateday=\d\relax
                \pgfcalendarmatchestrue
            \fi\fi}}}

\begin{document}

\begin{tikzpicture}
    \calendar[
        dates=2021-01-01 to 2021-01-last,
        day list downward, day yshift = 1em,
        day code={
            \ifdate{weekend, mybirthday, myholidays}{
                \node[shape=coordinate]{}; % trick (1)
                }{
                \node[anchor = east]{\tikzdaytext};
                \node[anchor = west, gray]{\myweekdayname{\pgfcalendarcurrentweekday}};
                }},
        execute after day scope={
            \ifdate{weekend, mybirthday, myholidays}{\pgftransformyshift{1em}}{};
            \ifdate{Sunday}{\pgftransformyshift{-0.5em}}{} % week skip
            }       
        ];
\end{tikzpicture}

\end{document}

(1) 带有 TikZ 的日历;仅打印星期几

答案1

的循环体\foreach被包含在一个组中,因此的改变\let\def以及派生的命令保持局部,并在循环结束时被遗忘。

由于\pgfcalendarmatchestrue定义为,因此只需在前面\let \ifpgfcalendarmatches \iftrue添加:\global

\pgfkeys{/pgf/calendar/myholidays/.code={
    \foreach \m / \d in {1/4, 1/5, 1/6, 1/7, 1/8}{
        \ifnum\pgfcalendarifdatemonth=\m\relax
            \ifnum\pgfcalendarifdateday=\d\relax
                \global\pgfcalendarmatchestrue
            \fi\fi}}}

答案2

您实际上并不需要自己的日历.code

图书馆calendar已经有了equals,这样你就可以做

my birthday/.style={equals=01-20}

对于假期,你可以定义

my holidays/.style={
  equals=1-4, equals=1-5, equals=1-6, equals=1-7, equals=1-8}

或者甚至只是

my holidays/.style={between=1-4 and 1-8}

但是如果您想指定一个以逗号分隔的日期格式列表, <month>/<day>您可以使用.list处理程序(它使用\foreach但不进行分组):

my holidays/.style={@my holidays/.list={1/4, 1/5, 1/6, 1/7, 1/8}},
@my holidays/.style args={#1/#2}{equals={#1-#2}},

代码

\documentclass[12pt,tikz]{standalone}
\usetikzlibrary{calendar}
\newcommand\myweekdayname[1]{\ifcase#1M\or T\or W\or T\or F\or S\or S\fi}
\pgfqkeys{/pgf/calendar}{
  my birthday/.style={equals=01-20},
  % A
  % my holidays/.style={@my holidays/.list={1/4, 1/5, 1/6, 1/7, 1/8}},
  % @my holidays/.style args={#1/#2}{equals={#1-#2}},
  % B
  % my holidays/.style={
  %   equals=1-4, equals=1-5, equals=1-6, equals=1-7, equals=1-8},
  % C
  my holidays/.style={between=1-4 and 1-8},
}

\begin{document}
\begin{tikzpicture}
\calendar[
  dates=2021-01-01 to 2021-01-last,
  day list downward, day yshift = 1em,
  day code={
    \ifdate{weekend, my birthday, my holidays}{}{
      \node[anchor = east]{\tikzdaytext};
      \node[anchor = west, gray]{\myweekdayname{\pgfcalendarcurrentweekday}};}},
  execute after day scope={
    \ifdate{weekend, my birthday, my holidays}{\pgftransformyshift{1em}}{}
    \ifdate{Sunday}{\pgftransformyshift{-0.5em}}{} % week skip
  }];
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容