Problem with nesting macros
Clash Royale CLAN TAG#URR8PPP
up vote
4
down vote
favorite
I have written a macro to denote either the Fourier transformation (curly F by itself) or the Fourier transform of a function (curly F followed by a function and enclosed in left( and right) ). It does so by testing if the argument is equal to void or not:
newcommand*fourier[1]ensuremathmathscrFifthenelseequal#1!left(#1right)%
Therefore
fourier
or
fourierf(omega t)
give the expected results.
I wanted to apply fourier twice to a function and therefore wrote
fourierfourierf(x)
However, I'm getting a ! Missing endcsname inserted.
error. How should I modify my macro so that it allows nesting? I'm guessing it's because of the ifthenelse
construct?
nesting ifthenelse
add a comment |Â
up vote
4
down vote
favorite
I have written a macro to denote either the Fourier transformation (curly F by itself) or the Fourier transform of a function (curly F followed by a function and enclosed in left( and right) ). It does so by testing if the argument is equal to void or not:
newcommand*fourier[1]ensuremathmathscrFifthenelseequal#1!left(#1right)%
Therefore
fourier
or
fourierf(omega t)
give the expected results.
I wanted to apply fourier twice to a function and therefore wrote
fourierfourierf(x)
However, I'm getting a ! Missing endcsname inserted.
error. How should I modify my macro so that it allows nesting? I'm guessing it's because of the ifthenelse
construct?
nesting ifthenelse
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I have written a macro to denote either the Fourier transformation (curly F by itself) or the Fourier transform of a function (curly F followed by a function and enclosed in left( and right) ). It does so by testing if the argument is equal to void or not:
newcommand*fourier[1]ensuremathmathscrFifthenelseequal#1!left(#1right)%
Therefore
fourier
or
fourierf(omega t)
give the expected results.
I wanted to apply fourier twice to a function and therefore wrote
fourierfourierf(x)
However, I'm getting a ! Missing endcsname inserted.
error. How should I modify my macro so that it allows nesting? I'm guessing it's because of the ifthenelse
construct?
nesting ifthenelse
I have written a macro to denote either the Fourier transformation (curly F by itself) or the Fourier transform of a function (curly F followed by a function and enclosed in left( and right) ). It does so by testing if the argument is equal to void or not:
newcommand*fourier[1]ensuremathmathscrFifthenelseequal#1!left(#1right)%
Therefore
fourier
or
fourierf(omega t)
give the expected results.
I wanted to apply fourier twice to a function and therefore wrote
fourierfourierf(x)
However, I'm getting a ! Missing endcsname inserted.
error. How should I modify my macro so that it allows nesting? I'm guessing it's because of the ifthenelse
construct?
nesting ifthenelse
edited Sep 5 at 18:58
Peter Mortensen
48736
48736
asked Sep 5 at 15:08
Frédéric Delacroix
333
333
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
5
down vote
accepted
Similar to Skillmon's original answer, but pretending to be mathtools
and sticking to the mandatory argument. The starred version uses left
/right
, the unstarred version has an optional parameter for big
/Big
/...
Taking the approach to left
and right
from Mateus Araújo's answer to Spacing around left and right with help from Philipp Stephani (thanks to Ruixi Zhang for the suggestion in the comments)
documentclass[british]article
usepackage[T1]fontenc
usepackage[utf8]inputenc
usepackagebabel
usepackageamsmath
usepackagemathrsfs
usepackageifthen
makeatletter
DeclareRobustCommandfourier%
mathscrF%
@ifstar
fourier@paren@star
fourier@paren@expl
newcommandfourier@paren@star[1]%
ifrelaxdetokenize#1relax
else
mathopenmathcloseleft(#1right)%
fi
newcommandfourier@paren@expl[2]%
ifrelaxdetokenize#2relax
else
mathopen#1(#2mathclose#1)%
fi
makeatother
begindocument
[ fourier ]
[ fourierf(omega t) ]
[ fourierfourierf(x) ]
[ fourier*fourier*fracf^22pi(x) ]
enddocument
That space!
beforeleft
andright
though. Why not use the classic solution by Philipp Stephani:mathopenmathcloseleft( #1 right)
. For thefourier[big]...
variants, I was wondering if there is a possible direct use ofbigl
andbigr
. ;-)
– Ruixi Zhang
Sep 5 at 15:56
1
@RuixiZhang Thanks for the hint. I had copied theleft
right
bit from the OP. I'll see if I can find something that works forbig
->bigl
/bigr
, though I'm not sure if that is necessary when we already usemathopen
andmathclose
.
– moewe
Sep 5 at 16:06
1
@RuixiZhang Given thatbigl
is justdefbiglmathopenbig
I don't think the conversion frombig
tobigl
is really necessary here. If anyone is interested I came up withnewcommandfrde@size@getlr[3]csnameexpandafter@gobblestring#1#2endcsname#3
which you can use asfrde@size@getlrbigl(
to getbigl(
.
– moewe
Sep 5 at 19:26
You are right. Unlike the “simple wrapper†frommathtools
which does@nameuse MH_cs_to_str:N ##1 l #2
and@nameuse MH_cs_to_str:N ##1 r #3
, going this extra mile to getbigl(
just seems convoluted.
– Ruixi Zhang
Sep 5 at 19:47
1
@FrédéricDelacroix Many expert users prefer the explicit size commands over the automatic sizing withleft
/right
because the automatic commands may pick out sizes that are unnecessarily large or too small in certain situations (there is even a quote from the TeXbook that acknowledges that and it is reproduced in an answer here, but I can't find that right now).
– moewe
Sep 6 at 8:13
 |Â
show 1 more comment
up vote
10
down vote
I'd use the following:
- don't use
ensuremath
it tends to obfuscate source code - don't use
ifthenelse
to check for an empty argument, butifrelaxdetokenize#1relax
(expandable, plus personal preferences) - use an optional argument for an optional argument
I've made a mistake therefore the former code grabbed the arguments wrong. The following uses xparse
to grab the arguments in a more robust way. It therefore doesn't use the ifrelaxdetokenize#1relax
test but xparse
's IfValueT
.
Results:
documentclassarticle
usepackagemathrsfs
usepackagexparse
NewDocumentCommand fourier o
%
mathscrFIfValueT#1!left(#1right)%
%
begindocument
$fourier[fourier[f]](x)$
enddocument
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
Similar to Skillmon's original answer, but pretending to be mathtools
and sticking to the mandatory argument. The starred version uses left
/right
, the unstarred version has an optional parameter for big
/Big
/...
Taking the approach to left
and right
from Mateus Araújo's answer to Spacing around left and right with help from Philipp Stephani (thanks to Ruixi Zhang for the suggestion in the comments)
documentclass[british]article
usepackage[T1]fontenc
usepackage[utf8]inputenc
usepackagebabel
usepackageamsmath
usepackagemathrsfs
usepackageifthen
makeatletter
DeclareRobustCommandfourier%
mathscrF%
@ifstar
fourier@paren@star
fourier@paren@expl
newcommandfourier@paren@star[1]%
ifrelaxdetokenize#1relax
else
mathopenmathcloseleft(#1right)%
fi
newcommandfourier@paren@expl[2]%
ifrelaxdetokenize#2relax
else
mathopen#1(#2mathclose#1)%
fi
makeatother
begindocument
[ fourier ]
[ fourierf(omega t) ]
[ fourierfourierf(x) ]
[ fourier*fourier*fracf^22pi(x) ]
enddocument
That space!
beforeleft
andright
though. Why not use the classic solution by Philipp Stephani:mathopenmathcloseleft( #1 right)
. For thefourier[big]...
variants, I was wondering if there is a possible direct use ofbigl
andbigr
. ;-)
– Ruixi Zhang
Sep 5 at 15:56
1
@RuixiZhang Thanks for the hint. I had copied theleft
right
bit from the OP. I'll see if I can find something that works forbig
->bigl
/bigr
, though I'm not sure if that is necessary when we already usemathopen
andmathclose
.
– moewe
Sep 5 at 16:06
1
@RuixiZhang Given thatbigl
is justdefbiglmathopenbig
I don't think the conversion frombig
tobigl
is really necessary here. If anyone is interested I came up withnewcommandfrde@size@getlr[3]csnameexpandafter@gobblestring#1#2endcsname#3
which you can use asfrde@size@getlrbigl(
to getbigl(
.
– moewe
Sep 5 at 19:26
You are right. Unlike the “simple wrapper†frommathtools
which does@nameuse MH_cs_to_str:N ##1 l #2
and@nameuse MH_cs_to_str:N ##1 r #3
, going this extra mile to getbigl(
just seems convoluted.
– Ruixi Zhang
Sep 5 at 19:47
1
@FrédéricDelacroix Many expert users prefer the explicit size commands over the automatic sizing withleft
/right
because the automatic commands may pick out sizes that are unnecessarily large or too small in certain situations (there is even a quote from the TeXbook that acknowledges that and it is reproduced in an answer here, but I can't find that right now).
– moewe
Sep 6 at 8:13
 |Â
show 1 more comment
up vote
5
down vote
accepted
Similar to Skillmon's original answer, but pretending to be mathtools
and sticking to the mandatory argument. The starred version uses left
/right
, the unstarred version has an optional parameter for big
/Big
/...
Taking the approach to left
and right
from Mateus Araújo's answer to Spacing around left and right with help from Philipp Stephani (thanks to Ruixi Zhang for the suggestion in the comments)
documentclass[british]article
usepackage[T1]fontenc
usepackage[utf8]inputenc
usepackagebabel
usepackageamsmath
usepackagemathrsfs
usepackageifthen
makeatletter
DeclareRobustCommandfourier%
mathscrF%
@ifstar
fourier@paren@star
fourier@paren@expl
newcommandfourier@paren@star[1]%
ifrelaxdetokenize#1relax
else
mathopenmathcloseleft(#1right)%
fi
newcommandfourier@paren@expl[2]%
ifrelaxdetokenize#2relax
else
mathopen#1(#2mathclose#1)%
fi
makeatother
begindocument
[ fourier ]
[ fourierf(omega t) ]
[ fourierfourierf(x) ]
[ fourier*fourier*fracf^22pi(x) ]
enddocument
That space!
beforeleft
andright
though. Why not use the classic solution by Philipp Stephani:mathopenmathcloseleft( #1 right)
. For thefourier[big]...
variants, I was wondering if there is a possible direct use ofbigl
andbigr
. ;-)
– Ruixi Zhang
Sep 5 at 15:56
1
@RuixiZhang Thanks for the hint. I had copied theleft
right
bit from the OP. I'll see if I can find something that works forbig
->bigl
/bigr
, though I'm not sure if that is necessary when we already usemathopen
andmathclose
.
– moewe
Sep 5 at 16:06
1
@RuixiZhang Given thatbigl
is justdefbiglmathopenbig
I don't think the conversion frombig
tobigl
is really necessary here. If anyone is interested I came up withnewcommandfrde@size@getlr[3]csnameexpandafter@gobblestring#1#2endcsname#3
which you can use asfrde@size@getlrbigl(
to getbigl(
.
– moewe
Sep 5 at 19:26
You are right. Unlike the “simple wrapper†frommathtools
which does@nameuse MH_cs_to_str:N ##1 l #2
and@nameuse MH_cs_to_str:N ##1 r #3
, going this extra mile to getbigl(
just seems convoluted.
– Ruixi Zhang
Sep 5 at 19:47
1
@FrédéricDelacroix Many expert users prefer the explicit size commands over the automatic sizing withleft
/right
because the automatic commands may pick out sizes that are unnecessarily large or too small in certain situations (there is even a quote from the TeXbook that acknowledges that and it is reproduced in an answer here, but I can't find that right now).
– moewe
Sep 6 at 8:13
 |Â
show 1 more comment
up vote
5
down vote
accepted
up vote
5
down vote
accepted
Similar to Skillmon's original answer, but pretending to be mathtools
and sticking to the mandatory argument. The starred version uses left
/right
, the unstarred version has an optional parameter for big
/Big
/...
Taking the approach to left
and right
from Mateus Araújo's answer to Spacing around left and right with help from Philipp Stephani (thanks to Ruixi Zhang for the suggestion in the comments)
documentclass[british]article
usepackage[T1]fontenc
usepackage[utf8]inputenc
usepackagebabel
usepackageamsmath
usepackagemathrsfs
usepackageifthen
makeatletter
DeclareRobustCommandfourier%
mathscrF%
@ifstar
fourier@paren@star
fourier@paren@expl
newcommandfourier@paren@star[1]%
ifrelaxdetokenize#1relax
else
mathopenmathcloseleft(#1right)%
fi
newcommandfourier@paren@expl[2]%
ifrelaxdetokenize#2relax
else
mathopen#1(#2mathclose#1)%
fi
makeatother
begindocument
[ fourier ]
[ fourierf(omega t) ]
[ fourierfourierf(x) ]
[ fourier*fourier*fracf^22pi(x) ]
enddocument
Similar to Skillmon's original answer, but pretending to be mathtools
and sticking to the mandatory argument. The starred version uses left
/right
, the unstarred version has an optional parameter for big
/Big
/...
Taking the approach to left
and right
from Mateus Araújo's answer to Spacing around left and right with help from Philipp Stephani (thanks to Ruixi Zhang for the suggestion in the comments)
documentclass[british]article
usepackage[T1]fontenc
usepackage[utf8]inputenc
usepackagebabel
usepackageamsmath
usepackagemathrsfs
usepackageifthen
makeatletter
DeclareRobustCommandfourier%
mathscrF%
@ifstar
fourier@paren@star
fourier@paren@expl
newcommandfourier@paren@star[1]%
ifrelaxdetokenize#1relax
else
mathopenmathcloseleft(#1right)%
fi
newcommandfourier@paren@expl[2]%
ifrelaxdetokenize#2relax
else
mathopen#1(#2mathclose#1)%
fi
makeatother
begindocument
[ fourier ]
[ fourierf(omega t) ]
[ fourierfourierf(x) ]
[ fourier*fourier*fracf^22pi(x) ]
enddocument
edited Sep 5 at 16:05
answered Sep 5 at 15:29
moewe
75.1k797285
75.1k797285
That space!
beforeleft
andright
though. Why not use the classic solution by Philipp Stephani:mathopenmathcloseleft( #1 right)
. For thefourier[big]...
variants, I was wondering if there is a possible direct use ofbigl
andbigr
. ;-)
– Ruixi Zhang
Sep 5 at 15:56
1
@RuixiZhang Thanks for the hint. I had copied theleft
right
bit from the OP. I'll see if I can find something that works forbig
->bigl
/bigr
, though I'm not sure if that is necessary when we already usemathopen
andmathclose
.
– moewe
Sep 5 at 16:06
1
@RuixiZhang Given thatbigl
is justdefbiglmathopenbig
I don't think the conversion frombig
tobigl
is really necessary here. If anyone is interested I came up withnewcommandfrde@size@getlr[3]csnameexpandafter@gobblestring#1#2endcsname#3
which you can use asfrde@size@getlrbigl(
to getbigl(
.
– moewe
Sep 5 at 19:26
You are right. Unlike the “simple wrapper†frommathtools
which does@nameuse MH_cs_to_str:N ##1 l #2
and@nameuse MH_cs_to_str:N ##1 r #3
, going this extra mile to getbigl(
just seems convoluted.
– Ruixi Zhang
Sep 5 at 19:47
1
@FrédéricDelacroix Many expert users prefer the explicit size commands over the automatic sizing withleft
/right
because the automatic commands may pick out sizes that are unnecessarily large or too small in certain situations (there is even a quote from the TeXbook that acknowledges that and it is reproduced in an answer here, but I can't find that right now).
– moewe
Sep 6 at 8:13
 |Â
show 1 more comment
That space!
beforeleft
andright
though. Why not use the classic solution by Philipp Stephani:mathopenmathcloseleft( #1 right)
. For thefourier[big]...
variants, I was wondering if there is a possible direct use ofbigl
andbigr
. ;-)
– Ruixi Zhang
Sep 5 at 15:56
1
@RuixiZhang Thanks for the hint. I had copied theleft
right
bit from the OP. I'll see if I can find something that works forbig
->bigl
/bigr
, though I'm not sure if that is necessary when we already usemathopen
andmathclose
.
– moewe
Sep 5 at 16:06
1
@RuixiZhang Given thatbigl
is justdefbiglmathopenbig
I don't think the conversion frombig
tobigl
is really necessary here. If anyone is interested I came up withnewcommandfrde@size@getlr[3]csnameexpandafter@gobblestring#1#2endcsname#3
which you can use asfrde@size@getlrbigl(
to getbigl(
.
– moewe
Sep 5 at 19:26
You are right. Unlike the “simple wrapper†frommathtools
which does@nameuse MH_cs_to_str:N ##1 l #2
and@nameuse MH_cs_to_str:N ##1 r #3
, going this extra mile to getbigl(
just seems convoluted.
– Ruixi Zhang
Sep 5 at 19:47
1
@FrédéricDelacroix Many expert users prefer the explicit size commands over the automatic sizing withleft
/right
because the automatic commands may pick out sizes that are unnecessarily large or too small in certain situations (there is even a quote from the TeXbook that acknowledges that and it is reproduced in an answer here, but I can't find that right now).
– moewe
Sep 6 at 8:13
That space
!
before left
and right
though. Why not use the classic solution by Philipp Stephani: mathopenmathcloseleft( #1 right)
. For the fourier[big]...
variants, I was wondering if there is a possible direct use of bigl
and bigr
. ;-)– Ruixi Zhang
Sep 5 at 15:56
That space
!
before left
and right
though. Why not use the classic solution by Philipp Stephani: mathopenmathcloseleft( #1 right)
. For the fourier[big]...
variants, I was wondering if there is a possible direct use of bigl
and bigr
. ;-)– Ruixi Zhang
Sep 5 at 15:56
1
1
@RuixiZhang Thanks for the hint. I had copied the
left
right
bit from the OP. I'll see if I can find something that works for big
->bigl
/bigr
, though I'm not sure if that is necessary when we already use mathopen
and mathclose
.– moewe
Sep 5 at 16:06
@RuixiZhang Thanks for the hint. I had copied the
left
right
bit from the OP. I'll see if I can find something that works for big
->bigl
/bigr
, though I'm not sure if that is necessary when we already use mathopen
and mathclose
.– moewe
Sep 5 at 16:06
1
1
@RuixiZhang Given that
bigl
is just defbiglmathopenbig
I don't think the conversion from big
to bigl
is really necessary here. If anyone is interested I came up with newcommandfrde@size@getlr[3]csnameexpandafter@gobblestring#1#2endcsname#3
which you can use as frde@size@getlrbigl(
to get bigl(
.– moewe
Sep 5 at 19:26
@RuixiZhang Given that
bigl
is just defbiglmathopenbig
I don't think the conversion from big
to bigl
is really necessary here. If anyone is interested I came up with newcommandfrde@size@getlr[3]csnameexpandafter@gobblestring#1#2endcsname#3
which you can use as frde@size@getlrbigl(
to get bigl(
.– moewe
Sep 5 at 19:26
You are right. Unlike the “simple wrapper†from
mathtools
which does @nameuse MH_cs_to_str:N ##1 l #2
and @nameuse MH_cs_to_str:N ##1 r #3
, going this extra mile to get bigl(
just seems convoluted.– Ruixi Zhang
Sep 5 at 19:47
You are right. Unlike the “simple wrapper†from
mathtools
which does @nameuse MH_cs_to_str:N ##1 l #2
and @nameuse MH_cs_to_str:N ##1 r #3
, going this extra mile to get bigl(
just seems convoluted.– Ruixi Zhang
Sep 5 at 19:47
1
1
@FrédéricDelacroix Many expert users prefer the explicit size commands over the automatic sizing with
left
/right
because the automatic commands may pick out sizes that are unnecessarily large or too small in certain situations (there is even a quote from the TeXbook that acknowledges that and it is reproduced in an answer here, but I can't find that right now).– moewe
Sep 6 at 8:13
@FrédéricDelacroix Many expert users prefer the explicit size commands over the automatic sizing with
left
/right
because the automatic commands may pick out sizes that are unnecessarily large or too small in certain situations (there is even a quote from the TeXbook that acknowledges that and it is reproduced in an answer here, but I can't find that right now).– moewe
Sep 6 at 8:13
 |Â
show 1 more comment
up vote
10
down vote
I'd use the following:
- don't use
ensuremath
it tends to obfuscate source code - don't use
ifthenelse
to check for an empty argument, butifrelaxdetokenize#1relax
(expandable, plus personal preferences) - use an optional argument for an optional argument
I've made a mistake therefore the former code grabbed the arguments wrong. The following uses xparse
to grab the arguments in a more robust way. It therefore doesn't use the ifrelaxdetokenize#1relax
test but xparse
's IfValueT
.
Results:
documentclassarticle
usepackagemathrsfs
usepackagexparse
NewDocumentCommand fourier o
%
mathscrFIfValueT#1!left(#1right)%
%
begindocument
$fourier[fourier[f]](x)$
enddocument
add a comment |Â
up vote
10
down vote
I'd use the following:
- don't use
ensuremath
it tends to obfuscate source code - don't use
ifthenelse
to check for an empty argument, butifrelaxdetokenize#1relax
(expandable, plus personal preferences) - use an optional argument for an optional argument
I've made a mistake therefore the former code grabbed the arguments wrong. The following uses xparse
to grab the arguments in a more robust way. It therefore doesn't use the ifrelaxdetokenize#1relax
test but xparse
's IfValueT
.
Results:
documentclassarticle
usepackagemathrsfs
usepackagexparse
NewDocumentCommand fourier o
%
mathscrFIfValueT#1!left(#1right)%
%
begindocument
$fourier[fourier[f]](x)$
enddocument
add a comment |Â
up vote
10
down vote
up vote
10
down vote
I'd use the following:
- don't use
ensuremath
it tends to obfuscate source code - don't use
ifthenelse
to check for an empty argument, butifrelaxdetokenize#1relax
(expandable, plus personal preferences) - use an optional argument for an optional argument
I've made a mistake therefore the former code grabbed the arguments wrong. The following uses xparse
to grab the arguments in a more robust way. It therefore doesn't use the ifrelaxdetokenize#1relax
test but xparse
's IfValueT
.
Results:
documentclassarticle
usepackagemathrsfs
usepackagexparse
NewDocumentCommand fourier o
%
mathscrFIfValueT#1!left(#1right)%
%
begindocument
$fourier[fourier[f]](x)$
enddocument
I'd use the following:
- don't use
ensuremath
it tends to obfuscate source code - don't use
ifthenelse
to check for an empty argument, butifrelaxdetokenize#1relax
(expandable, plus personal preferences) - use an optional argument for an optional argument
I've made a mistake therefore the former code grabbed the arguments wrong. The following uses xparse
to grab the arguments in a more robust way. It therefore doesn't use the ifrelaxdetokenize#1relax
test but xparse
's IfValueT
.
Results:
documentclassarticle
usepackagemathrsfs
usepackagexparse
NewDocumentCommand fourier o
%
mathscrFIfValueT#1!left(#1right)%
%
begindocument
$fourier[fourier[f]](x)$
enddocument
edited Sep 5 at 15:32
answered Sep 5 at 15:15


Skillmon
17.5k11535
17.5k11535
add a comment |Â
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%2f449483%2fproblem-with-nesting-macros%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