7

I was wondering if there is a way to use macro within a \foreach loop. For example some of my defined locals are:

\newcommand{\labA}{Adult}
\newcommand{\labB}{Adolescent}
\newcommand{\labC}{Child}

In the main text, what I want to do is generate a for loop with A B C, but present the \labA, \labB and \labC. For example

\foreach \age in {A,B,C}
{
       (I want to show \lab\age here)
}

However, \lab\age does not seem to work, and I was wondering if there is a way to show local that contains local (A, B, and C) from the loop.

2 Answers 2

7

You can construct the control sequence name using a \csname...\endcsname pair:

enter image description here

\documentclass{article}

\usepackage{pgffor}

\newcommand{\labA}{Adult}
\newcommand{\labB}{Adolescent}
\newcommand{\labC}{Child}

\begin{document}

\foreach \age in {A,B,C} {%
  Age~\age: \csname lab\age\endcsname\par
}

\end{document}
1

A rather flexible implementation with xparse and expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\agename}{m}
 {
  \str_case:nnF { #1 }
   {
    {A}{Adult}
    {B}{Adolescent}
    {C}{Child}
   }
   {You~fool!}
 }
\NewDocumentCommand{\xforeach}{m +m}
 {
  \clist_map_inline:nn { #1 } { #2 }
 }
\ExplSyntaxOff

\begin{document}

\xforeach{A,B,C}{%
  Age #1: \agename{#1}\par
}

\end{document}

As you see, the “variable” in the loop is denoted by #1 instead of defining a dummy macro.

The code is almost straightforward: the macro \agename checks its argument against the list of correspondences. The “false branch” might be a better error catching function, at present it just prints “You fool!”.

The \xforeach macro is a user's level version of \clist_map_inline:nn: each item in the comma separated list given as first argument is used as #1 in what's specified in the second argument.

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .