Kombinieren Sie datetime2 und csvsimple

Kombinieren Sie datetime2 und csvsimple

Wie kann ich den folgenden Code kompilieren:

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

Beachten Sie, dass es kompiliert wird, wenn ich \bdurch ersetze00:00:01

Antwort1

Das Problem besteht darin, dass \DTMtimeerwartet wird, dass das Argument bereits erweitert ist. Sie können das Problem erkennen, wenn Sie sagen:

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

dies wirft bereits einen Fehler. Sie müssen zuerst expandieren \testund dann \DTMtimedarauf ausführen. Eine Möglichkeit, dies zu tun, besteht darin, zu sagen

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

Der Befehl \edefdefiniert ein neues Makro, indem er den Hauptteil des Makros rekursiv erweitert. Der Befehl wird \noexpandnicht mehr \DTMtimeerweitert, daher \tempwird dies als definiert, \DTMtime{00:00:00}was dann wie erwartet funktioniert.

Ich definiere dies gerne in einem Makro, beispielsweise mit dem Namen \eval:

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

Eine andere Möglichkeit besteht darin, dies mit Latex3 zu tun. Latex3 definiert das Makro \exp_args:Nx, das \edefdas Argument eines Makros ist, bevor es aufgerufen wird, sodass es zuerst \exp_args:Nx\DTMtime{\test}erweitert \testund dann ausgeführt wird \DTMtime. Sie können ein Wrapper-Makro definieren, \DTMtimedas immer zuerst sein Argument erweitert. Hier ist ein Beispielcode dafür:

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

Hier ist der vollständige Code:

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

verwandte Informationen