Combinar datetime2 y csvsimple

Combinar datetime2 y csvsimple

¿Cómo puedo compilar el siguiente código?

\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}

Tenga en cuenta que se compila si lo reemplazo \bpor00:00:01

Respuesta1

El problema es que \DTMtimeespera que su argumento ya esté ampliado. Puedes ver el problema si dices:

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

esto ya arroja un error. Primero debe expandirse \testy luego ejecutarlo \DTMtime. Una forma de hacerlo es diciendo

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

El comando \edefdefine una nueva macro expandiendo recursivamente el cuerpo de la macro. El comando \noexpanddeja \DTMtimede expandirse, por lo que \tempse define y \DTMtime{00:00:00}luego funciona como se esperaba.

Me gusta definir esto dentro de una macro, digamos llamada \eval:

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

Otra opción es hacer esto usando Latex3. Latex3 define la macro \exp_args:Nx, que \edefes el argumento de una macro antes de llamarla, por lo que \exp_args:Nx\DTMtime{\test}se expandirá \testprimero y luego se ejecutará \DTMtimeen ella. Puede definir una macro contenedora para \DTMtimeque siempre expanda su argumento primero. Aquí hay un código de muestra para eso:

\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}

Aquí está el código completo:

\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}

información relacionada