Condition “if within another command†in LaTeX
Clash Royale CLAN TAG#URR8PPP
up vote
8
down vote
favorite
I would like to define a LaTeX (!) command which would change its behavior if it occurs withing the scope of another command. Something like:
newcommandaaa[1]#1
newcommandbbb[1] IF WITHIN aaa >>> it #1
ELSE> bf #1
Sorry for the "code" but I have little idea where to start looking for it or how to formulate my question correctly.
For example,
bbbsometext
prints: sometext
while
aaabbbsometext
prints: sometext
What I was able to find is only a similar question from some years ago: Detecting if inside section. The answer was to use "modes" in ConTeXt which is impossible for me as I am restricted to LaTeX due to very specific packages I need.
macros
add a comment |Â
up vote
8
down vote
favorite
I would like to define a LaTeX (!) command which would change its behavior if it occurs withing the scope of another command. Something like:
newcommandaaa[1]#1
newcommandbbb[1] IF WITHIN aaa >>> it #1
ELSE> bf #1
Sorry for the "code" but I have little idea where to start looking for it or how to formulate my question correctly.
For example,
bbbsometext
prints: sometext
while
aaabbbsometext
prints: sometext
What I was able to find is only a similar question from some years ago: Detecting if inside section. The answer was to use "modes" in ConTeXt which is impossible for me as I am restricted to LaTeX due to very specific packages I need.
macros
1
Does it have to bebbb
detecting if it's withinaaa
? Couldaaa
locally redefinebbb
instead?
– Teepeemm
Aug 30 at 1:42
Thank you for your comment. The latter is also an option of course but I still do not know how it could be implemented.
– Wa Wo
Aug 30 at 1:46
This question has already got its answer, I’m wondering what is the typical use of this? Any example?
– Mithun
Aug 30 at 16:12
add a comment |Â
up vote
8
down vote
favorite
up vote
8
down vote
favorite
I would like to define a LaTeX (!) command which would change its behavior if it occurs withing the scope of another command. Something like:
newcommandaaa[1]#1
newcommandbbb[1] IF WITHIN aaa >>> it #1
ELSE> bf #1
Sorry for the "code" but I have little idea where to start looking for it or how to formulate my question correctly.
For example,
bbbsometext
prints: sometext
while
aaabbbsometext
prints: sometext
What I was able to find is only a similar question from some years ago: Detecting if inside section. The answer was to use "modes" in ConTeXt which is impossible for me as I am restricted to LaTeX due to very specific packages I need.
macros
I would like to define a LaTeX (!) command which would change its behavior if it occurs withing the scope of another command. Something like:
newcommandaaa[1]#1
newcommandbbb[1] IF WITHIN aaa >>> it #1
ELSE> bf #1
Sorry for the "code" but I have little idea where to start looking for it or how to formulate my question correctly.
For example,
bbbsometext
prints: sometext
while
aaabbbsometext
prints: sometext
What I was able to find is only a similar question from some years ago: Detecting if inside section. The answer was to use "modes" in ConTeXt which is impossible for me as I am restricted to LaTeX due to very specific packages I need.
macros
asked Aug 30 at 1:33


Wa Wo
434
434
1
Does it have to bebbb
detecting if it's withinaaa
? Couldaaa
locally redefinebbb
instead?
– Teepeemm
Aug 30 at 1:42
Thank you for your comment. The latter is also an option of course but I still do not know how it could be implemented.
– Wa Wo
Aug 30 at 1:46
This question has already got its answer, I’m wondering what is the typical use of this? Any example?
– Mithun
Aug 30 at 16:12
add a comment |Â
1
Does it have to bebbb
detecting if it's withinaaa
? Couldaaa
locally redefinebbb
instead?
– Teepeemm
Aug 30 at 1:42
Thank you for your comment. The latter is also an option of course but I still do not know how it could be implemented.
– Wa Wo
Aug 30 at 1:46
This question has already got its answer, I’m wondering what is the typical use of this? Any example?
– Mithun
Aug 30 at 16:12
1
1
Does it have to be
bbb
detecting if it's within aaa
? Could aaa
locally redefine bbb
instead?– Teepeemm
Aug 30 at 1:42
Does it have to be
bbb
detecting if it's within aaa
? Could aaa
locally redefine bbb
instead?– Teepeemm
Aug 30 at 1:42
Thank you for your comment. The latter is also an option of course but I still do not know how it could be implemented.
– Wa Wo
Aug 30 at 1:46
Thank you for your comment. The latter is also an option of course but I still do not know how it could be implemented.
– Wa Wo
Aug 30 at 1:46
This question has already got its answer, I’m wondering what is the typical use of this? Any example?
– Mithun
Aug 30 at 16:12
This question has already got its answer, I’m wondering what is the typical use of this? Any example?
– Mithun
Aug 30 at 16:12
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
8
down vote
accepted
EDITED to reflect helpful insight from Jonas that the original method (setting 0/1) could be spoofed with repeated invocations of bbb
inside of aaa
. Thus I converted over to an analogous counter approach, such that the counter value reflects the depth of nesting.
documentclassarticle
newcounterinaaa
newcommandaaa[1]stepcounterinaaa#1addtocounterinaaa-1
newcommandbbb[1]%
ifnumvalueinaaa=0textbf#1elserelaxtextit#1fi
begindocument
bbbsometext
aaabbbsometext text
aaaaaabbbfoobbbbar
enddocument
Thank you very much. It worked for me! (it was of course not about bold or italics)
– Wa Wo
Aug 30 at 1:58
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
1
aaaaaabbbfoobbbbar
gives foo bar instead of foo bar. The problem is that the inneraaa
“turns offâ€Âinaaa
when it ends, before the secondbbb
is evaluated.
– Jonas Granholm
Aug 31 at 6:51
1
A trick that should work is to increase and decreaseinaaa
instead of setting it to 1 and 0, so that it measures nesting level instead.
– Jonas Granholm
Aug 31 at 6:53
1
@JonasGranholm Thanks. I will adopt a counter approach.
– Steven B. Segletes
Aug 31 at 12:42
 |Â
show 1 more comment
up vote
9
down vote
You can use the newif
command to define a new (very low-level) conditional and commands that alter the conditional test:
documentclassarticle
newififinsideaaa
newcommandaaa[1]%
insideaaatrue
#1%
insideaaafalse
newcommandbbb[1]
ifinsideaaa
itshape #1%
else
bfseries #1%
fi
begindocument
bbbSome text outside of textttstringaaa
aaabbbSome text inside of textttstringaaa
enddocument
The new commands defined by newifif<foo>
are:
if<foo>
: the conditional check to be used withif<foo> ... else ... fi
,<foo>true
: the command that sets the condition to true, and<foo>false
: the command that sets the condition to false.
As a side note, you should use itshape
and bfseries
instead of it
and bf
in LaTeX. The latter are outdated.
Thank you very much for your explanation! it and bf are just examples. It's actually about other command which would just distract if mentioned.
– Wa Wo
Aug 30 at 2:00
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
add a comment |Â
up vote
4
down vote
I tend to avoid the TeX primitives if..
whenever avoiding them is possible.
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA#1%
My@SetInAAATrue#1My@SetInAAAFalse%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
With this approach, the tokens forming the argument of aaa
get doubled and gobbled.
This can be avoided by defining another helper-macro:
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
newcommandMy@SetAAAconditions[1]My@SetInAAATrue#1My@SetInAAAFalse%
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA@firstofone%
My@SetAAAconditions%
#1%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
global
,makeatletter
,makeatother
,@firstoftwo
, and@secondoftwo
seems like a lot of machinery to avoid a tex primitive. And shouldMy@SetInaFalse
beMy@SetInAAAFalse
?
– Teepeemm
Aug 30 at 22:09
@JonasGranholm Thanks for editing.
– Ulrich Diez
Aug 31 at 0:09
1
@Teepeemm Indeed, should beMy@SetInAAAFalse
. I avoid things likeif...#1...else...fi
because providing unbalancedif
/else
/fi
as components of arguments might cause problems... As a rule of thumb macros get a little more "user-proof" by avoiding putting an argument (where you don't know what tokens the user will provide) somewhere betweenif..else..fi
. When I use them, I often doif..expandafter@firstoftwoelseexpandafter@secondoftwofi<true-case-stuff with macro arguments>false-case-stuff with macro arguments>
– Ulrich Diez
Aug 31 at 0:21
add a comment |Â
up vote
4
down vote
Siracusa's answer may fail if aaa
is used within itself, as in the following example:
aaa
aaabbbfoo
bbbbar
This will give foo bar instead of foo bar.
Ulrich's and the accepted answer do not have this weakness and are good solutions, especially if you want to define both versions of bbb
at the same time.
A quicker and simpler way that also behaves as expected in the example above is to let aaa
redefine bbb
locally, as Teepeemm commented:
newcommandbbb[1]textbf#1
newcommandaaa[1]bgroupdefbbb##1textit##1#1egroup
The double ##
in the second line is needed because it is a definition inside another definition.
(This method is by the way also useful if bbb
should only be defined inside aaa
– just remove the first line.)
It looks like you can also take Ulrich's of delaying#1
and saynewcommandbbbtextbf
. It looks like that lets you avoid##1
entirely.
– Teepeemm
Aug 30 at 22:06
Indeed. I included the full form since OP mentioned replacing the command with something more complicated. Another way to avoid##1
is to addnewcommandbbbinaaa[1]textit#1
and usenewcommandaaa[1]bgroupletbbbbbbinaaa#1egroup
instead.
– Jonas Granholm
Aug 30 at 22:29
@JonasGranholm Defining both versions ofbbb
at the same time is recommendable only in case there are more macros whereinbbb
shall work in the same way in which it shall work withinaaa
.
– Ulrich Diez
Aug 31 at 0:43
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
EDITED to reflect helpful insight from Jonas that the original method (setting 0/1) could be spoofed with repeated invocations of bbb
inside of aaa
. Thus I converted over to an analogous counter approach, such that the counter value reflects the depth of nesting.
documentclassarticle
newcounterinaaa
newcommandaaa[1]stepcounterinaaa#1addtocounterinaaa-1
newcommandbbb[1]%
ifnumvalueinaaa=0textbf#1elserelaxtextit#1fi
begindocument
bbbsometext
aaabbbsometext text
aaaaaabbbfoobbbbar
enddocument
Thank you very much. It worked for me! (it was of course not about bold or italics)
– Wa Wo
Aug 30 at 1:58
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
1
aaaaaabbbfoobbbbar
gives foo bar instead of foo bar. The problem is that the inneraaa
“turns offâ€Âinaaa
when it ends, before the secondbbb
is evaluated.
– Jonas Granholm
Aug 31 at 6:51
1
A trick that should work is to increase and decreaseinaaa
instead of setting it to 1 and 0, so that it measures nesting level instead.
– Jonas Granholm
Aug 31 at 6:53
1
@JonasGranholm Thanks. I will adopt a counter approach.
– Steven B. Segletes
Aug 31 at 12:42
 |Â
show 1 more comment
up vote
8
down vote
accepted
EDITED to reflect helpful insight from Jonas that the original method (setting 0/1) could be spoofed with repeated invocations of bbb
inside of aaa
. Thus I converted over to an analogous counter approach, such that the counter value reflects the depth of nesting.
documentclassarticle
newcounterinaaa
newcommandaaa[1]stepcounterinaaa#1addtocounterinaaa-1
newcommandbbb[1]%
ifnumvalueinaaa=0textbf#1elserelaxtextit#1fi
begindocument
bbbsometext
aaabbbsometext text
aaaaaabbbfoobbbbar
enddocument
Thank you very much. It worked for me! (it was of course not about bold or italics)
– Wa Wo
Aug 30 at 1:58
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
1
aaaaaabbbfoobbbbar
gives foo bar instead of foo bar. The problem is that the inneraaa
“turns offâ€Âinaaa
when it ends, before the secondbbb
is evaluated.
– Jonas Granholm
Aug 31 at 6:51
1
A trick that should work is to increase and decreaseinaaa
instead of setting it to 1 and 0, so that it measures nesting level instead.
– Jonas Granholm
Aug 31 at 6:53
1
@JonasGranholm Thanks. I will adopt a counter approach.
– Steven B. Segletes
Aug 31 at 12:42
 |Â
show 1 more comment
up vote
8
down vote
accepted
up vote
8
down vote
accepted
EDITED to reflect helpful insight from Jonas that the original method (setting 0/1) could be spoofed with repeated invocations of bbb
inside of aaa
. Thus I converted over to an analogous counter approach, such that the counter value reflects the depth of nesting.
documentclassarticle
newcounterinaaa
newcommandaaa[1]stepcounterinaaa#1addtocounterinaaa-1
newcommandbbb[1]%
ifnumvalueinaaa=0textbf#1elserelaxtextit#1fi
begindocument
bbbsometext
aaabbbsometext text
aaaaaabbbfoobbbbar
enddocument
EDITED to reflect helpful insight from Jonas that the original method (setting 0/1) could be spoofed with repeated invocations of bbb
inside of aaa
. Thus I converted over to an analogous counter approach, such that the counter value reflects the depth of nesting.
documentclassarticle
newcounterinaaa
newcommandaaa[1]stepcounterinaaa#1addtocounterinaaa-1
newcommandbbb[1]%
ifnumvalueinaaa=0textbf#1elserelaxtextit#1fi
begindocument
bbbsometext
aaabbbsometext text
aaaaaabbbfoobbbbar
enddocument
edited Aug 31 at 12:59
answered Aug 30 at 1:44


Steven B. Segletes
146k9185387
146k9185387
Thank you very much. It worked for me! (it was of course not about bold or italics)
– Wa Wo
Aug 30 at 1:58
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
1
aaaaaabbbfoobbbbar
gives foo bar instead of foo bar. The problem is that the inneraaa
“turns offâ€Âinaaa
when it ends, before the secondbbb
is evaluated.
– Jonas Granholm
Aug 31 at 6:51
1
A trick that should work is to increase and decreaseinaaa
instead of setting it to 1 and 0, so that it measures nesting level instead.
– Jonas Granholm
Aug 31 at 6:53
1
@JonasGranholm Thanks. I will adopt a counter approach.
– Steven B. Segletes
Aug 31 at 12:42
 |Â
show 1 more comment
Thank you very much. It worked for me! (it was of course not about bold or italics)
– Wa Wo
Aug 30 at 1:58
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
1
aaaaaabbbfoobbbbar
gives foo bar instead of foo bar. The problem is that the inneraaa
“turns offâ€Âinaaa
when it ends, before the secondbbb
is evaluated.
– Jonas Granholm
Aug 31 at 6:51
1
A trick that should work is to increase and decreaseinaaa
instead of setting it to 1 and 0, so that it measures nesting level instead.
– Jonas Granholm
Aug 31 at 6:53
1
@JonasGranholm Thanks. I will adopt a counter approach.
– Steven B. Segletes
Aug 31 at 12:42
Thank you very much. It worked for me! (it was of course not about bold or italics)
– Wa Wo
Aug 30 at 1:58
Thank you very much. It worked for me! (it was of course not about bold or italics)
– Wa Wo
Aug 30 at 1:58
1
1
This solution may fail if
aaa
is used within itself, see this answer.– Jonas Granholm
Aug 30 at 21:58
This solution may fail if
aaa
is used within itself, see this answer.– Jonas Granholm
Aug 30 at 21:58
1
1
aaaaaabbbfoobbbbar
gives foo bar instead of foo bar. The problem is that the inner aaa
“turns off†inaaa
when it ends, before the second bbb
is evaluated.– Jonas Granholm
Aug 31 at 6:51
aaaaaabbbfoobbbbar
gives foo bar instead of foo bar. The problem is that the inner aaa
“turns off†inaaa
when it ends, before the second bbb
is evaluated.– Jonas Granholm
Aug 31 at 6:51
1
1
A trick that should work is to increase and decrease
inaaa
instead of setting it to 1 and 0, so that it measures nesting level instead.– Jonas Granholm
Aug 31 at 6:53
A trick that should work is to increase and decrease
inaaa
instead of setting it to 1 and 0, so that it measures nesting level instead.– Jonas Granholm
Aug 31 at 6:53
1
1
@JonasGranholm Thanks. I will adopt a counter approach.
– Steven B. Segletes
Aug 31 at 12:42
@JonasGranholm Thanks. I will adopt a counter approach.
– Steven B. Segletes
Aug 31 at 12:42
 |Â
show 1 more comment
up vote
9
down vote
You can use the newif
command to define a new (very low-level) conditional and commands that alter the conditional test:
documentclassarticle
newififinsideaaa
newcommandaaa[1]%
insideaaatrue
#1%
insideaaafalse
newcommandbbb[1]
ifinsideaaa
itshape #1%
else
bfseries #1%
fi
begindocument
bbbSome text outside of textttstringaaa
aaabbbSome text inside of textttstringaaa
enddocument
The new commands defined by newifif<foo>
are:
if<foo>
: the conditional check to be used withif<foo> ... else ... fi
,<foo>true
: the command that sets the condition to true, and<foo>false
: the command that sets the condition to false.
As a side note, you should use itshape
and bfseries
instead of it
and bf
in LaTeX. The latter are outdated.
Thank you very much for your explanation! it and bf are just examples. It's actually about other command which would just distract if mentioned.
– Wa Wo
Aug 30 at 2:00
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
add a comment |Â
up vote
9
down vote
You can use the newif
command to define a new (very low-level) conditional and commands that alter the conditional test:
documentclassarticle
newififinsideaaa
newcommandaaa[1]%
insideaaatrue
#1%
insideaaafalse
newcommandbbb[1]
ifinsideaaa
itshape #1%
else
bfseries #1%
fi
begindocument
bbbSome text outside of textttstringaaa
aaabbbSome text inside of textttstringaaa
enddocument
The new commands defined by newifif<foo>
are:
if<foo>
: the conditional check to be used withif<foo> ... else ... fi
,<foo>true
: the command that sets the condition to true, and<foo>false
: the command that sets the condition to false.
As a side note, you should use itshape
and bfseries
instead of it
and bf
in LaTeX. The latter are outdated.
Thank you very much for your explanation! it and bf are just examples. It's actually about other command which would just distract if mentioned.
– Wa Wo
Aug 30 at 2:00
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
add a comment |Â
up vote
9
down vote
up vote
9
down vote
You can use the newif
command to define a new (very low-level) conditional and commands that alter the conditional test:
documentclassarticle
newififinsideaaa
newcommandaaa[1]%
insideaaatrue
#1%
insideaaafalse
newcommandbbb[1]
ifinsideaaa
itshape #1%
else
bfseries #1%
fi
begindocument
bbbSome text outside of textttstringaaa
aaabbbSome text inside of textttstringaaa
enddocument
The new commands defined by newifif<foo>
are:
if<foo>
: the conditional check to be used withif<foo> ... else ... fi
,<foo>true
: the command that sets the condition to true, and<foo>false
: the command that sets the condition to false.
As a side note, you should use itshape
and bfseries
instead of it
and bf
in LaTeX. The latter are outdated.
You can use the newif
command to define a new (very low-level) conditional and commands that alter the conditional test:
documentclassarticle
newififinsideaaa
newcommandaaa[1]%
insideaaatrue
#1%
insideaaafalse
newcommandbbb[1]
ifinsideaaa
itshape #1%
else
bfseries #1%
fi
begindocument
bbbSome text outside of textttstringaaa
aaabbbSome text inside of textttstringaaa
enddocument
The new commands defined by newifif<foo>
are:
if<foo>
: the conditional check to be used withif<foo> ... else ... fi
,<foo>true
: the command that sets the condition to true, and<foo>false
: the command that sets the condition to false.
As a side note, you should use itshape
and bfseries
instead of it
and bf
in LaTeX. The latter are outdated.
edited Aug 30 at 1:58
answered Aug 30 at 1:48
siracusa
3,4471926
3,4471926
Thank you very much for your explanation! it and bf are just examples. It's actually about other command which would just distract if mentioned.
– Wa Wo
Aug 30 at 2:00
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
add a comment |Â
Thank you very much for your explanation! it and bf are just examples. It's actually about other command which would just distract if mentioned.
– Wa Wo
Aug 30 at 2:00
1
This solution may fail ifaaa
is used within itself, see this answer.
– Jonas Granholm
Aug 30 at 21:58
Thank you very much for your explanation! it and bf are just examples. It's actually about other command which would just distract if mentioned.
– Wa Wo
Aug 30 at 2:00
Thank you very much for your explanation! it and bf are just examples. It's actually about other command which would just distract if mentioned.
– Wa Wo
Aug 30 at 2:00
1
1
This solution may fail if
aaa
is used within itself, see this answer.– Jonas Granholm
Aug 30 at 21:58
This solution may fail if
aaa
is used within itself, see this answer.– Jonas Granholm
Aug 30 at 21:58
add a comment |Â
up vote
4
down vote
I tend to avoid the TeX primitives if..
whenever avoiding them is possible.
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA#1%
My@SetInAAATrue#1My@SetInAAAFalse%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
With this approach, the tokens forming the argument of aaa
get doubled and gobbled.
This can be avoided by defining another helper-macro:
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
newcommandMy@SetAAAconditions[1]My@SetInAAATrue#1My@SetInAAAFalse%
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA@firstofone%
My@SetAAAconditions%
#1%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
global
,makeatletter
,makeatother
,@firstoftwo
, and@secondoftwo
seems like a lot of machinery to avoid a tex primitive. And shouldMy@SetInaFalse
beMy@SetInAAAFalse
?
– Teepeemm
Aug 30 at 22:09
@JonasGranholm Thanks for editing.
– Ulrich Diez
Aug 31 at 0:09
1
@Teepeemm Indeed, should beMy@SetInAAAFalse
. I avoid things likeif...#1...else...fi
because providing unbalancedif
/else
/fi
as components of arguments might cause problems... As a rule of thumb macros get a little more "user-proof" by avoiding putting an argument (where you don't know what tokens the user will provide) somewhere betweenif..else..fi
. When I use them, I often doif..expandafter@firstoftwoelseexpandafter@secondoftwofi<true-case-stuff with macro arguments>false-case-stuff with macro arguments>
– Ulrich Diez
Aug 31 at 0:21
add a comment |Â
up vote
4
down vote
I tend to avoid the TeX primitives if..
whenever avoiding them is possible.
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA#1%
My@SetInAAATrue#1My@SetInAAAFalse%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
With this approach, the tokens forming the argument of aaa
get doubled and gobbled.
This can be avoided by defining another helper-macro:
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
newcommandMy@SetAAAconditions[1]My@SetInAAATrue#1My@SetInAAAFalse%
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA@firstofone%
My@SetAAAconditions%
#1%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
global
,makeatletter
,makeatother
,@firstoftwo
, and@secondoftwo
seems like a lot of machinery to avoid a tex primitive. And shouldMy@SetInaFalse
beMy@SetInAAAFalse
?
– Teepeemm
Aug 30 at 22:09
@JonasGranholm Thanks for editing.
– Ulrich Diez
Aug 31 at 0:09
1
@Teepeemm Indeed, should beMy@SetInAAAFalse
. I avoid things likeif...#1...else...fi
because providing unbalancedif
/else
/fi
as components of arguments might cause problems... As a rule of thumb macros get a little more "user-proof" by avoiding putting an argument (where you don't know what tokens the user will provide) somewhere betweenif..else..fi
. When I use them, I often doif..expandafter@firstoftwoelseexpandafter@secondoftwofi<true-case-stuff with macro arguments>false-case-stuff with macro arguments>
– Ulrich Diez
Aug 31 at 0:21
add a comment |Â
up vote
4
down vote
up vote
4
down vote
I tend to avoid the TeX primitives if..
whenever avoiding them is possible.
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA#1%
My@SetInAAATrue#1My@SetInAAAFalse%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
With this approach, the tokens forming the argument of aaa
get doubled and gobbled.
This can be avoided by defining another helper-macro:
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
newcommandMy@SetAAAconditions[1]My@SetInAAATrue#1My@SetInAAAFalse%
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA@firstofone%
My@SetAAAconditions%
#1%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
I tend to avoid the TeX primitives if..
whenever avoiding them is possible.
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA#1%
My@SetInAAATrue#1My@SetInAAAFalse%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
With this approach, the tokens forming the argument of aaa
get doubled and gobbled.
This can be avoided by defining another helper-macro:
documentclassarticle
makeatletter
newcommandMy@CheckWhetherinAAA
newcommandMy@SetInAAATrueletMy@CheckWhetherinAAA=@firstoftwo
newcommandMy@SetInAAAFalseletMy@CheckWhetherinAAA=@secondoftwo
newcommandMy@SetAAAconditions[1]My@SetInAAATrue#1My@SetInAAAFalse%
globalMy@SetInAAAFalse
newcommandaaa[1]%
My@CheckWhetherinAAA@firstofone%
My@SetAAAconditions%
#1%
%
newcommandbbb[1]%
My@CheckWhetherinAAAtextit%
textbf%
#1%
%
% The result of the following is the same but LaTeX has to shuffle
% around more tokens:
%
% newcommandbbb[1]%
% My@CheckWhetherinAAAtextit#1%
% textbf#1%
% %
%
makeatother
begindocument
bbbsome text
aaabbbsome text
aaaaaabbbsome text aaabbbsome more text
begingroup aaaaaabbbsome text endgroupaaabbbsome more text
bbbsome text
enddocument
edited Aug 31 at 0:35
answered Aug 30 at 10:27
Ulrich Diez
3,250414
3,250414
global
,makeatletter
,makeatother
,@firstoftwo
, and@secondoftwo
seems like a lot of machinery to avoid a tex primitive. And shouldMy@SetInaFalse
beMy@SetInAAAFalse
?
– Teepeemm
Aug 30 at 22:09
@JonasGranholm Thanks for editing.
– Ulrich Diez
Aug 31 at 0:09
1
@Teepeemm Indeed, should beMy@SetInAAAFalse
. I avoid things likeif...#1...else...fi
because providing unbalancedif
/else
/fi
as components of arguments might cause problems... As a rule of thumb macros get a little more "user-proof" by avoiding putting an argument (where you don't know what tokens the user will provide) somewhere betweenif..else..fi
. When I use them, I often doif..expandafter@firstoftwoelseexpandafter@secondoftwofi<true-case-stuff with macro arguments>false-case-stuff with macro arguments>
– Ulrich Diez
Aug 31 at 0:21
add a comment |Â
global
,makeatletter
,makeatother
,@firstoftwo
, and@secondoftwo
seems like a lot of machinery to avoid a tex primitive. And shouldMy@SetInaFalse
beMy@SetInAAAFalse
?
– Teepeemm
Aug 30 at 22:09
@JonasGranholm Thanks for editing.
– Ulrich Diez
Aug 31 at 0:09
1
@Teepeemm Indeed, should beMy@SetInAAAFalse
. I avoid things likeif...#1...else...fi
because providing unbalancedif
/else
/fi
as components of arguments might cause problems... As a rule of thumb macros get a little more "user-proof" by avoiding putting an argument (where you don't know what tokens the user will provide) somewhere betweenif..else..fi
. When I use them, I often doif..expandafter@firstoftwoelseexpandafter@secondoftwofi<true-case-stuff with macro arguments>false-case-stuff with macro arguments>
– Ulrich Diez
Aug 31 at 0:21
global
, makeatletter
, makeatother
, @firstoftwo
, and @secondoftwo
seems like a lot of machinery to avoid a tex primitive. And should My@SetInaFalse
be My@SetInAAAFalse
?– Teepeemm
Aug 30 at 22:09
global
, makeatletter
, makeatother
, @firstoftwo
, and @secondoftwo
seems like a lot of machinery to avoid a tex primitive. And should My@SetInaFalse
be My@SetInAAAFalse
?– Teepeemm
Aug 30 at 22:09
@JonasGranholm Thanks for editing.
– Ulrich Diez
Aug 31 at 0:09
@JonasGranholm Thanks for editing.
– Ulrich Diez
Aug 31 at 0:09
1
1
@Teepeemm Indeed, should be
My@SetInAAAFalse
. I avoid things like if...#1...else...fi
because providing unbalanced if
/else
/fi
as components of arguments might cause problems... As a rule of thumb macros get a little more "user-proof" by avoiding putting an argument (where you don't know what tokens the user will provide) somewhere between if..else..fi
. When I use them, I often do if..expandafter@firstoftwoelseexpandafter@secondoftwofi<true-case-stuff with macro arguments>false-case-stuff with macro arguments>
– Ulrich Diez
Aug 31 at 0:21
@Teepeemm Indeed, should be
My@SetInAAAFalse
. I avoid things like if...#1...else...fi
because providing unbalanced if
/else
/fi
as components of arguments might cause problems... As a rule of thumb macros get a little more "user-proof" by avoiding putting an argument (where you don't know what tokens the user will provide) somewhere between if..else..fi
. When I use them, I often do if..expandafter@firstoftwoelseexpandafter@secondoftwofi<true-case-stuff with macro arguments>false-case-stuff with macro arguments>
– Ulrich Diez
Aug 31 at 0:21
add a comment |Â
up vote
4
down vote
Siracusa's answer may fail if aaa
is used within itself, as in the following example:
aaa
aaabbbfoo
bbbbar
This will give foo bar instead of foo bar.
Ulrich's and the accepted answer do not have this weakness and are good solutions, especially if you want to define both versions of bbb
at the same time.
A quicker and simpler way that also behaves as expected in the example above is to let aaa
redefine bbb
locally, as Teepeemm commented:
newcommandbbb[1]textbf#1
newcommandaaa[1]bgroupdefbbb##1textit##1#1egroup
The double ##
in the second line is needed because it is a definition inside another definition.
(This method is by the way also useful if bbb
should only be defined inside aaa
– just remove the first line.)
It looks like you can also take Ulrich's of delaying#1
and saynewcommandbbbtextbf
. It looks like that lets you avoid##1
entirely.
– Teepeemm
Aug 30 at 22:06
Indeed. I included the full form since OP mentioned replacing the command with something more complicated. Another way to avoid##1
is to addnewcommandbbbinaaa[1]textit#1
and usenewcommandaaa[1]bgroupletbbbbbbinaaa#1egroup
instead.
– Jonas Granholm
Aug 30 at 22:29
@JonasGranholm Defining both versions ofbbb
at the same time is recommendable only in case there are more macros whereinbbb
shall work in the same way in which it shall work withinaaa
.
– Ulrich Diez
Aug 31 at 0:43
add a comment |Â
up vote
4
down vote
Siracusa's answer may fail if aaa
is used within itself, as in the following example:
aaa
aaabbbfoo
bbbbar
This will give foo bar instead of foo bar.
Ulrich's and the accepted answer do not have this weakness and are good solutions, especially if you want to define both versions of bbb
at the same time.
A quicker and simpler way that also behaves as expected in the example above is to let aaa
redefine bbb
locally, as Teepeemm commented:
newcommandbbb[1]textbf#1
newcommandaaa[1]bgroupdefbbb##1textit##1#1egroup
The double ##
in the second line is needed because it is a definition inside another definition.
(This method is by the way also useful if bbb
should only be defined inside aaa
– just remove the first line.)
It looks like you can also take Ulrich's of delaying#1
and saynewcommandbbbtextbf
. It looks like that lets you avoid##1
entirely.
– Teepeemm
Aug 30 at 22:06
Indeed. I included the full form since OP mentioned replacing the command with something more complicated. Another way to avoid##1
is to addnewcommandbbbinaaa[1]textit#1
and usenewcommandaaa[1]bgroupletbbbbbbinaaa#1egroup
instead.
– Jonas Granholm
Aug 30 at 22:29
@JonasGranholm Defining both versions ofbbb
at the same time is recommendable only in case there are more macros whereinbbb
shall work in the same way in which it shall work withinaaa
.
– Ulrich Diez
Aug 31 at 0:43
add a comment |Â
up vote
4
down vote
up vote
4
down vote
Siracusa's answer may fail if aaa
is used within itself, as in the following example:
aaa
aaabbbfoo
bbbbar
This will give foo bar instead of foo bar.
Ulrich's and the accepted answer do not have this weakness and are good solutions, especially if you want to define both versions of bbb
at the same time.
A quicker and simpler way that also behaves as expected in the example above is to let aaa
redefine bbb
locally, as Teepeemm commented:
newcommandbbb[1]textbf#1
newcommandaaa[1]bgroupdefbbb##1textit##1#1egroup
The double ##
in the second line is needed because it is a definition inside another definition.
(This method is by the way also useful if bbb
should only be defined inside aaa
– just remove the first line.)
Siracusa's answer may fail if aaa
is used within itself, as in the following example:
aaa
aaabbbfoo
bbbbar
This will give foo bar instead of foo bar.
Ulrich's and the accepted answer do not have this weakness and are good solutions, especially if you want to define both versions of bbb
at the same time.
A quicker and simpler way that also behaves as expected in the example above is to let aaa
redefine bbb
locally, as Teepeemm commented:
newcommandbbb[1]textbf#1
newcommandaaa[1]bgroupdefbbb##1textit##1#1egroup
The double ##
in the second line is needed because it is a definition inside another definition.
(This method is by the way also useful if bbb
should only be defined inside aaa
– just remove the first line.)
edited Aug 31 at 15:22
answered Aug 30 at 21:53


Jonas Granholm
1,328710
1,328710
It looks like you can also take Ulrich's of delaying#1
and saynewcommandbbbtextbf
. It looks like that lets you avoid##1
entirely.
– Teepeemm
Aug 30 at 22:06
Indeed. I included the full form since OP mentioned replacing the command with something more complicated. Another way to avoid##1
is to addnewcommandbbbinaaa[1]textit#1
and usenewcommandaaa[1]bgroupletbbbbbbinaaa#1egroup
instead.
– Jonas Granholm
Aug 30 at 22:29
@JonasGranholm Defining both versions ofbbb
at the same time is recommendable only in case there are more macros whereinbbb
shall work in the same way in which it shall work withinaaa
.
– Ulrich Diez
Aug 31 at 0:43
add a comment |Â
It looks like you can also take Ulrich's of delaying#1
and saynewcommandbbbtextbf
. It looks like that lets you avoid##1
entirely.
– Teepeemm
Aug 30 at 22:06
Indeed. I included the full form since OP mentioned replacing the command with something more complicated. Another way to avoid##1
is to addnewcommandbbbinaaa[1]textit#1
and usenewcommandaaa[1]bgroupletbbbbbbinaaa#1egroup
instead.
– Jonas Granholm
Aug 30 at 22:29
@JonasGranholm Defining both versions ofbbb
at the same time is recommendable only in case there are more macros whereinbbb
shall work in the same way in which it shall work withinaaa
.
– Ulrich Diez
Aug 31 at 0:43
It looks like you can also take Ulrich's of delaying
#1
and say newcommandbbbtextbf
. It looks like that lets you avoid ##1
entirely.– Teepeemm
Aug 30 at 22:06
It looks like you can also take Ulrich's of delaying
#1
and say newcommandbbbtextbf
. It looks like that lets you avoid ##1
entirely.– Teepeemm
Aug 30 at 22:06
Indeed. I included the full form since OP mentioned replacing the command with something more complicated. Another way to avoid
##1
is to add newcommandbbbinaaa[1]textit#1
and use newcommandaaa[1]bgroupletbbbbbbinaaa#1egroup
instead.– Jonas Granholm
Aug 30 at 22:29
Indeed. I included the full form since OP mentioned replacing the command with something more complicated. Another way to avoid
##1
is to add newcommandbbbinaaa[1]textit#1
and use newcommandaaa[1]bgroupletbbbbbbinaaa#1egroup
instead.– Jonas Granholm
Aug 30 at 22:29
@JonasGranholm Defining both versions of
bbb
at the same time is recommendable only in case there are more macros wherein bbb
shall work in the same way in which it shall work within aaa
.– Ulrich Diez
Aug 31 at 0:43
@JonasGranholm Defining both versions of
bbb
at the same time is recommendable only in case there are more macros wherein bbb
shall work in the same way in which it shall work within aaa
.– Ulrich Diez
Aug 31 at 0:43
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f448430%2fcondition-if-within-another-command-in-latex%23new-answer', 'question_page');
);
Post as a guest
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
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
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
1
Does it have to be
bbb
detecting if it's withinaaa
? Couldaaa
locally redefinebbb
instead?– Teepeemm
Aug 30 at 1:42
Thank you for your comment. The latter is also an option of course but I still do not know how it could be implemented.
– Wa Wo
Aug 30 at 1:46
This question has already got its answer, I’m wondering what is the typical use of this? Any example?
– Mithun
Aug 30 at 16:12