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
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
add a comment |
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
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 supportingxparse
definitions, nor does it contain the detail provided by his answer.
– Werner
Dec 26 '12 at 0:40
add a comment |
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
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
macros
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 supportingxparse
definitions, nor does it contain the detail provided by his answer.
– Werner
Dec 26 '12 at 0:40
add a comment |
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 supportingxparse
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
add a comment |
1 Answer
1
active
oldest
votes
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.
2
Say I don't want to take risks!. Can I useLetLtxMacro
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, thenLetLtxMacro
does nothing different fromlet
.
– 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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
2
Say I don't want to take risks!. Can I useLetLtxMacro
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, thenLetLtxMacro
does nothing different fromlet
.
– 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
add a comment |
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.
2
Say I don't want to take risks!. Can I useLetLtxMacro
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, thenLetLtxMacro
does nothing different fromlet
.
– 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
add a comment |
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.
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.
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 useLetLtxMacro
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, thenLetLtxMacro
does nothing different fromlet
.
– 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
add a comment |
2
Say I don't want to take risks!. Can I useLetLtxMacro
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, thenLetLtxMacro
does nothing different fromlet
.
– 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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