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






do is used everywhere. You should redefine it only very locally.

– Ulrike Fischer
Sep 12 '18 at 22:12






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.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)