\def\filename{dowith} \def\fileinfo{simple list loop (UL)} \def\filedate{2012/11/05} \def\fileversion{v0.3} %% %% Copyright (C) 2011 2012 Uwe Lueck, %% http://www.contact-ednotes.sty.de.vu %% -- author-maintained in the sense of LPPL below -- %% %% This file can be redistributed and/or modified under %% the terms of the LaTeX Project Public License; either %% version 1.3c of the License, or any later version. %% The latest version of this license is in %% http://www.latex-project.org/lppl.txt %% We did our best to help you, but there is NO WARRANTY. %% %% Please report bugs, problems, and suggestions via %% %% http://www.contact-ednotes.sty.de.vu %% %% == Proceeding without \LaTeX == %% v0.3 mainly replaces imitating the %% \CtanPkgRef{german}{german.sty} approach to genericity %% by \ctanpkgref{plainpkg}: \input plainpkg \ProvidesPackage{\filename}[\filedate\space \fileversion\space \fileinfo] \PushCatMakeLetterAt %% If \LaTeX\ is not present ... \ifltx \else %% ... an old version of its `\in@' is introduced. %% It is bad as a subword test %% (false positive cases, cf. \CtanPkgRef{nicetext}{fifinddo} %% documentation), but 'dowith' will check for single tokens only. %% If \LaTeX\ \emph{is} present, %% on the other hand, `\ifin@' is recognized while skipping %% `false' parts of conditionals, without being matched %% by some `\fi' before the next `\else', so I hide it by `\csname': \expandafter\newif\csname ifin@\endcsname \def\in@#1#2{% \def\in@@##1#1##2##3\in@@{% \ifx\in@##2\in@false\else\in@true\fi}% \in@@#2#1\in@\in@@} \fi %% %% == Applying a Command == %% 2011/11/07 %% \label{sec:apply} %% === Core === %% \label{sec:core} %% |\DoWith{<cmd>}<list>\StopDoing| applies <cmd> to all elements %% of <list>. An element of <list> (after tokenizing) %% may be either a single token or a group `{<balanced>}'. \def\DoWith#1#2{% \ifx\StopDoing#2\empty %% The previous `\empty' (replacing `%') is a bug fix as of v0.22 %% (June 2012), %% 2012/11/05 %% while in my extension draft I already had it in January 2012. %% It allows ``empty" arglist items \qtd{\lbtok\rbtok}. %% Before v0.22, such an empty brace group would have resulted %% in comparing `\StopDoing' with `\else', so \qtd{\lbtok\rbtok} %% would have had the same effect as `\StopDoing', the token text %% after `\else' until `\fi' would have been skipped. %% Instead, the user may have a reason to allow empty arguments\slash %% brace groups. \else#1{#2}\expandafter\DoWith\expandafter#1\fi} %% |\StopDoing| delimits the list: \let\StopDoing\DoWith %% ... something arbitrary that is not expected to occur in a list. %% With \[`\let\StopDoing*'\] instead, the star would end lists. %% %% |\DoWithAllOf{<cmd>}{<list>}| works like %% \[`\DoWith{<cmd>}<list>\StopDoing':\] \def\DoWithAllOf#1#2{\DoWith#1#2\StopDoing} %% %% === `&\do' being the Command === %% \label{sec:do} %% When the <list> is worked at a single time in the \TeX\ run %% where assignments are possible, instead of introducing a new %% macro name for <cmd> you can use `\do' for <cmd> as a %% ``temporary" macro and define it right before %% \[`\DoWith{\do}<list>\StopDoing'\] %% However, we provide \[|\DoDoWith{<cmd>}<list>\StopDoing|\] %% as a substitute for the former line that at least saves one token. %% For the definition of `\do', we provide %% |\setdo{<def-text>}|. %% It works similarly to \[`\renewcommand{\do}[1]{<def-text>}',\] %% so <def-text> should contain a `#1': \def\setdo{\long\def\do##1} %% With |\letdo<cmd>| that is provided next where <cmd> is defined %% elsewhere, you could type %% \[`\letdo<cmd>\DoDoWith<list>\StopDoing'\] %% It seems to me, however, that you better type %% \[`\dowith<cmd><list>\StopDoing'\] instead. %% So I provide `\letdo' although I consider it useless here. %% It is provided somewhat for the sake of ``completeness," %% thinking that it might be useful at other occasions such as %% preceding `\dospecials'. \def\letdo{\let\do} %% |\DoDoWith| has been described above: \def\DoDoWith{\DoWith\do} %% By analogy to `\DoWithAllOf', we provide %% |\DoDoWithAllOf{<list>}|: \def\DoDoWithAllOf{\DoWithAllOf\do} %% %% === Expand List Macro === %% The former facilities may be quite useless %% as such a <list> will not be typed at a single place in the %% source code, rather the items to run <cmd> on may be collected %% occasionally when some routines run. The elements may be collected %% in a macro <list-macro> expanding to <list>. %% So we provide \[|\DoWithAllIn{<cmd>}{<list-macro>}|\] %% (or `\DoWithAllIn<cmd><list-macro>'). %% There is no need to type `\StopDoing' here: \def\DoWithAllIn#1#2{% \expandafter\DoWith\expandafter#1#2\StopDoing} %% |\DoDoWithAllIn{<list-macro>}| saves a backslash or token %% for `\do' as above in Sec.~\ref{sec:do}: \def\DoDoWithAllIn{\DoWithAllIn\do} %% %% %% == Handling List Macros == %% === Initializing === %% Here is some advanced `\let<cmd>\empty', perhaps a little %% irrelevant for practical purposes. Both %% \[|\InitializeListMacro{<list-macro>}|\] and %% \[|\ReInitializeListMacro{<list-macro>}|\] attempt to ``empty" %% <list-macro>, and when we don't believe that \LaTeX\ has been %% loaded, both do the same indeed. Otherwise the first one %% complains when <list-macro> seems to have been used earlier %% while the second complains when <list-macro> seems \emph{not} to %% have been used before: \ifltx %% v0.3 \def\InitializeListMacro#1{\@ifdefinable#1{\let#1\empty}} \def\ReInitializeListMacro#1{% \edef\@tempa{\expandafter\@gobble\string#1}% \expandafter\@ifundefined\expandafter{\@tempa}% {\@latex@error{\noexpand#1undefined}\@ehc}% {\let#1\empty}} \else \def\InitializeListMacro#1{\let#1\empty} %% not \@empty 2011/11/07 \let\ReInitializeListMacro\InitializeListMacro \fi %% |\ToListMacroAdd{<list-macro>}{<cmd-or>}| %% appends <cmd-or> to the replacement token list of <list-macro>. %% <cmd-or> may either be tokenized into a single token, %% or it is some `{<balanced>}'. \def\ToListMacroAdd#1#2{\DefExpandStart#1{#1#2}} \def\DefExpandStart#1{\expandafter\def\expandafter#1\expandafter} %% %% === Testing for Occurrence of a Token === %% |\TestListMacroForToken{<list-macro>}{<cmd>}| %% sets `\in@true' when <cmd> occurs in <list-macro> %% and sets `\in@false' otherwise: %% 2011/11/07 \def\TestListMacroForToken#1#2{% \expandafter \in@ \expandafter #2\expandafter{#1}} %% Indeed I removed an earlier `\IfTokenInListMacro', %% now it's a kind of compromise between having a shorthand macro %% below and a generalization for users of the package. %% %% === Adding and Removing === %% |\FromTokenListMacroRemove{<list-macro>}{<cmd>}| %% removes the token corresponding to <cmd> from the list %% stored in <list-macro> %% (our parsing method does not work with braces): %% 2011/11/07 \def\FromTokenListMacroRemove#1#2{% %% I am not happy about defining \emph{two} parser macros, %% but for now ... \TestListMacroForToken#1#2% \ifin@ \def\RemoveThisToken##1#2{##1}% \expandafter \DefExpandStart \expandafter #1\expandafter {% \expandafter\RemoveThisToken #1}% %% TODO warning otherwise? \fi} %% %% 2011/11/07: %% ... but this only removes a single occurrence ... %% \[|\InTokenListMacroProvide{<list-macro>}{<cmd>}|\] %% avoids multiple entries of a token %% by \emph{not} adding anything when <cmd> %% already occurs in <list-macro> (again, this does not work with %% braces, try `\in@{{}}{{}}'). \def\InTokenListMacroProvide#1#2{% \TestListMacroForToken#1#2% \ifin@ \else %% TODO warning? \ToListMacroAdd#1#2% \fi} %% %% %% == Leaving and History == \PopLetterCatAt %% v0.3 \endinput VERSION HISTORY v0.1 2011/06/23/28 stored separately v0.2 2011/11/02 simpler, documented 2011/11/03 corrected \if/\else for init 2011/11/07 \TestListMacroForToken, \InListMacroProvide; doc.: \pagebreak, structure 2011/11/19 modified LaTeX supplements v0.21 2012/05/14 fix for "generic" and `typeoutfileinfo': @ before ...! v0.21a 2012/05/19 \labels sec:apply, sec:core; \pagebreak? v0.22 2012/06/04 allow {} items v0.3 2012/11/05 updating copyright, using `plainpkg', rewording documentation there