Объединить 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}

Связанный контент