我怎样才能使以下代码编译:
\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}