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,...
)
\def\body{%
\renewcommand*{\SomeCommand}[1]{\color{red}#1}% Using ## here eliminates the error.
\par\SomeCommand{\x}%
}%
}
\def\x{a}\body
\def\x{b}\body
...
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 #
and 1
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
\let\hash=#
and \hash
will be let to #
but you can not define a macro as
\def\definehash{\let\hash=#}
as that generates
! Illegal parameter number in definition of \definehash.
You need ##
to refer to a literal #
in a macro definition. So it needs to be
\def\definehash{\let\hash=##}
You 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 define
\def\ddefinehash{\def\definehash{\let\hash=##}}
The 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:
! Illegal parameter number in definition of \definehash.
<to be read again>
}
l.12 \ddefinehash
So you need to get two #
into the definition of \definehash
and each of those has to be entered as ##
so you end up with
\def\ddefinehash{\def\definehash{\let\hash=####}}
Putting it all together:
{
\let\hash=#
}
{
\def\definehash{\let\hash=##}
}
{
\def\ddefinehash{\def\definehash{\let\hash=####}}
\ddefinehash
\definehash
\show\ddefinehash
\show\definehash
\show\hash
}
\bye
> \ddefinehash=macro:
->\def \definehash {\let \hash =####}.
l.15 \show\ddefinehash
?
> \definehash=macro:
->\let \hash =##.
l.16 \show\definehash
?
> \hash=macro parameter character #.
l.17 \show\hash
?
)
No pages of output.
Best Answer
With
you'd define
\iitthesis@authorEnglish
to expand to "Name of Author", that is, you'd have issued the equivalent ofThis wouldn't check for the defined command to be previously undefined. If you want also this check, do
but for internal commands this isn't usually done.
In your motivation I don't see any need of defining the new command with an argument. If you need also to define a user level command, you can do with the same technique:
In this case saying
would define the command
\authorEnglish
so that if the user typesthe effect would be as if doing
The
\long
prefix to\@namedef
causes\long\def
to be executed, so the argument can span one or more paragraphs.This technique is employed by the LaTeX kernel, where
\author{A. U. Thor}
actually defines\@author
expanding eventually to "A. U. Thor".