Introduction:
When you use \renewcommand
within another macro or environment, one needs to double up the ##
to access the parameters of the inner macro. This serves as a way to distinguish the inner macros ##1
with the outer macros #1
(even if the outer macro does not have any parameters, it provides for error checking). For example:
\newcommand*{\OuterCommand}{%
\renewcommand*{\SomeCommand}[1]{\color{red}##1}%
....
}%
The references below provide more details on this.
Issue:
It appears that the same doubling up of the #
is needed within a \foreach
loop as illustrated in the MWE below.
This took me quite some time to figure this out as the error message that the MWE below gives is:
Illegal parameter number in definition of \pgffor@body
This was within a very deeply nesting of \foreach
loops, so I was sure the problem was that I was nesting the \foreach
too deeply. Surprisingly, if you skip past the error, the output is still correct, so this made it even harder to locate the problem.
Questions:
- Since the
\foreach
does not have parameters like#1
(as\newcommand
does), why is it necessary to double up the#
within a definition within a\foreach
? - How is that the output is still correct, if you simply ignore the error and hit return to continue processing?
References:
- renewcommand in a newcommand.
- Defining LaTeX commands within other commands.
- Nesting command definitions more than two levels.
Code:
\documentclass{article}
\usepackage{xcolor}
\usepackage{pgffor}
\newcommand*{\MyList}{A,B,C}%
\newcommand{\SomeCommand}[1]{#1}%
\begin{document}
\foreach \x in \MyList {%
\renewcommand*{\SomeCommand}[1]{\color{red}#1}% Using ## here eliminates the error.
\par\SomeCommand{\x}%
}%
\end{document}
Best Answer
Internally the definition of foreach will be saving the body of the loop in a macro so it is like (if looping over
a,b,...
)That initial
\def
(or\newcommand
if you prefer) will require a#
in the body to be entered as##
. As shown above you would get an error on#1
as\body
doesn't take parameters it would have to be entered, as you found, as##1
.It is possible to define loops in such a way not to require this (for example it could use a token register rather than a macro for saving the body) but that is apparently not the case here.
Note that the need to double
#
is unrelated to the fact that there is an inner macro definition. It is not that inner macros require##1
to refer to the first parameter, it is simply that the inner macro definition requires the two tokens#
and1
to refer to the first parameter and to get a#
into a macro body you need##
. To see this consider a definition that doesn't have##1
.You can go
and
\hash
will be let to#
but you can not define a macro asas that generates
You need
##
to refer to a literal#
in a macro definition. So it needs to beYou ask in comments why it needs four
#
for a double nested definition. Again it is nothing special about the inner definitions, they never "see"##1
by the time they are evaluated they just see a single#
. If you tried to defineThe definition would proceed without error but then if you try to execute
\ddefinehash
you find that it just has a single#
in its definition and so you get the error as before:So you need to get two
#
into the definition of\definehash
and each of those has to be entered as##
so you end up withPutting it all together: