编辑

编辑

我正在修改日历罗伯特·克劳斯示例) 并尝试使代码更加动态。我将其拆分为两个文件。其中一个包含主代码(逻辑),另一个包含所有事件、假期等。

我的计划是在这个单独的干净文件中定义所有事件,然后让它tikz完成其余工作。它应该循环遍历所有“数组”并将内容填充到日历中。

不幸的是,我收到了九条错误消息。它们都如下所示:

包 pgf 错误:没有已知名为 cal-2016-01-01 的形状。

我不明白为什么会发生这种情况,如果有人能帮助我我会非常高兴。

以下是主要代码:

\documentclass[landscape, a4paper, ngerman, 10pt]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz}                       % Use the calendar.sty style
\usepackage{translator}                 % German Month and Day names
\usepackage{fancyhdr}                   % header and footer
\usepackage{fix-cm}                     % Large year in header
\usepackage{color}                      % Colors
\usepackage[
    landscape, 
    headheight = 2cm, 
    margin=.5cm,
    top = 3.2cm, 
    nofoot
]{geometry}

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

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

\input{termine}

% Color
\definecolor{nicegreen}{HTML}{00cc00}

% Names of Holidays are inserted by employing this macro
\def\feiertag#1#2{
    \node [
        anchor = north west, 
        text width = 3.4cm
    ] at
    ($(cal-#1.north west)+(3em, -0.2em)$) {\scriptsize{#2}};
}

% Names of Exams are inserted by employing this macro
\def\exam#1#2{
    \node [
        anchor = north west, 
        text width = 3.4cm,
        text = red,
        font = \bf
    ] at
    ($(cal-#1.north west)+(3em, -0.2em)$) {\scriptsize{#2}};
}

% Header
\renewcommand{\headrulewidth}{0.0pt}
\setlength{\headheight}{11ex}
\chead{
  \fontsize{60}{70}\selectfont\textbf{WS \year/\nextyear}
  \Large\textbf{}\hfill
}

% Footer
\cfoot{\footnotesize\texttt{}}


\begin{document}
    \pagestyle{fancy}
    \begin{center}

        % ------------------------------------------------------- 
        %
        % Wintersemester
        % September to February
        %
        % ------------------------------------------------------- 
        \begin{tikzpicture}[every day/.style={anchor = north}]
            \calendar[
                dates = \year-10-01 to \nextyear-03-31,
                name = cal,
                day yshift = 3em,
                day code = {
                    \node[
                        name = \pgfcalendarsuggestedname,
                        every day, 
                        shape = rectangle,
                        minimum height = .53cm, 
                        text width = 4.4cm, 
                        draw = gray
                    ]{\tikzdaytext};
                    \draw (-1.8cm, -.1ex) node[anchor = west]{\footnotesize%
                        \pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday}
                    };
                },
                execute before day scope={
                    \ifdate{day of month = 1} {
                        % Shift right
                        \pgftransformxshift{4.8cm}
                        % Print month name 
                        \draw (0,0)node [
                            shape = rectangle, 
                            minimum height = .53cm,
                            text width = 4.4cm, 
                            fill = nicegreen, 
                            text = white, 
                            draw = nicegreen, 
                            text centered
                        ]
                        {\textbf{\pgfcalendarmonthname{\pgfcalendarcurrentmonth}\strut}};
                    }{}
                    \ifdate{workday} {
                        % normal days are white
                        \tikzset{every day/.style = {fill = white}}
                        % Vacation (Uni Bonn)
                        % ----------------------
                        % Semesterferien Sommer
                        \ifdate{between = \sommerbegin and \sommerend}{%
                            \tikzset{every day/.style = {fill = gray!30}}%
                        }{}                        
                        % Weihnachtspause
                        \ifdate{between = \weihnachtsbegin and \weihnachtsend}{%
                            \tikzset{every day/.style = {fill = gray!30}}%
                        }{}
                        % Semesterferien Winter
                        \ifdate{between = \winterbegin and \winterend}{%
                            \tikzset{every day/.style = {fill = gray!30}}%
                        }{}
                    }{}
                    % Saturdays
                    \ifdate{Saturday} {
                        \tikzset{every day/.style = {fill = nicegreen!10}}%
                    }{}
                    % Sundays
                    \ifdate{Sunday} {
                        \tikzset{every day/.style = {fill = nicegreen!20}}%
                    }{}
                },
                execute at begin day scope = {
                    % each day is shifted down according to the day of month
                    \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
                }
            ];

            % Print name of Holidays (January to June)
            \foreach \subject/\eventdate in \feiertage{
               \feiertag{\eventdate}{\subject}
            }

            % Print name of Exams (January to June)
            \foreach \subject/\eventdate in \exams{
                \exam{\eventdate}{\subject}
            }

        \end{tikzpicture}

    \end{center}
\end{document}

以下是termine.tex

% ------------------------------------------------------- 
% ------------------------------------------------------- 
% Define the year, holidays, exams and vacations
% ------------------------------------------------------- 
% ------------------------------------------------------- 


% ------------------------------------------------------- 
% YEAR
% ------------------------------------------------------- 

\def\year{2016}                            % Year for the calendar
\edef\nextyear{\the\numexpr\year+1\relax}  % \year + 1


% ------------------------------------------------------- 
% Holidays
% Syntax {day description}/date
% ------------------------------------------------------- 

\def\feiertage {
    {Neujahr}/\year-01-01,
    {Karfreitag}/\year-04-14,
    {Tag der dt. Einheit}/\year-10-03,
    {Reformationstag}/\year-10-31,
    {Allerheiligen}/\year-11-01,
    {1. Weihnachtstag}/\year-12-25,
    {2. Weihnachtstag}/\year-12-26,
    {Sylvester}/\year-12-31,
}


% ------------------------------------------------------- 
% EXAMS
% Syntax: {exam name}/date
% ------------------------------------------------------- 

\def\exams {
    {Quantitative Analysen}/\year-01-09,
    {Pysikalische Chemie}/\year-01-20,
    {Biochemie}/\year-02-10,
}


% ------------------------------------------------------- 
% VACATIONS
% ------------------------------------------------------- 

% Semester break (Winter)
\def\winterbegin{\nextyear-02-10}
\def\winterend{\nextyear-04-18}

% Semester break (Sommer)
\def\sommerbegin{\year-07-28}
\def\sommerend{\year-10-17}

% Christmas vacation
\def\weihnachtsbegin{\year-12-26}
\def\weihnachtsend{\nextyear-01-06}

有人发现我的代码有错误吗?提前谢谢您!

\feiertage哦,我怎样才能将“数组”的日子填满灰色呢?

在假期中添加以下代码行也会导致错误消息 :-(

\ifdate{workday} {
    % normal days are white
    \tikzset{every day/.style = {fill = white}}
    % Vacation (Uni Bonn)
    % ----------------------
    % Semesterferien Sommer
    \ifdate{between = \sommerbegin and \sommerend}{%
        \tikzset{every day/.style = {fill = gray!30}}%
    }{}                        
    % Weihnachtspause
    \ifdate{between = \weihnachtsbegin and \weihnachtsend}{%
        \tikzset{every day/.style = {fill = gray!30}}%
    }{}
    % Semesterferien Winter
    \ifdate{between = \winterbegin and \winterend}{%
        \tikzset{every day/.style = {fill = gray!30}}%
    }{}
    % Feiertage
    \foreach \subject/\eventdate in \feiertage{
        \ifdate{equals=\eventdate}{%
            \tikzset{every day/.style={fill=gray!30}}%
        }{}
    }
}{}

编辑

回应成本加运费我在这里扩展我的问题,以便它包含一条评论。

\feiertage上面我要求一种方法来将“数组”中的事件标记为灰色。成本加运费的答案工作正常,但不幸的是它覆盖了之前的颜色设置。对我来说很清楚(但不幸的是我没有要求它),周末应该保持绿色,或者选择的任何颜色。所以我正在寻找一种方法,将所有事件都\feiertage设置为灰色背景,如果它们是不是在周末。成本加运费非常友好地编辑了他的答案,现在完全满足了我的愿望。

答案1

为了回答你在回答中提出的问题,

\def\feiertag#1#2{%
  \fill [gray!30, blend mode=darken] (cal-#1.north west) rectangle (cal-#1.south east);
    \node [
        anchor = north west,
        text width = 3.4cm,
    ] at ($(cal-#1.north west)+(3em, -0.2em)$) {\scriptsize{#2}};
}

编辑

为了回答评论中的问题(原始问题中根本没有问到这个问题),这里有一个版本,只有在没有其他特殊颜色应用时才应用灰色填充。实际上,它无论如何都会应用,但如果是周末,则用绿色或其他颜色填充。

请注意,KOMA 类在这里什么都不做,只是需要更长的加载时间,所以我使用了article。我修改了代码以避免覆盖现有命令(\year已定义)并使用\newcommand和朋友,尽可能符合最佳实践。另外,我已使用设置了有效头部高度geometry。如果使用(或类似)来管理布局尺寸,切勿手动设置布局尺寸geometry。代码仍然可以使用一些整理,例如一些字体命令仍然在节点的内容中,但我至少删除了那些已弃用 20 多年的命令。(两个字母的字体宏应该不是用于 LaTeX 2e。)等等。但它确实可以做一些简化,哪怕只是为了让它更容易阅读。

请注意此代码是好小呀好小呀。不过,我认为那只是 PGF。也就是说,原始代码确实很慢,我不知道这是否明显变慢。TiZ 不是一个快速计算器。

\documentclass[landscape, a4paper, ngerman, 10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz,xparse}
\usepackage{translator}
\usepackage{fancyhdr}
\usepackage[
  headheight = 11ex,% geometry needs to know the actual value you want! Don't change layout dimensions outside geometry, if using geometry
  margin=.5cm,
  top = 3.2cm,
  nofoot,
]{geometry}

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

\newcommand*\myyear{2016}% don't overwrite existing commands wily-nily
\edef\nextyear{\the\numexpr\myyear+1\relax}

\newcommand*\feiertage {%
  {Neujahr}/\nextyear-01-01,%
  {Tag der dt.\ Einheit}/\myyear-10-03,%
  {Reformationstag}/\myyear-10-31,%
  {Allerheiligen}/\myyear-11-01,%
  {1. Weihnachtstag}/\myyear-12-25,%
  {2. Weihnachtstag}/\myyear-12-26,%
  {Sylvester}/\myyear-12-31%
}

\ExplSyntaxOn
\clist_new:N \g_sam_feiertage_clist
\int_new:N \l_sam_feiertag_int
\foreach \i/\j in \feiertage
{%
  \pgfcalendardatetojulian{\j}{\l_sam_feiertag_int}
  \clist_gput_right:Nx \g_sam_feiertage_clist { \int_to_arabic:n { \l_sam_feiertag_int } }
}
\cs_new_protected_nopar:Nn \sam_feiertag_test:n
{
  \int_set:Nn \l_tmpa_int {#1}
  \clist_if_in:NVT \g_sam_feiertage_clist \l_tmpa_int
  {
    \pgfcalendarmatchestrue
  }
}
\cs_generate_variant:Nn \sam_feiertag_test:n {x}
\NewDocumentCommand \testhols { m }
{
  \sam_feiertag_test:x { #1 }
}
\ExplSyntaxOff

\tikzset{
  /pgf/calendar/feiertag/.code={%
    \testhols{\pgfcalendarifdatejulian}%
  },
}

\newcommand*\exams {%
  {Quantitative Analysen}/\nextyear-01-09,%
  {Pysikalische Chemie}/\nextyear-01-20,%
  {Biochemie}/\nextyear-02-10%
}

\newcommand*\winterbegin{\nextyear-02-10}
\newcommand*\winterend{\nextyear-04-18}
\newcommand*\sommerbegin{\myyear-07-28}
\newcommand*\sommerend{\myyear-10-17}
\newcommand*\weihnachtsbegin{\myyear-12-26}
\newcommand*\weihnachtsend{\nextyear-01-06}

\definecolor{nicegreen}{HTML}{00cc00}

\newcommand*\feiertag[2]{%
  \node [ anchor = north west, text width = 3.4cm ] at ($(cal-#1.north west)+(3em, -0.2em)$) {\scriptsize{#2}};
}
\newcommand*\exam[2]{%
  \node [ anchor = north west, text width = 3.4cm, text = red, font = \bfseries ] at ($(cal-#1.north west)+(3em, -0.2em)$) {\scriptsize{#2}};
}

\renewcommand{\headrulewidth}{0pt}
\fancyhf{}
\lhead{%
  \fontsize{60}{70}\selectfont\textbf{WS \myyear/\nextyear}}

\begin{document}
\pagestyle{fancy}
\centering
\begin{tikzpicture}[every day/.style={anchor = north}]
  \calendar[
  dates = \myyear-10-01 to \nextyear-03-31,
  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 = nicegreen, text = white, draw = nicegreen, text centered] {\textbf{\pgfcalendarmonthname{\pgfcalendarcurrentmonth}\strut}};
    }{}
    \ifdate{workday} {
      \tikzset{every day/.style = {fill = white}}
      \ifdate{between = \sommerbegin and \sommerend}{%
        \tikzset{every day/.style = {fill = gray!30}}%
      }{}
      \ifdate{between = \weihnachtsbegin and \weihnachtsend}{%
        \tikzset{every day/.style = {fill = gray!30}}%
      }{}
      \ifdate{between = \winterbegin and \winterend}{%
        \tikzset{every day/.style = {fill = gray!30}}%
      }{}
      \ifdate{feiertag}{%
        \tikzset{every day/.style = {fill = gray!30}}%
      }{}
    }{}
    \ifdate{Saturday} {
      \tikzset{every day/.style = {fill = nicegreen!10}}%
    }{}
    \ifdate{Sunday} {
      \tikzset{every day/.style = {fill = nicegreen!20}}%
    }{}
  },
  execute at begin day scope = {
    \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
  }
  ];
  \foreach \subject/\eventdate in \feiertage
  {
    \feiertag{\eventdate}{\subject}
  }
  \foreach \subject/\eventdate in \exams
  {
    \exam{\eventdate}{\subject}
  }
\end{tikzpicture}
\end{document}

一天之内花了这么多功夫才填平了一点灰色......

答案2

解决了!

我在每个事件后添加了注释符号,现在它可以正常工作了。看起来好像tikz试图将节点绘制到不存在的地方……

\def\feiertage {
    {Neujahr}/\nextyear-01-01,%
    {Tag der dt. Einheit}/\year-10-03,%
    {Reformationstag}/\year-10-31,%
    {Allerheiligen}/\year-11-01,%
    {1. Weihnachtstag}/\year-12-25,%
    {2. Weihnachtstag}/\year-12-26,%
    {Sylvester}/\year-12-31%
}

此外,我忘了写\nextyear新年发生的事件......

1 问题依然存在

\feiertage我怎样才能用灰色填充字段,就像假期一样?

相关内容