我对乳胶编程还很陌生(我经常用它来写文本)。我试图在数据工具数据库中插入数据,然后根据其中一个字段对数据进行排序。但是,如果这个字段是通过宏参数填充的,那么只有当参数本身不是另一个宏的结果。代码如下:
\documentclass{article}
\usepackage{datatool}
\newcommand{\sortitem}[3]{%
\DTLnewrow{list}%
\DTLnewdbentry{list}{value}{#1}%
\DTLnewdbentry{list}{label}{#2}%
\DTLnewdbentry{list}{description}{#3}%
}
\newcommand{\aaa}{a}
\newcommand{\fff}{f}
\newcommand{\bbb}{b}
\newcommand{\zzz}{z}
\newcommand{\ccc}{c}
\newenvironment{sortedlist}%
{%
\DTLifdbexists{list}{\DTLcleardb{list}}{\DTLnewdb{list}}%
}%
{%
\DTLsort*{value}{list}%
\begin{enumerate}
\DTLforeach*{list}{\theLabel=label,\theDesc=description, \theValue=value}{%
\item \theValue~\theLabel
}%
\end{enumerate}%
}
\begin{document}
Sorted:
\begin{sortedlist}
\sortitem{a}{item}{opt}
\sortitem{f}{item}{opt}
\sortitem{b}{item}{opt}
\sortitem{z}{item}{opt}
\sortitem{c}{item}{opt}
\end{sortedlist}
Not sorted:
\begin{sortedlist}
\sortitem{\aaa}{item}{opt}
\sortitem{\fff}{item}{opt}
\sortitem{\bbb}{item}{opt}
\sortitem{\zzz}{item}{opt}
\sortitem{\ccc}{item}{opt}
\end{sortedlist}
\end{document}
输出是:
Sorted:
1. a item
2. b item
3. c item
4. f item
5. z item
Not sorted (wrong):
1. a item
2. f item
3. b item
4. z item
5. c item
也就是说,在第一种情况下如预期的那样,但在第二种情况下却不是。我怀疑这是由于宏扩展的顺序造成的,因此我尝试插入\expandafter
但没有成功。有人能解释一下这个问题,给我一些线索,告诉我该调查什么吗?
编辑: koleygr 解决方案确实有效。但是,如果我引入更复杂的宏,例如:
\usepackage[first=1, last=9]{lcg}
\newcommand{\random}{\rand\arabic{rand}}
...
\begin{sortedlist}
\sortitem{\random}{item}{opt}
\sortitem{\random}{item}{opt}
\sortitem{\random}{item}{opt}
\sortitem{\random}{item}{opt}
\sortitem{\random}{item}{opt}
\end{sortedlist}
Latex 不再编译(TeX 容量超出,抱歉 [输入堆栈大小=5000])。我尝试更改输入堆栈大小,但没有帮助。另一方面,如果我定义\random
为健壮命令,情况会回到之前的情况(数据库没有按预期排序)。还有其他线索吗?
答案1
根据编辑的要求进行了更改
\documentclass{article}
\usepackage{datatool}
\usepackage{tikz}
%\def\random#1{\pgfmathparse{random(#1)}\pgfmathresult} %<-This or any
% simmilar I tied doesn't work
\newcommand{\sortitem}[3]{%
\DTLnewrow{list}%
\dtlexpandnewvalue
\DTLnewdbentry{list}{value}{#1}%
\DTLnewdbentry{list}{label}{#2}%
\DTLnewdbentry{list}{description}{#3}%
}
\newcommand{\aaa}{a}
\newcommand{\fff}{f}
\newcommand{\bbb}{b}
\newcommand{\zzz}{z}
\newcommand{\ccc}{c}
\newenvironment{sortedlist}%
{%
\DTLifdbexists{list}{\DTLcleardb{list}}{\DTLnewdb{list}}%
}%
{%
\DTLsort*{value}{list}%
\begin{enumerate}
\DTLforeach*{list}{\theLabel=label,\theDesc=description, \theValue=value}{%
\item \theValue~\theLabel
}%
\end{enumerate}%
}
\begin{document}
Sorted:
\begin{sortedlist}
\sortitem{a}{item}{opt}
\sortitem{f}{item}{opt}
\sortitem{b}{item}{opt}
\sortitem{z}{item}{opt}
\sortitem{c}{item}{opt}
\end{sortedlist}
Not sorted:
\foreach \i in {1,...,5}{
\pgfmathparse{random(9)}
\expandafter\xdef\csname MyItem\i\endcsname{\pgfmathresult}
Item\i=\pgfmathresult\par
}
Sorted:
\begin{sortedlist}
\foreach \i in {1,...,5}{
\sortitem{\csname MyItem\i\endcsname}{item}{opt}
}
\end{sortedlist}\vspace*{10pt}
\begin{sortedlist}
\foreach \i in {\aaa,\bbb,\ccc,\zzz,\fff}{
\sortitem{\i}{item}{opt}
}
\end{sortedlist}
\end{document}
上述代码给出以下结果:
您可以找到在 tikz 包的帮助下使用随机数的方法。使用注释\random
命令或任何类似命令都没有给我想要的结果。数字每次都在变化,在排序过程中也是如此。但我认为您可以像上面一样完成您的工作。
旧答案
您必须使用以下方式扩展值\dtlexpandvalue
:
\documentclass{article}
\usepackage{datatool}
\newcommand{\sortitem}[3]{%
\DTLnewrow{list}%
\dtlexpandnewvalue
\DTLnewdbentry{list}{value}{#1}%
\DTLnewdbentry{list}{label}{#2}%
\DTLnewdbentry{list}{description}{#3}%
}
\newcommand{\aaa}{a}
\newcommand{\fff}{f}
\newcommand{\bbb}{b}
\newcommand{\zzz}{z}
\newcommand{\ccc}{c}
\newenvironment{sortedlist}%
{%
\DTLifdbexists{list}{\DTLcleardb{list}}{\DTLnewdb{list}}%
}%
{%
\DTLsort*{value}{list}%
\begin{enumerate}
\DTLforeach*{list}{\theLabel=label,\theDesc=description, \theValue=value}{%
\item \theValue~\theLabel
}%
\end{enumerate}%
}
\begin{document}
Sorted:
\begin{sortedlist}
\sortitem{a}{item}{opt}
\sortitem{f}{item}{opt}
\sortitem{b}{item}{opt}
\sortitem{z}{item}{opt}
\sortitem{c}{item}{opt}
\end{sortedlist}
Not sorted:
\begin{sortedlist}
\sortitem{\aaa}{item}{opt}
\sortitem{\fff}{item}{opt}
\sortitem{\bbb}{item}{opt}
\sortitem{\zzz}{item}{opt}
\sortitem{\ccc}{item}{opt}
\end{sortedlist}
\end{document}
在这里找到:Datatool \DTLnewdbentry 不接受关键列的值但这个答案适用于多个扩展(你或其他有类似问题的人可能需要)