我正在寻找一种方法来自动完成设置单日计划背后的一些工作。我最终想要的结果大致如下:
| Time | Presenter |
-------------------------------
| 12:00 - 12:20 | presenter 1 |
| 12:20 - 12:50 | presenter 2 |
| 12:50 - 13:10 | presenter 3 |
| 13:10 - 13:20 | break |
| 13:20 - 14:00 | presenter 4 |
这个想法是,左列中的时间应该或多或少地自动生成。请注意,有些条目比其他条目花费的时间更多。如果我们可以自动生成左列,则可以轻松进行任何后续的时间表更改,而无需手动重新制定整个时间表。
我能想到的最方便的方法是定义一个设置开始时间的命令,以及另一个跟踪当前时间并在每次调用时增加给定量的命令。
生成上述表格的代码将如下所示:
\SetStartTime{12:00}
\begin{tabular}[H!]{|l|l|}
\hline
Time & Presenter \\
\hline
\NewEntry{00:20} & presenter 1 \\
\NewEntry{00:30} & presenter 2 (with more time) \\
\NewEntry{00:20} & presenter 3 \\
\NewEntry{00:10} & break \\
\NewEntry{00:40} & presenter 4 \\
\end{tabular}
我还没有找到任何可以处理类似问题的软件包,所以我想我必须借助自定义命令才能使其工作。
答案1
下面是一个使用 的实现expl3
。我们定义一个以开始时间为参数的环境;这将转换为十进制形式以便进行后续计算,并将结果存储在整数变量中。
环境将充满以\Entry
分配时间(分钟)和标题为参数的命令。此命令打印当前时间值(将其转换回hh:mm
格式),添加分配时间,保存该值并将其打印为结束时间。然后添加&
标题和。\\
由于分隔符是冒号,我们必须使用间接方法将其用作转换辅助宏中的分隔符,并使用函数\char_generate:nn
(这是下面代码中唯一的非标准技巧)。
\documentclass{article}
\usepackage{xparse}
\usepackage{booktabs}
\ExplSyntaxOn
\NewDocumentEnvironment{schedule}{m}
{% #1 is the starting time
% save the starting time in an integer variable
\int_gset:Nn \g_metnix_schedule_start_int { \metnix_schedule_time_decimal:n { #1 } }
% start a tabular
\begin{tabular}{ll}
\toprule
\multicolumn{1}{c}{Time} & Presenter \\
\midrule
}
{
% end the tabular
\bottomrule
\end{tabular}
}
\NewDocumentCommand{\Entry}{mm}
{% #1 is the allotted time, #2 is the title
% print the starting time
\metnix_schedule_time_print:
% separate the two times with <space><endash><space>
{ ~--~ }
% add the allotted time
\metnix_schedule_time_add:n { #1 }
% print the end time
\metnix_schedule_time_print:
&
#2 \\
}
% allocate an integer variable
% (global, because the computations take place in tabular cell)
\int_new:N \g_metnix_schedule_start_int
% convert to decimal form, passing hh:mm to an auxiliary function
\cs_new:Nn \metnix_schedule_time_decimal:n
{
\__metnix_schedule_time_decimal:w #1 \q_stop
}
% \__metnix_schedule_time_decimal:w has two arguments,
% the first is delimited by :, the second by \q_stop
\use:x
{% we need the trick because : is special
\cs_new:Npn
\exp_not:N \__metnix_schedule_time_decimal:w
##1 \char_generate:nn { `: } { 12 } ##2 \exp_not:N \q_stop
}
{
% hours times 60 + minutes
#1*60+#2
}
\cs_new:Nn \metnix_schedule_time_print:
{
% add a leading zero if the hour is less than 10
\int_compare:nT { \int_div_truncate:nn { \g_metnix_schedule_start_int } { 60 } < 10 } { 0 }
\int_eval:n { \int_div_truncate:nn { \g_metnix_schedule_start_int } { 60 } }
% print a colon
:
% add a leading zero if the minutes are less than 10
\int_compare:nT { \int_mod:nn { \g_metnix_schedule_start_int } { 60 } < 10 } { 0 }
\int_eval:n { \int_mod:nn { \g_metnix_schedule_start_int } { 60 } }
}
% syntactic sugar for adding time
\cs_new:Nn \metnix_schedule_time_add:n
{
\int_gadd:Nn \g_metnix_schedule_start_int { #1 }
}
\ExplSyntaxOff
\begin{document}
\begin{schedule}{12:00}
\Entry{20}{Presenter 1}
\Entry{30}{Presenter 2}
\Entry{20}{Presenter 3}
\Entry{10}{Break}
\Entry{80}{Presenter 4}
\end{schedule}
\end{document}