Condition “if within another command” in LaTeX

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite
5












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.







share|improve this question
















  • 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










  • 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














up vote
8
down vote

favorite
5












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.







share|improve this question
















  • 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










  • 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












up vote
8
down vote

favorite
5









up vote
8
down vote

favorite
5






5





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.







share|improve this question












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.









share|improve this question











share|improve this question




share|improve this question










asked Aug 30 at 1:33









Wa Wo

434




434







  • 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










  • 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




    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










  • 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










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


enter image description here






share|improve this answer






















  • 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 if aaa 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 inner aaa “turns off” inaaa when it ends, before the second bbb is evaluated.
    – Jonas Granholm
    Aug 31 at 6:51






  • 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






  • 1




    @JonasGranholm Thanks. I will adopt a counter approach.
    – Steven B. Segletes
    Aug 31 at 12:42

















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


enter image description here



The new commands defined by newifif<foo> are:




  • if<foo>: the conditional check to be used with if<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.






share|improve this answer






















  • 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 if aaa is used within itself, see this answer.
    – Jonas Granholm
    Aug 30 at 21:58

















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





share|improve this answer






















  • 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






  • 1




    @Teepeemm Indeed, should be My@SetInAAAFalse. I avoid things like if...#1...else...fi because providing unbalanced if/else/fias 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

















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.)






share|improve this answer






















  • 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











  • @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










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',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
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%2f448430%2fcondition-if-within-another-command-in-latex%23new-answer', 'question_page');

);

Post as a guest






























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


enter image description here






share|improve this answer






















  • 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 if aaa 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 inner aaa “turns off” inaaa when it ends, before the second bbb is evaluated.
    – Jonas Granholm
    Aug 31 at 6:51






  • 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






  • 1




    @JonasGranholm Thanks. I will adopt a counter approach.
    – Steven B. Segletes
    Aug 31 at 12:42














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


enter image description here






share|improve this answer






















  • 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 if aaa 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 inner aaa “turns off” inaaa when it ends, before the second bbb is evaluated.
    – Jonas Granholm
    Aug 31 at 6:51






  • 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






  • 1




    @JonasGranholm Thanks. I will adopt a counter approach.
    – Steven B. Segletes
    Aug 31 at 12:42












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


enter image description here






share|improve this answer














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


enter image description here







share|improve this answer














share|improve this answer



share|improve this answer








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 if aaa 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 inner aaa “turns off” inaaa when it ends, before the second bbb is evaluated.
    – Jonas Granholm
    Aug 31 at 6:51






  • 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






  • 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






  • 1




    This solution may fail if aaa 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 inner aaa “turns off” inaaa when it ends, before the second bbb is evaluated.
    – Jonas Granholm
    Aug 31 at 6:51






  • 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






  • 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










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


enter image description here



The new commands defined by newifif<foo> are:




  • if<foo>: the conditional check to be used with if<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.






share|improve this answer






















  • 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 if aaa is used within itself, see this answer.
    – Jonas Granholm
    Aug 30 at 21:58














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


enter image description here



The new commands defined by newifif<foo> are:




  • if<foo>: the conditional check to be used with if<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.






share|improve this answer






















  • 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 if aaa is used within itself, see this answer.
    – Jonas Granholm
    Aug 30 at 21:58












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


enter image description here



The new commands defined by newifif<foo> are:




  • if<foo>: the conditional check to be used with if<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.






share|improve this answer














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


enter image description here



The new commands defined by newifif<foo> are:




  • if<foo>: the conditional check to be used with if<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.







share|improve this answer














share|improve this answer



share|improve this answer








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 if aaa 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







  • 1




    This solution may fail if aaa 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










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





share|improve this answer






















  • 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






  • 1




    @Teepeemm Indeed, should be My@SetInAAAFalse. I avoid things like if...#1...else...fi because providing unbalanced if/else/fias 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














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





share|improve this answer






















  • 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






  • 1




    @Teepeemm Indeed, should be My@SetInAAAFalse. I avoid things like if...#1...else...fi because providing unbalanced if/else/fias 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












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





share|improve this answer














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






share|improve this answer














share|improve this answer



share|improve this answer








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 should My@SetInaFalse be My@SetInAAAFalse?
    – Teepeemm
    Aug 30 at 22:09










  • @JonasGranholm Thanks for editing.
    – Ulrich Diez
    Aug 31 at 0:09






  • 1




    @Teepeemm Indeed, should be My@SetInAAAFalse. I avoid things like if...#1...else...fi because providing unbalanced if/else/fias 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
















  • 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






  • 1




    @Teepeemm Indeed, should be My@SetInAAAFalse. I avoid things like if...#1...else...fi because providing unbalanced if/else/fias 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















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/fias 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/fias 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










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.)






share|improve this answer






















  • 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











  • @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














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.)






share|improve this answer






















  • 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











  • @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












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.)






share|improve this answer














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.)







share|improve this answer














share|improve this answer



share|improve this answer








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











  • @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
















  • 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











  • @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















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

















 

draft saved


draft discarded















































 


draft saved


draft discarded














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













































































Comments

Popular posts from this blog

What does second last employer means? [closed]

List of Gilmore Girls characters

Confectionery