Problems with def
up vote
8
down vote
favorite
I have created the following macros in LaTeX:
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
Where twomate
is a 2x2 matrix, twoclmn
creates a 2x1 column vector, and pwr
is a command to raise the argument to the power.
However, if I try to do the following:
$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )$$
I get an error. However, if I replace the last entry with something that is not a def
command:
$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),5 )$$
The document complies successfully. In addition, the following does not compile successfully:
$$twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t) + frac25 t epwr(2t))$$
But the following does:
$$twoclmn(frac625e^2t-frac15te^2t,-frac225e^2t + frac25 t e^2t)$$
So the problem seems to be the nested def
commands. How may I nest def
commands, without the compiler complaining?
math-mode macros
add a comment |
up vote
8
down vote
favorite
I have created the following macros in LaTeX:
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
Where twomate
is a 2x2 matrix, twoclmn
creates a 2x1 column vector, and pwr
is a command to raise the argument to the power.
However, if I try to do the following:
$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )$$
I get an error. However, if I replace the last entry with something that is not a def
command:
$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),5 )$$
The document complies successfully. In addition, the following does not compile successfully:
$$twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t) + frac25 t epwr(2t))$$
But the following does:
$$twoclmn(frac625e^2t-frac15te^2t,-frac225e^2t + frac25 t e^2t)$$
So the problem seems to be the nested def
commands. How may I nest def
commands, without the compiler complaining?
math-mode macros
Since you're using LaTeX, please consider using[ ... ]
instead of$$ ... $$
, as the latter causes some inconsistencies.
– AJFarmar
Nov 10 at 13:14
add a comment |
up vote
8
down vote
favorite
up vote
8
down vote
favorite
I have created the following macros in LaTeX:
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
Where twomate
is a 2x2 matrix, twoclmn
creates a 2x1 column vector, and pwr
is a command to raise the argument to the power.
However, if I try to do the following:
$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )$$
I get an error. However, if I replace the last entry with something that is not a def
command:
$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),5 )$$
The document complies successfully. In addition, the following does not compile successfully:
$$twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t) + frac25 t epwr(2t))$$
But the following does:
$$twoclmn(frac625e^2t-frac15te^2t,-frac225e^2t + frac25 t e^2t)$$
So the problem seems to be the nested def
commands. How may I nest def
commands, without the compiler complaining?
math-mode macros
I have created the following macros in LaTeX:
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
Where twomate
is a 2x2 matrix, twoclmn
creates a 2x1 column vector, and pwr
is a command to raise the argument to the power.
However, if I try to do the following:
$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )$$
I get an error. However, if I replace the last entry with something that is not a def
command:
$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),5 )$$
The document complies successfully. In addition, the following does not compile successfully:
$$twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t) + frac25 t epwr(2t))$$
But the following does:
$$twoclmn(frac625e^2t-frac15te^2t,-frac225e^2t + frac25 t e^2t)$$
So the problem seems to be the nested def
commands. How may I nest def
commands, without the compiler complaining?
math-mode macros
math-mode macros
asked Nov 9 at 22:49
Hossmeister
433
433
Since you're using LaTeX, please consider using[ ... ]
instead of$$ ... $$
, as the latter causes some inconsistencies.
– AJFarmar
Nov 10 at 13:14
add a comment |
Since you're using LaTeX, please consider using[ ... ]
instead of$$ ... $$
, as the latter causes some inconsistencies.
– AJFarmar
Nov 10 at 13:14
Since you're using LaTeX, please consider using
[ ... ]
instead of $$ ... $$
, as the latter causes some inconsistencies.– AJFarmar
Nov 10 at 13:14
Since you're using LaTeX, please consider using
[ ... ]
instead of $$ ... $$
, as the latter causes some inconsistencies.– AJFarmar
Nov 10 at 13:14
add a comment |
4 Answers
4
active
oldest
votes
up vote
12
down vote
accepted
You can use xparse
for this job, because the r
argument type takes care of nesting.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,r()%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrr()^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
]
enddocument
However, using ()
as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,m%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrm^#1
begindocument
[
twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
]
enddocument
can one nest like thisfoo(a,bar(b,c,d),baz(e,f),g)
?
– jfbu
Nov 10 at 16:11
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
Nov 10 at 16:13
actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"
). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
– jfbu
Nov 10 at 16:50
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
Nov 10 at 16:51
twomate(twomate(1,2,3,4),5,6,7)
, withNewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4)
in place of the definition in your code
– jfbu
Nov 10 at 16:52
|
show 3 more comments
up vote
10
down vote
Your def
contains a very specific sequence defined as the parameter text:
% 1 2 3 4 5
deftwomate(<1>,<2>,<3>,<4>) ...
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └ comma ┘ │
% └─── bracket ───┘
This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>
, <2>
, <3>
and <4>
. Here's how the elements are grabbed for twomate
with the above notation:
% 1 2 3 4 5
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └────── comma ────────┘ │
% └───────────────── bracket ──────────────────┘
It should be clear that the last bracket )
isn't properly captured for pwr
. The way around it is to hide pwr(.)
from twomate
:
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
enddocument
This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ...
.
add a comment |
up vote
6
down vote
TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...)
, the final )
for twomate
isn't found at the end of that line but at the end of pwr(-3t)
. The improperly formed call of pwr
then causes trouble.
To hide nested calls of your commands, put them into ...
groups (though this probably defeats the purpose):
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
begindocument
[ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
enddocument
By the way, don't use $$ ... $$
for display math environments but LaTeX's or amsmath
's variants like [ ... ]
.
add a comment |
up vote
2
down vote
Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...)
input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.
Nesting works, as we will test with this kind of input:
foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))
Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.
As this all works purely by expansion, expandable commands remain expandable commands.
Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c)
should first expand completely the a
, b
, c
before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded
primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q
governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c
, before applying the foo
macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc
.
documentclassarticle
usepackageamsmath
% copy over some utility code from package xintexpr
catcode`_ 11
makeatletter
letxint_c_monem@ne
letxint_c_z@
letxint_c_i@ne
longdefxint_bye #1xint_bye %
makeatother
% THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
% HERE ALL long
% % endmacrocode
% subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
% lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
% it, to @ne if opening ( had no closing ) matching it, to z@ if expression
% was balanced.|
% beginmacrocode
% use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
longdefXINT_isbalanced_b #1)#2%
xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
% endmacrocode
% lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
% beginmacrocode
longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
% endmacrocode
% lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
% beginmacrocode
longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
% endmacrocode
% lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
% we see a ). If we do, we then loop until no ( nor ) is to be found.|
% beginmacrocode
longdefXINT_isbalanced_d #1)#2%
xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
% endmacrocode
% lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
% beginmacrocode
longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% NEW EXPANDABLE UTILITY
longdefapplyfunction #1#2)%
%
ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
expandafterapplyfunction_b
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
longdefapplyfunction_again #1applyfunction #1)%
longdefmy_bbye #1my_bbye %
longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
longdefapplyfunction_c #1(applyfunction_d #1%
% we will take care of brace removal another day
longdefapplyfunction_d #1#2#3#4,%
%
ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
expandafterapplyfunction_e
orexpandafterapplyfunction_d_again
elseexpandafterwe_are_doomed
fi #1#2#3#4%
%
longdefapplyfunction_d_again #1#2#3#4%
%
applyfunction_d #1#2#3#4,%
%
longdefapplyfunction_e #1#2#3#4%
%
my_bbye#4applyfunction_finishmy_bbye
applyfunction_g #1#2#3#4%
%
longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%
catcode`_ 8
%% USAGE
% to define a "function" to be used as foo(a,b,c,...),
% we need a foomacro which uses standard non-delimited parameters,
% thus e.g. defined via newcommand, and then one only needs
% newcommandfooapplyfunctionfoomacro
% to get a foo to be used with parentheses.
newcommandtwomateapplyfunctiontwomatemacro
newcommandpwrapplyfunctionpwrmacro
newcommandtwoclmnapplyfunctiontwoclmnmacro
% define here the **non-delimited** auxiliary macros
newcommandtwomatemacro[4]beginpmatrix#1\#3endpmatrix
newcommandpwrmacro[1]^#1
newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix
%% TESTING NESTING
newcommandfooapplyfunctionfoomacro
newcommandfoomacro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBarmacro
newcommandBarmacro[3]left(#1*#2*#3right)
delimiterfactor1001
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
[foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
enddocument
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
12
down vote
accepted
You can use xparse
for this job, because the r
argument type takes care of nesting.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,r()%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrr()^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
]
enddocument
However, using ()
as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,m%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrm^#1
begindocument
[
twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
]
enddocument
can one nest like thisfoo(a,bar(b,c,d),baz(e,f),g)
?
– jfbu
Nov 10 at 16:11
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
Nov 10 at 16:13
actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"
). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
– jfbu
Nov 10 at 16:50
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
Nov 10 at 16:51
twomate(twomate(1,2,3,4),5,6,7)
, withNewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4)
in place of the definition in your code
– jfbu
Nov 10 at 16:52
|
show 3 more comments
up vote
12
down vote
accepted
You can use xparse
for this job, because the r
argument type takes care of nesting.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,r()%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrr()^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
]
enddocument
However, using ()
as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,m%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrm^#1
begindocument
[
twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
]
enddocument
can one nest like thisfoo(a,bar(b,c,d),baz(e,f),g)
?
– jfbu
Nov 10 at 16:11
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
Nov 10 at 16:13
actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"
). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
– jfbu
Nov 10 at 16:50
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
Nov 10 at 16:51
twomate(twomate(1,2,3,4),5,6,7)
, withNewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4)
in place of the definition in your code
– jfbu
Nov 10 at 16:52
|
show 3 more comments
up vote
12
down vote
accepted
up vote
12
down vote
accepted
You can use xparse
for this job, because the r
argument type takes care of nesting.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,r()%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrr()^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
]
enddocument
However, using ()
as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,m%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrm^#1
begindocument
[
twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
]
enddocument
You can use xparse
for this job, because the r
argument type takes care of nesting.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,r()%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrr()^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
]
enddocument
However, using ()
as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.
documentclassarticle
usepackageamsmath
usepackagexparse
NewDocumentCommandtwomate>SplitArgument3,m%
maketwomate#1%
NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1\#3endpmatrix%
NewDocumentCommandpwrm^#1
begindocument
[
twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
]
enddocument
answered Nov 10 at 0:13
egreg
701k8618673141
701k8618673141
can one nest like thisfoo(a,bar(b,c,d),baz(e,f),g)
?
– jfbu
Nov 10 at 16:11
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
Nov 10 at 16:13
actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"
). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
– jfbu
Nov 10 at 16:50
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
Nov 10 at 16:51
twomate(twomate(1,2,3,4),5,6,7)
, withNewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4)
in place of the definition in your code
– jfbu
Nov 10 at 16:52
|
show 3 more comments
can one nest like thisfoo(a,bar(b,c,d),baz(e,f),g)
?
– jfbu
Nov 10 at 16:11
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
Nov 10 at 16:13
actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"
). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
– jfbu
Nov 10 at 16:50
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
Nov 10 at 16:51
twomate(twomate(1,2,3,4),5,6,7)
, withNewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4)
in place of the definition in your code
– jfbu
Nov 10 at 16:52
can one nest like this
foo(a,bar(b,c,d),baz(e,f),g)
?– jfbu
Nov 10 at 16:11
can one nest like this
foo(a,bar(b,c,d),baz(e,f),g)
?– jfbu
Nov 10 at 16:11
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
Nov 10 at 16:13
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
Nov 10 at 16:13
actually I now tried and it does not seem to work with the code you posted (
LaTeX error: "xparse/split-excess-tokens"
). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.– jfbu
Nov 10 at 16:50
actually I now tried and it does not seem to work with the code you posted (
LaTeX error: "xparse/split-excess-tokens"
). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.– jfbu
Nov 10 at 16:50
@jfbu Without seeing how you define
foo
, bar
and baz
it's just guesswork.– egreg
Nov 10 at 16:51
@jfbu Without seeing how you define
foo
, bar
and baz
it's just guesswork.– egreg
Nov 10 at 16:51
twomate(twomate(1,2,3,4),5,6,7)
, with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4)
in place of the definition in your code– jfbu
Nov 10 at 16:52
twomate(twomate(1,2,3,4),5,6,7)
, with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4)
in place of the definition in your code– jfbu
Nov 10 at 16:52
|
show 3 more comments
up vote
10
down vote
Your def
contains a very specific sequence defined as the parameter text:
% 1 2 3 4 5
deftwomate(<1>,<2>,<3>,<4>) ...
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └ comma ┘ │
% └─── bracket ───┘
This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>
, <2>
, <3>
and <4>
. Here's how the elements are grabbed for twomate
with the above notation:
% 1 2 3 4 5
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └────── comma ────────┘ │
% └───────────────── bracket ──────────────────┘
It should be clear that the last bracket )
isn't properly captured for pwr
. The way around it is to hide pwr(.)
from twomate
:
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
enddocument
This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ...
.
add a comment |
up vote
10
down vote
Your def
contains a very specific sequence defined as the parameter text:
% 1 2 3 4 5
deftwomate(<1>,<2>,<3>,<4>) ...
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └ comma ┘ │
% └─── bracket ───┘
This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>
, <2>
, <3>
and <4>
. Here's how the elements are grabbed for twomate
with the above notation:
% 1 2 3 4 5
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └────── comma ────────┘ │
% └───────────────── bracket ──────────────────┘
It should be clear that the last bracket )
isn't properly captured for pwr
. The way around it is to hide pwr(.)
from twomate
:
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
enddocument
This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ...
.
add a comment |
up vote
10
down vote
up vote
10
down vote
Your def
contains a very specific sequence defined as the parameter text:
% 1 2 3 4 5
deftwomate(<1>,<2>,<3>,<4>) ...
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └ comma ┘ │
% └─── bracket ───┘
This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>
, <2>
, <3>
and <4>
. Here's how the elements are grabbed for twomate
with the above notation:
% 1 2 3 4 5
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └────── comma ────────┘ │
% └───────────────── bracket ──────────────────┘
It should be clear that the last bracket )
isn't properly captured for pwr
. The way around it is to hide pwr(.)
from twomate
:
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
enddocument
This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ...
.
Your def
contains a very specific sequence defined as the parameter text:
% 1 2 3 4 5
deftwomate(<1>,<2>,<3>,<4>) ...
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └ comma ┘ │
% └─── bracket ───┘
This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>
, <2>
, <3>
and <4>
. Here's how the elements are grabbed for twomate
with the above notation:
% 1 2 3 4 5
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └────── comma ────────┘ │
% └───────────────── bracket ──────────────────┘
It should be clear that the last bracket )
isn't properly captured for pwr
. The way around it is to hide pwr(.)
from twomate
:
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
enddocument
This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ...
.
edited Nov 9 at 23:10
answered Nov 9 at 23:04
Werner
432k609511633
432k609511633
add a comment |
add a comment |
up vote
6
down vote
TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...)
, the final )
for twomate
isn't found at the end of that line but at the end of pwr(-3t)
. The improperly formed call of pwr
then causes trouble.
To hide nested calls of your commands, put them into ...
groups (though this probably defeats the purpose):
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
begindocument
[ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
enddocument
By the way, don't use $$ ... $$
for display math environments but LaTeX's or amsmath
's variants like [ ... ]
.
add a comment |
up vote
6
down vote
TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...)
, the final )
for twomate
isn't found at the end of that line but at the end of pwr(-3t)
. The improperly formed call of pwr
then causes trouble.
To hide nested calls of your commands, put them into ...
groups (though this probably defeats the purpose):
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
begindocument
[ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
enddocument
By the way, don't use $$ ... $$
for display math environments but LaTeX's or amsmath
's variants like [ ... ]
.
add a comment |
up vote
6
down vote
up vote
6
down vote
TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...)
, the final )
for twomate
isn't found at the end of that line but at the end of pwr(-3t)
. The improperly formed call of pwr
then causes trouble.
To hide nested calls of your commands, put them into ...
groups (though this probably defeats the purpose):
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
begindocument
[ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
enddocument
By the way, don't use $$ ... $$
for display math environments but LaTeX's or amsmath
's variants like [ ... ]
.
TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...)
, the final )
for twomate
isn't found at the end of that line but at the end of pwr(-3t)
. The improperly formed call of pwr
then causes trouble.
To hide nested calls of your commands, put them into ...
groups (though this probably defeats the purpose):
documentclassarticle
usepackageamsmath
deftwomate(#1,#2,#3,#4)beginpmatrix#1\#3endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix
begindocument
[ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
enddocument
By the way, don't use $$ ... $$
for display math environments but LaTeX's or amsmath
's variants like [ ... ]
.
edited Nov 9 at 23:11
answered Nov 9 at 23:00
siracusa
4,48011127
4,48011127
add a comment |
add a comment |
up vote
2
down vote
Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...)
input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.
Nesting works, as we will test with this kind of input:
foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))
Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.
As this all works purely by expansion, expandable commands remain expandable commands.
Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c)
should first expand completely the a
, b
, c
before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded
primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q
governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c
, before applying the foo
macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc
.
documentclassarticle
usepackageamsmath
% copy over some utility code from package xintexpr
catcode`_ 11
makeatletter
letxint_c_monem@ne
letxint_c_z@
letxint_c_i@ne
longdefxint_bye #1xint_bye %
makeatother
% THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
% HERE ALL long
% % endmacrocode
% subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
% lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
% it, to @ne if opening ( had no closing ) matching it, to z@ if expression
% was balanced.|
% beginmacrocode
% use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
longdefXINT_isbalanced_b #1)#2%
xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
% endmacrocode
% lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
% beginmacrocode
longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
% endmacrocode
% lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
% beginmacrocode
longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
% endmacrocode
% lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
% we see a ). If we do, we then loop until no ( nor ) is to be found.|
% beginmacrocode
longdefXINT_isbalanced_d #1)#2%
xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
% endmacrocode
% lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
% beginmacrocode
longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% NEW EXPANDABLE UTILITY
longdefapplyfunction #1#2)%
%
ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
expandafterapplyfunction_b
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
longdefapplyfunction_again #1applyfunction #1)%
longdefmy_bbye #1my_bbye %
longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
longdefapplyfunction_c #1(applyfunction_d #1%
% we will take care of brace removal another day
longdefapplyfunction_d #1#2#3#4,%
%
ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
expandafterapplyfunction_e
orexpandafterapplyfunction_d_again
elseexpandafterwe_are_doomed
fi #1#2#3#4%
%
longdefapplyfunction_d_again #1#2#3#4%
%
applyfunction_d #1#2#3#4,%
%
longdefapplyfunction_e #1#2#3#4%
%
my_bbye#4applyfunction_finishmy_bbye
applyfunction_g #1#2#3#4%
%
longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%
catcode`_ 8
%% USAGE
% to define a "function" to be used as foo(a,b,c,...),
% we need a foomacro which uses standard non-delimited parameters,
% thus e.g. defined via newcommand, and then one only needs
% newcommandfooapplyfunctionfoomacro
% to get a foo to be used with parentheses.
newcommandtwomateapplyfunctiontwomatemacro
newcommandpwrapplyfunctionpwrmacro
newcommandtwoclmnapplyfunctiontwoclmnmacro
% define here the **non-delimited** auxiliary macros
newcommandtwomatemacro[4]beginpmatrix#1\#3endpmatrix
newcommandpwrmacro[1]^#1
newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix
%% TESTING NESTING
newcommandfooapplyfunctionfoomacro
newcommandfoomacro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBarmacro
newcommandBarmacro[3]left(#1*#2*#3right)
delimiterfactor1001
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
[foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
enddocument
add a comment |
up vote
2
down vote
Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...)
input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.
Nesting works, as we will test with this kind of input:
foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))
Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.
As this all works purely by expansion, expandable commands remain expandable commands.
Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c)
should first expand completely the a
, b
, c
before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded
primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q
governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c
, before applying the foo
macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc
.
documentclassarticle
usepackageamsmath
% copy over some utility code from package xintexpr
catcode`_ 11
makeatletter
letxint_c_monem@ne
letxint_c_z@
letxint_c_i@ne
longdefxint_bye #1xint_bye %
makeatother
% THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
% HERE ALL long
% % endmacrocode
% subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
% lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
% it, to @ne if opening ( had no closing ) matching it, to z@ if expression
% was balanced.|
% beginmacrocode
% use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
longdefXINT_isbalanced_b #1)#2%
xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
% endmacrocode
% lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
% beginmacrocode
longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
% endmacrocode
% lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
% beginmacrocode
longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
% endmacrocode
% lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
% we see a ). If we do, we then loop until no ( nor ) is to be found.|
% beginmacrocode
longdefXINT_isbalanced_d #1)#2%
xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
% endmacrocode
% lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
% beginmacrocode
longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% NEW EXPANDABLE UTILITY
longdefapplyfunction #1#2)%
%
ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
expandafterapplyfunction_b
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
longdefapplyfunction_again #1applyfunction #1)%
longdefmy_bbye #1my_bbye %
longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
longdefapplyfunction_c #1(applyfunction_d #1%
% we will take care of brace removal another day
longdefapplyfunction_d #1#2#3#4,%
%
ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
expandafterapplyfunction_e
orexpandafterapplyfunction_d_again
elseexpandafterwe_are_doomed
fi #1#2#3#4%
%
longdefapplyfunction_d_again #1#2#3#4%
%
applyfunction_d #1#2#3#4,%
%
longdefapplyfunction_e #1#2#3#4%
%
my_bbye#4applyfunction_finishmy_bbye
applyfunction_g #1#2#3#4%
%
longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%
catcode`_ 8
%% USAGE
% to define a "function" to be used as foo(a,b,c,...),
% we need a foomacro which uses standard non-delimited parameters,
% thus e.g. defined via newcommand, and then one only needs
% newcommandfooapplyfunctionfoomacro
% to get a foo to be used with parentheses.
newcommandtwomateapplyfunctiontwomatemacro
newcommandpwrapplyfunctionpwrmacro
newcommandtwoclmnapplyfunctiontwoclmnmacro
% define here the **non-delimited** auxiliary macros
newcommandtwomatemacro[4]beginpmatrix#1\#3endpmatrix
newcommandpwrmacro[1]^#1
newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix
%% TESTING NESTING
newcommandfooapplyfunctionfoomacro
newcommandfoomacro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBarmacro
newcommandBarmacro[3]left(#1*#2*#3right)
delimiterfactor1001
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
[foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
enddocument
add a comment |
up vote
2
down vote
up vote
2
down vote
Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...)
input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.
Nesting works, as we will test with this kind of input:
foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))
Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.
As this all works purely by expansion, expandable commands remain expandable commands.
Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c)
should first expand completely the a
, b
, c
before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded
primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q
governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c
, before applying the foo
macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc
.
documentclassarticle
usepackageamsmath
% copy over some utility code from package xintexpr
catcode`_ 11
makeatletter
letxint_c_monem@ne
letxint_c_z@
letxint_c_i@ne
longdefxint_bye #1xint_bye %
makeatother
% THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
% HERE ALL long
% % endmacrocode
% subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
% lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
% it, to @ne if opening ( had no closing ) matching it, to z@ if expression
% was balanced.|
% beginmacrocode
% use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
longdefXINT_isbalanced_b #1)#2%
xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
% endmacrocode
% lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
% beginmacrocode
longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
% endmacrocode
% lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
% beginmacrocode
longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
% endmacrocode
% lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
% we see a ). If we do, we then loop until no ( nor ) is to be found.|
% beginmacrocode
longdefXINT_isbalanced_d #1)#2%
xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
% endmacrocode
% lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
% beginmacrocode
longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% NEW EXPANDABLE UTILITY
longdefapplyfunction #1#2)%
%
ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
expandafterapplyfunction_b
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
longdefapplyfunction_again #1applyfunction #1)%
longdefmy_bbye #1my_bbye %
longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
longdefapplyfunction_c #1(applyfunction_d #1%
% we will take care of brace removal another day
longdefapplyfunction_d #1#2#3#4,%
%
ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
expandafterapplyfunction_e
orexpandafterapplyfunction_d_again
elseexpandafterwe_are_doomed
fi #1#2#3#4%
%
longdefapplyfunction_d_again #1#2#3#4%
%
applyfunction_d #1#2#3#4,%
%
longdefapplyfunction_e #1#2#3#4%
%
my_bbye#4applyfunction_finishmy_bbye
applyfunction_g #1#2#3#4%
%
longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%
catcode`_ 8
%% USAGE
% to define a "function" to be used as foo(a,b,c,...),
% we need a foomacro which uses standard non-delimited parameters,
% thus e.g. defined via newcommand, and then one only needs
% newcommandfooapplyfunctionfoomacro
% to get a foo to be used with parentheses.
newcommandtwomateapplyfunctiontwomatemacro
newcommandpwrapplyfunctionpwrmacro
newcommandtwoclmnapplyfunctiontwoclmnmacro
% define here the **non-delimited** auxiliary macros
newcommandtwomatemacro[4]beginpmatrix#1\#3endpmatrix
newcommandpwrmacro[1]^#1
newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix
%% TESTING NESTING
newcommandfooapplyfunctionfoomacro
newcommandfoomacro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBarmacro
newcommandBarmacro[3]left(#1*#2*#3right)
delimiterfactor1001
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
[foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
enddocument
Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...)
input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.
Nesting works, as we will test with this kind of input:
foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))
Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.
As this all works purely by expansion, expandable commands remain expandable commands.
Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c)
should first expand completely the a
, b
, c
before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded
primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q
governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c
, before applying the foo
macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc
.
documentclassarticle
usepackageamsmath
% copy over some utility code from package xintexpr
catcode`_ 11
makeatletter
letxint_c_monem@ne
letxint_c_z@
letxint_c_i@ne
longdefxint_bye #1xint_bye %
makeatother
% THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
% HERE ALL long
% % endmacrocode
% subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
% lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
% it, to @ne if opening ( had no closing ) matching it, to z@ if expression
% was balanced.|
% beginmacrocode
% use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
longdefXINT_isbalanced_b #1)#2%
xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
% endmacrocode
% lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
% beginmacrocode
longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
% endmacrocode
% lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
% beginmacrocode
longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
% endmacrocode
% lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
% we see a ). If we do, we then loop until no ( nor ) is to be found.|
% beginmacrocode
longdefXINT_isbalanced_d #1)#2%
xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
% endmacrocode
% lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
% beginmacrocode
longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% NEW EXPANDABLE UTILITY
longdefapplyfunction #1#2)%
%
ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
expandafterapplyfunction_b
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
longdefapplyfunction_again #1applyfunction #1)%
longdefmy_bbye #1my_bbye %
longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
longdefapplyfunction_c #1(applyfunction_d #1%
% we will take care of brace removal another day
longdefapplyfunction_d #1#2#3#4,%
%
ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
expandafterapplyfunction_e
orexpandafterapplyfunction_d_again
elseexpandafterwe_are_doomed
fi #1#2#3#4%
%
longdefapplyfunction_d_again #1#2#3#4%
%
applyfunction_d #1#2#3#4,%
%
longdefapplyfunction_e #1#2#3#4%
%
my_bbye#4applyfunction_finishmy_bbye
applyfunction_g #1#2#3#4%
%
longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%
catcode`_ 8
%% USAGE
% to define a "function" to be used as foo(a,b,c,...),
% we need a foomacro which uses standard non-delimited parameters,
% thus e.g. defined via newcommand, and then one only needs
% newcommandfooapplyfunctionfoomacro
% to get a foo to be used with parentheses.
newcommandtwomateapplyfunctiontwomatemacro
newcommandpwrapplyfunctionpwrmacro
newcommandtwoclmnapplyfunctiontwoclmnmacro
% define here the **non-delimited** auxiliary macros
newcommandtwomatemacro[4]beginpmatrix#1\#3endpmatrix
newcommandpwrmacro[1]^#1
newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix
%% TESTING NESTING
newcommandfooapplyfunctionfoomacro
newcommandfoomacro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBarmacro
newcommandBarmacro[3]left(#1*#2*#3right)
delimiterfactor1001
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
[foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
enddocument
edited Nov 12 at 13:53
answered Nov 10 at 8:59
jfbu
44.7k65143
44.7k65143
add a comment |
add a comment |
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f459229%2fproblems-with-def%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Since you're using LaTeX, please consider using
[ ... ]
instead of$$ ... $$
, as the latter causes some inconsistencies.– AJFarmar
Nov 10 at 13:14