我目前正在修改以下日历(示例) 来满足我的需求,我想重建定义假期的选项。
如果你看一下代码罗伯特·克劳斯你看,他在第一个环境中定义了前六个月的假期\begin{tikzfigure}
,在第二个环境中定义了后六个月的假期tikzfigure
。为了拥有更易于维护的日历,我想在序言中定义假期,让日历完成其余的工作。
此外,我想将这个日历用于大学,所以我想添加应该填写的考试日期red!20
。
因此,我想在序言中定义所有这些假期(用 填充gray!30
)和考试日期(用 填充),并使代码动态化。编译时,应该检查是否定义了任何考试日期,如果是,它应该在相应的字段中写入名称并将该字段填充为红色。如果定义了假期,它应该在字段中写入其名称并将其填充为灰色。red!20
tikz
以下是我认为我需要的类似逻辑,写于php
:
<?php
$holidays = array(
"2017-01-01" => "New Year",
"2017-04-16" => "Easter Sunday",
"2017-05-01" => "Labour Day",
"2017-12-25" => "First Christmas Day"
);
foreach( $holidays as $holiday => $name ){
$date = strtotime($holiday);
if($date <= strtotime("2017-06-30")) {
// Place $name in the corrensponding field of the first six month and colour the field with gray!30
echo "January to June: " . $name . "\r\n";
}
else if($date > strtotime("2017-06-30")) {
// Place $name in the corrensponding field of the last six month and colour the field with gray!30
echo "July to December: " . $name . "\r\n";
}
}
?>
对于假期,如果能定义开始和结束日期,tikz 会将所有字段填充为灰色,这样就太棒了。目前,假期也必须在任一环境中定义tikzpicture
。
答案1
这基本上是来自我的另一个答案它涉及某种挂历,但在某些部分进行了调整(主要是删除了学校周数)。
答案主要包括以下几个部分:
该
month columns
样式设置了尺寸(每页 6 个月,两边边距 5 毫米,每月 31 天,加上月份标签的空间,其高度为一天高度的 1.2 倍)、所有标记以及组成日历的实际节点的位置。\foreach
使用了两个应该像列表一样填充的宏:\termine
对于固定日期的形式<test> / <label> / <style>
其中
<test>
只是任何 PGFcalendar 测试,并且<style>
是应该应用于当天的样式。在这个例子中,我使用不同的颜色来表示非基督教节日和基督教节日。
\bereiche
对于以下形式的日期范围<start>--<end> / <label> / <style>
<start>--<end>
将被转发到哪里between=<start> and <end>
并将<start>
用于放置<label>
。
有多种标记样式:
- 星期一的右上角设有“KW标记”标记日历周
mark up
和其中前者mark down
用于范围而后者用于固定日期。
这些样式用于解析元素并设置标记和样式的键
bereiche
。termine
最后,定义一些样式(已在
\termine
和`\bereiche 中使用)。这些只是设置一些颜色。
该my calendar
样式通过使用样式将所有内容整合在一起,month columns
并为标签以及周末设置几种颜色(这些颜色在之后指定,bereiche
以便termine
它们覆盖任何假期的颜色,尽管我们也可以不在周末应用它们的样式)。
我选择将年份放在月份标签内,因为在我看来,大大的 2022 会占用大量空间,而这些空间最好用于日历。
但当然可以在日历顶部添加年份(甚至在里面\calendar
),尽管我们需要测量其高度以便我们高效地填充页面。
然后这两个页面只需由两个 TikZpictures 即可创建:
\tikz\calendar[dates = 2023-01-01 to 2023-06-30, my calendar];
\tikz\calendar[dates = 2023-07-01 to 2023-12-31, my calendar];
一切都已在里面my calendar
,我们无需弄清楚哪一个是第一张图片或第二张图片中的内容。
由于您没有提供日期的例子,我只是使用德国的公共假期和柏林的学校假期。
更改一些样式并添加日期以获得所需的输出应该不是什么大任务。(但无论如何请随时询问。)
代码
\documentclass[ngerman,multi=tikzpicture,varwidth=false]{standalone}
\usepackage{
translator, % translator is used by the calendar library
babel, % provides the actual translations
tikz, % duh
libertine} % nice sf font
\usetikzlibrary{
ext.calendar-plus} % nestable if, expandable shortcuts and week numbering
\tikzset{
%%% the actual calendar style
month columns/.style={% Mondays get yearweek number
month width/.initial=(297mm-10mm)/6, % 5mm borders on left and right side
day height/.initial =(210mm-10mm)/32.2,% 5mm borders on the top and bottom
day text={\%d=~~\%w.},
textual/.style = {
font=\strut,
text depth=+0pt,
outer sep=+0pt,
anchor=south,
text height=1em,
text width=\pgfkeysvalueof{/tikz/month width}
-2*(\pgfkeysvalueof{/pgf/inner xsep})},
every day/.append style = {
textual,
align=left,
minimum height= \pgfkeysvalueof{/tikz/day height}},
every month/.append style = {
textual,
align=center,
minimum height=1.2*(\pgfkeysvalueof{/tikz/day height}),
font=\Large\bfseries,
label={[every year, anchor=base east]base east:\%y0},
label={[every year, anchor=base west]base west:\%y0}},
execute before day scope = {%
\ifdate{day of month=1, equals=\pgfcalendarbeginiso}{\tikzmonthcode}{}%
\ifdate{equals=\pgfcalendarbeginiso}{% in case cal doesn't start at 1st
\pgftransformyshift{-(\%d--1)*(\pgfkeysvalueof{/tikz/day height})}}{}%
\pgftransformyshift{-(\pgfkeysvalueof{/tikz/day height})}},
execute after day scope = {%
\ifdate{end of month=1}{% back up we go
\pgftransformyshift{\%d-*(\pgfkeysvalueof{/tikz/day height})}%
\pgftransformxshift{\pgfkeysvalueof{/tikz/month width}}}{}}}}
\newcommand*\termine{% repeating fixed day
equals=01-01 / Neujahr / Feiertag,
equals=01-06 / Heilige Drei Könige / chrFeiertag,
equals=03-08 / Int. Frauentag / Feiertag,
equals=05-01 / Tag der Arbeit / Feiertag,
equals=10-03 / Tag der dt. Einheit / Feiertag,
equals=12-25 / 1. Weihnachtstag / chrFeiertag,
equals=12-26 / 2. Weihnachtstag / chrFeiertag,
Easter=-2 / Karfreitag / chrFeiertag,
Easter= 0 / Ostersonntag / chrFeiertag,
Easter= 1 / Ostermontag / chrFeiertag,
Easter=39 / Christi Himmelfahrt / chrFeiertag,
Easter=49 / Pfingstsonntag / chrFeiertag,
Easter=50 / Pfingstmontag / chrFeiertag}
\newcommand*\bereiche{% holidays
2022-12-22--2023-01-02 / Weihnachtsferien / Ferien,
2023-01-30--2023-02-04 / Winterferien / Ferien,
2023-04-03--2023-04-14 / Osterferien / Ferien,
2023-05-19--2023-05-19 / Brückentag / chrBruecke,
2023-05-30--2023-05-30 / Pfingstferien / Ferien,
2023-07-13--2023-08-25 / Sommerferien / Ferien,
2023-10-02--2023-10-02 / Brückentag / Bruecke,
2023-10-23--2023-11-04 / Herbstferien / Ferien,
2023-12-23--2024-01-05 / Weihnachtsferien / Ferien}
\tikzset{
%%% marking styles
mark up/.style = {label = {[every mark up] north west: #1}},
mark down/.style = {label = {[every mark down] south west: #1}},
mark KW/.style = {label = {[anchor=north east, every KW mark]
north east: KW~\%n-}},
every KW mark/.style = {every mark, text = gray!50!black},
every mark/.style = {font = \scriptsize, text = black,
text depth = +0pt, inner ysep = .3em},
every mark up/.style = {every mark, xshift = +3.3em, anchor=north west},
every mark down/.style = {every mark, xshift = +3.3em, anchor=south west},
%
%%% Parsing
bereiche/.style args={#1--#2/#3/#4}{
if = {(between = #1 and #2) [
if = {(workday) [days = {style=#4}]},
if = {(equals=#1) [days = {mark up = {#3}}]}
]},
},
termine/.style args = {#1/#2/#3}{
if = {(#1) [days = {mark down = {#2},style=#3} ]}},
%
%%% visualization
Feiertag/.style = {fill = red!75, },
chrFeiertag/.style = {fill = red!75!blue!50},
Ferien/.style = {fill = gray!25, },
Bruecke/.style = {fill = red!67 },
chrBruecke/.style = {fill = red!75!blue!33}}
\tikzset{
my calendar/.style = {
month columns,
every month/.append style={fill=red, text=white},
every year/.append style={text=white},
if = {(Monday) [days=mark KW]}, % Mondays get the week number
bereiche/.list/.expand once=\bereiche,
termine/.list/.expand once=\termine,
if = {(Sunday) [days={fill=red!50}]},
if = {(Saturday) [days={fill=red!25}]}}}
\begin{document}
\sffamily\small
\tikz\calendar[dates = 2023-01-01 to 2023-06-30, my calendar];
\tikz\calendar[dates = 2023-07-01 to 2023-12-31, my calendar];
\end{document}