4

I am getting an error while trying to compile this minimal example:

min.cls:

\ProvidesClass{min}

\LoadClass{minimal}
\NeedsTeXFormat{LaTeX2e}

\newenvironment{myenv}{}{
\def\aaa{test }
\expandafter\def\csname bbb\endcsname{$4\sqrt{2}$}
\bbb
\edef\aaa{\aaa \bbb}
\aaa
}

\endinput

mintest.tex:

\documentclass{min}

\begin{document}

\begin{myenv}
Test
\end{myenv}

\end{document}

Running latex over mintest.tex produces this error:

ERROR: Use of \@sqrt doesn't match its definition.

--- TeX said ---
\@ifnextchar ...eserved@d =#1\def \reserved@a {#2}
                                                  \def \reserved@b {#3}\futu...
l.7 \end{myenv}

Peculiar. I want to expand the definition of \aaa by concatenation. Any thoughts?

lockstep
  • 250,273
osolmaz
  • 1,283
  • 1
    LaTeX doesn't like that commands with optional arguments are passed through an \edef. It's difficult to say more from your example, but \protected@edef\aaa{\aaa\bbb} should work. – egreg Oct 29 '12 at 10:07
  • @egreg WOW, thanks, it worked. Can you post as an answer so I can mark it? – osolmaz Oct 29 '12 at 10:09

1 Answers1

7

TeX doesn't like to find commands with optional arguments or defined with \DeclareRobustCommand inside an \edef; \sqrt fall in the first type, \bfseries in the second one.

In your case

\protected@edef\aaa{\aaa\bbb}

will work.

Be careful, though: fragile commands such as \linebreak can't go in \protected@edef directly and must be preceded by \protect. Some knowledge of how dubious commands are defined is necessary.

See also Minimal \protected@edef example and Problem with nested \noexpand and \edef

egreg
  • 1,121,712