结合 datetime2 和 csvsimple

结合 datetime2 和 csvsimple

我怎样才能使以下代码编译:

\documentclass{standalone} 
\usepackage{csvsimple}
\usepackage{datetime2}
\usepackage{filecontents}
\begin{filecontents*}{test.csv}
a,b
2019,00:00:00
2019,00:00:01
2020,00:00:02
2018,00:00:03
2018,00:00:04
\end{filecontents*}
\begin{document}
\csvreader[head to column names,tabular=llllll]{test.csv}{}
{\a&\DTMtime{\b}}
\end{document}

\b请注意,如果我用以下代码替换,它确实可以编译:00:00:01

答案1

问题在于它\DTMtime期望它的参数已经展开。如果你这样写,你就会发现问题所在:

\def\test{00:00:00}
\DTMtime{\test}

这已经引发错误。您需要先展开\test,然后运行\DTMtime。一种方法是说

\edef\temp{\noexpand\DTMtime{\test}}\temp

该命令\edef通过递归扩展宏主体来定义新宏。该命令\noexpand停止\DTMtime扩展,因此\temp被定义为,\DTMtime{00:00:00}然后按预期工作。

我喜欢在宏内部定义它,比如说\eval

\def\eval#1{\edef\temp{#1}\temp}
\eval{\noexpand\DTMtime{\test}}

另一个选项是使用 Latex3 执行此操作。Latex3 在调用宏之前定义宏,\exp_args:Nx\edef是宏的参数,因此\exp_args:Nx\DTMtime{\test}将首先展开\test,然后运行\DTMtime它。您可以定义一个包装器宏,\DTMtime它总是先展开其参数。以下是示例代码:

\documentclass{standalone} 
\usepackage{expl3}
\usepackage{datetime2}
\ExplSyntaxOn
\cs_new:Npn\DTMtimex { \exp_args:Nx\DTMtime }
\ExplSyntaxOff

\begin{document}
\def\test{00:00:00}
\DTMtimex{\test}
\end{document}

完整代码如下:

\documentclass{standalone} 
\usepackage{csvsimple}
\usepackage{datetime2}
\usepackage{filecontents}
\begin{filecontents*}{test.csv}
a,b
2019,00:00:00
2019,00:00:01
2020,00:00:02
2018,00:00:03
2018,00:00:04
\end{filecontents*}

\def\eval#1{\edef\temp{#1}\temp}
\def\DTMtimex#1{\eval{\noexpand\DTMtime{#1}}}

\begin{document}
\csvreader[head to column names,tabular=llllll]{test.csv}{}
{\a&\DTMtimex{\b}}
\end{document}

相关内容