\forlistloop
我在使用of命令时遇到问题
etoolbox
与典型的 C 程序不同,
int a[5]
for ( i = 0; i <5; i++)
{
a[i]
}
可以访问i
我不确定如何使用命令访问列表中的各个元素。
我看到这\forlistloop<handler><list>
就是给出的基本序列。
我尝试了以下操作并收到未定义序列的错误。
\def\myrowlist{}
\forcsvlist{\listadd\myrowlist}{r,\theta,z}
$ \newcounter{itemcount}
%\begin{itemize}
\forlistloop{\stepcounter{itemcount}\itemRaone}{\myrowlist}
\itemRaone
%\item Total: \number\value{itemcount} items
%\end{itemize}
$
r, \theta and z
我的期望是每次都应该能够单独提取。
答案1
尝试\grabitem{number}
从列表中获取项目。当然,这不是万无一失的。
一般来说,最好使用wrapper
命令而不是\forcsvlist{\stepcounter...}{..}
直接执行类似操作。
\documentclass{article}
\usepackage{etoolbox}
\listadd\myrowlist{}
\newcounter{itemcount}
\newcommand{\additem}[2][\myrowlist]{%
\listadd{#1}{#2}%
\stepcounter{itemcount}%
}%
\newcommand{\addtolist}[2][\myrowlist]{%
\setcounter{itemcount}{0}
\let #1\relax
\listgadd #1{}%
\forcsvlist{\additem[#1]}{#2}%
}
\makeatletter
\newcounter{temp@@count}
\newcommand{\getitem}[2]{%
\stepcounter{temp@@count}%
\ifnumequal{\value{temp@@count}}{#1}{%
\ensuremath{#2}%
\listbreak
}{}
}%
\newcommand{\grabitem}[2][\myrowlist]{%
\setcounter{temp@@count}{0}
\ifnumgreater{#2}{\value{itemcount}}{%
\GenericError{Error}{Number #2 for grabbing item too large}{There are only \number\value{itemcount} items}{Check your code!}
}{% All is ok.
\forlistloop{\getitem{#2}}{#1}%
}
}
\makeatother
\newcommand{\showlist}[1]{%
$#1$
}%
\begin{document}
\addtolist{r,\theta,z,\Gamma,\Delta}
\forlistloop{\showlist}{\myrowlist}
\grabitem{1}
\grabitem{5}
\begin{itemize}
\forcsvlist{\item \grabitem[\myrowlist]}{1,3,5,4,5,2}
\end{itemize}
\end{document}
答案2
如果您愿意切换etoolbox
到更强大的expl3
编程环境,您可以这样做:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newlist}{m}
{
\seq_new:c { g_sumanta_lists_#1_seq }
}
\newlist{myrow} % default
\NewDocumentCommand{\additems}{O{myrow} m}
{
\clist_map_inline:nn { #2 }
{
\seq_gput_right:cn { g_sumanta_lists_#1_seq } { ##1 }
}
}
\NewDocumentCommand{\getitem}{O{myrow} m O{\use:n}}
{
\int_compare:nTF { #2 > \seq_count:c { g_sumanta_lists_#1_seq } }
{
NO ITEM
}
{
#3 { \seq_item:cn { g_sumanta_lists_#1_seq } { #2 } }
}
}
\NewDocumentCommand{\uselist}{O{\use:n}m}
{
\seq_map_inline:cn { g_sumanta_lists_#2_seq } { #1 { ##1 } }
}
\ExplSyntaxOff
\newcommand{\makeitem}[1]{\item $#1$}
\begin{document}
\additems{r,\theta,z,\Gamma}
\additems{\Delta}
\getitem{1}
\getitem{2}[\ensuremath]
\getitem{99}
\begin{itemize}
\uselist[\makeitem]{myrow}
\end{itemize}
\newlist{foo}
\additems[foo]{a,b,c}
\begin{enumerate}
\uselist[\makeitem]{foo}
\end{enumerate}
\end{document}
可选参数\additems
是列表名称(默认myrow
),强制参数是用逗号分隔的项目列表。
通过\getitem
强制参数获取指定数量的项目;第一个可选参数是列表名称,后面的可选参数是包装该项目的一个参数宏(默认仅生成项目)。如果数量超出可用项目,则NOITEM
打印;这可能会变成错误消息。
该\uselist
命令将一个应包装项目的参数宏作为可选参数。默认仅生成项目。
答案3
为了迭代基本项目列表,可以使用类似数组的结构/接口(类似于 C 等编程语言中的内容),由arrayjobx
:
\documentclass{article}
\usepackage{multido,arrayjobx}
\newarray\myrowlist\readarray{myrowlist}{r & \theta & z}
\begin{document}
\newcommand{\itemdelim}{\renewcommand{\itemdelim}{,\,}}% http://tex.stackexchange.com/a/89187/5764
$\multido{\i=1+1}{3}{\itemdelim\myrowlist(\i)}$
\end{document}
数组内的元素使用\readarray{<array>}
以- 分隔的<array>
序列来指定&
。
multido
有一个足够简单的界面来迭代一些\i
整数序列。