Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I recently came across \protected@edef in the/a LaTeX2e source. Can anyone give me a minimal or simple example, where I need this? I know this has to do with fragile commands/robustness, but I am looking for a concrete example.

share|improve this question
    
Two great answers, hard to decide which one is the correct one. So I'll flip a coin to choose :) Thank you very much for the good explanation and example! –  topskip Nov 21 '10 at 10:47

2 Answers 2

up vote 10 down vote accepted

Joseph has given a very good explanation. To give you a complete tiny example just for testing to see a difference:

\documentclass{article}
\newcommand*{\firstsection}{\protect\centering First section}
\begin{document}
\edef\currentsection{\firstsection}
\section{\currentsection}
\end{document}

This fails to compile. We got Undefined control sequence. because \edef has thrown away the \protect.

\documentclass{article}
\newcommand*{\firstsection}{\protect\centering First section}
\begin{document}
\makeatletter
\protected@edef\currentsection{\firstsection}
\makeatother
\section{\currentsection}
\end{document}

This compiles and works as expected, because \protected@edef keeps the effect of \protect within our macro.

share|improve this answer
    
Nice example :-) –  Joseph Wright Nov 20 '10 at 14:33

As you might guess, \protected@edef is a wrapper around the TeX \edef primitive. To understand what is going on, you need to understand the difference between fragile and robust commands: as this has been covered before here I'll assume you've read up on that difference!

What you may well know is that with fragile commands, it is often necessary to add \protect in front of them. When you define a macro with an optional argument, using \DeclareRobustCommand will set up an internal macro which includes this automatically.

I'm going to take as an example the \cite macro, which takes an optional argument and is defined using \DeclareRobustCommand. If you do

\show\cite

the result is

> \cite=macro:
->\protect \cite  .

Now, the \protect mechanism will not work inside a simple \edef. Try

\edef\test{\cite{stuff}}

with the article class and you get the rather cryptic

! Use of \\deftranslation doesn't match its definition.
\@ifnextchar ... \reserved@d =#1\def \reserved@a {
                                                  #2}\def \reserved@b

Of course, you would not do this directly, but can imagine some user input being passed to an internal macro which needs to \edef the material. So how do you do the \edef while still allowing \cite to appear in the input? This is where \protected@edef comes in:

\makeatletter
\protected@edef\test{\cite{stuff}}
\show\test

gives the rather more reasonable

> \test=macro:
->\protect \cite  {stuff}.

Multiple \protected@edef calls will simply repeat this process: the \cite will not be expanded until the material is actually typeset (or you forgot to be safe and use \edef!).

How does this work? Well, \protect does not always have the same definition. Most of the time it is defined as \relax, so does nothing at all. However, \protected@edef changes the definition to

\noexpand\protect\noexpand

Inside an \edef, this will preserve the presence of \protect (to allow multiple \protected@edef calls), and will then prevent expansion of the next token: the macro we want to leave alone.

Similar considerations apply to \protected@xdef and \protectd@write, which have the same issues with expansion.

All of this is very clever, but you do have to remember to use \protected@edef and there are some circumstances where the protection fails. For that reason, the e-TeX extensions include the \protected primitive, which defines 'engine robust' macros. These never expand inside an \edef, without the need for any extra steps.

share|improve this answer
    
The 'normal' definition of \protect as \relax shows up nicely in Stefan's example. –  Joseph Wright Nov 20 '10 at 14:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.