How to make a command with default if missing

Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
I want to make a command that has as inputs $X,t$ and outputs
E[X_t] if t is given and outputs
E[X]
if t is missing.
So far
If I don't have the condition on t then
newcommande[1]E[#1]
works, but otherwise... I'm stumpted.
macros
add a comment |Â
up vote
6
down vote
favorite
I want to make a command that has as inputs $X,t$ and outputs
E[X_t] if t is given and outputs
E[X]
if t is missing.
So far
If I don't have the condition on t then
newcommande[1]E[#1]
works, but otherwise... I'm stumpted.
macros
Maybe tex.stackexchange.com/questions/217757/⦠will help. I searched in Google for: "latex detect default argument"
â albert
Sep 8 at 15:00
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I want to make a command that has as inputs $X,t$ and outputs
E[X_t] if t is given and outputs
E[X]
if t is missing.
So far
If I don't have the condition on t then
newcommande[1]E[#1]
works, but otherwise... I'm stumpted.
macros
I want to make a command that has as inputs $X,t$ and outputs
E[X_t] if t is given and outputs
E[X]
if t is missing.
So far
If I don't have the condition on t then
newcommande[1]E[#1]
works, but otherwise... I'm stumpted.
macros
asked Sep 8 at 14:53
AIM_BLB
1824
1824
Maybe tex.stackexchange.com/questions/217757/⦠will help. I searched in Google for: "latex detect default argument"
â albert
Sep 8 at 15:00
add a comment |Â
Maybe tex.stackexchange.com/questions/217757/⦠will help. I searched in Google for: "latex detect default argument"
â albert
Sep 8 at 15:00
Maybe tex.stackexchange.com/questions/217757/⦠will help. I searched in Google for: "latex detect default argument"
â albert
Sep 8 at 15:00
Maybe tex.stackexchange.com/questions/217757/⦠will help. I searched in Google for: "latex detect default argument"
â albert
Sep 8 at 15:00
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
7
down vote
accepted
To allow that syntax you can use @ifnextchar to check if there is a comma after the first argument. This is, however, a dubious syntax, and can cause unpredictable behavior. Either way you shouldn't use one-letter command names:
documentclassarticle
% Option 1:
makeatletter
newcommandCmdE[1]%
E[#1%
@ifnextchar,grab@sub]
defgrab@sub,#1%
_#1]
makeatother
begindocument
pagenumberinggobble
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X,t) & (CmdE XX,t) \
(CmdE X,tt) & (CmdE XX,tt) \
endtabular
enddocument
produces:
I propose a clearer (and more robust) syntax, using xparse:
documentclassarticle
% Option 2:
usepackagexparse
NewDocumentCommandCmdEmo
%
E[#1IfValueT#2_#2]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X[t]) & (CmdE XX[t]) \
(CmdE X[tt]) & (CmdE XX[tt]) \
endtabular
enddocument
the result is the same for both approaches.
Ooh, yes, there's plain LaTeX syntax too:
documentclassarticle
% Option 3:
newcommandCmdE[2]
%
E[#2%
ifrelaxdetokenize#1relax
else
_#1%
fi]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE [t]X) & (CmdE [t]XX) \
(CmdE [tt]X) & (CmdE [tt]XX) \
endtabular
enddocument
I really like option 2...so clear an legible! :D Thanks so much Phelype, I really appreciate it... I think this is one of the best and clearest answers I've ever gotten on any of the exchanges :0
â AIM_BLB
Sep 8 at 15:15
1
@AIM_BLB Glad that you liked it :) The second option is certainly the safest. For example, you can say(CmdE X[t[t]])(note the two pairs of). The third option would produce weird output with(CmdE [t[t]]X).
â Phelype Oleinik
Sep 8 at 15:19
It's really cool, I'm toying around with it now and will share it will my friends soon :) Thanks again! :)
â AIM_BLB
Sep 8 at 15:39
add a comment |Â
up vote
6
down vote
With the example below, CmdE takes an undelimited argument and checks whether one of the tokens of that argument is a comma.
Use CmdE only in mathmode as it does nothing about space tokens surrounding the comma and the other components of its argument.
documentclassarticle
makeatletter
newcommandCheckWhetherArgBlank[1]%
ifrelaxdetokenizeexpandafter@firstoftwo#1.relax
expandafter@firstoftwoelseexpandafter@secondoftwofi
%
newcommandgobbletocommalongdefgobbletocomma#1,%
newcommandremovecommalongdefremovecomma#1,#1%
newcommandgobbledotdefgobbledot.%
newcommandfirsttoSelDoMlongdeffirsttoSelDoM#1,#2SelDoM#1,%
newcommandkeeptillcomma[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
expandaftergobbledotremovecomma#1%
%
expandafterkeeptillcommaexpandafterfirsttoSelDoM#1%
%
%
newcommandCmdE[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1,%
E[#1]% no comma
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
removecomma E[#1]% comma but only blankness behind it.
E[keeptillcomma.#1SelDoM_gobbletocomma#1]% comma and something other than blankness behind it
%
%
% Blankness = Either only explicit space tokens or no tokens at all.
makeatother
begindocument
beginverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
enddocument

Interesting! Mine breaks when there's nothing after the comma :)
â Phelype Oleinik
Sep 8 at 19:52
add a comment |Â
up vote
2
down vote
A different expl3 implementation:
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandEm
clist_set:Nn l_aimblb_e_clist #1
clist_pop:NN l_aimblb_e_clist l_aimblb_e_main_tl
E[ l_aimblb_e_main_tl % print the main
clist_if_empty:NF l_aimblb_e_clist
sb clist_use:Nn l_aimblb_e_clist ,
]
clist_new:N l_aimblb_e_clist
tl_new:N l_aimblb_e_main_tl
ExplSyntaxOff
begindocument
Simple: $EX$
With subscript: $EX,t$
More subscripts: $EX,t,u$
enddocument
This supports more subscripts; since it is for free, I added them. You may have different usages for them.

A classical implementation:
documentclassarticle
makeatletter
newcommandE[1]aimblb@E#1,,@nil
defaimblb@E#1,#2,#3@nil%
E[#1ifrelaxdetokenize#2relaxelse_#2fi]
begindocument
$EX$
$EX,t$
$EX,abcdef$
Comparing with Ulrich's:
beginverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
enddocument

Withaimblb@Efrom the classical implementation brace-stripping at the delimited arguments might occur. Besides this,@nilis not allowed in the argument. I suppose, in everyday use these are not problems. Nonetheless I tried to avoid this.
â Ulrich Diez
Sep 9 at 9:55
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
To allow that syntax you can use @ifnextchar to check if there is a comma after the first argument. This is, however, a dubious syntax, and can cause unpredictable behavior. Either way you shouldn't use one-letter command names:
documentclassarticle
% Option 1:
makeatletter
newcommandCmdE[1]%
E[#1%
@ifnextchar,grab@sub]
defgrab@sub,#1%
_#1]
makeatother
begindocument
pagenumberinggobble
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X,t) & (CmdE XX,t) \
(CmdE X,tt) & (CmdE XX,tt) \
endtabular
enddocument
produces:
I propose a clearer (and more robust) syntax, using xparse:
documentclassarticle
% Option 2:
usepackagexparse
NewDocumentCommandCmdEmo
%
E[#1IfValueT#2_#2]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X[t]) & (CmdE XX[t]) \
(CmdE X[tt]) & (CmdE XX[tt]) \
endtabular
enddocument
the result is the same for both approaches.
Ooh, yes, there's plain LaTeX syntax too:
documentclassarticle
% Option 3:
newcommandCmdE[2]
%
E[#2%
ifrelaxdetokenize#1relax
else
_#1%
fi]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE [t]X) & (CmdE [t]XX) \
(CmdE [tt]X) & (CmdE [tt]XX) \
endtabular
enddocument
I really like option 2...so clear an legible! :D Thanks so much Phelype, I really appreciate it... I think this is one of the best and clearest answers I've ever gotten on any of the exchanges :0
â AIM_BLB
Sep 8 at 15:15
1
@AIM_BLB Glad that you liked it :) The second option is certainly the safest. For example, you can say(CmdE X[t[t]])(note the two pairs of). The third option would produce weird output with(CmdE [t[t]]X).
â Phelype Oleinik
Sep 8 at 15:19
It's really cool, I'm toying around with it now and will share it will my friends soon :) Thanks again! :)
â AIM_BLB
Sep 8 at 15:39
add a comment |Â
up vote
7
down vote
accepted
To allow that syntax you can use @ifnextchar to check if there is a comma after the first argument. This is, however, a dubious syntax, and can cause unpredictable behavior. Either way you shouldn't use one-letter command names:
documentclassarticle
% Option 1:
makeatletter
newcommandCmdE[1]%
E[#1%
@ifnextchar,grab@sub]
defgrab@sub,#1%
_#1]
makeatother
begindocument
pagenumberinggobble
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X,t) & (CmdE XX,t) \
(CmdE X,tt) & (CmdE XX,tt) \
endtabular
enddocument
produces:
I propose a clearer (and more robust) syntax, using xparse:
documentclassarticle
% Option 2:
usepackagexparse
NewDocumentCommandCmdEmo
%
E[#1IfValueT#2_#2]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X[t]) & (CmdE XX[t]) \
(CmdE X[tt]) & (CmdE XX[tt]) \
endtabular
enddocument
the result is the same for both approaches.
Ooh, yes, there's plain LaTeX syntax too:
documentclassarticle
% Option 3:
newcommandCmdE[2]
%
E[#2%
ifrelaxdetokenize#1relax
else
_#1%
fi]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE [t]X) & (CmdE [t]XX) \
(CmdE [tt]X) & (CmdE [tt]XX) \
endtabular
enddocument
I really like option 2...so clear an legible! :D Thanks so much Phelype, I really appreciate it... I think this is one of the best and clearest answers I've ever gotten on any of the exchanges :0
â AIM_BLB
Sep 8 at 15:15
1
@AIM_BLB Glad that you liked it :) The second option is certainly the safest. For example, you can say(CmdE X[t[t]])(note the two pairs of). The third option would produce weird output with(CmdE [t[t]]X).
â Phelype Oleinik
Sep 8 at 15:19
It's really cool, I'm toying around with it now and will share it will my friends soon :) Thanks again! :)
â AIM_BLB
Sep 8 at 15:39
add a comment |Â
up vote
7
down vote
accepted
up vote
7
down vote
accepted
To allow that syntax you can use @ifnextchar to check if there is a comma after the first argument. This is, however, a dubious syntax, and can cause unpredictable behavior. Either way you shouldn't use one-letter command names:
documentclassarticle
% Option 1:
makeatletter
newcommandCmdE[1]%
E[#1%
@ifnextchar,grab@sub]
defgrab@sub,#1%
_#1]
makeatother
begindocument
pagenumberinggobble
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X,t) & (CmdE XX,t) \
(CmdE X,tt) & (CmdE XX,tt) \
endtabular
enddocument
produces:
I propose a clearer (and more robust) syntax, using xparse:
documentclassarticle
% Option 2:
usepackagexparse
NewDocumentCommandCmdEmo
%
E[#1IfValueT#2_#2]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X[t]) & (CmdE XX[t]) \
(CmdE X[tt]) & (CmdE XX[tt]) \
endtabular
enddocument
the result is the same for both approaches.
Ooh, yes, there's plain LaTeX syntax too:
documentclassarticle
% Option 3:
newcommandCmdE[2]
%
E[#2%
ifrelaxdetokenize#1relax
else
_#1%
fi]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE [t]X) & (CmdE [t]XX) \
(CmdE [tt]X) & (CmdE [tt]XX) \
endtabular
enddocument
To allow that syntax you can use @ifnextchar to check if there is a comma after the first argument. This is, however, a dubious syntax, and can cause unpredictable behavior. Either way you shouldn't use one-letter command names:
documentclassarticle
% Option 1:
makeatletter
newcommandCmdE[1]%
E[#1%
@ifnextchar,grab@sub]
defgrab@sub,#1%
_#1]
makeatother
begindocument
pagenumberinggobble
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X,t) & (CmdE XX,t) \
(CmdE X,tt) & (CmdE XX,tt) \
endtabular
enddocument
produces:
I propose a clearer (and more robust) syntax, using xparse:
documentclassarticle
% Option 2:
usepackagexparse
NewDocumentCommandCmdEmo
%
E[#1IfValueT#2_#2]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE X[t]) & (CmdE XX[t]) \
(CmdE X[tt]) & (CmdE XX[tt]) \
endtabular
enddocument
the result is the same for both approaches.
Ooh, yes, there's plain LaTeX syntax too:
documentclassarticle
% Option 3:
newcommandCmdE[2]
%
E[#2%
ifrelaxdetokenize#1relax
else
_#1%
fi]%
begindocument
begintabularll
(CmdE X) & (CmdE XX) \
(CmdE [t]X) & (CmdE [t]XX) \
(CmdE [tt]X) & (CmdE [tt]XX) \
endtabular
enddocument
answered Sep 8 at 15:06
Phelype Oleinik
16.2k33466
16.2k33466
I really like option 2...so clear an legible! :D Thanks so much Phelype, I really appreciate it... I think this is one of the best and clearest answers I've ever gotten on any of the exchanges :0
â AIM_BLB
Sep 8 at 15:15
1
@AIM_BLB Glad that you liked it :) The second option is certainly the safest. For example, you can say(CmdE X[t[t]])(note the two pairs of). The third option would produce weird output with(CmdE [t[t]]X).
â Phelype Oleinik
Sep 8 at 15:19
It's really cool, I'm toying around with it now and will share it will my friends soon :) Thanks again! :)
â AIM_BLB
Sep 8 at 15:39
add a comment |Â
I really like option 2...so clear an legible! :D Thanks so much Phelype, I really appreciate it... I think this is one of the best and clearest answers I've ever gotten on any of the exchanges :0
â AIM_BLB
Sep 8 at 15:15
1
@AIM_BLB Glad that you liked it :) The second option is certainly the safest. For example, you can say(CmdE X[t[t]])(note the two pairs of). The third option would produce weird output with(CmdE [t[t]]X).
â Phelype Oleinik
Sep 8 at 15:19
It's really cool, I'm toying around with it now and will share it will my friends soon :) Thanks again! :)
â AIM_BLB
Sep 8 at 15:39
I really like option 2...so clear an legible! :D Thanks so much Phelype, I really appreciate it... I think this is one of the best and clearest answers I've ever gotten on any of the exchanges :0
â AIM_BLB
Sep 8 at 15:15
I really like option 2...so clear an legible! :D Thanks so much Phelype, I really appreciate it... I think this is one of the best and clearest answers I've ever gotten on any of the exchanges :0
â AIM_BLB
Sep 8 at 15:15
1
1
@AIM_BLB Glad that you liked it :) The second option is certainly the safest. For example, you can say
(CmdE X[t[t]]) (note the two pairs of ). The third option would produce weird output with (CmdE [t[t]]X).â Phelype Oleinik
Sep 8 at 15:19
@AIM_BLB Glad that you liked it :) The second option is certainly the safest. For example, you can say
(CmdE X[t[t]]) (note the two pairs of ). The third option would produce weird output with (CmdE [t[t]]X).â Phelype Oleinik
Sep 8 at 15:19
It's really cool, I'm toying around with it now and will share it will my friends soon :) Thanks again! :)
â AIM_BLB
Sep 8 at 15:39
It's really cool, I'm toying around with it now and will share it will my friends soon :) Thanks again! :)
â AIM_BLB
Sep 8 at 15:39
add a comment |Â
up vote
6
down vote
With the example below, CmdE takes an undelimited argument and checks whether one of the tokens of that argument is a comma.
Use CmdE only in mathmode as it does nothing about space tokens surrounding the comma and the other components of its argument.
documentclassarticle
makeatletter
newcommandCheckWhetherArgBlank[1]%
ifrelaxdetokenizeexpandafter@firstoftwo#1.relax
expandafter@firstoftwoelseexpandafter@secondoftwofi
%
newcommandgobbletocommalongdefgobbletocomma#1,%
newcommandremovecommalongdefremovecomma#1,#1%
newcommandgobbledotdefgobbledot.%
newcommandfirsttoSelDoMlongdeffirsttoSelDoM#1,#2SelDoM#1,%
newcommandkeeptillcomma[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
expandaftergobbledotremovecomma#1%
%
expandafterkeeptillcommaexpandafterfirsttoSelDoM#1%
%
%
newcommandCmdE[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1,%
E[#1]% no comma
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
removecomma E[#1]% comma but only blankness behind it.
E[keeptillcomma.#1SelDoM_gobbletocomma#1]% comma and something other than blankness behind it
%
%
% Blankness = Either only explicit space tokens or no tokens at all.
makeatother
begindocument
beginverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
enddocument

Interesting! Mine breaks when there's nothing after the comma :)
â Phelype Oleinik
Sep 8 at 19:52
add a comment |Â
up vote
6
down vote
With the example below, CmdE takes an undelimited argument and checks whether one of the tokens of that argument is a comma.
Use CmdE only in mathmode as it does nothing about space tokens surrounding the comma and the other components of its argument.
documentclassarticle
makeatletter
newcommandCheckWhetherArgBlank[1]%
ifrelaxdetokenizeexpandafter@firstoftwo#1.relax
expandafter@firstoftwoelseexpandafter@secondoftwofi
%
newcommandgobbletocommalongdefgobbletocomma#1,%
newcommandremovecommalongdefremovecomma#1,#1%
newcommandgobbledotdefgobbledot.%
newcommandfirsttoSelDoMlongdeffirsttoSelDoM#1,#2SelDoM#1,%
newcommandkeeptillcomma[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
expandaftergobbledotremovecomma#1%
%
expandafterkeeptillcommaexpandafterfirsttoSelDoM#1%
%
%
newcommandCmdE[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1,%
E[#1]% no comma
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
removecomma E[#1]% comma but only blankness behind it.
E[keeptillcomma.#1SelDoM_gobbletocomma#1]% comma and something other than blankness behind it
%
%
% Blankness = Either only explicit space tokens or no tokens at all.
makeatother
begindocument
beginverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
enddocument

Interesting! Mine breaks when there's nothing after the comma :)
â Phelype Oleinik
Sep 8 at 19:52
add a comment |Â
up vote
6
down vote
up vote
6
down vote
With the example below, CmdE takes an undelimited argument and checks whether one of the tokens of that argument is a comma.
Use CmdE only in mathmode as it does nothing about space tokens surrounding the comma and the other components of its argument.
documentclassarticle
makeatletter
newcommandCheckWhetherArgBlank[1]%
ifrelaxdetokenizeexpandafter@firstoftwo#1.relax
expandafter@firstoftwoelseexpandafter@secondoftwofi
%
newcommandgobbletocommalongdefgobbletocomma#1,%
newcommandremovecommalongdefremovecomma#1,#1%
newcommandgobbledotdefgobbledot.%
newcommandfirsttoSelDoMlongdeffirsttoSelDoM#1,#2SelDoM#1,%
newcommandkeeptillcomma[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
expandaftergobbledotremovecomma#1%
%
expandafterkeeptillcommaexpandafterfirsttoSelDoM#1%
%
%
newcommandCmdE[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1,%
E[#1]% no comma
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
removecomma E[#1]% comma but only blankness behind it.
E[keeptillcomma.#1SelDoM_gobbletocomma#1]% comma and something other than blankness behind it
%
%
% Blankness = Either only explicit space tokens or no tokens at all.
makeatother
begindocument
beginverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
enddocument

With the example below, CmdE takes an undelimited argument and checks whether one of the tokens of that argument is a comma.
Use CmdE only in mathmode as it does nothing about space tokens surrounding the comma and the other components of its argument.
documentclassarticle
makeatletter
newcommandCheckWhetherArgBlank[1]%
ifrelaxdetokenizeexpandafter@firstoftwo#1.relax
expandafter@firstoftwoelseexpandafter@secondoftwofi
%
newcommandgobbletocommalongdefgobbletocomma#1,%
newcommandremovecommalongdefremovecomma#1,#1%
newcommandgobbledotdefgobbledot.%
newcommandfirsttoSelDoMlongdeffirsttoSelDoM#1,#2SelDoM#1,%
newcommandkeeptillcomma[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
expandaftergobbledotremovecomma#1%
%
expandafterkeeptillcommaexpandafterfirsttoSelDoM#1%
%
%
newcommandCmdE[1]%
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1,%
E[#1]% no comma
expandafterCheckWhetherArgBlankexpandaftergobbletocomma#1%
removecomma E[#1]% comma but only blankness behind it.
E[keeptillcomma.#1SelDoM_gobbletocomma#1]% comma and something other than blankness behind it
%
%
% Blankness = Either only explicit space tokens or no tokens at all.
makeatother
begindocument
beginverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(CmdEX) & (CmdEXX) \
(CmdEX,t) & (CmdEXX,t) \
(CmdEX, t) & (CmdEXX, t) \
(CmdEX,tt) & (CmdEXX,tt) \
(CmdEX, tt) & (CmdEXX, tt) \
(CmdE[XX], [tt]) & (CmdE[XX], [tt],u) \
(CmdEX,) & (CmdE[XX], [tt],u)\
endtabular
enddocument

edited Sep 9 at 9:59
answered Sep 8 at 19:47
Ulrich Diez
3,350414
3,350414
Interesting! Mine breaks when there's nothing after the comma :)
â Phelype Oleinik
Sep 8 at 19:52
add a comment |Â
Interesting! Mine breaks when there's nothing after the comma :)
â Phelype Oleinik
Sep 8 at 19:52
Interesting! Mine breaks when there's nothing after the comma :)
â Phelype Oleinik
Sep 8 at 19:52
Interesting! Mine breaks when there's nothing after the comma :)
â Phelype Oleinik
Sep 8 at 19:52
add a comment |Â
up vote
2
down vote
A different expl3 implementation:
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandEm
clist_set:Nn l_aimblb_e_clist #1
clist_pop:NN l_aimblb_e_clist l_aimblb_e_main_tl
E[ l_aimblb_e_main_tl % print the main
clist_if_empty:NF l_aimblb_e_clist
sb clist_use:Nn l_aimblb_e_clist ,
]
clist_new:N l_aimblb_e_clist
tl_new:N l_aimblb_e_main_tl
ExplSyntaxOff
begindocument
Simple: $EX$
With subscript: $EX,t$
More subscripts: $EX,t,u$
enddocument
This supports more subscripts; since it is for free, I added them. You may have different usages for them.

A classical implementation:
documentclassarticle
makeatletter
newcommandE[1]aimblb@E#1,,@nil
defaimblb@E#1,#2,#3@nil%
E[#1ifrelaxdetokenize#2relaxelse_#2fi]
begindocument
$EX$
$EX,t$
$EX,abcdef$
Comparing with Ulrich's:
beginverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
enddocument

Withaimblb@Efrom the classical implementation brace-stripping at the delimited arguments might occur. Besides this,@nilis not allowed in the argument. I suppose, in everyday use these are not problems. Nonetheless I tried to avoid this.
â Ulrich Diez
Sep 9 at 9:55
add a comment |Â
up vote
2
down vote
A different expl3 implementation:
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandEm
clist_set:Nn l_aimblb_e_clist #1
clist_pop:NN l_aimblb_e_clist l_aimblb_e_main_tl
E[ l_aimblb_e_main_tl % print the main
clist_if_empty:NF l_aimblb_e_clist
sb clist_use:Nn l_aimblb_e_clist ,
]
clist_new:N l_aimblb_e_clist
tl_new:N l_aimblb_e_main_tl
ExplSyntaxOff
begindocument
Simple: $EX$
With subscript: $EX,t$
More subscripts: $EX,t,u$
enddocument
This supports more subscripts; since it is for free, I added them. You may have different usages for them.

A classical implementation:
documentclassarticle
makeatletter
newcommandE[1]aimblb@E#1,,@nil
defaimblb@E#1,#2,#3@nil%
E[#1ifrelaxdetokenize#2relaxelse_#2fi]
begindocument
$EX$
$EX,t$
$EX,abcdef$
Comparing with Ulrich's:
beginverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
enddocument

Withaimblb@Efrom the classical implementation brace-stripping at the delimited arguments might occur. Besides this,@nilis not allowed in the argument. I suppose, in everyday use these are not problems. Nonetheless I tried to avoid this.
â Ulrich Diez
Sep 9 at 9:55
add a comment |Â
up vote
2
down vote
up vote
2
down vote
A different expl3 implementation:
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandEm
clist_set:Nn l_aimblb_e_clist #1
clist_pop:NN l_aimblb_e_clist l_aimblb_e_main_tl
E[ l_aimblb_e_main_tl % print the main
clist_if_empty:NF l_aimblb_e_clist
sb clist_use:Nn l_aimblb_e_clist ,
]
clist_new:N l_aimblb_e_clist
tl_new:N l_aimblb_e_main_tl
ExplSyntaxOff
begindocument
Simple: $EX$
With subscript: $EX,t$
More subscripts: $EX,t,u$
enddocument
This supports more subscripts; since it is for free, I added them. You may have different usages for them.

A classical implementation:
documentclassarticle
makeatletter
newcommandE[1]aimblb@E#1,,@nil
defaimblb@E#1,#2,#3@nil%
E[#1ifrelaxdetokenize#2relaxelse_#2fi]
begindocument
$EX$
$EX,t$
$EX,abcdef$
Comparing with Ulrich's:
beginverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
enddocument

A different expl3 implementation:
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandEm
clist_set:Nn l_aimblb_e_clist #1
clist_pop:NN l_aimblb_e_clist l_aimblb_e_main_tl
E[ l_aimblb_e_main_tl % print the main
clist_if_empty:NF l_aimblb_e_clist
sb clist_use:Nn l_aimblb_e_clist ,
]
clist_new:N l_aimblb_e_clist
tl_new:N l_aimblb_e_main_tl
ExplSyntaxOff
begindocument
Simple: $EX$
With subscript: $EX,t$
More subscripts: $EX,t,u$
enddocument
This supports more subscripts; since it is for free, I added them. You may have different usages for them.

A classical implementation:
documentclassarticle
makeatletter
newcommandE[1]aimblb@E#1,,@nil
defaimblb@E#1,#2,#3@nil%
E[#1ifrelaxdetokenize#2relaxelse_#2fi]
begindocument
$EX$
$EX,t$
$EX,abcdef$
Comparing with Ulrich's:
beginverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
endverbatim
begintabularll
(EX) & (EXX) \
(EX,t) & (EXX,t) \
(EX, t) & (EXX, t) \
(EX,tt) & (EXX,tt) \
(EX, tt) & (EXX, tt) \
(E[XX], [tt]) & (E[XX], [tt],u) \
(EX,) & (E[XX], [tt],u)\
endtabular
enddocument

edited Sep 8 at 20:47
Phelype Oleinik
16.2k33466
16.2k33466
answered Sep 8 at 20:36
egreg
681k8318113059
681k8318113059
Withaimblb@Efrom the classical implementation brace-stripping at the delimited arguments might occur. Besides this,@nilis not allowed in the argument. I suppose, in everyday use these are not problems. Nonetheless I tried to avoid this.
â Ulrich Diez
Sep 9 at 9:55
add a comment |Â
Withaimblb@Efrom the classical implementation brace-stripping at the delimited arguments might occur. Besides this,@nilis not allowed in the argument. I suppose, in everyday use these are not problems. Nonetheless I tried to avoid this.
â Ulrich Diez
Sep 9 at 9:55
With
aimblb@E from the classical implementation brace-stripping at the delimited arguments might occur. Besides this, @nil is not allowed in the argument. I suppose, in everyday use these are not problems. Nonetheless I tried to avoid this.â Ulrich Diez
Sep 9 at 9:55
With
aimblb@E from the classical implementation brace-stripping at the delimited arguments might occur. Besides this, @nil is not allowed in the argument. I suppose, in everyday use these are not problems. Nonetheless I tried to avoid this.â Ulrich Diez
Sep 9 at 9:55
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%2f450007%2fhow-to-make-a-command-with-default-if-missing%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


Maybe tex.stackexchange.com/questions/217757/⦠will help. I searched in Google for: "latex detect default argument"
â albert
Sep 8 at 15:00