我正在尝试通过 CSV 文件获取命令的值来创建新命令,并将datatool
其加载到数据库中。问题是,使用此过程创建的每个命令都以分配给最后的数据库中的条目。
平均能量损失
这里我把使用的 CSV 和 MWE 都放了下来(感谢 Werner 提供的“命令包装器”,下落不明这里):
CSV 文件:
Campo,Valor,Aux
hallo,"Cmon",
another,"Piece",
whuzzat,"abc",
LaTeX
用于加载CSV文件的文档:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{datatool}
\newcommand{\assignto}[2]{%
\ifcsdef{#2}{%
\csdef{#1}{\csuse{#2}}%
}{%
\csdef{#1}{#2}%
}%
}
\begin{document}
\section*{Hard-coded variables}
\newcommand{\abc}{ABC}
\assignto{AAA}{aaa}\AAA\ %end to denote space
\assignto{BBB}{abc}\BBB
\section*{DB variables}
\DTLloaddb{Datos}{datos.csv}
\DTLforeach{Datos}{\campo=Campo,\valor=Valor,\valorb=Aux}{%
\assignto{\campo}{\valor}
}
\hallo\ % It should be "Cmon"
\another\ % It should be "Piece"
\whuzzat\ % It should be "\abc", i.e. "ABC"
\end{document}
输出:
答案1
你基本上是在做
\def\hallo{\valor}
\valor
并且在进行定义之前你应该进行扩展:
\DTLforeach{Datos}{\campo=Campo,\valor=Valor,\valorb=Aux}{%
\expandafter\assignto\expandafter{\expandafter\campo\expandafter}\expandafter{\valor}
}
当然还有更好更短的方法;例如
\newcommand\assignto[2]{\expandafter\assigntoaux\expandafter{#2}{#1}}
\newcommand{\assigntoaux}[2]{%
\ifcsdef{#1}{%
\csdef{#2}{\csuse{#1}}%
}{%
\csdef{#2}{#1}%
}%
}
只是切换参数。
更好的方法是使用xparse
和expl3
:
\begin{filecontents*}{\jobname.csv}
Campo,Valor,Aux
hallo,"Cmon",
another,"Piece",
whuzzat,"abc",
\end{filecontents*}
\documentclass{article}
\usepackage{datatool}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\assignto}{smm}
{
\IfBooleanTF{#1}
{
\logowriter_assignto:no { #2 } { #3 }
}
{
\logowriter_assignto:nn { #2 } { #3 }
}
}
\cs_new_protected:Nn \logowriter_assignto:nn
{
\cs_new:cpn { #1 } { #2 }
}
\cs_generate_variant:Nn \logowriter_assignto:nn { no }
\ExplSyntaxOff
\begin{document}
\section*{Hard-coded variables}
\newcommand{\abc}{ABC}
\assignto{AAA}{aaa}\AAA\ %end to denote space
\assignto{BBB}{abc}\BBB
\section*{DB variables}
\DTLloaddb{Datos}{\jobname.csv}
\DTLforeach{Datos}{\campo=Campo,\valor=Valor,\valorb=Aux}{%
\assignto*{\campo}{\valor}
}
\hallo\ % It should be "Cmon"
\another\ % It should be "Piece"
\whuzzat\ % It should be "\abc", i.e. "ABC"
\end{document}
请注意,\assignto*
在进行定义之前,第二个参数会扩展一次,这与\expandafter
上面的长链标记相同,但要简单得多。