When to use LetLtxMacro? The Next CEO of Stack Overflowlet, renewcommand, and optional argumentsrenewcommand cause memory error when using default argumentlet on macro defined by newcommand with optional argumentRenewenvironment of with optional arguments enumerate goes wrong with enumitem (compilation stalls)“Closed” (square) root symbolA new environment to decide dynamically which commands to run?Duplicating EnvironmentsHow to do a recursive renewcommand?TeX newcommand and D.R.Y. (don't repeat yourself)Changing all single quotes to be straight when within textttProblem redefining an internal macro of a sty fileWhat do @firstoftwo and @secondoftwo do?When not to use ensuremath for math macro?How to execute codes inside a macro?How to expand a macro to use it inside a question in AMC?Similar Structured Macrosodd vertical alignment for mathopusing csname to define intern commands(variables) and their settersConverting .tex files to .tex files without personally-defined macrosProtecting blocks of text and commands, not just one command, from expansion

Help understanding this unsettling image of Titan, Epimetheus, and Saturn's rings?

What does "Its cash flow is deeply negative" mean?

Is it possible to search for a directory/file combination?

Can we say or write : "No, it'sn't"?

Written every which way

Indicator light circuit

Can I equip Skullclamp on a creature I am sacrificing?

Is there a way to save my career from absolute disaster?

MessageLevel in QGIS3

Several mode to write the symbol of a vector

What does convergence in distribution "in the Gromov–Hausdorff" sense mean?

Anatomically Correct Strange Women In Ponds Distributing Swords

How did the Bene Gesserit know how to make a Kwisatz Haderach?

If the heap is initialized for security, then why is the stack uninitialized?

Why do we use the plural of movies in this phrase "We went to the movies last night."?

If a black hole is created from light, can this black hole then move at speed of light?

Which tube will fit a -(700 x 25c) wheel?

Preparing Indesign booklet with .psd graphics for print

Why don't programming languages automatically manage the synchronous/asynchronous problem?

What benefits would be gained by using human laborers instead of drones in deep sea mining?

Why am I allowed to create multiple unique pointers from a single object?

Inappropriate reference requests from Journal reviewers

Are there any limitations on attacking while grappling?

Do I need to enable Dev Hub in my PROD Org?



When to use LetLtxMacro?



The Next CEO of Stack Overflowlet, renewcommand, and optional argumentsrenewcommand cause memory error when using default argumentlet on macro defined by newcommand with optional argumentRenewenvironment of with optional arguments enumerate goes wrong with enumitem (compilation stalls)“Closed” (square) root symbolA new environment to decide dynamically which commands to run?Duplicating EnvironmentsHow to do a recursive renewcommand?TeX newcommand and D.R.Y. (don't repeat yourself)Changing all single quotes to be straight when within textttProblem redefining an internal macro of a sty fileWhat do @firstoftwo and @secondoftwo do?When not to use ensuremath for math macro?How to execute codes inside a macro?How to expand a macro to use it inside a question in AMC?Similar Structured Macrosodd vertical alignment for mathopusing csname to define intern commands(variables) and their settersConverting .tex files to .tex files without personally-defined macrosProtecting blocks of text and commands, not just one command, from expansion










76















Frequently I see users redefine macros using (for example)



letoldmacromacro% Store macro in oldmacro
renewcommandmacro%
% ...redefined macro
oldmacro%



and other times they use



usepackageletltxmacro% http://ctan.org/pkg/letltxmacro
LetLtxMacrooldmacromacro% Store macro in oldmacro
renewcommandmacro%
% ...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















76















Frequently I see users redefine macros using (for example)



letoldmacromacro% Store macro in oldmacro
renewcommandmacro%
% ...redefined macro
oldmacro%



and other times they use



usepackageletltxmacro% http://ctan.org/pkg/letltxmacro
LetLtxMacrooldmacromacro% Store macro in oldmacro
renewcommandmacro%
% ...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













76












76








76


22






Frequently I see users redefine macros using (for example)



letoldmacromacro% Store macro in oldmacro
renewcommandmacro%
% ...redefined macro
oldmacro%



and other times they use



usepackageletltxmacro% http://ctan.org/pkg/letltxmacro
LetLtxMacrooldmacromacro% Store macro in oldmacro
renewcommandmacro%
% ...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














Frequently I see users redefine macros using (for example)



letoldmacromacro% Store macro in oldmacro
renewcommandmacro%
% ...redefined macro
oldmacro%



and other times they use



usepackageletltxmacro% http://ctan.org/pkg/letltxmacro
LetLtxMacrooldmacromacro% Store macro in oldmacro
renewcommandmacro%
% ...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?







macros






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 23 '12 at 7:03









WernerWerner

449k719941700




449k719941700












  • 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

















  • 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
















See “Closed” (square) root symbol. In particular, see @egreg's comment.

– A.Ellett
Dec 23 '12 at 7:26





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






@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





This is explained clearly in the package documentation.

– Martin Schröder
Dec 25 '12 at 22:41




1




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





@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






active

oldest

votes


















64














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



DeclareRobustCommandfoo[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



deffooprotectfoo•
newcommandfoo•[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 #1else hmode@bgroup text@command #1ttfamily check@icl #1check@icr expandafter egroup fi


This shows precisely what's happening: texdef prints first the meaning of texttt, which is protecttexttt• (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



letoldfoofoo
renewcommandfoo[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).



fooBAR
!oldfooBAR!
!protectfoo•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 fooBAR 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



fooBAR
!oldfooBAR!
!protectfoo•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



LetLtxMacrooldfoofoo


LaTeX will essentially do



defoldfooprotectoldfoo•
letoldfoo•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



newcommandxyz[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




















  • 2





    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)

    – user11232
    Dec 23 '12 at 12:01







  • 2





    @HarishKumar If the macro is not risky, then LetLtxMacro does nothing different from let.

    – egreg
    Dec 23 '12 at 12:03






  • 2





    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








StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "85"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f88001%2fwhen-to-use-letltxmacro%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









64














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



DeclareRobustCommandfoo[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



deffooprotectfoo•
newcommandfoo•[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 #1else hmode@bgroup text@command #1ttfamily check@icl #1check@icr expandafter egroup fi


This shows precisely what's happening: texdef prints first the meaning of texttt, which is protecttexttt• (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



letoldfoofoo
renewcommandfoo[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).



fooBAR
!oldfooBAR!
!protectfoo•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 fooBAR 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



fooBAR
!oldfooBAR!
!protectfoo•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



LetLtxMacrooldfoofoo


LaTeX will essentially do



defoldfooprotectoldfoo•
letoldfoo•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



newcommandxyz[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




















  • 2





    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)

    – user11232
    Dec 23 '12 at 12:01







  • 2





    @HarishKumar If the macro is not risky, then LetLtxMacro does nothing different from let.

    – egreg
    Dec 23 '12 at 12:03






  • 2





    Thanks for the warning. I assume, I’m not the only one, who did not know this.

    – Speravir
    Dec 23 '12 at 19:17















64














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



DeclareRobustCommandfoo[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



deffooprotectfoo•
newcommandfoo•[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 #1else hmode@bgroup text@command #1ttfamily check@icl #1check@icr expandafter egroup fi


This shows precisely what's happening: texdef prints first the meaning of texttt, which is protecttexttt• (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



letoldfoofoo
renewcommandfoo[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).



fooBAR
!oldfooBAR!
!protectfoo•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 fooBAR 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



fooBAR
!oldfooBAR!
!protectfoo•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



LetLtxMacrooldfoofoo


LaTeX will essentially do



defoldfooprotectoldfoo•
letoldfoo•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



newcommandxyz[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




















  • 2





    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)

    – user11232
    Dec 23 '12 at 12:01







  • 2





    @HarishKumar If the macro is not risky, then LetLtxMacro does nothing different from let.

    – egreg
    Dec 23 '12 at 12:03






  • 2





    Thanks for the warning. I assume, I’m not the only one, who did not know this.

    – Speravir
    Dec 23 '12 at 19:17













64












64








64







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



DeclareRobustCommandfoo[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



deffooprotectfoo•
newcommandfoo•[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 #1else hmode@bgroup text@command #1ttfamily check@icl #1check@icr expandafter egroup fi


This shows precisely what's happening: texdef prints first the meaning of texttt, which is protecttexttt• (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



letoldfoofoo
renewcommandfoo[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).



fooBAR
!oldfooBAR!
!protectfoo•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 fooBAR 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



fooBAR
!oldfooBAR!
!protectfoo•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



LetLtxMacrooldfoofoo


LaTeX will essentially do



defoldfooprotectoldfoo•
letoldfoo•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



newcommandxyz[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















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



DeclareRobustCommandfoo[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



deffooprotectfoo•
newcommandfoo•[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 #1else hmode@bgroup text@command #1ttfamily check@icl #1check@icr expandafter egroup fi


This shows precisely what's happening: texdef prints first the meaning of texttt, which is protecttexttt• (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



letoldfoofoo
renewcommandfoo[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).



fooBAR
!oldfooBAR!
!protectfoo•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 fooBAR 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



fooBAR
!oldfooBAR!
!protectfoo•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



LetLtxMacrooldfoofoo


LaTeX will essentially do



defoldfooprotectoldfoo•
letoldfoo•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



newcommandxyz[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














share|improve this answer



share|improve this answer








edited Apr 13 '17 at 12:35









Community

1




1










answered Dec 23 '12 at 10:29









egregegreg

730k8819283242




730k8819283242







  • 2





    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)

    – user11232
    Dec 23 '12 at 12:01







  • 2





    @HarishKumar If the macro is not risky, then LetLtxMacro does nothing different from let.

    – egreg
    Dec 23 '12 at 12:03






  • 2





    Thanks for the warning. I assume, I’m not the only one, who did not know this.

    – Speravir
    Dec 23 '12 at 19:17












  • 2





    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)

    – user11232
    Dec 23 '12 at 12:01







  • 2





    @HarishKumar If the macro is not risky, then LetLtxMacro does nothing different from let.

    – egreg
    Dec 23 '12 at 12:03






  • 2





    Thanks for the warning. I assume, I’m not the only one, who did not know this.

    – Speravir
    Dec 23 '12 at 19:17







2




2





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)

– user11232
Dec 23 '12 at 12:01






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)

– user11232
Dec 23 '12 at 12:01





2




2





@HarishKumar If the macro is not risky, then LetLtxMacro does nothing different from let.

– egreg
Dec 23 '12 at 12:03





@HarishKumar If the macro is not risky, then LetLtxMacro does nothing different from let.

– egreg
Dec 23 '12 at 12:03




2




2





Thanks for the warning. I assume, I’m not the only one, who did not know this.

– Speravir
Dec 23 '12 at 19:17





Thanks for the warning. I assume, I’m not the only one, who did not know this.

– Speravir
Dec 23 '12 at 19:17

















draft saved

draft discarded
















































Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f88001%2fwhen-to-use-letltxmacro%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wikipedia:Contact us Navigation menu Navigation menuLeave a Reply Cancel reply Post navigationRecent PostsRecent CommentsArchivesCategoriesMeta

Farafra Inhaltsverzeichnis Geschichte | Badr-Museum Farafra | Nationalpark Weiße Wüste (as-Sahra al-baida) | Literatur | Weblinks | Navigationsmenü27° 3′ N, 27° 58′ OCommons: Farafra

Tórshavn Kliima | Partnerstääden | Luke uk diar | Nawigatsjuun62° 1′ N, 6° 46′ W62° 1′ 0″ N, 6° 46′ 0″ WWMOTórshavn