[Tex/LaTex] Useful applications of \edef with macro arguments

expansionmacrostex-core

Well, it's been in my head for some time, but I haven't got anything out of it, so I ask here. At what places could be useful to have \edef\foo#1{..}? What applications could it have? Is it useful at all?

Here's one example. \foo gives ten thousand times the argument after one expansion. Of course, this probably could be done in another way, but seems like a good example.

\def\byten#1{#1#1#1#1#1#1#1#1#1#1}
\edef\foo#1{\byten{\byten{\byten{\byten{#1}}}}}

Ten thousand letters: \foo{a\hskip0ptplus1pt}
\bye

But apart from that, I've been looking for a chance to use \edef\foo#1 and it hasn't appeared.

To make this answerable, in case some applications don't appear, or there's no interest in the question, it could also be answered like Have you ever seen \edef used that way? or for instance Is there any use of this in a full TeX Live installation?

Note

The question is not clear enough, the suggestions of egreg and Heiko are both acceptable answers, since they are uses of \edef with arguments. However, what I was looking for are situations where the argument are inside the argument of a macro that gets expanded when \edefed (like in my example). I don't know how to write this clear, feel free to edit the question.

Best Answer

Searching for \edef or \xdef (global variant) with command to be defined and argument in TeX Live 2015 and filtering out possible false positives (when the command is constructed with \csname):

 egrep -r '\\[ex]def\\[a-zA-Z@]+#1' texmf-dist/tex/ | grep -v '\\[ex]def\\csname'

Result are 219 lines.

I do not want to discuss all findings, thus I restrict myself to few examples.

Example \TextOrMath of the LaTeX kernel (latex.ltx)

Recently, macro \TextOrMath was added to the LaTeX kernel:

\edef\TextOrMath#1#2{%
  \expandafter\noexpand\csname TextOrMath\space\endcsname
  {#1}{#2}}

Here, the \edef has the purpose to construct a macro name with a space in it: \TextOrMath␣. The definition would simpler, if the space would be a letter:

\def\TextOrMath#1#2{\TextOrMath␣{#1}{#2}}

But, this is not possible with the usual category code of the space. An alternative with \def and lots of \expandafter is more cumbersome:

\expandafter\def\expandafter\TextOrMath
\expandafter#\expandafter1\expandafter#\expandafter2\expandafter{%
  \csname TextOrMath\space\endcsname{#1}{#2}%
}

Therefore, \edef works on the non-argument part of the definition text. To make it clear, arguments are not expanded during the definition with \edef, #1 to #9 are non-expandable tokens.

Example \split@err of package amsmath

Another example can be found in package amsmath:

\edef\split@err#1{%
    \@nx\@amsmath@err{%
        \string\begin{split} won't work here%
    }{%
        \@xp\@nx\csname
  Did you forget a preceding \string\begin{equation}?^^J%
  If not, perhaps the `aligned' environment is what
  you want.\endcsname}%
}

Here, the argument is not used at all, it is ignored as part of the error recovery.

Example \mleftright@Def of package mleftright

Package mleftright has an example, where the argument is used three times:

\edef\mleftright@Def#1{%
  \noexpand\ltx@IfUndefined{%
    \noexpand\expandafter\noexpand\ltx@gobble\noexpand\string#1%
  }{%
    \expandafter\noexpand\mleftright@Def#1%
  }{%
    \noexpand\@PackageError{mleftright}{%
      Command \noexpand\string#1 already defined%
    }\noexpand\@ehd
    \noexpand\ltx@gobble
  }%
}

The purpose of the expansion is \mleftright@Def inside the definition. Previously, it was defined as \protected\def, \DeclareRobustCommand* or \def, depending, which method is available (e-TeX, LaTeX, or neither of them).

Arguments #1, ...

At definition time, the argument place holders (#1, #2, ..., #9) are just two non-expandable tokens, the hash character # and the digit 1 to 9. Therefore, there isn't a difference between \edef or \def, because \edef cannot expand non-expandable tokens.

The argument place holders get replaced with the actual arguments, when the macro is used, that is after the definition of the macro.

Related Question