7

I would like to define a series of command using two loops.

For instance I want to create a series of variables that can have YY or NN as subscripts.

I would like to define commands \yy and \nn that puts those letters as UPPER CASE subscripts.

Following this solution, I use Tikz / pgffor:

\documentclass{minimal}
\usepackage{pgffor}

\foreach \p in {yy,nn}{%
    \expandafter\xdef\csname \p\endcsname{
         \noexpand\ensuremath{_{\uppercase{\p}}}
     }
}

\begin{document}
    $B\nn$ and $B\yy$
\end{document}

Now I would like to know how to create variables \ann, \ayy, \bnn, \byy, \cnn and so on, that would be the equivalent of $A\nn$, $A\yy$, $B\nn$, etc.

I would like to do something along the line of

\foreach \p in {yy,nn}{%
    \expandafter\xdef\csname \a\\p\endcsname{
         \noexpand\ensuremath{A\\p}
     }
}

where I have written \\p when I wanted the loop to use functions \yy and \nn previously defined. But obviously it doesn't work

(! Undefined control sequence.
\GenericError  ...                                                                                 \@empty \def \MessageBreak...)

Any idea?

3 Answers 3

3

With more cowbell you have the solution

\documentclass{article}
\usepackage{pgffor}
\foreach \x in {a,...,z}{
\foreach \p in {yy,nn}{%
    \expandafter\expandafter\expandafter\xdef\expandafter\csname\x\p\endcsname{
         \noexpand\ensuremath{\uppercase{\x}_{\uppercase{\p}}}
     }
}
}
\begin{document}
    \foreach \var in {a,f,...,z}{
    \csname\var nn\endcsname and} \zyy
\end{document}

enter image description here

EDIT (Ahmed)

percusse used more \expandafter than necessary:

\documentclass{article}
\usepackage{pgffor}
\foreach \x in {a,...,z}{%
  \foreach \p in {yy,nn}{%
    \expandafter\xdef\csname\x\p\endcsname{%
      \noexpand\ensuremath{\uppercase{\x_\p}}%
    }%
  }%
}
\begin{document}
\foreach \var in {a,f,...,z}{%
  \csname\var nn\endcsname\space and
}
\zyy
\end{document}

I would have used a stack for this exercise, instead of defining potentially countless commands.

3
  • @AhmedMusa There's also one \uppercase too much, to be picky.
    – egreg
    Oct 24, 2012 at 22:46
  • @AhmedMusa Thanks for the update. Apparently I got it mostly wrong :)
    – percusse
    Oct 24, 2012 at 22:56
  • @egreg: Underscore has no uppercase if its uccode isn't changed.
    – Ahmed Musa
    Oct 25, 2012 at 0:01
4

With your definitions, the macro \yy expands to _{\uppercase{yy}}. One can do better and have it expand to _{YY} instead.

\documentclass{article}
\usepackage{pgffor}

\foreach \p in {yy,nn}{
  \begingroup\edef\x{\endgroup
  \unexpanded{\expandafter\gdef\csname\p\endcsname}{_{\p}}}
  \uppercase\expandafter{\x}
}
\foreach \l in {a,b,c}{
  \foreach \p in {yy,nn}{
    \begingroup\edef\x{\endgroup
    \unexpanded{\expandafter\gdef\csname\l\p\endcsname}{\l_{\p}}}
    \uppercase\expandafter{\x}
  }
}

\begin{document}
$B\nn$ and $B\yy$ --- $\ann$ and  $\byy$

\texttt{\meaning\ann}
\end{document}

enter image description here

As you see, \ann expands to A_{NN} and not to \uppercase{a}_{\uppercase{nn}}. You may fall in some cases where, for some reasons, \uppercase is temporarily redefined to do nothing (or, worse, to do something else) and havoc would ensue.

I leave as an exercise how to add \ensuremath (don't hope I'll help perpetrating misdemeanors).

1

OK I think I just found out how to do that:

   \documentclass{minimal}
   \usepackage{pgffor}

    \foreach \p in {yy,nn}{%
        \expandafter\xdef\csname \p\endcsname{\noexpand\ensuremath{_{\uppercase{\p}}}
    }
    }
    \foreach \l in {a,b,c} {
    \foreach \p in {yy,nn}{%
        \expandafter\xdef \csname \l\p\endcsname{
             \noexpand\ensuremath{\uppercase{\l}\csname \p\endcsname}}
    }
    }
    \begin{document}
        $\ann$  $\byy$
    \end{document}

It does throw errors "missing $ inserted" that I can't solve but that's start...

Bottom line: the trick was to use \csname \endcsname.

You must log in to answer this question.

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