我想以某种自动方式创建一个简单的基于周的时间表。例如室友之间的清洁时间表、邻居之间的冬季服务时间表等。
基本上我想转移一个简单的案例区分规则,例如
x % n == 0 -> party_1 负责 x % n == 1 -> party_2 负责 ... x % n == n-1 -> party_n 负责
(其中 x 是当前周数)
变成类似 DIN-A4 日历的时间表。例如,每个月是一个区块,每个星期是该区块中的一行,上面标注了指定的派对和周数(可能还带有颜色)。
tikz 的日历库看起来很有前途,但我找不到访问周数的命令(用于 if/ifdate 子句)。
当然,我总是可以为 tikz-calendar 命令自动生成 52 个 if 子句,但也许有更优雅的方法?
答案1
我做了一点 rtfm 并且为这项任务想出了一些宏。
首先,我们需要计算给定日期的“一年中的第几天”,即相对于给定日期,从一年开始已经过去的天数:
\newcount\begincnt
\def\initbegin{%
\pgfcalendardatetojulian{2014-01-01}{\begincnt}
}
\def\doy#1#2{%
\initbegin#1=#2\advance#1by-\begincnt\relax%
}
该initbegin
宏将计数器初始化begincnt
为儒略日数 (JDN)我们想要在日历中使用 1 月 1 日。
doy
获取 2014 年日期的 JDN 作为输入,并将作为第一个参数给出的计数器设置为年份结果。
通过它我们可以定义年度弱(woy)宏:
\def\woy#1#2{%
\doy{#1}{#2}\yearoff{\cnte}{#2}\advance#1by\cnte\divide#1by7\advance#1by1\relax%
}
再次,结果计数器是第一个参数,第二个参数是包含日期 JDN 的计数器。
对于 2014 年的日期,该yearoff
宏返回 2 - 对于 1 月 1 日不是星期一的年份,需要将其作为“更正”。其代码:
\newcount\cntd
\newcount\cnte
\def\myyear{}
\def\mydummy{}
\def\yearoff#1#2{%
\pgfcalendarjuliantodate{#2}{\myyear}{\mydummy}{\mydummy}%
\pgfcalendardatetojulian{\myyear-01-01}{\cntd}%
\pgfcalendarjuliantoweekday{\cntd}{#1}\relax%
}
这样,我们(几乎)就可以为 PGF 和 TikZ-Calendar 构造中的 ifdate 子句定义自定义 pgf-key 了:
\newcount\cnta
\newcount\cntb
\newcount\cntp
\pgfkeys{/pgf/calendar/modb/.cd,.value required,.code={
\woy{\cnta}{\pgfcalendarifdatejulian}\mod{\cntb}{\cnta}{\cntp}
\ifnum\cntb=#1\relax%
\pgfcalendarmatchestrue%
\fi%
}}
此过滤器使用另一个自定义宏mod
来计算模数(\cntp
包含各方的数量):
\def\mod#1#2#3{%
#1=#2\relax%
\divide#1by#3\relax%
\multiply#1by-#3\relax%
\advance#1by#2\relax%
}
例子
我们可以像这样使用过滤器:
On 2014-01-06 the 2nd party is \pgfcalendarifdate{2014-01-06}{modb=1}{not} in charge.
或者在 TikZ-calendar 命令中:
\tikz
\calendar[dates=2014-01-01 to 2014-03-last, week list,month label above centered]
if (modb=2) [nodes={fill=blue!60}]
;
(将第三方负责的所有日子都涂成彩色)
或者作为日历样式的一部分:
\begin{tikzpicture}[every calendar/.style={
if={(modb=0) [nodes={fill=yellow!60}]}
}