pgf
pgf copied to clipboard
`node contents` key for nodes on a path
Migrated from SourceForge Author: flnev Timestamp: 2014-10-18 21:05:13.183000
In the example below, I need to add {} just after "but this is not", or I get an error. I would expect the correct this extra pair of braces not to be needed.
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node[at={(0,0)}, node contents=this is fine];
\draw (0,0) to node [node contents=but this is not]{} (0,-1);
\end{tikzpicture}
\end{document}
Migrated from SourceForge Author: hmenke Timestamp: 2018-12-28 05:42:50.395000
The problem is that if node is encountered as part of a path, TikZ first scans the rest of the path before processing the node options.
Migrated from SourceForge Author: hmenke Timestamp: 2019-01-21 20:59:44.069000
- assigned_to: Henri Menke
This is a really nasty one. Even if we don't require {} we still somehow have to differentiate between these two situations. This will require a lot of extra code.
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\path (0,0) -- node[node contents=foo] (1,1);
\path (0,0) -- node[node contents=foo] (a) (1,1);
\end{tikzpicture}
\end{document}
Just for reference, here is the code. We'd need some sort of backtracking in \tikz@collect@paran.
https://github.com/pgf-tikz/pgf/blob/969b1f8d5cd0459aa13dcfa4478159301139c93e/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex#L2781-L2862
There is a related issue which, according to what I find, does not get fixed by this patch. One needs to add the node name before node contents=.... To see what that means, consider
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\path (0,0) node (x) [node contents=x]; % <- works
%\path (1,0) node [node contents=y] (y); % <- doesn't work
\end{tikzpicture}
\end{document}
I added your patch sandwiched between \makeatletter and \makeatother to the preamble, but it did not fix this issue. (I am not saying it should, all I am saying is that I tried if the patch happens to fix this issue, but it does not seem to do that.) I will be happy move this to a separate issue if needed.
What patch? I don't have a patch for this issue. The code above is just the existing implementation, so that I don't forget where it is.
All I want to say is that there is the related issue.
What related issue? You just repeated the original issue.
@hmenke No, not really. Please read the original issue and my comment. It might well be that they are related but mine is about naming of nodes. So in my comment dropping (y) to get
\path (1,0) node [node contents=y] ; removes the error. Neither the original issue, nor any of your statements mention any of this, do they?
It's the same issue.
@hmenke I do not see that, sorry. At least the symptoms are not the same, but yes at some level these things are related, which is why I commented here rather than adding a new issue. Your description above "The problem is that if node is encountered as part of a path, TikZ first scans the rest of the path before processing the node options." does not really explain why using the node contents (!) key requires us to put the name before the options.
This is a really nasty one. Even if we don't require
{}we still somehow have to differentiate between these two situations. This will require a lot of extra code.\path (0,0) -- node[node contents=foo] (a) (1,1);
I argue, we don't. The manual says https://github.com/pgf-tikz/pgf/blob/44f8137449b34f62bc6371bd442ae5cc98f60f18/doc/generic/pgf/pgfmanual-en-tikz-shapes.tex#L116-L123
The parsing of the node stops immediately after the end of the option block.
You cannot name a node a even if not along a path: \node[node contents=foo](a); will fail.
There is a related issue which, according to what I find, does not get fixed by this patch. One needs to add the node name before
node contents=.... To see what that means, consider
You always have to set the node name either by using the name options before or in the options where node contents appears or in (…) before those options:
\node (name) [node contents=text];
\node [name=name] [node contents=text];
\node […] (name) [node contents=text];
\node [name=name, node contents=text];
\node [node contents=text, name=name];
Nothing else is valid according to the manual. Doesn't matter if it's along a path operation (to be collected) or just a normal node.
I can see an option via key-filtering to not have to deal with options that might have global effects. Are there any?
\documentclass{article}
\usepackage{tikz}
\tikzset{
key filter/collect contents/.is family,
node contents/.belongs to family=/tikz/key filter/collect contents,
pic type/.belongs to family=/tikz/key filter/collect contents}
\makeatletter
\def\tikz@collect@options#1]{%
\expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath#1]}%
\begingroup
\pgfkeysinstallkeyfilter
{/pgf/key filters/equals}
{/tikz/key filter/collect contents}%
\pgfqkeysfiltered{/tikz}{every node,#1}%
\pgfutil@ifxempty\tikz@node@content
{\endgroup\tikz@collect@label@scan}
{\endgroup
\pgfutil@ifnextchar\bgroup % ← backwards compat
{\expandafter\tikz@collect@cont\pgfutil@gobble}% ← backwards compat
\tikz@collect@cont}%
}
\makeatother
\begin{document}
\begin{tikzpicture}[but this is not/.pic=]
%\node[at={(0,0)}, node contents=this is fine];
\draw (0,0) to node [node contents=but this is not] (0, -1);
\draw (0,0) to node [node contents=but this is not] {} (0, -1); % backwards compat?
\path (0,0) to pic [pic type=but this is not] (0, -1);
\path (0,0) to pic [pic type=but this is not] {} (0, -1); % backwards compat?
\end{tikzpicture}
\end{document}