@nameuse with value relax in conditionals
This is a follow-up to this question: @nameuse as conditional where i asked about how to use expandafter
if i combine @nameuse
with ifx
. However, in my real-life example, i use relax
as a default value for dynamically assigned csnames. I want to know if these control sequences have a specific value, or if they are default. My naive approach would be something like:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
but this doesn't work. In its simplest form it gives "false", but in more complex form (with xmltex, a macro definition, and another ifx-structure around) i get Extra else
errors. I'd like to understand why that is and what i need to do to make it work.
Bonus: I'd prefer a “plain” solution, i.e. no expl3-syntax or complex packages since i want to be as independent as possible from my code's user's configurations.
EDIT:
Here is the problem i'm facing: I want to store some information of the cells of a table. I'm using David Carlisle's xmltex mechanism to parse html tables. Elements are grabbed and transmitted directly into corresponding tex macros. The necessary counters are incremented at the beginning of every such macro.
In the cell definiton iterate over all cells and use a global macro
gdefSetCellProp#1#2{expandafterdefcsname cell-thecurtab-thecurrow-thecurcel-#2endcsname{#1}}
to store properties like the cells calculated width (content in mybox
; @tempdima=wdmybox
), its content, and its background-color. E.g., i am in the second table, third row, second column, then the width of that cell (e.g. "12mm") is stored with SetCellProp{12mm}{width} which "creates" a control sequence named cell-3-2-2-width
that yields the value "12mm".
Likewise, i have want to store the biggest value for width so far using
gdefSetColProp#1#2{expandafterdefcsname col-thecurtab-thecurcel-#2endcsname{#1}}
The macro that returns that value is defined as
gdefGetCurColProp#1{csname cell-thecurtab-thecurcel-#1endcsname}
Note, that this definition doesn't care about the row i am in. Since i re-count cells each row, i need to decide whether to overwrite the maximum value, or not if it is present at all.
To do so, in each cell, we need to check if
- a maxwidth for the column the current cell is in, is already given
- 2a. if no, make the current cell's width maxwidth for the whole column
- 2b. if yes, look if the value for the current width is larger than maxwidth for the column
- 3a if yes, make that current value the new maxwidth for the while column,
- 3b if no, leave everything as it is.
The part of my cell definition so far looks like:
%% check if maxwidth for the col is already given:
ifxcsname cell-thecurtab-thecurcel-maxidthendcsnamerelax
%% if no, take current width (@tempdima) as maxwidth
expandafterSetColPropexpandafter{the@tempdima}{maxwidth}%
else
%% else check if current width is larger than maxwidth:
expandafter@tempdimbGetCurColProp{maxwidth}%
ifdim@tempdimb<@tempdima
%% if so, reassign maxwidth with curwidth:
expandafterSetColPropexpandafter{the@tempdima}{maxwidth}%
fi
fi
where curtab
counts the tables, currow
counts the current row, and curcel
the number of the cell in the row (gets reset to 1 at the beginning of every row). The aim is to get the maximum width of any column my table has.
I hope that explains my problem a little bit.
tex-core conditionals
|
show 2 more comments
This is a follow-up to this question: @nameuse as conditional where i asked about how to use expandafter
if i combine @nameuse
with ifx
. However, in my real-life example, i use relax
as a default value for dynamically assigned csnames. I want to know if these control sequences have a specific value, or if they are default. My naive approach would be something like:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
but this doesn't work. In its simplest form it gives "false", but in more complex form (with xmltex, a macro definition, and another ifx-structure around) i get Extra else
errors. I'd like to understand why that is and what i need to do to make it work.
Bonus: I'd prefer a “plain” solution, i.e. no expl3-syntax or complex packages since i want to be as independent as possible from my code's user's configurations.
EDIT:
Here is the problem i'm facing: I want to store some information of the cells of a table. I'm using David Carlisle's xmltex mechanism to parse html tables. Elements are grabbed and transmitted directly into corresponding tex macros. The necessary counters are incremented at the beginning of every such macro.
In the cell definiton iterate over all cells and use a global macro
gdefSetCellProp#1#2{expandafterdefcsname cell-thecurtab-thecurrow-thecurcel-#2endcsname{#1}}
to store properties like the cells calculated width (content in mybox
; @tempdima=wdmybox
), its content, and its background-color. E.g., i am in the second table, third row, second column, then the width of that cell (e.g. "12mm") is stored with SetCellProp{12mm}{width} which "creates" a control sequence named cell-3-2-2-width
that yields the value "12mm".
Likewise, i have want to store the biggest value for width so far using
gdefSetColProp#1#2{expandafterdefcsname col-thecurtab-thecurcel-#2endcsname{#1}}
The macro that returns that value is defined as
gdefGetCurColProp#1{csname cell-thecurtab-thecurcel-#1endcsname}
Note, that this definition doesn't care about the row i am in. Since i re-count cells each row, i need to decide whether to overwrite the maximum value, or not if it is present at all.
To do so, in each cell, we need to check if
- a maxwidth for the column the current cell is in, is already given
- 2a. if no, make the current cell's width maxwidth for the whole column
- 2b. if yes, look if the value for the current width is larger than maxwidth for the column
- 3a if yes, make that current value the new maxwidth for the while column,
- 3b if no, leave everything as it is.
The part of my cell definition so far looks like:
%% check if maxwidth for the col is already given:
ifxcsname cell-thecurtab-thecurcel-maxidthendcsnamerelax
%% if no, take current width (@tempdima) as maxwidth
expandafterSetColPropexpandafter{the@tempdima}{maxwidth}%
else
%% else check if current width is larger than maxwidth:
expandafter@tempdimbGetCurColProp{maxwidth}%
ifdim@tempdimb<@tempdima
%% if so, reassign maxwidth with curwidth:
expandafterSetColPropexpandafter{the@tempdima}{maxwidth}%
fi
fi
where curtab
counts the tables, currow
counts the current row, and curcel
the number of the cell in the row (gets reset to 1 at the beginning of every row). The aim is to get the maximum width of any column my table has.
I hope that explains my problem a little bit.
tex-core conditionals
> blafasel=macro://->relax .//l.9 showblafasel
andrelax=relax.//l.10 showrelax
show thatrelax
andblafasel
are different forifx
. One is a macro expanding torelax
, the other one isrelax
.
– moewe
Jan 24 at 12:17
Tryexpandafterexpandafterexpandafterifx@nameuse{blafasel}testrelax
wheretestrelax
isdeftestrelax{relax}
. Orexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
to test notblafasel
againstrelax
, but the expansion ofblafasel
.
– moewe
Jan 24 at 12:18
1
Copying my comment from the other post:ifx
compares the meaning of two tokens without expanding them previously, sorelax
is valid. Of course the comparison will only be true if both tokens expand torelax
, for instance this code first yieldsfoo is NOT relax
because, obviously,foo
is notrelax
, it only containsrelax
in its definition. The second comparison yieldsfoo is relax
because you makefoo
an exact copy ofrelax
.
– Phelype Oleinik
Jan 24 at 12:22
Note that undefinedcsname
s arerelax
by default, so if you had not initialisedblafasel
with@namedef{blafasel}{relax}
thenexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
would have worked.
– moewe
Jan 24 at 12:23
@moewe the whole point of this exersice is to test whether my cs is initialised, or not. If not, then my next step is to initialise it with a pre-defined default value (other thanrelax
).
– Lupino
Jan 24 at 12:28
|
show 2 more comments
This is a follow-up to this question: @nameuse as conditional where i asked about how to use expandafter
if i combine @nameuse
with ifx
. However, in my real-life example, i use relax
as a default value for dynamically assigned csnames. I want to know if these control sequences have a specific value, or if they are default. My naive approach would be something like:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
but this doesn't work. In its simplest form it gives "false", but in more complex form (with xmltex, a macro definition, and another ifx-structure around) i get Extra else
errors. I'd like to understand why that is and what i need to do to make it work.
Bonus: I'd prefer a “plain” solution, i.e. no expl3-syntax or complex packages since i want to be as independent as possible from my code's user's configurations.
EDIT:
Here is the problem i'm facing: I want to store some information of the cells of a table. I'm using David Carlisle's xmltex mechanism to parse html tables. Elements are grabbed and transmitted directly into corresponding tex macros. The necessary counters are incremented at the beginning of every such macro.
In the cell definiton iterate over all cells and use a global macro
gdefSetCellProp#1#2{expandafterdefcsname cell-thecurtab-thecurrow-thecurcel-#2endcsname{#1}}
to store properties like the cells calculated width (content in mybox
; @tempdima=wdmybox
), its content, and its background-color. E.g., i am in the second table, third row, second column, then the width of that cell (e.g. "12mm") is stored with SetCellProp{12mm}{width} which "creates" a control sequence named cell-3-2-2-width
that yields the value "12mm".
Likewise, i have want to store the biggest value for width so far using
gdefSetColProp#1#2{expandafterdefcsname col-thecurtab-thecurcel-#2endcsname{#1}}
The macro that returns that value is defined as
gdefGetCurColProp#1{csname cell-thecurtab-thecurcel-#1endcsname}
Note, that this definition doesn't care about the row i am in. Since i re-count cells each row, i need to decide whether to overwrite the maximum value, or not if it is present at all.
To do so, in each cell, we need to check if
- a maxwidth for the column the current cell is in, is already given
- 2a. if no, make the current cell's width maxwidth for the whole column
- 2b. if yes, look if the value for the current width is larger than maxwidth for the column
- 3a if yes, make that current value the new maxwidth for the while column,
- 3b if no, leave everything as it is.
The part of my cell definition so far looks like:
%% check if maxwidth for the col is already given:
ifxcsname cell-thecurtab-thecurcel-maxidthendcsnamerelax
%% if no, take current width (@tempdima) as maxwidth
expandafterSetColPropexpandafter{the@tempdima}{maxwidth}%
else
%% else check if current width is larger than maxwidth:
expandafter@tempdimbGetCurColProp{maxwidth}%
ifdim@tempdimb<@tempdima
%% if so, reassign maxwidth with curwidth:
expandafterSetColPropexpandafter{the@tempdima}{maxwidth}%
fi
fi
where curtab
counts the tables, currow
counts the current row, and curcel
the number of the cell in the row (gets reset to 1 at the beginning of every row). The aim is to get the maximum width of any column my table has.
I hope that explains my problem a little bit.
tex-core conditionals
This is a follow-up to this question: @nameuse as conditional where i asked about how to use expandafter
if i combine @nameuse
with ifx
. However, in my real-life example, i use relax
as a default value for dynamically assigned csnames. I want to know if these control sequences have a specific value, or if they are default. My naive approach would be something like:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
but this doesn't work. In its simplest form it gives "false", but in more complex form (with xmltex, a macro definition, and another ifx-structure around) i get Extra else
errors. I'd like to understand why that is and what i need to do to make it work.
Bonus: I'd prefer a “plain” solution, i.e. no expl3-syntax or complex packages since i want to be as independent as possible from my code's user's configurations.
EDIT:
Here is the problem i'm facing: I want to store some information of the cells of a table. I'm using David Carlisle's xmltex mechanism to parse html tables. Elements are grabbed and transmitted directly into corresponding tex macros. The necessary counters are incremented at the beginning of every such macro.
In the cell definiton iterate over all cells and use a global macro
gdefSetCellProp#1#2{expandafterdefcsname cell-thecurtab-thecurrow-thecurcel-#2endcsname{#1}}
to store properties like the cells calculated width (content in mybox
; @tempdima=wdmybox
), its content, and its background-color. E.g., i am in the second table, third row, second column, then the width of that cell (e.g. "12mm") is stored with SetCellProp{12mm}{width} which "creates" a control sequence named cell-3-2-2-width
that yields the value "12mm".
Likewise, i have want to store the biggest value for width so far using
gdefSetColProp#1#2{expandafterdefcsname col-thecurtab-thecurcel-#2endcsname{#1}}
The macro that returns that value is defined as
gdefGetCurColProp#1{csname cell-thecurtab-thecurcel-#1endcsname}
Note, that this definition doesn't care about the row i am in. Since i re-count cells each row, i need to decide whether to overwrite the maximum value, or not if it is present at all.
To do so, in each cell, we need to check if
- a maxwidth for the column the current cell is in, is already given
- 2a. if no, make the current cell's width maxwidth for the whole column
- 2b. if yes, look if the value for the current width is larger than maxwidth for the column
- 3a if yes, make that current value the new maxwidth for the while column,
- 3b if no, leave everything as it is.
The part of my cell definition so far looks like:
%% check if maxwidth for the col is already given:
ifxcsname cell-thecurtab-thecurcel-maxidthendcsnamerelax
%% if no, take current width (@tempdima) as maxwidth
expandafterSetColPropexpandafter{the@tempdima}{maxwidth}%
else
%% else check if current width is larger than maxwidth:
expandafter@tempdimbGetCurColProp{maxwidth}%
ifdim@tempdimb<@tempdima
%% if so, reassign maxwidth with curwidth:
expandafterSetColPropexpandafter{the@tempdima}{maxwidth}%
fi
fi
where curtab
counts the tables, currow
counts the current row, and curcel
the number of the cell in the row (gets reset to 1 at the beginning of every row). The aim is to get the maximum width of any column my table has.
I hope that explains my problem a little bit.
tex-core conditionals
tex-core conditionals
edited Jan 24 at 14:06
Lupino
asked Jan 24 at 12:13


LupinoLupino
1,176610
1,176610
> blafasel=macro://->relax .//l.9 showblafasel
andrelax=relax.//l.10 showrelax
show thatrelax
andblafasel
are different forifx
. One is a macro expanding torelax
, the other one isrelax
.
– moewe
Jan 24 at 12:17
Tryexpandafterexpandafterexpandafterifx@nameuse{blafasel}testrelax
wheretestrelax
isdeftestrelax{relax}
. Orexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
to test notblafasel
againstrelax
, but the expansion ofblafasel
.
– moewe
Jan 24 at 12:18
1
Copying my comment from the other post:ifx
compares the meaning of two tokens without expanding them previously, sorelax
is valid. Of course the comparison will only be true if both tokens expand torelax
, for instance this code first yieldsfoo is NOT relax
because, obviously,foo
is notrelax
, it only containsrelax
in its definition. The second comparison yieldsfoo is relax
because you makefoo
an exact copy ofrelax
.
– Phelype Oleinik
Jan 24 at 12:22
Note that undefinedcsname
s arerelax
by default, so if you had not initialisedblafasel
with@namedef{blafasel}{relax}
thenexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
would have worked.
– moewe
Jan 24 at 12:23
@moewe the whole point of this exersice is to test whether my cs is initialised, or not. If not, then my next step is to initialise it with a pre-defined default value (other thanrelax
).
– Lupino
Jan 24 at 12:28
|
show 2 more comments
> blafasel=macro://->relax .//l.9 showblafasel
andrelax=relax.//l.10 showrelax
show thatrelax
andblafasel
are different forifx
. One is a macro expanding torelax
, the other one isrelax
.
– moewe
Jan 24 at 12:17
Tryexpandafterexpandafterexpandafterifx@nameuse{blafasel}testrelax
wheretestrelax
isdeftestrelax{relax}
. Orexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
to test notblafasel
againstrelax
, but the expansion ofblafasel
.
– moewe
Jan 24 at 12:18
1
Copying my comment from the other post:ifx
compares the meaning of two tokens without expanding them previously, sorelax
is valid. Of course the comparison will only be true if both tokens expand torelax
, for instance this code first yieldsfoo is NOT relax
because, obviously,foo
is notrelax
, it only containsrelax
in its definition. The second comparison yieldsfoo is relax
because you makefoo
an exact copy ofrelax
.
– Phelype Oleinik
Jan 24 at 12:22
Note that undefinedcsname
s arerelax
by default, so if you had not initialisedblafasel
with@namedef{blafasel}{relax}
thenexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
would have worked.
– moewe
Jan 24 at 12:23
@moewe the whole point of this exersice is to test whether my cs is initialised, or not. If not, then my next step is to initialise it with a pre-defined default value (other thanrelax
).
– Lupino
Jan 24 at 12:28
> blafasel=macro://->relax .//l.9 showblafasel
and relax=relax.//l.10 showrelax
show that relax
and blafasel
are different for ifx
. One is a macro expanding to relax
, the other one is relax
.– moewe
Jan 24 at 12:17
> blafasel=macro://->relax .//l.9 showblafasel
and relax=relax.//l.10 showrelax
show that relax
and blafasel
are different for ifx
. One is a macro expanding to relax
, the other one is relax
.– moewe
Jan 24 at 12:17
Try
expandafterexpandafterexpandafterifx@nameuse{blafasel}testrelax
where testrelax
is deftestrelax{relax}
. Or expandafterexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
to test not blafasel
against relax
, but the expansion of blafasel
.– moewe
Jan 24 at 12:18
Try
expandafterexpandafterexpandafterifx@nameuse{blafasel}testrelax
where testrelax
is deftestrelax{relax}
. Or expandafterexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
to test not blafasel
against relax
, but the expansion of blafasel
.– moewe
Jan 24 at 12:18
1
1
Copying my comment from the other post:
ifx
compares the meaning of two tokens without expanding them previously, so relax
is valid. Of course the comparison will only be true if both tokens expand to relax
, for instance this code first yields foo is NOT relax
because, obviously, foo
is not relax
, it only contains relax
in its definition. The second comparison yields foo is relax
because you make foo
an exact copy of relax
.– Phelype Oleinik
Jan 24 at 12:22
Copying my comment from the other post:
ifx
compares the meaning of two tokens without expanding them previously, so relax
is valid. Of course the comparison will only be true if both tokens expand to relax
, for instance this code first yields foo is NOT relax
because, obviously, foo
is not relax
, it only contains relax
in its definition. The second comparison yields foo is relax
because you make foo
an exact copy of relax
.– Phelype Oleinik
Jan 24 at 12:22
Note that undefined
csname
s are relax
by default, so if you had not initialised blafasel
with @namedef{blafasel}{relax}
then expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
would have worked.– moewe
Jan 24 at 12:23
Note that undefined
csname
s are relax
by default, so if you had not initialised blafasel
with @namedef{blafasel}{relax}
then expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
would have worked.– moewe
Jan 24 at 12:23
@moewe the whole point of this exersice is to test whether my cs is initialised, or not. If not, then my next step is to initialise it with a pre-defined default value (other than
relax
).– Lupino
Jan 24 at 12:28
@moewe the whole point of this exersice is to test whether my cs is initialised, or not. If not, then my next step is to initialise it with a pre-defined default value (other than
relax
).– Lupino
Jan 24 at 12:28
|
show 2 more comments
3 Answers
3
active
oldest
votes
The problem you will confront will be that, unless you know in advance the types of arguments that may be passed to this test, they each may require differing numbers of expansions to finally reach the relax
or not-relax
condition.
Perhaps you need to fully expand your argument for the test:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
edeftmp{@nameuse{blafasel}}% MUST, HOWEVER, BE FULLY EXPANDABLE
expandafterifxtmprelax
true
else
false
fi
end{document}
Of course, this approach only works if the test argument is fully expandable.
Alternately, if it will always be a @nameuse
that is part of the test, then the use of 3xexpandafter
only produces 2 expansions. You need 7xexpandafter
to get 3 expansions, resulting in a true test.
Rule: to get n expansions, you need 2^n - 1 instances of expandafter
.
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterexpandafterexpandafter%
expandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
Thanks. I fear, i dont understand "fully expandable". my actual exampe is@namedef{blafaselc@mycounter}
. The "value" ofblasasel<x>
can be a string, a dimension, a length, a number, a cs, orrelax
... Say, i know thatblafasel1
is a string (or relax),blafasel2
is a dimension (or relax), does that help me?
– Lupino
Jan 24 at 12:25
What do you mean, you don't know how many expansions are necessary?@nameuse{foo}
will always take exactly 3 expansions to arrive at the expansion offoo
, won't it?
– schtandard
Jan 24 at 13:00
Imagine a table and for each cell of any that table, i want to store width, height, content. So my version of@namedef
isdef@mynamedef#1#2{expandaftergdefcsname cell-thetable-thec@row-thec@cell-#2endcsname{#1}}
with#2
being the propety (content, width, height), and #1 the value. I sorta switched #1 and #2 so i can expand length registers prior to assignment into my property matrix usingexpandafter@mynamedefexpandafter{the@tempdima}{width}
which stores (e.g.)12mm
as value ofcsname cell-1-2-2-widthendcsname
.
– Lupino
Jan 24 at 13:12
@Lupino I will try to understand what you are asking here, but it would be useful for you to edit your question and provide additional code on what does and doesn't work for you.
– Steven B. Segletes
Jan 24 at 13:25
@Lupino See my edit. The use of 3xexpandafter
in your MWE only produces 2 expansions. You would need 7xexpandafter
to get the triple expansion you seek.
– Steven B. Segletes
Jan 24 at 13:38
|
show 1 more comment
You just need to give no initial definition to blafasel
. If you want to test whether it has received a definition, just do
expandafterifxcsname blafaselendcsnamerelax
<still not defined>%
else
<is defined>%
fi
This exploits the fact that a token constructed with csname
is made equivalent to relax
if it has no previous definition.
add a comment |
@nameuse{blafasel}
expands to csname blafaselendcsname
, which you expand once again yielding blafasel
. You then compare this to relax
, which is different. You have three possibilities of solving your problem:
You can expand
blafasel
once more:
@namedef{blafasel}{relax}%
expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
Note that this
ifx
will always follow thetrue
branch when the expansionblafasel
starts with two equal tokens and is thus not a good test. Try@namedef{blafasel}{OOH, LOOK, AN ERROR!}
, for example.
You can define a different macro to compare it to:
@namedef{blafasel}{relax}%
def@test@macro{relax}%
expandafterexpandafterexpandafterifx@nameuse{blafasel}@test@macro
true
else
false
fi
You can initialize your macros to be the same as
relax
instead of a macro expanding torelax
:
def@namelet#1#2{expandafterletcsname #1endcsname#2}%
@namelet{blafasel}relax
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
As egreg points out, you could just as well leave
blafasel
undefined (i.e. omit the first two lines of this code block), sincecsname
will default torelax
, when the macro is not defined.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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%2f471632%2fnameuse-with-value-relax-in-conditionals%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The problem you will confront will be that, unless you know in advance the types of arguments that may be passed to this test, they each may require differing numbers of expansions to finally reach the relax
or not-relax
condition.
Perhaps you need to fully expand your argument for the test:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
edeftmp{@nameuse{blafasel}}% MUST, HOWEVER, BE FULLY EXPANDABLE
expandafterifxtmprelax
true
else
false
fi
end{document}
Of course, this approach only works if the test argument is fully expandable.
Alternately, if it will always be a @nameuse
that is part of the test, then the use of 3xexpandafter
only produces 2 expansions. You need 7xexpandafter
to get 3 expansions, resulting in a true test.
Rule: to get n expansions, you need 2^n - 1 instances of expandafter
.
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterexpandafterexpandafter%
expandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
Thanks. I fear, i dont understand "fully expandable". my actual exampe is@namedef{blafaselc@mycounter}
. The "value" ofblasasel<x>
can be a string, a dimension, a length, a number, a cs, orrelax
... Say, i know thatblafasel1
is a string (or relax),blafasel2
is a dimension (or relax), does that help me?
– Lupino
Jan 24 at 12:25
What do you mean, you don't know how many expansions are necessary?@nameuse{foo}
will always take exactly 3 expansions to arrive at the expansion offoo
, won't it?
– schtandard
Jan 24 at 13:00
Imagine a table and for each cell of any that table, i want to store width, height, content. So my version of@namedef
isdef@mynamedef#1#2{expandaftergdefcsname cell-thetable-thec@row-thec@cell-#2endcsname{#1}}
with#2
being the propety (content, width, height), and #1 the value. I sorta switched #1 and #2 so i can expand length registers prior to assignment into my property matrix usingexpandafter@mynamedefexpandafter{the@tempdima}{width}
which stores (e.g.)12mm
as value ofcsname cell-1-2-2-widthendcsname
.
– Lupino
Jan 24 at 13:12
@Lupino I will try to understand what you are asking here, but it would be useful for you to edit your question and provide additional code on what does and doesn't work for you.
– Steven B. Segletes
Jan 24 at 13:25
@Lupino See my edit. The use of 3xexpandafter
in your MWE only produces 2 expansions. You would need 7xexpandafter
to get the triple expansion you seek.
– Steven B. Segletes
Jan 24 at 13:38
|
show 1 more comment
The problem you will confront will be that, unless you know in advance the types of arguments that may be passed to this test, they each may require differing numbers of expansions to finally reach the relax
or not-relax
condition.
Perhaps you need to fully expand your argument for the test:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
edeftmp{@nameuse{blafasel}}% MUST, HOWEVER, BE FULLY EXPANDABLE
expandafterifxtmprelax
true
else
false
fi
end{document}
Of course, this approach only works if the test argument is fully expandable.
Alternately, if it will always be a @nameuse
that is part of the test, then the use of 3xexpandafter
only produces 2 expansions. You need 7xexpandafter
to get 3 expansions, resulting in a true test.
Rule: to get n expansions, you need 2^n - 1 instances of expandafter
.
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterexpandafterexpandafter%
expandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
Thanks. I fear, i dont understand "fully expandable". my actual exampe is@namedef{blafaselc@mycounter}
. The "value" ofblasasel<x>
can be a string, a dimension, a length, a number, a cs, orrelax
... Say, i know thatblafasel1
is a string (or relax),blafasel2
is a dimension (or relax), does that help me?
– Lupino
Jan 24 at 12:25
What do you mean, you don't know how many expansions are necessary?@nameuse{foo}
will always take exactly 3 expansions to arrive at the expansion offoo
, won't it?
– schtandard
Jan 24 at 13:00
Imagine a table and for each cell of any that table, i want to store width, height, content. So my version of@namedef
isdef@mynamedef#1#2{expandaftergdefcsname cell-thetable-thec@row-thec@cell-#2endcsname{#1}}
with#2
being the propety (content, width, height), and #1 the value. I sorta switched #1 and #2 so i can expand length registers prior to assignment into my property matrix usingexpandafter@mynamedefexpandafter{the@tempdima}{width}
which stores (e.g.)12mm
as value ofcsname cell-1-2-2-widthendcsname
.
– Lupino
Jan 24 at 13:12
@Lupino I will try to understand what you are asking here, but it would be useful for you to edit your question and provide additional code on what does and doesn't work for you.
– Steven B. Segletes
Jan 24 at 13:25
@Lupino See my edit. The use of 3xexpandafter
in your MWE only produces 2 expansions. You would need 7xexpandafter
to get the triple expansion you seek.
– Steven B. Segletes
Jan 24 at 13:38
|
show 1 more comment
The problem you will confront will be that, unless you know in advance the types of arguments that may be passed to this test, they each may require differing numbers of expansions to finally reach the relax
or not-relax
condition.
Perhaps you need to fully expand your argument for the test:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
edeftmp{@nameuse{blafasel}}% MUST, HOWEVER, BE FULLY EXPANDABLE
expandafterifxtmprelax
true
else
false
fi
end{document}
Of course, this approach only works if the test argument is fully expandable.
Alternately, if it will always be a @nameuse
that is part of the test, then the use of 3xexpandafter
only produces 2 expansions. You need 7xexpandafter
to get 3 expansions, resulting in a true test.
Rule: to get n expansions, you need 2^n - 1 instances of expandafter
.
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterexpandafterexpandafter%
expandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
The problem you will confront will be that, unless you know in advance the types of arguments that may be passed to this test, they each may require differing numbers of expansions to finally reach the relax
or not-relax
condition.
Perhaps you need to fully expand your argument for the test:
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
edeftmp{@nameuse{blafasel}}% MUST, HOWEVER, BE FULLY EXPANDABLE
expandafterifxtmprelax
true
else
false
fi
end{document}
Of course, this approach only works if the test argument is fully expandable.
Alternately, if it will always be a @nameuse
that is part of the test, then the use of 3xexpandafter
only produces 2 expansions. You need 7xexpandafter
to get 3 expansions, resulting in a true test.
Rule: to get n expansions, you need 2^n - 1 instances of expandafter
.
documentclass{standalone}
makeatletter
parindentz@
@namedef{blafasel}{relax}
begin{document}
expandafterexpandafterexpandafterexpandafterexpandafter%
expandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
end{document}
edited Jan 24 at 16:42
answered Jan 24 at 12:18


Steven B. SegletesSteven B. Segletes
158k9204411
158k9204411
Thanks. I fear, i dont understand "fully expandable". my actual exampe is@namedef{blafaselc@mycounter}
. The "value" ofblasasel<x>
can be a string, a dimension, a length, a number, a cs, orrelax
... Say, i know thatblafasel1
is a string (or relax),blafasel2
is a dimension (or relax), does that help me?
– Lupino
Jan 24 at 12:25
What do you mean, you don't know how many expansions are necessary?@nameuse{foo}
will always take exactly 3 expansions to arrive at the expansion offoo
, won't it?
– schtandard
Jan 24 at 13:00
Imagine a table and for each cell of any that table, i want to store width, height, content. So my version of@namedef
isdef@mynamedef#1#2{expandaftergdefcsname cell-thetable-thec@row-thec@cell-#2endcsname{#1}}
with#2
being the propety (content, width, height), and #1 the value. I sorta switched #1 and #2 so i can expand length registers prior to assignment into my property matrix usingexpandafter@mynamedefexpandafter{the@tempdima}{width}
which stores (e.g.)12mm
as value ofcsname cell-1-2-2-widthendcsname
.
– Lupino
Jan 24 at 13:12
@Lupino I will try to understand what you are asking here, but it would be useful for you to edit your question and provide additional code on what does and doesn't work for you.
– Steven B. Segletes
Jan 24 at 13:25
@Lupino See my edit. The use of 3xexpandafter
in your MWE only produces 2 expansions. You would need 7xexpandafter
to get the triple expansion you seek.
– Steven B. Segletes
Jan 24 at 13:38
|
show 1 more comment
Thanks. I fear, i dont understand "fully expandable". my actual exampe is@namedef{blafaselc@mycounter}
. The "value" ofblasasel<x>
can be a string, a dimension, a length, a number, a cs, orrelax
... Say, i know thatblafasel1
is a string (or relax),blafasel2
is a dimension (or relax), does that help me?
– Lupino
Jan 24 at 12:25
What do you mean, you don't know how many expansions are necessary?@nameuse{foo}
will always take exactly 3 expansions to arrive at the expansion offoo
, won't it?
– schtandard
Jan 24 at 13:00
Imagine a table and for each cell of any that table, i want to store width, height, content. So my version of@namedef
isdef@mynamedef#1#2{expandaftergdefcsname cell-thetable-thec@row-thec@cell-#2endcsname{#1}}
with#2
being the propety (content, width, height), and #1 the value. I sorta switched #1 and #2 so i can expand length registers prior to assignment into my property matrix usingexpandafter@mynamedefexpandafter{the@tempdima}{width}
which stores (e.g.)12mm
as value ofcsname cell-1-2-2-widthendcsname
.
– Lupino
Jan 24 at 13:12
@Lupino I will try to understand what you are asking here, but it would be useful for you to edit your question and provide additional code on what does and doesn't work for you.
– Steven B. Segletes
Jan 24 at 13:25
@Lupino See my edit. The use of 3xexpandafter
in your MWE only produces 2 expansions. You would need 7xexpandafter
to get the triple expansion you seek.
– Steven B. Segletes
Jan 24 at 13:38
Thanks. I fear, i dont understand "fully expandable". my actual exampe is
@namedef{blafaselc@mycounter}
. The "value" of blasasel<x>
can be a string, a dimension, a length, a number, a cs, or relax
... Say, i know that blafasel1
is a string (or relax), blafasel2
is a dimension (or relax), does that help me?– Lupino
Jan 24 at 12:25
Thanks. I fear, i dont understand "fully expandable". my actual exampe is
@namedef{blafaselc@mycounter}
. The "value" of blasasel<x>
can be a string, a dimension, a length, a number, a cs, or relax
... Say, i know that blafasel1
is a string (or relax), blafasel2
is a dimension (or relax), does that help me?– Lupino
Jan 24 at 12:25
What do you mean, you don't know how many expansions are necessary?
@nameuse{foo}
will always take exactly 3 expansions to arrive at the expansion of foo
, won't it?– schtandard
Jan 24 at 13:00
What do you mean, you don't know how many expansions are necessary?
@nameuse{foo}
will always take exactly 3 expansions to arrive at the expansion of foo
, won't it?– schtandard
Jan 24 at 13:00
Imagine a table and for each cell of any that table, i want to store width, height, content. So my version of
@namedef
is def@mynamedef#1#2{expandaftergdefcsname cell-thetable-thec@row-thec@cell-#2endcsname{#1}}
with #2
being the propety (content, width, height), and #1 the value. I sorta switched #1 and #2 so i can expand length registers prior to assignment into my property matrix using expandafter@mynamedefexpandafter{the@tempdima}{width}
which stores (e.g.) 12mm
as value of csname cell-1-2-2-widthendcsname
.– Lupino
Jan 24 at 13:12
Imagine a table and for each cell of any that table, i want to store width, height, content. So my version of
@namedef
is def@mynamedef#1#2{expandaftergdefcsname cell-thetable-thec@row-thec@cell-#2endcsname{#1}}
with #2
being the propety (content, width, height), and #1 the value. I sorta switched #1 and #2 so i can expand length registers prior to assignment into my property matrix using expandafter@mynamedefexpandafter{the@tempdima}{width}
which stores (e.g.) 12mm
as value of csname cell-1-2-2-widthendcsname
.– Lupino
Jan 24 at 13:12
@Lupino I will try to understand what you are asking here, but it would be useful for you to edit your question and provide additional code on what does and doesn't work for you.
– Steven B. Segletes
Jan 24 at 13:25
@Lupino I will try to understand what you are asking here, but it would be useful for you to edit your question and provide additional code on what does and doesn't work for you.
– Steven B. Segletes
Jan 24 at 13:25
@Lupino See my edit. The use of 3x
expandafter
in your MWE only produces 2 expansions. You would need 7xexpandafter
to get the triple expansion you seek.– Steven B. Segletes
Jan 24 at 13:38
@Lupino See my edit. The use of 3x
expandafter
in your MWE only produces 2 expansions. You would need 7xexpandafter
to get the triple expansion you seek.– Steven B. Segletes
Jan 24 at 13:38
|
show 1 more comment
You just need to give no initial definition to blafasel
. If you want to test whether it has received a definition, just do
expandafterifxcsname blafaselendcsnamerelax
<still not defined>%
else
<is defined>%
fi
This exploits the fact that a token constructed with csname
is made equivalent to relax
if it has no previous definition.
add a comment |
You just need to give no initial definition to blafasel
. If you want to test whether it has received a definition, just do
expandafterifxcsname blafaselendcsnamerelax
<still not defined>%
else
<is defined>%
fi
This exploits the fact that a token constructed with csname
is made equivalent to relax
if it has no previous definition.
add a comment |
You just need to give no initial definition to blafasel
. If you want to test whether it has received a definition, just do
expandafterifxcsname blafaselendcsnamerelax
<still not defined>%
else
<is defined>%
fi
This exploits the fact that a token constructed with csname
is made equivalent to relax
if it has no previous definition.
You just need to give no initial definition to blafasel
. If you want to test whether it has received a definition, just do
expandafterifxcsname blafaselendcsnamerelax
<still not defined>%
else
<is defined>%
fi
This exploits the fact that a token constructed with csname
is made equivalent to relax
if it has no previous definition.
answered Jan 24 at 13:05


egregegreg
727k8819223231
727k8819223231
add a comment |
add a comment |
@nameuse{blafasel}
expands to csname blafaselendcsname
, which you expand once again yielding blafasel
. You then compare this to relax
, which is different. You have three possibilities of solving your problem:
You can expand
blafasel
once more:
@namedef{blafasel}{relax}%
expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
Note that this
ifx
will always follow thetrue
branch when the expansionblafasel
starts with two equal tokens and is thus not a good test. Try@namedef{blafasel}{OOH, LOOK, AN ERROR!}
, for example.
You can define a different macro to compare it to:
@namedef{blafasel}{relax}%
def@test@macro{relax}%
expandafterexpandafterexpandafterifx@nameuse{blafasel}@test@macro
true
else
false
fi
You can initialize your macros to be the same as
relax
instead of a macro expanding torelax
:
def@namelet#1#2{expandafterletcsname #1endcsname#2}%
@namelet{blafasel}relax
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
As egreg points out, you could just as well leave
blafasel
undefined (i.e. omit the first two lines of this code block), sincecsname
will default torelax
, when the macro is not defined.
add a comment |
@nameuse{blafasel}
expands to csname blafaselendcsname
, which you expand once again yielding blafasel
. You then compare this to relax
, which is different. You have three possibilities of solving your problem:
You can expand
blafasel
once more:
@namedef{blafasel}{relax}%
expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
Note that this
ifx
will always follow thetrue
branch when the expansionblafasel
starts with two equal tokens and is thus not a good test. Try@namedef{blafasel}{OOH, LOOK, AN ERROR!}
, for example.
You can define a different macro to compare it to:
@namedef{blafasel}{relax}%
def@test@macro{relax}%
expandafterexpandafterexpandafterifx@nameuse{blafasel}@test@macro
true
else
false
fi
You can initialize your macros to be the same as
relax
instead of a macro expanding torelax
:
def@namelet#1#2{expandafterletcsname #1endcsname#2}%
@namelet{blafasel}relax
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
As egreg points out, you could just as well leave
blafasel
undefined (i.e. omit the first two lines of this code block), sincecsname
will default torelax
, when the macro is not defined.
add a comment |
@nameuse{blafasel}
expands to csname blafaselendcsname
, which you expand once again yielding blafasel
. You then compare this to relax
, which is different. You have three possibilities of solving your problem:
You can expand
blafasel
once more:
@namedef{blafasel}{relax}%
expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
Note that this
ifx
will always follow thetrue
branch when the expansionblafasel
starts with two equal tokens and is thus not a good test. Try@namedef{blafasel}{OOH, LOOK, AN ERROR!}
, for example.
You can define a different macro to compare it to:
@namedef{blafasel}{relax}%
def@test@macro{relax}%
expandafterexpandafterexpandafterifx@nameuse{blafasel}@test@macro
true
else
false
fi
You can initialize your macros to be the same as
relax
instead of a macro expanding torelax
:
def@namelet#1#2{expandafterletcsname #1endcsname#2}%
@namelet{blafasel}relax
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
As egreg points out, you could just as well leave
blafasel
undefined (i.e. omit the first two lines of this code block), sincecsname
will default torelax
, when the macro is not defined.
@nameuse{blafasel}
expands to csname blafaselendcsname
, which you expand once again yielding blafasel
. You then compare this to relax
, which is different. You have three possibilities of solving your problem:
You can expand
blafasel
once more:
@namedef{blafasel}{relax}%
expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
Note that this
ifx
will always follow thetrue
branch when the expansionblafasel
starts with two equal tokens and is thus not a good test. Try@namedef{blafasel}{OOH, LOOK, AN ERROR!}
, for example.
You can define a different macro to compare it to:
@namedef{blafasel}{relax}%
def@test@macro{relax}%
expandafterexpandafterexpandafterifx@nameuse{blafasel}@test@macro
true
else
false
fi
You can initialize your macros to be the same as
relax
instead of a macro expanding torelax
:
def@namelet#1#2{expandafterletcsname #1endcsname#2}%
@namelet{blafasel}relax
expandafterexpandafterexpandafterifx@nameuse{blafasel}relax
true
else
false
fi
As egreg points out, you could just as well leave
blafasel
undefined (i.e. omit the first two lines of this code block), sincecsname
will default torelax
, when the macro is not defined.
edited Jan 24 at 13:09
answered Jan 24 at 12:52


schtandardschtandard
1,904718
1,904718
add a comment |
add a comment |
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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%2f471632%2fnameuse-with-value-relax-in-conditionals%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
> blafasel=macro://->relax .//l.9 showblafasel
andrelax=relax.//l.10 showrelax
show thatrelax
andblafasel
are different forifx
. One is a macro expanding torelax
, the other one isrelax
.– moewe
Jan 24 at 12:17
Try
expandafterexpandafterexpandafterifx@nameuse{blafasel}testrelax
wheretestrelax
isdeftestrelax{relax}
. Orexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
to test notblafasel
againstrelax
, but the expansion ofblafasel
.– moewe
Jan 24 at 12:18
1
Copying my comment from the other post:
ifx
compares the meaning of two tokens without expanding them previously, sorelax
is valid. Of course the comparison will only be true if both tokens expand torelax
, for instance this code first yieldsfoo is NOT relax
because, obviously,foo
is notrelax
, it only containsrelax
in its definition. The second comparison yieldsfoo is relax
because you makefoo
an exact copy ofrelax
.– Phelype Oleinik
Jan 24 at 12:22
Note that undefined
csname
s arerelax
by default, so if you had not initialisedblafasel
with@namedef{blafasel}{relax}
thenexpandafterexpandafterexpandafterifx@nameuse{blafasel}relax
would have worked.– moewe
Jan 24 at 12:23
@moewe the whole point of this exersice is to test whether my cs is initialised, or not. If not, then my next step is to initialise it with a pre-defined default value (other than
relax
).– Lupino
Jan 24 at 12:28