Expanding macro twice
up vote
1
down vote
favorite
How would you expand a macro twice in LaTeX 2 (or 2epsilon). I am aware of the question What is the preferred way of expanding twice in expl3?, but I'm curious as to how you'd do it in LaTeX.
I'd like to point out that I suspect that if you actually need to do this in your code, you'd probably want to reformulate your code and not find a way to do this. However, I'm still curious for educational purposes.
Below is my (failing) attempt
documentclass{article}
makeatletter
% Command for printing stuff to the error log
definspect#1{@latex@warning{string#1:meaning#1}}
makeatother
defa{3}
defb{2a}
defc{1b}
% I want to obtain a macro containing "12a" from using only c
% Expand once
edefexpandedOnce{unexpandedexpandafter{c}}
inspectexpandedOnce
%% ^ produces 1b in the error log
expandafterexpandafteredefexpandafterexpandedTwice{unexpandedexpandafter{expandedOnce}}
inspectexpandedTwice
%% ^ Also produces 1b in the error log, but I'd want it to
%% produce 12a
begin{document}
~
end{document}
macros expansion
|
show 2 more comments
up vote
1
down vote
favorite
How would you expand a macro twice in LaTeX 2 (or 2epsilon). I am aware of the question What is the preferred way of expanding twice in expl3?, but I'm curious as to how you'd do it in LaTeX.
I'd like to point out that I suspect that if you actually need to do this in your code, you'd probably want to reformulate your code and not find a way to do this. However, I'm still curious for educational purposes.
Below is my (failing) attempt
documentclass{article}
makeatletter
% Command for printing stuff to the error log
definspect#1{@latex@warning{string#1:meaning#1}}
makeatother
defa{3}
defb{2a}
defc{1b}
% I want to obtain a macro containing "12a" from using only c
% Expand once
edefexpandedOnce{unexpandedexpandafter{c}}
inspectexpandedOnce
%% ^ produces 1b in the error log
expandafterexpandafteredefexpandafterexpandedTwice{unexpandedexpandafter{expandedOnce}}
inspectexpandedTwice
%% ^ Also produces 1b in the error log, but I'd want it to
%% produce 12a
begin{document}
~
end{document}
macros expansion
2
you haven't really defined what expanding twice means, normally i'd take it to meanexpandafterexpandafterexpandafterc
but1
isn't expandable so that gives you1b
you say you want12a
but do you want to expand all tokens inc
by one step, or just the first expandable token. (clearly you don't mean the first token, as I note above.) what would you want if the definition ofc
wasdefc{1b1b}
?
– David Carlisle
1 hour ago
Good question! As I note in my original question, I don't have a specific use case. I'm mostly curious about expanding all tokens inc
by one step though.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle, for the case when the definition isdefc{1b1b}
, I then guess I'd want the result to be12a12a
because then, since 1 can't be expanded further, it stays as a1
andb
is2a
after one expansion.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle No, wait. That's not twice.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle So that would be12a12a
after the first expansion and123123
after the second.
– Andreas Storvik Strauman
1 hour ago
|
show 2 more comments
up vote
1
down vote
favorite
up vote
1
down vote
favorite
How would you expand a macro twice in LaTeX 2 (or 2epsilon). I am aware of the question What is the preferred way of expanding twice in expl3?, but I'm curious as to how you'd do it in LaTeX.
I'd like to point out that I suspect that if you actually need to do this in your code, you'd probably want to reformulate your code and not find a way to do this. However, I'm still curious for educational purposes.
Below is my (failing) attempt
documentclass{article}
makeatletter
% Command for printing stuff to the error log
definspect#1{@latex@warning{string#1:meaning#1}}
makeatother
defa{3}
defb{2a}
defc{1b}
% I want to obtain a macro containing "12a" from using only c
% Expand once
edefexpandedOnce{unexpandedexpandafter{c}}
inspectexpandedOnce
%% ^ produces 1b in the error log
expandafterexpandafteredefexpandafterexpandedTwice{unexpandedexpandafter{expandedOnce}}
inspectexpandedTwice
%% ^ Also produces 1b in the error log, but I'd want it to
%% produce 12a
begin{document}
~
end{document}
macros expansion
How would you expand a macro twice in LaTeX 2 (or 2epsilon). I am aware of the question What is the preferred way of expanding twice in expl3?, but I'm curious as to how you'd do it in LaTeX.
I'd like to point out that I suspect that if you actually need to do this in your code, you'd probably want to reformulate your code and not find a way to do this. However, I'm still curious for educational purposes.
Below is my (failing) attempt
documentclass{article}
makeatletter
% Command for printing stuff to the error log
definspect#1{@latex@warning{string#1:meaning#1}}
makeatother
defa{3}
defb{2a}
defc{1b}
% I want to obtain a macro containing "12a" from using only c
% Expand once
edefexpandedOnce{unexpandedexpandafter{c}}
inspectexpandedOnce
%% ^ produces 1b in the error log
expandafterexpandafteredefexpandafterexpandedTwice{unexpandedexpandafter{expandedOnce}}
inspectexpandedTwice
%% ^ Also produces 1b in the error log, but I'd want it to
%% produce 12a
begin{document}
~
end{document}
macros expansion
macros expansion
asked 1 hour ago
Andreas Storvik Strauman
2,317418
2,317418
2
you haven't really defined what expanding twice means, normally i'd take it to meanexpandafterexpandafterexpandafterc
but1
isn't expandable so that gives you1b
you say you want12a
but do you want to expand all tokens inc
by one step, or just the first expandable token. (clearly you don't mean the first token, as I note above.) what would you want if the definition ofc
wasdefc{1b1b}
?
– David Carlisle
1 hour ago
Good question! As I note in my original question, I don't have a specific use case. I'm mostly curious about expanding all tokens inc
by one step though.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle, for the case when the definition isdefc{1b1b}
, I then guess I'd want the result to be12a12a
because then, since 1 can't be expanded further, it stays as a1
andb
is2a
after one expansion.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle No, wait. That's not twice.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle So that would be12a12a
after the first expansion and123123
after the second.
– Andreas Storvik Strauman
1 hour ago
|
show 2 more comments
2
you haven't really defined what expanding twice means, normally i'd take it to meanexpandafterexpandafterexpandafterc
but1
isn't expandable so that gives you1b
you say you want12a
but do you want to expand all tokens inc
by one step, or just the first expandable token. (clearly you don't mean the first token, as I note above.) what would you want if the definition ofc
wasdefc{1b1b}
?
– David Carlisle
1 hour ago
Good question! As I note in my original question, I don't have a specific use case. I'm mostly curious about expanding all tokens inc
by one step though.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle, for the case when the definition isdefc{1b1b}
, I then guess I'd want the result to be12a12a
because then, since 1 can't be expanded further, it stays as a1
andb
is2a
after one expansion.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle No, wait. That's not twice.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle So that would be12a12a
after the first expansion and123123
after the second.
– Andreas Storvik Strauman
1 hour ago
2
2
you haven't really defined what expanding twice means, normally i'd take it to mean
expandafterexpandafterexpandafterc
but 1
isn't expandable so that gives you 1b
you say you want 12a
but do you want to expand all tokens in c
by one step, or just the first expandable token. (clearly you don't mean the first token, as I note above.) what would you want if the definition of c
was defc{1b1b}
?– David Carlisle
1 hour ago
you haven't really defined what expanding twice means, normally i'd take it to mean
expandafterexpandafterexpandafterc
but 1
isn't expandable so that gives you 1b
you say you want 12a
but do you want to expand all tokens in c
by one step, or just the first expandable token. (clearly you don't mean the first token, as I note above.) what would you want if the definition of c
was defc{1b1b}
?– David Carlisle
1 hour ago
Good question! As I note in my original question, I don't have a specific use case. I'm mostly curious about expanding all tokens in
c
by one step though.– Andreas Storvik Strauman
1 hour ago
Good question! As I note in my original question, I don't have a specific use case. I'm mostly curious about expanding all tokens in
c
by one step though.– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle, for the case when the definition is
defc{1b1b}
, I then guess I'd want the result to be 12a12a
because then, since 1 can't be expanded further, it stays as a 1
and b
is 2a
after one expansion.– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle, for the case when the definition is
defc{1b1b}
, I then guess I'd want the result to be 12a12a
because then, since 1 can't be expanded further, it stays as a 1
and b
is 2a
after one expansion.– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle No, wait. That's not twice.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle No, wait. That's not twice.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle So that would be
12a12a
after the first expansion and 123123
after the second.– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle So that would be
12a12a
after the first expansion and 123123
after the second.– Andreas Storvik Strauman
1 hour ago
|
show 2 more comments
2 Answers
2
active
oldest
votes
up vote
2
down vote
I get
> zz=macro:
->12a 12a .
on the terminal from etex (or pdftex) from
defa{3}
defb{2a}
defc{1b1b}
defafterfi#1fi{fi#1}
deffoo#1{ifxrelax#1elseafterfiexpandafterunexpandedexpandafter{#1}foofi}
edefzz{expandafterfoocrelax}
showzz
bye
Note that this is the expansion order that you asked for, as far as I can tell but is not the order that TeX would use normally so it isnt really "expanding twice"
Consider
defa{b} defb#1{} defc{zzzzz}
defz{ac}
by your definition I think you want to expand a
and c
once in the first step so getting a "first expansion" of z
as b zzzzz
then on a second step expand b
so get zzzz
.
However TeX would fully expand the first token at each stage, so in the first step get bc
then in the second step get an empty list. c
would never be expanded at all by TeX.
add a comment |
up vote
1
down vote
New answer
The following expands every token in tmp
(which is what you want, I hope) in a more reliable way. I didn't test it thoroughly though.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
defa{3}
defb{2a}
defc{1{b}}
defafterfi#1fi{fi#1}
makeatletter
defq@stop{q@stop}
defexpandingloop@a#1#%
{%
expandingloop@b#1q@stop
expandingloop@c
}
defexpandingloop@b#1%
{%
ifxq@stop#1%
else
afterfiunexpandedexpandafter{#1}expandingloop@b
fi
}
newcommandexpandingloop@c[1]
{%
ifxq@stop#1%
else
afterfi{expandingloop@a#1{q@stop}}expandingloop@a%
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop@a#1{q@stop}}%
}
makeatother
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
noindent
For verb|foo|:
lettmpfoo
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
noindent
For verb|c|:
lettmpc
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
end{document}
Old answer
Both of the following only expand the first token.
You can use edeffooA{unexpandedexpandafterexpandafterexpandafter{fooB}}
to define fooA
to be the same as a fooB
expanded twice.
Doing stuff with a temporary macro one could do something like the following.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
newcommandsingleexpand[1]
{%
edef#1{unexpandedexpandafterexpandafterexpandafter{#1}}%
}
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
lettmpfoo
Unexpanded:
Meaningtmp
singleexpandtmp
Expanded once:
Meaningtmp
singleexpandtmp
Expanded twice:
Meaningtmp
end{document}
Being evil when the argument contains a group (but it works in the minimal example, everything else is a matter of adding an infinite number of tests):
defafterfi#1fi{fi#1}
defexpandingloop#1#2endexpandingloop
{%
unexpandedexpandafter{#1}%
ifrelaxdetokenize{#2}relax
else
afterfiexpandingloop#2endexpandingloop
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop#1endexpandingloop}%
}
Sorry. I really should have explicitly said that it's not only the first expandable token.
– Andreas Storvik Strauman
1 hour ago
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
I get
> zz=macro:
->12a 12a .
on the terminal from etex (or pdftex) from
defa{3}
defb{2a}
defc{1b1b}
defafterfi#1fi{fi#1}
deffoo#1{ifxrelax#1elseafterfiexpandafterunexpandedexpandafter{#1}foofi}
edefzz{expandafterfoocrelax}
showzz
bye
Note that this is the expansion order that you asked for, as far as I can tell but is not the order that TeX would use normally so it isnt really "expanding twice"
Consider
defa{b} defb#1{} defc{zzzzz}
defz{ac}
by your definition I think you want to expand a
and c
once in the first step so getting a "first expansion" of z
as b zzzzz
then on a second step expand b
so get zzzz
.
However TeX would fully expand the first token at each stage, so in the first step get bc
then in the second step get an empty list. c
would never be expanded at all by TeX.
add a comment |
up vote
2
down vote
I get
> zz=macro:
->12a 12a .
on the terminal from etex (or pdftex) from
defa{3}
defb{2a}
defc{1b1b}
defafterfi#1fi{fi#1}
deffoo#1{ifxrelax#1elseafterfiexpandafterunexpandedexpandafter{#1}foofi}
edefzz{expandafterfoocrelax}
showzz
bye
Note that this is the expansion order that you asked for, as far as I can tell but is not the order that TeX would use normally so it isnt really "expanding twice"
Consider
defa{b} defb#1{} defc{zzzzz}
defz{ac}
by your definition I think you want to expand a
and c
once in the first step so getting a "first expansion" of z
as b zzzzz
then on a second step expand b
so get zzzz
.
However TeX would fully expand the first token at each stage, so in the first step get bc
then in the second step get an empty list. c
would never be expanded at all by TeX.
add a comment |
up vote
2
down vote
up vote
2
down vote
I get
> zz=macro:
->12a 12a .
on the terminal from etex (or pdftex) from
defa{3}
defb{2a}
defc{1b1b}
defafterfi#1fi{fi#1}
deffoo#1{ifxrelax#1elseafterfiexpandafterunexpandedexpandafter{#1}foofi}
edefzz{expandafterfoocrelax}
showzz
bye
Note that this is the expansion order that you asked for, as far as I can tell but is not the order that TeX would use normally so it isnt really "expanding twice"
Consider
defa{b} defb#1{} defc{zzzzz}
defz{ac}
by your definition I think you want to expand a
and c
once in the first step so getting a "first expansion" of z
as b zzzzz
then on a second step expand b
so get zzzz
.
However TeX would fully expand the first token at each stage, so in the first step get bc
then in the second step get an empty list. c
would never be expanded at all by TeX.
I get
> zz=macro:
->12a 12a .
on the terminal from etex (or pdftex) from
defa{3}
defb{2a}
defc{1b1b}
defafterfi#1fi{fi#1}
deffoo#1{ifxrelax#1elseafterfiexpandafterunexpandedexpandafter{#1}foofi}
edefzz{expandafterfoocrelax}
showzz
bye
Note that this is the expansion order that you asked for, as far as I can tell but is not the order that TeX would use normally so it isnt really "expanding twice"
Consider
defa{b} defb#1{} defc{zzzzz}
defz{ac}
by your definition I think you want to expand a
and c
once in the first step so getting a "first expansion" of z
as b zzzzz
then on a second step expand b
so get zzzz
.
However TeX would fully expand the first token at each stage, so in the first step get bc
then in the second step get an empty list. c
would never be expanded at all by TeX.
edited 1 hour ago
answered 1 hour ago
David Carlisle
477k3811061841
477k3811061841
add a comment |
add a comment |
up vote
1
down vote
New answer
The following expands every token in tmp
(which is what you want, I hope) in a more reliable way. I didn't test it thoroughly though.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
defa{3}
defb{2a}
defc{1{b}}
defafterfi#1fi{fi#1}
makeatletter
defq@stop{q@stop}
defexpandingloop@a#1#%
{%
expandingloop@b#1q@stop
expandingloop@c
}
defexpandingloop@b#1%
{%
ifxq@stop#1%
else
afterfiunexpandedexpandafter{#1}expandingloop@b
fi
}
newcommandexpandingloop@c[1]
{%
ifxq@stop#1%
else
afterfi{expandingloop@a#1{q@stop}}expandingloop@a%
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop@a#1{q@stop}}%
}
makeatother
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
noindent
For verb|foo|:
lettmpfoo
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
noindent
For verb|c|:
lettmpc
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
end{document}
Old answer
Both of the following only expand the first token.
You can use edeffooA{unexpandedexpandafterexpandafterexpandafter{fooB}}
to define fooA
to be the same as a fooB
expanded twice.
Doing stuff with a temporary macro one could do something like the following.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
newcommandsingleexpand[1]
{%
edef#1{unexpandedexpandafterexpandafterexpandafter{#1}}%
}
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
lettmpfoo
Unexpanded:
Meaningtmp
singleexpandtmp
Expanded once:
Meaningtmp
singleexpandtmp
Expanded twice:
Meaningtmp
end{document}
Being evil when the argument contains a group (but it works in the minimal example, everything else is a matter of adding an infinite number of tests):
defafterfi#1fi{fi#1}
defexpandingloop#1#2endexpandingloop
{%
unexpandedexpandafter{#1}%
ifrelaxdetokenize{#2}relax
else
afterfiexpandingloop#2endexpandingloop
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop#1endexpandingloop}%
}
Sorry. I really should have explicitly said that it's not only the first expandable token.
– Andreas Storvik Strauman
1 hour ago
add a comment |
up vote
1
down vote
New answer
The following expands every token in tmp
(which is what you want, I hope) in a more reliable way. I didn't test it thoroughly though.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
defa{3}
defb{2a}
defc{1{b}}
defafterfi#1fi{fi#1}
makeatletter
defq@stop{q@stop}
defexpandingloop@a#1#%
{%
expandingloop@b#1q@stop
expandingloop@c
}
defexpandingloop@b#1%
{%
ifxq@stop#1%
else
afterfiunexpandedexpandafter{#1}expandingloop@b
fi
}
newcommandexpandingloop@c[1]
{%
ifxq@stop#1%
else
afterfi{expandingloop@a#1{q@stop}}expandingloop@a%
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop@a#1{q@stop}}%
}
makeatother
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
noindent
For verb|foo|:
lettmpfoo
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
noindent
For verb|c|:
lettmpc
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
end{document}
Old answer
Both of the following only expand the first token.
You can use edeffooA{unexpandedexpandafterexpandafterexpandafter{fooB}}
to define fooA
to be the same as a fooB
expanded twice.
Doing stuff with a temporary macro one could do something like the following.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
newcommandsingleexpand[1]
{%
edef#1{unexpandedexpandafterexpandafterexpandafter{#1}}%
}
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
lettmpfoo
Unexpanded:
Meaningtmp
singleexpandtmp
Expanded once:
Meaningtmp
singleexpandtmp
Expanded twice:
Meaningtmp
end{document}
Being evil when the argument contains a group (but it works in the minimal example, everything else is a matter of adding an infinite number of tests):
defafterfi#1fi{fi#1}
defexpandingloop#1#2endexpandingloop
{%
unexpandedexpandafter{#1}%
ifrelaxdetokenize{#2}relax
else
afterfiexpandingloop#2endexpandingloop
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop#1endexpandingloop}%
}
Sorry. I really should have explicitly said that it's not only the first expandable token.
– Andreas Storvik Strauman
1 hour ago
add a comment |
up vote
1
down vote
up vote
1
down vote
New answer
The following expands every token in tmp
(which is what you want, I hope) in a more reliable way. I didn't test it thoroughly though.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
defa{3}
defb{2a}
defc{1{b}}
defafterfi#1fi{fi#1}
makeatletter
defq@stop{q@stop}
defexpandingloop@a#1#%
{%
expandingloop@b#1q@stop
expandingloop@c
}
defexpandingloop@b#1%
{%
ifxq@stop#1%
else
afterfiunexpandedexpandafter{#1}expandingloop@b
fi
}
newcommandexpandingloop@c[1]
{%
ifxq@stop#1%
else
afterfi{expandingloop@a#1{q@stop}}expandingloop@a%
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop@a#1{q@stop}}%
}
makeatother
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
noindent
For verb|foo|:
lettmpfoo
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
noindent
For verb|c|:
lettmpc
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
end{document}
Old answer
Both of the following only expand the first token.
You can use edeffooA{unexpandedexpandafterexpandafterexpandafter{fooB}}
to define fooA
to be the same as a fooB
expanded twice.
Doing stuff with a temporary macro one could do something like the following.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
newcommandsingleexpand[1]
{%
edef#1{unexpandedexpandafterexpandafterexpandafter{#1}}%
}
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
lettmpfoo
Unexpanded:
Meaningtmp
singleexpandtmp
Expanded once:
Meaningtmp
singleexpandtmp
Expanded twice:
Meaningtmp
end{document}
Being evil when the argument contains a group (but it works in the minimal example, everything else is a matter of adding an infinite number of tests):
defafterfi#1fi{fi#1}
defexpandingloop#1#2endexpandingloop
{%
unexpandedexpandafter{#1}%
ifrelaxdetokenize{#2}relax
else
afterfiexpandingloop#2endexpandingloop
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop#1endexpandingloop}%
}
New answer
The following expands every token in tmp
(which is what you want, I hope) in a more reliable way. I didn't test it thoroughly though.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
defa{3}
defb{2a}
defc{1{b}}
defafterfi#1fi{fi#1}
makeatletter
defq@stop{q@stop}
defexpandingloop@a#1#%
{%
expandingloop@b#1q@stop
expandingloop@c
}
defexpandingloop@b#1%
{%
ifxq@stop#1%
else
afterfiunexpandedexpandafter{#1}expandingloop@b
fi
}
newcommandexpandingloop@c[1]
{%
ifxq@stop#1%
else
afterfi{expandingloop@a#1{q@stop}}expandingloop@a%
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop@a#1{q@stop}}%
}
makeatother
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
noindent
For verb|foo|:
lettmpfoo
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
noindent
For verb|c|:
lettmpc
Unexpanded:
Meaningtmp
singleallexpandtmp
Expanded once:
Meaningtmp
singleallexpandtmp
Expanded twice:
Meaningtmp
end{document}
Old answer
Both of the following only expand the first token.
You can use edeffooA{unexpandedexpandafterexpandafterexpandafter{fooB}}
to define fooA
to be the same as a fooB
expanded twice.
Doing stuff with a temporary macro one could do something like the following.
documentclass{article}
newcommandfoo{bazA}
newcommandbazA{bazB}
newcommandbazB{bar}
newcommandsingleexpand[1]
{%
edef#1{unexpandedexpandafterexpandafterexpandafter{#1}}%
}
newcommandMeaning[1]{texttt{meaning#1}}
begin{document}
lettmpfoo
Unexpanded:
Meaningtmp
singleexpandtmp
Expanded once:
Meaningtmp
singleexpandtmp
Expanded twice:
Meaningtmp
end{document}
Being evil when the argument contains a group (but it works in the minimal example, everything else is a matter of adding an infinite number of tests):
defafterfi#1fi{fi#1}
defexpandingloop#1#2endexpandingloop
{%
unexpandedexpandafter{#1}%
ifrelaxdetokenize{#2}relax
else
afterfiexpandingloop#2endexpandingloop
fi
}
newcommandsingleallexpand[1]
{%
edef#1{expandafterexpandingloop#1endexpandingloop}%
}
edited 7 mins ago
answered 1 hour ago
Skillmon
20.4k11840
20.4k11840
Sorry. I really should have explicitly said that it's not only the first expandable token.
– Andreas Storvik Strauman
1 hour ago
add a comment |
Sorry. I really should have explicitly said that it's not only the first expandable token.
– Andreas Storvik Strauman
1 hour ago
Sorry. I really should have explicitly said that it's not only the first expandable token.
– Andreas Storvik Strauman
1 hour ago
Sorry. I really should have explicitly said that it's not only the first expandable token.
– Andreas Storvik Strauman
1 hour ago
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f461620%2fexpanding-macro-twice%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
2
you haven't really defined what expanding twice means, normally i'd take it to mean
expandafterexpandafterexpandafterc
but1
isn't expandable so that gives you1b
you say you want12a
but do you want to expand all tokens inc
by one step, or just the first expandable token. (clearly you don't mean the first token, as I note above.) what would you want if the definition ofc
wasdefc{1b1b}
?– David Carlisle
1 hour ago
Good question! As I note in my original question, I don't have a specific use case. I'm mostly curious about expanding all tokens in
c
by one step though.– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle, for the case when the definition is
defc{1b1b}
, I then guess I'd want the result to be12a12a
because then, since 1 can't be expanded further, it stays as a1
andb
is2a
after one expansion.– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle No, wait. That's not twice.
– Andreas Storvik Strauman
1 hour ago
@DavidCarlisle So that would be
12a12a
after the first expansion and123123
after the second.– Andreas Storvik Strauman
1 hour ago