How does \renewcommand immediately following a \begin{itemize} prevent missing \item error
Because \do
is used at the \begin{document}
by the LaTeX kernel to make the \@onlypreamble
commands throw an error when used outside the preamble.
The definition of \document
contains:
\gdef\do##1{\global\let ##1\@notprerr}%
\@preamblecmds
\global\let \@nodocument \relax
\global\let\do\noexpand % <-- this causes the problem
so \do
becomes \noexpand
right after \begin{document}
, so your \newcommand
in the preamble has no effect.
If you put the \renewcommand
inside the itemize
, when the environment group ends, the previous definition of \do
(\noexpand
) is restored and this raises the missing \item
.
If you move the \renewcommand
outside the itemize
, its new definition is kept until the second itemize
and everything works fine.
Try this:
\documentclass{article}
\usepackage{etoolbox}
\newcommand{\CSVList}{}
\listadd{\CSVList}{a}
\listadd{\CSVList}{b}
\listadd{\CSVList}{c}
\renewcommand*{\do}[1]{\item #1.}%
\begin{document}
\begin{itemize}
\renewcommand*{\do}[1]{\item #1.}%
\dolistloop{\CSVList}%
\end{itemize}
\begin{itemize}
\show\do
\dolistloop{\CSVList}%
\end{itemize}
\end{document}
The console will show
> \do=\noexpand.
l.18 \show\do
Thus your \do{a}
will do
\noexpand\item a
and the output will be, after the “missing \item
” error, just
abc
Much better is to define a specific handler:
\documentclass{article}
\usepackage{etoolbox}
\newcommand{\CSVList}{}
\listadd{\CSVList}{a}
\listadd{\CSVList}{b}
\listadd{\CSVList}{c}
\newcommand*{\doCSV}[1]{\item #1.}
\begin{document}
\begin{itemize}
\forlistloop{\doCSV}{\CSVList}
\end{itemize}
\end{document}
I have removed all superfluous %
characters.
A different implementation, where the handler is built on the fly; the current item in the list is denoted by #1
.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\addtolist}{mm}
{
\clist_if_exist:cF { l_grill_list_#1_clist }
{
\clist_new:c { l_grill_list_#1_clist }
}
\clist_map_inline:nn { #2 }
{
\clist_put_right:cn { l_grill_list_#1_clist } { ##1 }
}
}
\NewDocumentCommand{\uselist}{mm}
{
\cs_set_protected:Nn \__grill_uselist:n { #2 }
\clist_map_function:cN { l_grill_list_#1_clist } \__grill_uselist:n
}
\ExplSyntaxOff
\addtolist{CSVList}{a}
\addtolist{CSVList}{b,c}
\begin{document}
\begin{itemize}
\uselist{CSVList}{\item #1.}
\end{itemize}
\end{document}