How does renewcommand immediately following a beginitemize prevent missing item error
How does renewcommand immediately following a beginitemize prevent missing item error
The itemize
list below works fine. However, if I attempt to move the
itemize
renewcommand*do[1]item #1.
outside of the itemize, it results in a
Something's wrong--perhaps a missing item
renewcommand*do[1]item #1.
renewcommand
documentclassarticle
usepackageetoolbox
newcommandCSVList
listaddCSVLista
listaddCSVListb
listaddCSVListc
renewcommand*do[1]item #1.%
begindocument
beginitemize
renewcommand*do[1]item #1.%
dolistloopCSVList%
enditemize
%% -------------------- This results in the "missing item" error.
% beginitemize
% dolistloopCSVList%
% enditemize
enddocument
Avoid
dolistloop
and prefer forlistloop
, where you specify a handler.– egreg
Sep 12 '18 at 22:14
dolistloop
forlistloop
2 Answers
2
Because do
is used at the begindocument
by the LaTeX kernel to make the @onlypreamble
commands throw an error when used outside the preamble.
do
begindocument
@onlypreamble
The definition of document
contains:
document
gdefdo##1globallet ##1@notprerr%
@preamblecmds
globallet @nodocument relax
globalletdonoexpand % <-- this causes the problem
so do
becomes noexpand
right after begindocument
, so your newcommand
in the preamble has no effect.
do
noexpand
begindocument
newcommand
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
.
renewcommand
itemize
do
noexpand
missing item
If you move the renewcommand
outside the itemize
, its new definition is kept until the second itemize
and everything works fine.
renewcommand
itemize
itemize
Try this:
documentclassarticle
usepackageetoolbox
newcommandCSVList
listaddCSVLista
listaddCSVListb
listaddCSVListc
renewcommand*do[1]item #1.%
begindocument
beginitemize
renewcommand*do[1]item #1.%
dolistloopCSVList%
enditemize
beginitemize
showdo
dolistloopCSVList%
enditemize
enddocument
The console will show
> do=noexpand.
l.18 showdo
Thus your doa
will do
doa
noexpanditem a
and the output will be, after the “missing item
” error, just
item
abc
Much better is to define a specific handler:
documentclassarticle
usepackageetoolbox
newcommandCSVList
listaddCSVLista
listaddCSVListb
listaddCSVListc
newcommand*doCSV[1]item #1.
begindocument
beginitemize
forlistloopdoCSVCSVList
enditemize
enddocument
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
.
#1
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandaddtolistmm
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
NewDocumentCommanduselistmm
cs_set_protected:Nn __grill_uselist:n #2
clist_map_function:cN l_grill_list_#1_clist __grill_uselist:n
ExplSyntaxOff
addtolistCSVLista
addtolistCSVListb,c
begindocument
beginitemize
uselistCSVListitem #1.
enditemize
enddocument
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
do is used everywhere. You should redefine it only very locally.
– Ulrike Fischer
Sep 12 '18 at 22:12