我正在修改日历罗伯特·克劳斯(示例) 并尝试使代码更加动态。我将其拆分为两个文件。其中一个包含主代码(逻辑),另一个包含所有事件、假期等。
我的计划是在这个单独的干净文件中定义所有事件,然后让它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。也就是说,原始代码确实很慢,我不知道这是否明显变慢。Ti钾Z 不是一个快速计算器。
\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
我怎样才能用灰色填充字段,就像假期一样?