Visibility of path names declared in foreach loops
Buildup
Basic setting
Using the intersection library,
I encountered some behaviour of path names
that I do not understand.
The following works in the intended way:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
draw[name path=neg] (0, 1) -- (2, -1);
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
Looping into a problem
But I have multiple paths to intersect,
so lets change it up a bit:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
% Only change: A senseless “loop”
foreach i in {0} {
draw[name path=neg] (0, 1) -- (2, -1);
}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
This looks to me as if it should be completely equivalent,
but now I get error messages:
Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it. ...[red, name intersections={of=pos and neg}]
Package pgf Error: No shape named intersection-1 is known. ...ections={of=pos and neg}] (intersection-1)
The circle is drawn anyway,
since pgf simply assumes the coordinates of (intersection-1)
to be (0, 0)
,
but this was not the behaviour I expected or hoped for.
A strange workaround
By drawing anything afterwards,
we can get it to run smoothly again:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
foreach i in {0} {
draw[name path=neg] (0, 1) -- (2, -1);
}
% Only change: Senseless path of vanishing length
path (5, -1);
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
Question
I would like to know why this happens.
Solutions and workarounds are of interest, too,
but might be better suited as answers to this similar question,
even though the existing answers
are mostly concerned with the expansion of options.
Non-Explanations
As the third variant works without any problems,
there is no general problem exporting path names out of loops,
even though using name path global
provides another workaround.
I did not encounter the same behaviour when declaring nodes,
so this seems to be a rather specific problem
of the intersection library.
tikz-pgf foreach intersections
|
show 7 more comments
Buildup
Basic setting
Using the intersection library,
I encountered some behaviour of path names
that I do not understand.
The following works in the intended way:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
draw[name path=neg] (0, 1) -- (2, -1);
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
Looping into a problem
But I have multiple paths to intersect,
so lets change it up a bit:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
% Only change: A senseless “loop”
foreach i in {0} {
draw[name path=neg] (0, 1) -- (2, -1);
}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
This looks to me as if it should be completely equivalent,
but now I get error messages:
Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it. ...[red, name intersections={of=pos and neg}]
Package pgf Error: No shape named intersection-1 is known. ...ections={of=pos and neg}] (intersection-1)
The circle is drawn anyway,
since pgf simply assumes the coordinates of (intersection-1)
to be (0, 0)
,
but this was not the behaviour I expected or hoped for.
A strange workaround
By drawing anything afterwards,
we can get it to run smoothly again:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
foreach i in {0} {
draw[name path=neg] (0, 1) -- (2, -1);
}
% Only change: Senseless path of vanishing length
path (5, -1);
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
Question
I would like to know why this happens.
Solutions and workarounds are of interest, too,
but might be better suited as answers to this similar question,
even though the existing answers
are mostly concerned with the expansion of options.
Non-Explanations
As the third variant works without any problems,
there is no general problem exporting path names out of loops,
even though using name path global
provides another workaround.
I did not encounter the same behaviour when declaring nodes,
so this seems to be a rather specific problem
of the intersection library.
tikz-pgf foreach intersections
2
Yes, that's an interesting observation. I guess to really understand that you need to look atlibraries/tikzlibraryintersections.code.tex
. There you can find all sorts ofFIXME
statements and questions whether or not one needs to reset the path. Once you will have the choice to either rewrite this library or just to usename path global
, which worked perfectly fine in all situations I needed it so far.
– marmot
Aug 14 '18 at 14:54
It's also curious that, if you move thepath (5, -1);
into the loop, the error reappears.
– marmot
Aug 14 '18 at 15:51
@marmot I do not actually think that is curious. It seems to be a bug in the handling of the loop. There is no reason to assume that moving more stuff into the loop makes the list of path names update the same way pretty much any command after the loop seems to do.
– Hermann Döppes
Aug 14 '18 at 15:58
I had forgotten to add the x-offset from my experiments into the question before posting. This is fixed now.
– Hermann Döppes
Aug 14 '18 at 16:03
1
I would argue that the fix shouldn't work, and that it may stop working without warning after an update.
– John Kormylo
Aug 14 '18 at 20:44
|
show 7 more comments
Buildup
Basic setting
Using the intersection library,
I encountered some behaviour of path names
that I do not understand.
The following works in the intended way:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
draw[name path=neg] (0, 1) -- (2, -1);
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
Looping into a problem
But I have multiple paths to intersect,
so lets change it up a bit:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
% Only change: A senseless “loop”
foreach i in {0} {
draw[name path=neg] (0, 1) -- (2, -1);
}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
This looks to me as if it should be completely equivalent,
but now I get error messages:
Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it. ...[red, name intersections={of=pos and neg}]
Package pgf Error: No shape named intersection-1 is known. ...ections={of=pos and neg}] (intersection-1)
The circle is drawn anyway,
since pgf simply assumes the coordinates of (intersection-1)
to be (0, 0)
,
but this was not the behaviour I expected or hoped for.
A strange workaround
By drawing anything afterwards,
we can get it to run smoothly again:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
foreach i in {0} {
draw[name path=neg] (0, 1) -- (2, -1);
}
% Only change: Senseless path of vanishing length
path (5, -1);
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
Question
I would like to know why this happens.
Solutions and workarounds are of interest, too,
but might be better suited as answers to this similar question,
even though the existing answers
are mostly concerned with the expansion of options.
Non-Explanations
As the third variant works without any problems,
there is no general problem exporting path names out of loops,
even though using name path global
provides another workaround.
I did not encounter the same behaviour when declaring nodes,
so this seems to be a rather specific problem
of the intersection library.
tikz-pgf foreach intersections
Buildup
Basic setting
Using the intersection library,
I encountered some behaviour of path names
that I do not understand.
The following works in the intended way:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
draw[name path=neg] (0, 1) -- (2, -1);
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
Looping into a problem
But I have multiple paths to intersect,
so lets change it up a bit:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
% Only change: A senseless “loop”
foreach i in {0} {
draw[name path=neg] (0, 1) -- (2, -1);
}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
This looks to me as if it should be completely equivalent,
but now I get error messages:
Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it. ...[red, name intersections={of=pos and neg}]
Package pgf Error: No shape named intersection-1 is known. ...ections={of=pos and neg}] (intersection-1)
The circle is drawn anyway,
since pgf simply assumes the coordinates of (intersection-1)
to be (0, 0)
,
but this was not the behaviour I expected or hoped for.
A strange workaround
By drawing anything afterwards,
we can get it to run smoothly again:
documentclass{scrartcl}
usepackage{tikz}
usetikzlibrary{intersections}
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
foreach i in {0} {
draw[name path=neg] (0, 1) -- (2, -1);
}
% Only change: Senseless path of vanishing length
path (5, -1);
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
Question
I would like to know why this happens.
Solutions and workarounds are of interest, too,
but might be better suited as answers to this similar question,
even though the existing answers
are mostly concerned with the expansion of options.
Non-Explanations
As the third variant works without any problems,
there is no general problem exporting path names out of loops,
even though using name path global
provides another workaround.
I did not encounter the same behaviour when declaring nodes,
so this seems to be a rather specific problem
of the intersection library.
tikz-pgf foreach intersections
tikz-pgf foreach intersections
edited Aug 14 '18 at 16:03
Hermann Döppes
asked Aug 14 '18 at 14:29
Hermann DöppesHermann Döppes
1608
1608
2
Yes, that's an interesting observation. I guess to really understand that you need to look atlibraries/tikzlibraryintersections.code.tex
. There you can find all sorts ofFIXME
statements and questions whether or not one needs to reset the path. Once you will have the choice to either rewrite this library or just to usename path global
, which worked perfectly fine in all situations I needed it so far.
– marmot
Aug 14 '18 at 14:54
It's also curious that, if you move thepath (5, -1);
into the loop, the error reappears.
– marmot
Aug 14 '18 at 15:51
@marmot I do not actually think that is curious. It seems to be a bug in the handling of the loop. There is no reason to assume that moving more stuff into the loop makes the list of path names update the same way pretty much any command after the loop seems to do.
– Hermann Döppes
Aug 14 '18 at 15:58
I had forgotten to add the x-offset from my experiments into the question before posting. This is fixed now.
– Hermann Döppes
Aug 14 '18 at 16:03
1
I would argue that the fix shouldn't work, and that it may stop working without warning after an update.
– John Kormylo
Aug 14 '18 at 20:44
|
show 7 more comments
2
Yes, that's an interesting observation. I guess to really understand that you need to look atlibraries/tikzlibraryintersections.code.tex
. There you can find all sorts ofFIXME
statements and questions whether or not one needs to reset the path. Once you will have the choice to either rewrite this library or just to usename path global
, which worked perfectly fine in all situations I needed it so far.
– marmot
Aug 14 '18 at 14:54
It's also curious that, if you move thepath (5, -1);
into the loop, the error reappears.
– marmot
Aug 14 '18 at 15:51
@marmot I do not actually think that is curious. It seems to be a bug in the handling of the loop. There is no reason to assume that moving more stuff into the loop makes the list of path names update the same way pretty much any command after the loop seems to do.
– Hermann Döppes
Aug 14 '18 at 15:58
I had forgotten to add the x-offset from my experiments into the question before posting. This is fixed now.
– Hermann Döppes
Aug 14 '18 at 16:03
1
I would argue that the fix shouldn't work, and that it may stop working without warning after an update.
– John Kormylo
Aug 14 '18 at 20:44
2
2
Yes, that's an interesting observation. I guess to really understand that you need to look at
libraries/tikzlibraryintersections.code.tex
. There you can find all sorts of FIXME
statements and questions whether or not one needs to reset the path. Once you will have the choice to either rewrite this library or just to use name path global
, which worked perfectly fine in all situations I needed it so far.– marmot
Aug 14 '18 at 14:54
Yes, that's an interesting observation. I guess to really understand that you need to look at
libraries/tikzlibraryintersections.code.tex
. There you can find all sorts of FIXME
statements and questions whether or not one needs to reset the path. Once you will have the choice to either rewrite this library or just to use name path global
, which worked perfectly fine in all situations I needed it so far.– marmot
Aug 14 '18 at 14:54
It's also curious that, if you move the
path (5, -1);
into the loop, the error reappears.– marmot
Aug 14 '18 at 15:51
It's also curious that, if you move the
path (5, -1);
into the loop, the error reappears.– marmot
Aug 14 '18 at 15:51
@marmot I do not actually think that is curious. It seems to be a bug in the handling of the loop. There is no reason to assume that moving more stuff into the loop makes the list of path names update the same way pretty much any command after the loop seems to do.
– Hermann Döppes
Aug 14 '18 at 15:58
@marmot I do not actually think that is curious. It seems to be a bug in the handling of the loop. There is no reason to assume that moving more stuff into the loop makes the list of path names update the same way pretty much any command after the loop seems to do.
– Hermann Döppes
Aug 14 '18 at 15:58
I had forgotten to add the x-offset from my experiments into the question before posting. This is fixed now.
– Hermann Döppes
Aug 14 '18 at 16:03
I had forgotten to add the x-offset from my experiments into the question before posting. This is fixed now.
– Hermann Döppes
Aug 14 '18 at 16:03
1
1
I would argue that the fix shouldn't work, and that it may stop working without warning after an update.
– John Kormylo
Aug 14 '18 at 20:44
I would argue that the fix shouldn't work, and that it may stop working without warning after an update.
– John Kormylo
Aug 14 '18 at 20:44
|
show 7 more comments
1 Answer
1
active
oldest
votes
The problem is global vs local as suggested by @marmot in his comment.
The body of foreach
is executed in a group, so all paths named with name path
(or the equivalent name path local
) are supposed to be non accessible outside the group because they are defined with def
and not with gdef
(as is the case for name path global
).
You can check that the problem is group related and not specific to foreach
in the following example where typeout
is used to display to the console the "neg" path stored in tikz@intersect@path@name@neg
.
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside === : undefined
! Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it.
So what is happening when we add some path command outside of the group ?
The TikZ library intersections
redefine tikz@finish
that is executed at every tikz command and run the GLOBAL tikz@intersect@namedpaths
(which contains the definition of the last path) if there is no name intersections
option. So any path
command outside the group redefine the last path in the current group.
This is a bug. Which is probably known because we can see in the code :
% FIXME : it is reasonable to reset this globally as it is global
% in its nature. But the reset instruction should be moved to
% endscope or something related. Resetting it here breaks the
% manual
We can check all of this in the following code
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside, neg === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside, before path === : meaningtikz@intersect@path@name@neg}
typeout{=== the tikz@intersect@namedpaths === : meaningtikz@intersect@namedpaths}
path;
typeout{=== outside, after path === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside, neg === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside, before path === : undefined
=== the tikz@intersect@namedpaths === : macro:->def tikz@intersect@path@name@neg {pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken{56.90549pt}{-28.45274pt}}
=== outside, after path === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
Conclusion
The normal behavior is that if you name a path with name path
inside a group (for example inside foreach
) it should not be available outside the group.
If you want to make it available outside the group you should use name path global
instead (as indicated by @marmot in his commentary).
The fact that using a simple path
outside the group make last named path available in the current group is a bug.
Comment: Actually this bug is already reported.
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%2f446025%2fvisibility-of-path-names-declared-in-foreach-loops%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The problem is global vs local as suggested by @marmot in his comment.
The body of foreach
is executed in a group, so all paths named with name path
(or the equivalent name path local
) are supposed to be non accessible outside the group because they are defined with def
and not with gdef
(as is the case for name path global
).
You can check that the problem is group related and not specific to foreach
in the following example where typeout
is used to display to the console the "neg" path stored in tikz@intersect@path@name@neg
.
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside === : undefined
! Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it.
So what is happening when we add some path command outside of the group ?
The TikZ library intersections
redefine tikz@finish
that is executed at every tikz command and run the GLOBAL tikz@intersect@namedpaths
(which contains the definition of the last path) if there is no name intersections
option. So any path
command outside the group redefine the last path in the current group.
This is a bug. Which is probably known because we can see in the code :
% FIXME : it is reasonable to reset this globally as it is global
% in its nature. But the reset instruction should be moved to
% endscope or something related. Resetting it here breaks the
% manual
We can check all of this in the following code
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside, neg === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside, before path === : meaningtikz@intersect@path@name@neg}
typeout{=== the tikz@intersect@namedpaths === : meaningtikz@intersect@namedpaths}
path;
typeout{=== outside, after path === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside, neg === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside, before path === : undefined
=== the tikz@intersect@namedpaths === : macro:->def tikz@intersect@path@name@neg {pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken{56.90549pt}{-28.45274pt}}
=== outside, after path === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
Conclusion
The normal behavior is that if you name a path with name path
inside a group (for example inside foreach
) it should not be available outside the group.
If you want to make it available outside the group you should use name path global
instead (as indicated by @marmot in his commentary).
The fact that using a simple path
outside the group make last named path available in the current group is a bug.
Comment: Actually this bug is already reported.
add a comment |
The problem is global vs local as suggested by @marmot in his comment.
The body of foreach
is executed in a group, so all paths named with name path
(or the equivalent name path local
) are supposed to be non accessible outside the group because they are defined with def
and not with gdef
(as is the case for name path global
).
You can check that the problem is group related and not specific to foreach
in the following example where typeout
is used to display to the console the "neg" path stored in tikz@intersect@path@name@neg
.
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside === : undefined
! Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it.
So what is happening when we add some path command outside of the group ?
The TikZ library intersections
redefine tikz@finish
that is executed at every tikz command and run the GLOBAL tikz@intersect@namedpaths
(which contains the definition of the last path) if there is no name intersections
option. So any path
command outside the group redefine the last path in the current group.
This is a bug. Which is probably known because we can see in the code :
% FIXME : it is reasonable to reset this globally as it is global
% in its nature. But the reset instruction should be moved to
% endscope or something related. Resetting it here breaks the
% manual
We can check all of this in the following code
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside, neg === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside, before path === : meaningtikz@intersect@path@name@neg}
typeout{=== the tikz@intersect@namedpaths === : meaningtikz@intersect@namedpaths}
path;
typeout{=== outside, after path === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside, neg === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside, before path === : undefined
=== the tikz@intersect@namedpaths === : macro:->def tikz@intersect@path@name@neg {pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken{56.90549pt}{-28.45274pt}}
=== outside, after path === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
Conclusion
The normal behavior is that if you name a path with name path
inside a group (for example inside foreach
) it should not be available outside the group.
If you want to make it available outside the group you should use name path global
instead (as indicated by @marmot in his commentary).
The fact that using a simple path
outside the group make last named path available in the current group is a bug.
Comment: Actually this bug is already reported.
add a comment |
The problem is global vs local as suggested by @marmot in his comment.
The body of foreach
is executed in a group, so all paths named with name path
(or the equivalent name path local
) are supposed to be non accessible outside the group because they are defined with def
and not with gdef
(as is the case for name path global
).
You can check that the problem is group related and not specific to foreach
in the following example where typeout
is used to display to the console the "neg" path stored in tikz@intersect@path@name@neg
.
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside === : undefined
! Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it.
So what is happening when we add some path command outside of the group ?
The TikZ library intersections
redefine tikz@finish
that is executed at every tikz command and run the GLOBAL tikz@intersect@namedpaths
(which contains the definition of the last path) if there is no name intersections
option. So any path
command outside the group redefine the last path in the current group.
This is a bug. Which is probably known because we can see in the code :
% FIXME : it is reasonable to reset this globally as it is global
% in its nature. But the reset instruction should be moved to
% endscope or something related. Resetting it here breaks the
% manual
We can check all of this in the following code
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside, neg === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside, before path === : meaningtikz@intersect@path@name@neg}
typeout{=== the tikz@intersect@namedpaths === : meaningtikz@intersect@namedpaths}
path;
typeout{=== outside, after path === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside, neg === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside, before path === : undefined
=== the tikz@intersect@namedpaths === : macro:->def tikz@intersect@path@name@neg {pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken{56.90549pt}{-28.45274pt}}
=== outside, after path === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
Conclusion
The normal behavior is that if you name a path with name path
inside a group (for example inside foreach
) it should not be available outside the group.
If you want to make it available outside the group you should use name path global
instead (as indicated by @marmot in his commentary).
The fact that using a simple path
outside the group make last named path available in the current group is a bug.
Comment: Actually this bug is already reported.
The problem is global vs local as suggested by @marmot in his comment.
The body of foreach
is executed in a group, so all paths named with name path
(or the equivalent name path local
) are supposed to be non accessible outside the group because they are defined with def
and not with gdef
(as is the case for name path global
).
You can check that the problem is group related and not specific to foreach
in the following example where typeout
is used to display to the console the "neg" path stored in tikz@intersect@path@name@neg
.
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside === : undefined
! Package tikz Error: I do not know the path named `neg'. Perhaps you misspelt it.
So what is happening when we add some path command outside of the group ?
The TikZ library intersections
redefine tikz@finish
that is executed at every tikz command and run the GLOBAL tikz@intersect@namedpaths
(which contains the definition of the last path) if there is no name intersections
option. So any path
command outside the group redefine the last path in the current group.
This is a bug. Which is probably known because we can see in the code :
% FIXME : it is reasonable to reset this globally as it is global
% in its nature. But the reset instruction should be moved to
% endscope or something related. Resetting it here breaks the
% manual
We can check all of this in the following code
documentclass[tikz,border=7pt]{standalone}
usetikzlibrary{intersections}
makeatletter
begin{document}
begin{tikzpicture}
draw[name path=pos] (0, -1) -- (2, 1);
{
draw[name path=neg] (0, 1) -- (2, -1);
typeout{=== inside, neg === : meaningtikz@intersect@path@name@neg}
}
typeout{=== outside, before path === : meaningtikz@intersect@path@name@neg}
typeout{=== the tikz@intersect@namedpaths === : meaningtikz@intersect@namedpaths}
path;
typeout{=== outside, after path === : meaningtikz@intersect@path@name@neg}
fill[name intersections={of=pos and neg}] (intersection-1) circle (2pt);
end{tikzpicture}
end{document}
where the output is
=== inside, neg === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
=== outside, before path === : undefined
=== the tikz@intersect@namedpaths === : macro:->def tikz@intersect@path@name@neg {pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken{56.90549pt}{-28.45274pt}}
=== outside, after path === : macro:->pgfsyssoftpath@movetotoken {0.0pt}{28.45274pt}pgfsyssoftpath@linetotoken {56.90549pt}{-28.45274pt}
Conclusion
The normal behavior is that if you name a path with name path
inside a group (for example inside foreach
) it should not be available outside the group.
If you want to make it available outside the group you should use name path global
instead (as indicated by @marmot in his commentary).
The fact that using a simple path
outside the group make last named path available in the current group is a bug.
Comment: Actually this bug is already reported.
edited Jan 6 at 14:05
answered Jan 6 at 11:48
KpymKpym
15.9k23986
15.9k23986
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%2f446025%2fvisibility-of-path-names-declared-in-foreach-loops%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
Yes, that's an interesting observation. I guess to really understand that you need to look at
libraries/tikzlibraryintersections.code.tex
. There you can find all sorts ofFIXME
statements and questions whether or not one needs to reset the path. Once you will have the choice to either rewrite this library or just to usename path global
, which worked perfectly fine in all situations I needed it so far.– marmot
Aug 14 '18 at 14:54
It's also curious that, if you move the
path (5, -1);
into the loop, the error reappears.– marmot
Aug 14 '18 at 15:51
@marmot I do not actually think that is curious. It seems to be a bug in the handling of the loop. There is no reason to assume that moving more stuff into the loop makes the list of path names update the same way pretty much any command after the loop seems to do.
– Hermann Döppes
Aug 14 '18 at 15:58
I had forgotten to add the x-offset from my experiments into the question before posting. This is fixed now.
– Hermann Döppes
Aug 14 '18 at 16:03
1
I would argue that the fix shouldn't work, and that it may stop working without warning after an update.
– John Kormylo
Aug 14 '18 at 20:44