System Macros/Comma Separated Lists

< Prev: Action Processing | Top: System Macros | Next: Key-Value Assignments >

We've already seen some macros that take care of comma separated lists. Such list can be processed with

\processcommalist[string,string,...]\commando


The user supplied command \commando receives one argument: the string. This command permits nesting and spaces after commas are skipped. Empty sets are no problem.

Empty arguments are not processed. Empty items (,,) however are treated.

\def\dosomething#1{(#1)}
1: \processcommalist [\hbox{$a,b,c,d,e,f$}] \dosomething \par
2: \processcommalist [{a,b,c,d,e,f}]        \dosomething \par
3: \processcommalist [{a,b,c},d,e,f]        \dosomething \par
4: \processcommalist [a,b,{c,d,e},f]        \dosomething \par
5: \processcommalist [a{b,c},d,e,f]         \dosomething \par
6: \processcommalist [{a,b}c,d,e,f]         \dosomething \par
7: \processcommalist []                     \dosomething \par
8: \processcommalist [{[}]                  \dosomething \par


And here is the result:

Quitting a commalist halfway can be done by using \quitcommalist within the execution macro.

When a list is saved in a macro, we can use a construction like:

\expandafter\processcommalist\expandafter[\list]\dosomething


Such solutions suit most situations, but we wanted a bit more.

\processcommacommand[string,\stringset,string]\dosomething


where \stringset is a predefined set, like:

\def\first{zeroeth,first}
\def\second{last}
\processcommacommand[\first]\message
\processcommacommand[\first,second,third]\message
\processcommacommand[\first,between,\second]\message


Commands that are part of the list are expanded, so the use of this macro has its limititations.

The argument to \dosomething is not delimited. Because we often use [] as delimiters, we also have:

\processcommalistwithparameters[string,string,...]\dosomething


where \dosomething looks like:

\def\dosomething[#1]{... #1 ...}


Some of the commands mentioned earlier are effective but slow. When one is desperately in need of faster alternatives and when the conditions are predictable safe, the \raw alternatives come into focus. A major drawback is that they do not take \c!constants into account, simply because no expansion is done. (This is not a problem for \rawprocesscommalist), because this macro does not compare anything. Expandable macros are permitted as search string for \rawdoifinsetelse.

\rawdoifinsetelse{string}{string,...}{...}{...}
\rawprocesscommalist[string,string,...]\commando
\rawprocessaction[x][a=>\a,b=>\b,c=>\c]


Spaces embedded in the list, for instance after commas, spoil the search process. The gain in speed depends on the length of the argument (the longer the argument, the less gain).

When we process the list a,b,c,d,e, the raw routine takes over 30% less time, when we feed 20+ character strings we gain about 20%.

It's possible to get an element from a commalist or a command representing a commalist.

\getfromcommalist    [string] [n]
\getfromcommacommand [string,\strings,string,...] [n]


The difference between the two of them is the same as the difference between \processcomma.... The found string is stored in \commalistelement.

Because 0, 1 and 2 are often asked for, the macros are optimized on those numbers.

We can calculate the size of a comma separated list by using:

\getcommalistsize    [string,string,...]
\getcommacommandsize [string,\strings,string,...]


Afterwards, the length is available in the macro \commalistsize (not a <counter>).

Watertight (and efficient) solutions are hard to find, due to the handling of braces during parameters passing and scanning. Nevertheless, the macros function quite well.

For low level (fast) purposes, we can also use the next alternative, which can handle up to 8 elements at most.

\dogetcommalistelement1\from a,b,c\to\commalistelement


It's ugly, but it is very fast indeed. Keep in mind that this version does not strip leading spaces from the list items.

< Prev: Action Processing | Top: System Macros | Next: Key-Value Assignments >

C O N T E X T G A R D E N