Problems with def
up vote
7
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
New contributor
add a comment |
up vote
7
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
New contributor
Since you're using LaTeX, please consider using[ ... ]
instead of$$ ... $$
, as the latter causes some inconsistencies.
– AJFarmar
15 hours ago
add a comment |
up vote
7
down vote
favorite
up vote
7
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
New contributor
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
New contributor
New contributor
New contributor
asked yesterday
Hossmeister
383
383
New contributor
New contributor
Since you're using LaTeX, please consider using[ ... ]
instead of$$ ... $$
, as the latter causes some inconsistencies.
– AJFarmar
15 hours ago
add a comment |
Since you're using LaTeX, please consider using[ ... ]
instead of$$ ... $$
, as the latter causes some inconsistencies.
– AJFarmar
15 hours ago
Since you're using LaTeX, please consider using
[ ... ]
instead of $$ ... $$
, as the latter causes some inconsistencies.– AJFarmar
15 hours ago
Since you're using LaTeX, please consider using
[ ... ]
instead of $$ ... $$
, as the latter causes some inconsistencies.– AJFarmar
15 hours ago
add a comment |
4 Answers
4
active
oldest
votes
up vote
10
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
12 hours ago
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
12 hours ago
ok, just curious because I am not familiar with xparse, so your first solution allows that already? (will clean up comments afterwards). I agree with what you say over input syntax.
– jfbu
12 hours ago
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
11 hours ago
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
11 hours ago
|
show 4 more comments
up vote
9
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
5
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
original answer
Here is a way to define macros fetching their arguments like "functions" in many programming language.
It is lifted from the xintexpr
code.
I had a bit forgotten the details, and left the code comments of XINT_isbalanced_a
for those interested.
now that things come back more to my memory: of course comma separation of arguments will cause further issues. The xintexpr parser does not use at all this mechanism for implementing comma separated arguments of "functions". The mechanism as here is applied only for things such as seq(<expression>, x=1..10)
where the <expression>
if fetched as delimited by a comma, and then the balancing test is applied to it in case it was for example seq(myfunction(x,x^2),x=1..10)
where the first comma would have been intially mistakendly taken as delimiter, but then the code realizes it is not balanced so it goes further.
thus, now that I think about it, nesting here would need checking the arguments picked up by comma delimited macros are balanced with respect to parentheses. I have not applied it yet, as the poor man approach here is still very low-weight and is enough for the OP use cases
See below how applyfunction
is to be used.
(but as I explained in paragraphs above this is not provided as a nestable thing, only "functions" with 1 argument can be nested inside others; perhaps I will edit later to provide fuller solution).
Thus this is a no-package solution.
documentclassarticle
% 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
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% Define a utility to apply a "function", comma separated arguments
defapplyfunction #1(#2)%
%
ifcaseXINT_isbalanced_a relax #1#2(xint_bye)xint_bye
expandafterapplyfunction_doit
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
defapplyfunction_doit #1#1,
defapplyfunction_again #1applyfunction #1)(
catcode`_ 8
usepackageamsmath
makeatletter
% function wrappers
deftwomateapplyfunctiontwomate@csv
defpwrapplyfunctionpwr@csv
deftwoclmnapplyfunctiontwoclmn@csv
% define macros with comma delimited arguments
deftwomate@csv#1,#2,#3,#4,beginpmatrix#1\#3endpmatrix
defpwr@csv#1,^#1
deftwoclmn@csv#1,#2,beginpmatrix#1\#2endpmatrix
%
makeatother
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
enddocument
updated answer
Original code allowed only nesting of "function" with one-argument inside other "functions".
Updated code makes more general nesting possible, we will test it with this 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))
and it works.
Notice that this code works only by expansion.
Code:
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
% NOTICE THAT ALL MACROS NEXT SHOULD BE MADE `long` ARGUABLY
% IT WAS NOT NEEDED IN XINTEXPR CONTEXT
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% New utility (expandable)
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
% "functions" to be used as foo(a,b,c,...)
% Syntax: applyfunctionnondelimitedmacro
% Number of arguments is determined dynamically (at most 9)
makeatletter
newcommandtwomateapplyfunctiontwomate@macro
newcommandpwrapplyfunctionpwr@macro
newcommandtwoclmnapplyfunctiontwoclmn@macro
% define here the **non-delimited** auxiliary macros
newcommandtwomate@macro[4]beginpmatrix#1\#3endpmatrix
newcommandpwr@macro[1]^#1
newcommandtwoclmn@macro[2]beginpmatrix#1\#2endpmatrix
makeatother
%% TESTING NESTING
makeatletter
newcommandfooapplyfunctionfoo@macro
newcommandfoo@macro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBar@macro
newcommandBar@macro[3]left(#1*#2*#3right)
makeatother
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
10
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
12 hours ago
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
12 hours ago
ok, just curious because I am not familiar with xparse, so your first solution allows that already? (will clean up comments afterwards). I agree with what you say over input syntax.
– jfbu
12 hours ago
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
11 hours ago
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
11 hours ago
|
show 4 more comments
up vote
10
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
12 hours ago
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
12 hours ago
ok, just curious because I am not familiar with xparse, so your first solution allows that already? (will clean up comments afterwards). I agree with what you say over input syntax.
– jfbu
12 hours ago
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
11 hours ago
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
11 hours ago
|
show 4 more comments
up vote
10
down vote
accepted
up vote
10
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 yesterday
egreg
696k8518483108
696k8518483108
can one nest like thisfoo(a,bar(b,c,d),baz(e,f),g)
?
– jfbu
12 hours ago
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
12 hours ago
ok, just curious because I am not familiar with xparse, so your first solution allows that already? (will clean up comments afterwards). I agree with what you say over input syntax.
– jfbu
12 hours ago
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
11 hours ago
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
11 hours ago
|
show 4 more comments
can one nest like thisfoo(a,bar(b,c,d),baz(e,f),g)
?
– jfbu
12 hours ago
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
12 hours ago
ok, just curious because I am not familiar with xparse, so your first solution allows that already? (will clean up comments afterwards). I agree with what you say over input syntax.
– jfbu
12 hours ago
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
11 hours ago
@jfbu Without seeing how you definefoo
,bar
andbaz
it's just guesswork.
– egreg
11 hours ago
can one nest like this
foo(a,bar(b,c,d),baz(e,f),g)
?– jfbu
12 hours ago
can one nest like this
foo(a,bar(b,c,d),baz(e,f),g)
?– jfbu
12 hours ago
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
12 hours ago
@jfbu Yes, but why? There's no advantage whatsoever over braces.
– egreg
12 hours ago
ok, just curious because I am not familiar with xparse, so your first solution allows that already? (will clean up comments afterwards). I agree with what you say over input syntax.
– jfbu
12 hours ago
ok, just curious because I am not familiar with xparse, so your first solution allows that already? (will clean up comments afterwards). I agree with what you say over input syntax.
– jfbu
12 hours ago
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
11 hours ago
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
11 hours ago
@jfbu Without seeing how you define
foo
, bar
and baz
it's just guesswork.– egreg
11 hours ago
@jfbu Without seeing how you define
foo
, bar
and baz
it's just guesswork.– egreg
11 hours ago
|
show 4 more comments
up vote
9
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
9
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
9
down vote
up vote
9
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 yesterday
answered yesterday
Werner
429k589421618
429k589421618
add a comment |
add a comment |
up vote
5
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
5
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
5
down vote
up vote
5
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 yesterday
answered yesterday
siracusa
4,31911127
4,31911127
add a comment |
add a comment |
up vote
2
down vote
original answer
Here is a way to define macros fetching their arguments like "functions" in many programming language.
It is lifted from the xintexpr
code.
I had a bit forgotten the details, and left the code comments of XINT_isbalanced_a
for those interested.
now that things come back more to my memory: of course comma separation of arguments will cause further issues. The xintexpr parser does not use at all this mechanism for implementing comma separated arguments of "functions". The mechanism as here is applied only for things such as seq(<expression>, x=1..10)
where the <expression>
if fetched as delimited by a comma, and then the balancing test is applied to it in case it was for example seq(myfunction(x,x^2),x=1..10)
where the first comma would have been intially mistakendly taken as delimiter, but then the code realizes it is not balanced so it goes further.
thus, now that I think about it, nesting here would need checking the arguments picked up by comma delimited macros are balanced with respect to parentheses. I have not applied it yet, as the poor man approach here is still very low-weight and is enough for the OP use cases
See below how applyfunction
is to be used.
(but as I explained in paragraphs above this is not provided as a nestable thing, only "functions" with 1 argument can be nested inside others; perhaps I will edit later to provide fuller solution).
Thus this is a no-package solution.
documentclassarticle
% 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
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% Define a utility to apply a "function", comma separated arguments
defapplyfunction #1(#2)%
%
ifcaseXINT_isbalanced_a relax #1#2(xint_bye)xint_bye
expandafterapplyfunction_doit
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
defapplyfunction_doit #1#1,
defapplyfunction_again #1applyfunction #1)(
catcode`_ 8
usepackageamsmath
makeatletter
% function wrappers
deftwomateapplyfunctiontwomate@csv
defpwrapplyfunctionpwr@csv
deftwoclmnapplyfunctiontwoclmn@csv
% define macros with comma delimited arguments
deftwomate@csv#1,#2,#3,#4,beginpmatrix#1\#3endpmatrix
defpwr@csv#1,^#1
deftwoclmn@csv#1,#2,beginpmatrix#1\#2endpmatrix
%
makeatother
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
enddocument
updated answer
Original code allowed only nesting of "function" with one-argument inside other "functions".
Updated code makes more general nesting possible, we will test it with this 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))
and it works.
Notice that this code works only by expansion.
Code:
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
% NOTICE THAT ALL MACROS NEXT SHOULD BE MADE `long` ARGUABLY
% IT WAS NOT NEEDED IN XINTEXPR CONTEXT
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% New utility (expandable)
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
% "functions" to be used as foo(a,b,c,...)
% Syntax: applyfunctionnondelimitedmacro
% Number of arguments is determined dynamically (at most 9)
makeatletter
newcommandtwomateapplyfunctiontwomate@macro
newcommandpwrapplyfunctionpwr@macro
newcommandtwoclmnapplyfunctiontwoclmn@macro
% define here the **non-delimited** auxiliary macros
newcommandtwomate@macro[4]beginpmatrix#1\#3endpmatrix
newcommandpwr@macro[1]^#1
newcommandtwoclmn@macro[2]beginpmatrix#1\#2endpmatrix
makeatother
%% TESTING NESTING
makeatletter
newcommandfooapplyfunctionfoo@macro
newcommandfoo@macro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBar@macro
newcommandBar@macro[3]left(#1*#2*#3right)
makeatother
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
original answer
Here is a way to define macros fetching their arguments like "functions" in many programming language.
It is lifted from the xintexpr
code.
I had a bit forgotten the details, and left the code comments of XINT_isbalanced_a
for those interested.
now that things come back more to my memory: of course comma separation of arguments will cause further issues. The xintexpr parser does not use at all this mechanism for implementing comma separated arguments of "functions". The mechanism as here is applied only for things such as seq(<expression>, x=1..10)
where the <expression>
if fetched as delimited by a comma, and then the balancing test is applied to it in case it was for example seq(myfunction(x,x^2),x=1..10)
where the first comma would have been intially mistakendly taken as delimiter, but then the code realizes it is not balanced so it goes further.
thus, now that I think about it, nesting here would need checking the arguments picked up by comma delimited macros are balanced with respect to parentheses. I have not applied it yet, as the poor man approach here is still very low-weight and is enough for the OP use cases
See below how applyfunction
is to be used.
(but as I explained in paragraphs above this is not provided as a nestable thing, only "functions" with 1 argument can be nested inside others; perhaps I will edit later to provide fuller solution).
Thus this is a no-package solution.
documentclassarticle
% 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
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% Define a utility to apply a "function", comma separated arguments
defapplyfunction #1(#2)%
%
ifcaseXINT_isbalanced_a relax #1#2(xint_bye)xint_bye
expandafterapplyfunction_doit
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
defapplyfunction_doit #1#1,
defapplyfunction_again #1applyfunction #1)(
catcode`_ 8
usepackageamsmath
makeatletter
% function wrappers
deftwomateapplyfunctiontwomate@csv
defpwrapplyfunctionpwr@csv
deftwoclmnapplyfunctiontwoclmn@csv
% define macros with comma delimited arguments
deftwomate@csv#1,#2,#3,#4,beginpmatrix#1\#3endpmatrix
defpwr@csv#1,^#1
deftwoclmn@csv#1,#2,beginpmatrix#1\#2endpmatrix
%
makeatother
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
enddocument
updated answer
Original code allowed only nesting of "function" with one-argument inside other "functions".
Updated code makes more general nesting possible, we will test it with this 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))
and it works.
Notice that this code works only by expansion.
Code:
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
% NOTICE THAT ALL MACROS NEXT SHOULD BE MADE `long` ARGUABLY
% IT WAS NOT NEEDED IN XINTEXPR CONTEXT
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% New utility (expandable)
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
% "functions" to be used as foo(a,b,c,...)
% Syntax: applyfunctionnondelimitedmacro
% Number of arguments is determined dynamically (at most 9)
makeatletter
newcommandtwomateapplyfunctiontwomate@macro
newcommandpwrapplyfunctionpwr@macro
newcommandtwoclmnapplyfunctiontwoclmn@macro
% define here the **non-delimited** auxiliary macros
newcommandtwomate@macro[4]beginpmatrix#1\#3endpmatrix
newcommandpwr@macro[1]^#1
newcommandtwoclmn@macro[2]beginpmatrix#1\#2endpmatrix
makeatother
%% TESTING NESTING
makeatletter
newcommandfooapplyfunctionfoo@macro
newcommandfoo@macro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBar@macro
newcommandBar@macro[3]left(#1*#2*#3right)
makeatother
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
original answer
Here is a way to define macros fetching their arguments like "functions" in many programming language.
It is lifted from the xintexpr
code.
I had a bit forgotten the details, and left the code comments of XINT_isbalanced_a
for those interested.
now that things come back more to my memory: of course comma separation of arguments will cause further issues. The xintexpr parser does not use at all this mechanism for implementing comma separated arguments of "functions". The mechanism as here is applied only for things such as seq(<expression>, x=1..10)
where the <expression>
if fetched as delimited by a comma, and then the balancing test is applied to it in case it was for example seq(myfunction(x,x^2),x=1..10)
where the first comma would have been intially mistakendly taken as delimiter, but then the code realizes it is not balanced so it goes further.
thus, now that I think about it, nesting here would need checking the arguments picked up by comma delimited macros are balanced with respect to parentheses. I have not applied it yet, as the poor man approach here is still very low-weight and is enough for the OP use cases
See below how applyfunction
is to be used.
(but as I explained in paragraphs above this is not provided as a nestable thing, only "functions" with 1 argument can be nested inside others; perhaps I will edit later to provide fuller solution).
Thus this is a no-package solution.
documentclassarticle
% 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
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% Define a utility to apply a "function", comma separated arguments
defapplyfunction #1(#2)%
%
ifcaseXINT_isbalanced_a relax #1#2(xint_bye)xint_bye
expandafterapplyfunction_doit
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
defapplyfunction_doit #1#1,
defapplyfunction_again #1applyfunction #1)(
catcode`_ 8
usepackageamsmath
makeatletter
% function wrappers
deftwomateapplyfunctiontwomate@csv
defpwrapplyfunctionpwr@csv
deftwoclmnapplyfunctiontwoclmn@csv
% define macros with comma delimited arguments
deftwomate@csv#1,#2,#3,#4,beginpmatrix#1\#3endpmatrix
defpwr@csv#1,^#1
deftwoclmn@csv#1,#2,beginpmatrix#1\#2endpmatrix
%
makeatother
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
enddocument
updated answer
Original code allowed only nesting of "function" with one-argument inside other "functions".
Updated code makes more general nesting possible, we will test it with this 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))
and it works.
Notice that this code works only by expansion.
Code:
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
% NOTICE THAT ALL MACROS NEXT SHOULD BE MADE `long` ARGUABLY
% IT WAS NOT NEEDED IN XINTEXPR CONTEXT
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% New utility (expandable)
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
% "functions" to be used as foo(a,b,c,...)
% Syntax: applyfunctionnondelimitedmacro
% Number of arguments is determined dynamically (at most 9)
makeatletter
newcommandtwomateapplyfunctiontwomate@macro
newcommandpwrapplyfunctionpwr@macro
newcommandtwoclmnapplyfunctiontwoclmn@macro
% define here the **non-delimited** auxiliary macros
newcommandtwomate@macro[4]beginpmatrix#1\#3endpmatrix
newcommandpwr@macro[1]^#1
newcommandtwoclmn@macro[2]beginpmatrix#1\#2endpmatrix
makeatother
%% TESTING NESTING
makeatletter
newcommandfooapplyfunctionfoo@macro
newcommandfoo@macro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBar@macro
newcommandBar@macro[3]left(#1*#2*#3right)
makeatother
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
original answer
Here is a way to define macros fetching their arguments like "functions" in many programming language.
It is lifted from the xintexpr
code.
I had a bit forgotten the details, and left the code comments of XINT_isbalanced_a
for those interested.
now that things come back more to my memory: of course comma separation of arguments will cause further issues. The xintexpr parser does not use at all this mechanism for implementing comma separated arguments of "functions". The mechanism as here is applied only for things such as seq(<expression>, x=1..10)
where the <expression>
if fetched as delimited by a comma, and then the balancing test is applied to it in case it was for example seq(myfunction(x,x^2),x=1..10)
where the first comma would have been intially mistakendly taken as delimiter, but then the code realizes it is not balanced so it goes further.
thus, now that I think about it, nesting here would need checking the arguments picked up by comma delimited macros are balanced with respect to parentheses. I have not applied it yet, as the poor man approach here is still very low-weight and is enough for the OP use cases
See below how applyfunction
is to be used.
(but as I explained in paragraphs above this is not provided as a nestable thing, only "functions" with 1 argument can be nested inside others; perhaps I will edit later to provide fuller solution).
Thus this is a no-package solution.
documentclassarticle
% 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
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% Define a utility to apply a "function", comma separated arguments
defapplyfunction #1(#2)%
%
ifcaseXINT_isbalanced_a relax #1#2(xint_bye)xint_bye
expandafterapplyfunction_doit
orexpandafterapplyfunction_again
elseexpandafterwe_are_doomed
fi #1#2%
%
defapplyfunction_doit #1#1,
defapplyfunction_again #1applyfunction #1)(
catcode`_ 8
usepackageamsmath
makeatletter
% function wrappers
deftwomateapplyfunctiontwomate@csv
defpwrapplyfunctionpwr@csv
deftwoclmnapplyfunctiontwoclmn@csv
% define macros with comma delimited arguments
deftwomate@csv#1,#2,#3,#4,beginpmatrix#1\#3endpmatrix
defpwr@csv#1,^#1
deftwoclmn@csv#1,#2,beginpmatrix#1\#2endpmatrix
%
makeatother
begindocument
[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]
[
twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
+ frac25 t epwr(2t))
]
enddocument
updated answer
Original code allowed only nesting of "function" with one-argument inside other "functions".
Updated code makes more general nesting possible, we will test it with this 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))
and it works.
Notice that this code works only by expansion.
Code:
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
% NOTICE THAT ALL MACROS NEXT SHOULD BE MADE `long` ARGUABLY
% IT WAS NOT NEEDED IN XINTEXPR CONTEXT
% % 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
defXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
defXINT_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
defXINT_isbalanced_error #1)xint_bye xint_c_mone%
% endmacrocode
% lverb|#2 was xint_bye, was there a ) in original #1?|
% beginmacrocode
defXINT_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
defXINT_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
defXINT_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
defXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %
% New utility (expandable)
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
% "functions" to be used as foo(a,b,c,...)
% Syntax: applyfunctionnondelimitedmacro
% Number of arguments is determined dynamically (at most 9)
makeatletter
newcommandtwomateapplyfunctiontwomate@macro
newcommandpwrapplyfunctionpwr@macro
newcommandtwoclmnapplyfunctiontwoclmn@macro
% define here the **non-delimited** auxiliary macros
newcommandtwomate@macro[4]beginpmatrix#1\#3endpmatrix
newcommandpwr@macro[1]^#1
newcommandtwoclmn@macro[2]beginpmatrix#1\#2endpmatrix
makeatother
%% TESTING NESTING
makeatletter
newcommandfooapplyfunctionfoo@macro
newcommandfoo@macro[4]left[#1+#2+#3+#4right]
letBarrelax
newcommandBarapplyfunctionBar@macro
newcommandBar@macro[3]left(#1*#2*#3right)
makeatother
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 12 hours ago
answered 19 hours ago
jfbu
43.9k65142
43.9k65142
add a comment |
add a comment |
Hossmeister is a new contributor. Be nice, and check out our Code of Conduct.
Hossmeister is a new contributor. Be nice, and check out our Code of Conduct.
Hossmeister is a new contributor. Be nice, and check out our Code of Conduct.
Hossmeister is a new contributor. Be nice, and check out our Code of Conduct.
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%2f459229%2fproblems-with-def%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
Since you're using LaTeX, please consider using
[ ... ]
instead of$$ ... $$
, as the latter causes some inconsistencies.– AJFarmar
15 hours ago