Continuing with my struggle to deal with expansion issues, I am stuck on how to use an \edef
properly. The code below with the switches set as:
%\def\ApplyColorToTitle{}
%\def\UseMathrmInTitle{}
\def\UseEdefInsteasOfDef{}
produces:
but as soon as I attempt to apply color formatting of the title, or even use \mathrm{}
(surprisingly using \text{}
does not exhibit this problem) in the title I get compile errors if I attempt to use the \edef
. That is, the following settings work:
\def\ApplyColorToTitle{}
\def\UseMathrmInTitle{}
%\def\UseEdefInsteasOfDef{}
and produce the desired result:
However, I would like to be able to use this code with all the switches enabled:
\def\ApplyColorToTitle{}
\def\UseMathrmInTitle{}
\def\UseEdefInsteasOfDef{}
In this case I thought I needed to use a \noexpand
on the formatting macro in the \edef
:
\edef\FormattedTitle{\noexpand\FormatTitle{\Title}}
This \noexpand
does work for the case of:
\def\ApplyColorToTitle{}
%\def\UseMathrmInTitle{}
\def\UseEdefInsteasOfDef{}
and hence I thought I was on the right track, but still fails with the use \mathrm{}
.
Question:
How do I use the \edef
instead of a \def
and allow for use of \mathrm{}
along with the color formatting?
Note:
-
I have to admit I am not sure why I have the
\edef
here in the first place, but there must have been a case that was not working that got fixed when I switched to using an\edef
. I realize that it is not a very good reason, but that is why I would prefer to continue to use the\edef
. If the expansion gurus here see no reason to be using an\edef
here and recommend that I just use the\def
I will do that until I am able to provide a MWE that actually requires a\edef
. -
I do need to use
\mathrm{}
instead of\text{}
to ensure that theth
is in roman font even if the title is wrapped in another formatting macro..
Code:
%\def\ApplyColorToTitle{}
%\def\UseMathrmInTitle{}
\def\UseEdefInsteasOfDef{}
\documentclass{article}
\usepackage{xcolor}
\usepackage{amsmath}
\newcommand*{\Title}{}%
\newcommand*{\SetTitle}[1]{%
\renewcommand*{\Title}{#1}%
}%
\ifdefined\ApplyColorToTitle
\newcommand{\FormatTitle}[1]{\textbf{\textcolor{blue}{\boldmath#1}}}%
\else
\newcommand{\FormatTitle}[1]{#1}%
\fi
\begin{document}
\ifdefined\UseMathrmInTitle
\SetTitle{$n^{\mathrm{th}}$ Root}%
\else
\SetTitle{$n^{\text{th}}$ Root}%
\fi
\ifdefined\UseEdefInsteasOfDef% Would prefer to use an edef
\edef\FormattedTitle{\FormatTitle{\Title}}%
% Thought that adding this \noexpand would do the trick as
% it seems to alow for \ApplyColorToTitle being defined.
%\edef\FormattedTitle{\noexpand\FormatTitle{\Title}}%
\else
\def\FormattedTitle{\FormatTitle{\Title}}%
\fi
Title is: \FormattedTitle
\end{document}
Best Answer
works but that's the same as not using
\edef
at all.Basically the answer really is don't do that.
\noexpand
just stops one expansion occuring so you need exactly the right number of\noexpand
s depending on how many expansion contexts the token passes through. Too many and the token will finally act like\relax
and do nothing. Not enough and things blow up.The LaTeX
\protect
mechanism (or the e-tex protected primitive) is designed to avoid this, it holds tokens as if via\noexpand
until you want to execute them. But this (for classic LaTeX protection) means using\protected@edef
. Even with\protected@edef
though you have to be careful not to suppress expansion of a command but allow its arguments to expand. If you dothen
\FormatTitle
expands to itself but\Title
still expands as normal.The error message you get from
is quite obscure
It's quite entertaining (for some definition of entertainment) to see why, and what those
...
are.Let's start with an easier case.
If you try
You get the error
what is happening here is that to define
x
TeX goes along each token in the replacement text expanding every expandable token until the token is not expandable when it is added to the definition and the next token is expanded until you get to the closing}
.So the first token is
\def
. That is not expandable so is just added to teh definition of\x
. the next token is\something
which is intended to be the token defined by\def
but that definition has not been executed, so the edef trues to expand\something
and you get an undefined control sequence error (if the command is not defined).If you first go
so
\something
is not expandable, then the initial edef does not generate an error and producesSo in the middle of the expansion of
\mathrm
there is a test and an error message in case the test fails, but in an edef the test doesn't really happen TeX just expands all the tokens anway so it ends up expanding\GenericError
which has exactly the construct just described but with a slightly unusual control sequence whose name isthat is, its name includes 65 space characters!
It turns out that this is the only token that is undefined so if you define this token you do not get an error:
Produces:
Note however that though the obscure error has gone, the defined command
\x
is completely useless. For example it containswhich comes about as the original had an expansion like
but
\edef
has left\let \protect
but\string
has expanded converting the\edef
token to the 5 character tokens\ e d e f
so if executed the\let
would define\protect
to be let to a backslash character token.