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.

Frequently I see users redefine macros using (for example)

\let\oldmacro\macro% Store \macro in \oldmacro
\renewcommand{\macro}{%
  % ...redefined \macro
  \oldmacro%
}

and other times they use

\usepackage{letltxmacro}% http://ctan.org/pkg/letltxmacro
\LetLtxMacro{\oldmacro}{\macro}% Store \macro in \oldmacro
\renewcommand{\macro}{%
   % ...redefined \macro
  \oldmacro%
}

Why would one use \LetLtxMacro when \let works just as well? Or, more specifically, when would one use \LetLtxMacro and/or why?

share|improve this question
    
See “Closed” (square) root symbol. In particular, see @egreg's comment. –  A.Ellett Dec 23 '12 at 7:26
    
@A.Ellett The "x mins/hours ago" text at the end of each comment is a link that leads directly to the comment. At the end of each answer there is a light grey list of functions "share edit flag". The "share" is a link to the corresponding answer as well. –  Benedikt Bauer Dec 23 '12 at 21:26
    
This is explained clearly in the package documentation. –  Martin Schröder Dec 25 '12 at 22:41
1  
@MartinSchröder: Only partially, if you read through egreg's answer. There is no mention of it not supporting xparse definitions, nor does it contain the detail provided by his answer. –  Werner Dec 26 '12 at 0:40

1 Answer 1

up vote 43 down vote accepted

There are two main cases when \LetLtxMacro should be used (and it doesn't harm if used in other cases).

Case 1

The command to get a copy of has been defined with \DeclareRobustCommand, like

\DeclareRobustCommand{\foo}[1]{-#1-}

(with any number of arguments, even zero). There are other commands defined in different ways, but at the end come up as being in this same case.

What happens here is that LaTeX defines two commands, in a way similar to this

\def\foo{\protect\foo•}
\newcommand\foo•[1]{-#1-}

where by I mean a space in the name of the second command. How this trick is achieved is unimportant. We can realize if a command is of this kind by asking texdef: with the command line

> texdef -t latex texttt

we get

\texttt:
macro:->\protect \texttt  

\texttt :
\long macro:#1->\ifmmode \nfss@text {\ttfamily #1}\else \hmode@bgroup \text@command {#1}\ttfamily \check@icl #1\check@icr \expandafter \egroup \fi 

This shows precisely what's happening: texdef prints first the meaning of \texttt, which is \protect\texttt• (the space here is invisibile), but then know about the nature of this command and so prints also the meaning of \texttt• and this is shown by the space before the colon.

What would be the problem in doing

\let\oldfoo\foo
\renewcommand\foo[1]{!\oldfoo{#1}!}

for changing the working of \foo? Let's see what happens (I'll continue to use for denoting the space in the name of a macro).

\foo{BAR}
!\oldfoo{BAR}!
!\protect\foo•{BAR}!
!-BAR-!

which seems pretty good: the renewed macro does what we want. But wait! We use \DeclareRobustCommand to be sure that \foo in moving arguments is treated correctly. So let's see what happens when \foo{BAR} is used in a moving argument, such as a section title; the annotation in the .toc file will contain

!\foo  {BAR}!

which in the end will result in printing !!-BAR-!!, which is not what we want. Why? Because the writing process expands unprotected macros. So LaTeX does

\foo{BAR}
!\oldfoo{BAR}!
!\protect\foo•{BAR}!
!\foo• {BAR}!

Since \foo• was preceded by \protect, the last line is what's written. But when the .toc file is read in, TeX only sees a space after \foo, because it inputs a text file, so it will dutily expand \foo.

If one uses

\LetLtxMacro{\oldfoo}{\foo}

LaTeX will essentially do

\def\oldfoo{\protect\oldfoo•}
\let\oldfoo•\foo•

so that the problem above will not appear any more.

Case 2

If the command we want to save the meaning of has been defined with \newcommand to have an optional argument, then there are risks like in the previous case; they are explained in this answer. The situation is of the form

\newcommand{\xyz}[2][!]{#1-#2}

and, for instance, \smash (as redefined by amsmath) falls in this case. With

texdef -t latex -p amsmath smash

we'd get

\smash:
macro:->\@protected@testopt \smash \\smash {tb}

and this is a clear sign that \LetLtxMacro should be used.

Other cases

If the command to save has been defined with \newrobustcmd from the etoolbox package, then \LetLtxMacro should be used in order to safely copy its meaning.

Warning

Don't try \LetLtxMacro with commands defined by \NewDocumentCommand (or similar commands) from xparse. The letltxmacro package doesn't support them.

share|improve this answer
1  
Say I don't want to take risks!. Can I use \LetLtxMacro for all instances (everywhere)? Will it hurt if done so? (I read your first line but want confirmation) –  Harish Kumar Dec 23 '12 at 12:01
1  
@HarishKumar If the macro is not risky, then \LetLtxMacro does nothing different from \let. –  egreg Dec 23 '12 at 12:03
1  
Thanks for the warning. I assume, I’m not the only one, who did not know this. –  Speravir Dec 23 '12 at 19:17

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.