Visibility of path names declared in foreach loops












6















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.










share|improve this question




















  • 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











  • 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
















6















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.










share|improve this question




















  • 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











  • 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














6












6








6


0






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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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











  • @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





    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











  • @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










1 Answer
1






active

oldest

votes


















3














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.






share|improve this answer

























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    3














    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.






    share|improve this answer






























      3














      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.






      share|improve this answer




























        3












        3








        3







        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.






        share|improve this answer















        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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 6 at 14:05

























        answered Jan 6 at 11:48









        KpymKpym

        15.9k23986




        15.9k23986






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?