It seems that a common operation needed when defining new commands is to scan over a list of arguments (separated e.g. by a comma, but maybe by something else) and do something with each argument in the list, find the last one, or whatever.

For example to write commands that look like \Command{a,b,c} or \Command{c.d.e} and do something with each a, b, and c. See e.g. questions on defining a list of operators and ignoring even numbered inputs.

Some solutions have been posted there, but what would be the best idiom to perform such kind of operations? LaTeX's \@for looks very nice, but is it possible to use it to scan anything other than comma-separated lists?


I have not progressed to the level of processing a list myself but I have been using etoolbox by Philipp Lehman for some other TeX programming tasks I am doing. I believe 3.7 List processing should give you a good solution.

For example (on a recent version of etoolbox) you can write:

\myfor{\fbox}{item1; item2; item3}
  • 1
    Thanks for the reference! It does have some nice commands to process a list of arguments. If you don't mind I can edit your answer to include an example. Aug 6 '10 at 20:53
  • Please go ahead.
    – Leo Liu
    Aug 6 '10 at 21:44

I was hoping someone to post a better/nicer solution, but so far this seems to be the best one I've seen.


Of course instead of : one can use , or any other sensible separator.

  • I agree that this is a very good solution, since it does not require any other package at all and needs very few lines of code nevertheless. Mar 25 '11 at 14:32

Since Morbusg's answer pushed that question to the top, let me add a LaTeX3 answer. The idea is to convert the list to an internal structure called a sequence, and then map over that sequence \l_MyMap_seq.

\usepackage{expl3, xparse}
\seq_new:N \l_MyMap_seq
    \seq_set_split:Nnn \l_MyMap_seq {#1} {#2}
    \seq_map_inline:Nn \l_MyMap_seq {#3}
  \MyMap{a,b,c}{\fbox{#1} }

The first (optional) argument is the delimiter, by default a comma. The second argument is the list, and the third is a function, taking each item of the list as #1.

The xparse package also provides \SplitList, which can be used as

\NewDocumentCommand {\foo} { >{\SplitList{.}} m m } { \tl_map_inline:nn {#1}{#2} }

hard-coding the delimiter in the definition of \foo.


Here is an LPEG based solution. This is written in ConTeXt, but should be easy to modify for LuaLaTeX

\unprotected\def\ProcessListWithDelim#1[#2]#3% delim list command
  {\ctxlua{userdata.ProcessListWithDelim(\!!bs#1\!!es, \!!bs#2\!!es, \!!bs\noexpand#3\!!es)}} 

  userdata = userdata or {}

  function userdata.ProcessListWithDelim(delim, list, command)
    local splitter = lpeg.Ct(lpeg.splitat(lpeg.P(delim)))
    local items    = lpeg.match(splitter, list)

    for i=1,#items do
      tex.sprint(tex.ctxcatcodes, command .. '{' .. items[i] .. '}')






In ConTeXt, list processing is done using \processcommalist. Suppose you want to apply the macro \doCommand over each list element passed to \Command. The following definition of \Command does this:


If the list may contain macros, like


then you can use \processcommacommand, like


There are a some faster alternatives, \rawprocesscommalist and \rawprocesscommacommand but they have certain limitations. See the ConTeXt wiki page on list processing for details.

To process a list with an arbitrary separator, \processlist may be used. \processlist takes 5 arguments: beginning of list marker, end of list marker, element separator, command to apply to each element, and the list. For example, a command \Command[a:b:c] that uses colon as the separator, can be defined as

  • but what about lists separated by a character other than a comma? Oct 14 '10 at 14:58
  • \processlist can be used to process a list with a particular separator. I added that information in the answer.
    – Aditya
    Oct 21 '10 at 1:11

Here's a complete example using the \docsvlist command provided by etoolbox. The example introduces a package called csvfont and its usecsvfont environment. The font and formatting of this environment can be set using the package/environment options font (which resets the font definition) and font+ (which appends the font definition). Both options may take a comma-separated list of values; as individual values one may specify the names (without preceding backslash) of LaTeX's font-switching/formatting commands. (This syntax is used in the upcoming version 0.1b of my quoting package.)





  \renewcommand*{\do}[1]{\appto{\csvfont}{\csname ##1\endcsname}}%
  \renewcommand*{\do}[1]{\appto{\csvfont}{\csname ##1\endcsname}}%












enter image description here

  • ...that pushed you over the 50K edge. Glad I could be the one. :)
    – Werner
    Feb 24 '12 at 18:35

Here's my solution (borrowed form Kevin Walker):

% tricky way to iterate macros over a list
    \expandafter\def\csname multi#1\endcsname##1{
            \csname #1\endcsname{##1}
            \def\next{\csname multi#1\endcsname}
    \csname multi#1\endcsname}

And some examples of its use:

% \def\cA{{\cal A}} for A..Z
\def\calc#1{\expandafter\def\csname c#1\endcsname{{\mathcal #1}}}

% \DeclareMathOperator{\pr}{pr} etc.
\def\declaremathop#1{\expandafter\DeclareMathOperator\csname #1\endcsname{#1}}
  • This is very similar to the proposed solutions posted in the original threads (see the question), I wanted to know if there is anything better. Moreover, I would like to process lists of arguments given as \Command{a,b,c} or \Command{a:b:c}. Jul 27 '10 at 16:39

Plain example of “Lists in TeX's mouth”, lambda.sty (TUGboat article):

\input lambda.sty
\def\MathOp#1{\csnameafter\def{#1}{\mathop{\it #1}}%
  #1} % show it, too
\def\Odd#1{\TeXif{\ifodd#1 }}

\Show\Filter\Odd[1,2,3,4,5,6,7,8,9,10,11,12,13] % => [1,3,5,7,9,11,13]

\Show\Map\MathOp[Rep,Tet,Maps,Diff] $ \Rep\Tet\Maps\Diff $

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.