我正在尝试使用 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
的循环体\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}