Tikz 日历:循环遍历日期数组来标记假期

Tikz 日历:循环遍历日期数组来标记假期

我正在编写一个日历蒂克兹我在尝试显示假期时遇到了问题。在下面的代码中,我尝试使用循环,因为它更具动态性,我不必在实际函数中对其进行硬编码\calendar[]。注释掉的代码运行良好。日期之间的所有天数都变灰。使用循环,什么都没有发生。没有错误消息(我认为这是好事),但也没有灰色单元格,这很糟糕……

为什么它不起作用?我怎样才能让它起作用?


日历

\documentclass[landscape, a4paper, ngerman, 10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz, xparse}
\usepackage{lmodern}
\usepackage{translator}                 % German Month and Day names
\usepackage{fancyhdr}                   % header and footer
\usepackage{color}                      % Colors
\usepackage[
  headheight = 11ex,
  margin=.5cm,
  top = 3.2cm,
  nofoot,
]{geometry}

\usetikzlibrary{calc, calendar}
\renewcommand*\familydefault{\sfdefault}

% ------------------------------------------------------- 
%
% User defined
%
% -------------------------------------------------------

% Input the variables.tex
% Defines the user variables
\input{variables}

% Header
\renewcommand{\headrulewidth}{0pt}
\fancyhf{}
\lhead{%
    \fontsize{60}{70}\selectfont\bfseries{%
        SS \currentyear
    }
}

% ------------------------------------------------------- 
%
% Calendar
%
% -------------------------------------------------------

\begin{document}
    \pagestyle{fancy}
    \centering

    % ------------------------------------------------------- 
    %
    % Summersemester
    % April to September
    %
    % ------------------------------------------------------- 
    \begin{tikzpicture}[every day/.style={anchor = north}]
        \calendar[
            dates = \currentyear-04-01 to \currentyear-09-30,
            name = cal,
            day yshift = 3em,
            day code = {
                \node[name = \pgfcalendarsuggestedname, every day, minimum height = .53cm, text width = 4.4cm, draw = gray] {\tikzdaytext};
                \draw (-1.8cm, -.1ex) node [anchor = west, font=\footnotesize] {\pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday}};
            },
            execute before day scope={
                \ifdate{day of month = 1} {
                    \pgftransformxshift{4.8cm}
                    \draw (0,0) node [minimum height = .53cm, text width = 4.4cm, fill = definedcolor, text = white, draw = definedcolor, text centered] {\textbf{\pgfcalendarmonthname{\pgfcalendarcurrentmonth}\strut}};
                }{}
                \ifdate{workday} {
                    \tikzset{every day/.style = {fill = white}}
                    \foreach \vacationBegin/\vacationEnd in \vacations {
                        \ifdate{between = \vacationBegin and \vacationEnd}{%
                            \tikzset{every day/.style = {fill = gray!30}}%
                        }{}
                    }
                    % \ifdate{between = \sommerbegin and \sommerend}{%
                    %     \tikzset{every day/.style = {fill = gray!30}}%
                    % }{}
                    % \ifdate{between = \pfingstenbegin and \pfingstenend}{%
                    %     \tikzset{every day/.style = {fill = gray!30}}%
                    % }{}
                    % \ifdate{between = \winterbegin and \winterend}{%
                    %     \tikzset{every day/.style = {fill = gray!30}}%
                    % }{}
                }{}
                \ifdate{Saturday} {
                    \tikzset{every day/.style = {fill = definedcolor!10}}%
                }{}
                \ifdate{Sunday} {
                    \tikzset{every day/.style = {fill = definedcolor!20}}%
                }{}
            },
            execute at begin day scope = {
                \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
            }
        ];
    \end{tikzpicture}

\end{document}

变量

\newcommand*\vacations{%
    \currentyear-02-10/\currentyear-04-18,%
    \currentyear-07-28/\currentyear-10-02,%
    \currentyear-06-05/\currentyear-06-10
}

% Semester break (Winter)
% \newcommand*\winterbegin{\currentyear-02-10}
% \newcommand*\winterend{\currentyear-04-18}

% Semester break (Summer)
% \newcommand*\summerbegin{\currentyear-07-28}
% \newcommand*\summerend{\currentyear-10-02}

% Pentecost vacation
% \newcommand*\pentecostbegin{\currentyear-06-05}
% \newcommand*\pentecostend{\currentyear-06-10}

带循环的输出 在此处输入图片描述

无循环输出 在此处输入图片描述


哦,当我在这里时:是否有可能在单元格内写下假期的名称?

这样我的数组看起来就会像这样:

\newcommand*\vacations{%
    \currentyear-02-10/\currentyear-04-18/{Winter},%
    \currentyear-07-28/\currentyear-10-02/{Summer},%
    \currentyear-06-05/\currentyear-06-10/{Pentecost}%
}

答案1

这是对 OP 代码的一次或多或少的完全重写。使用循环导致的 TeX 迭代范围问题(阻止休假键的设置在迭代范围之外仍然存在)可以通过使用\foreachpgfkeys.list中的处理程序来避免。

几乎所有样式都已移出日历代码,并在其中添加了一个部分来day code检查是否已设置键,如果已设置,则使用节点(可自定义)来排版假期名称。目前,周末条目的假期名称尚未排版,可以通过从and子句/tikz/vacation name中删除键来更改此情况。vacation name=\ifdate{Saturday}\ifdate{Sunday}

\documentclass[landscape,a4paper,ngerman,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz,xparse}
\usepackage{lmodern}
\usepackage{translator}           
\usepackage{fancyhdr}
\usepackage[
  headheight=11ex,
  margin=.5cm,
  top=3.2cm,
  nofoot
]{geometry}
\usetikzlibrary{calc, calendar}
\renewcommand*\familydefault{\sfdefault}
\colorlet{calendar}{red}
\def\currentyear{\the\year}
\newcommand*\vacations{%
  \currentyear-02-10/\currentyear-04-18/Winter,%
  \currentyear-07-28/\currentyear-10-02/Summer,%
  \currentyear-06-05/\currentyear-06-10/Penticost
}
% Header
\renewcommand{\headrulewidth}{0pt}
\fancyhf{}
\lhead{\fontsize{60}{70}\selectfont\bfseries SS \currentyear}

\pagestyle{fancy}
\newif\ifvacation
\tikzset{%
every 1st of month/.style={
  every day/.try,
  fill=calendar, text=white, draw=calendar, text centered,
  font=\bfseries, execute at end node=\strut
},
every day/.style={
   minimum height=.53cm, 
   text width=4.4cm, 
   draw=gray,
   text=black
},
every day name/.style={
  text=black, font=\footnotesize
},
every workday/.style={
  every day/.append style={
    fill=white
  }
},
every saturday/.style={
  every day/.append style={
    fill=calendar!10
  }
},
every sunday/.style={
  every day/.append style={
    fill=calendar!20
  }
},
every vacation/.style={
  every day/.append style={
    fill=gray!30
  },
  text=black!60
},
vacation name/.initial=,
}
\begin{document}
\centering
\begin{tikzpicture}
\calendar[
  dates=\currentyear-04-01 to \currentyear-09-30,
  name=cal,
  day code={
    \node  [name=\pgfcalendarsuggestedname, every day/.try] {\tikzdaytext};
    \node  [anchor=west, every day name/.try] 
      at ([xshift=0.5cm]\pgfcalendarsuggestedname.west)
        {\pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday}};
    \pgfkeysifdefined{/tikz/vacation name}{%
      \node [every vacation/.try]  {\pgfkeysvalueof{/tikz/vacation name}};
    }{}%
  },
  execute before day scope={
    \ifdate{day of month=1} {
      \pgftransformxshift{4.8cm}
      \node [every 1st of month] 
        {\pgfcalendarmonthname{\pgfcalendarcurrentmonth}};
    }{}
    \ifdate{workday} {
      \tikzset{every workday/.try, vacation name=,
        loop over item/.code args={##1/##2/##3}{%
          \ifdate{between=##1 and ##2}{%
            \tikzset{every vacation/.try, vacation name/.expanded=##3}%
          }{}},
        loop over item/.list/.expanded=\vacations}%
      }{}
    \ifdate{Saturday}{\tikzset{every saturday/.try, vacation name=}}{}%
    \ifdate{Sunday}{\tikzset{every sunday/.try, vacation name=}}{}%
   },
   execute at begin day scope={%
     \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
   }
];
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容