pgf icon indicating copy to clipboard operation
pgf copied to clipboard

`node contents` key for nodes on a path

Open pgf-tikz-bot opened this issue 11 years ago • 12 comments

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}

pgf-tikz-bot avatar Oct 18 '14 21:10 pgf-tikz-bot

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.

pgf-tikz-bot avatar Dec 28 '18 05:12 pgf-tikz-bot

Migrated from SourceForge Author: hmenke Timestamp: 2019-01-21 20:59:44.069000

  • assigned_to: Henri Menke

pgf-tikz-bot avatar Jan 21 '19 20:01 pgf-tikz-bot

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}

hmenke avatar Nov 20 '19 21:11 hmenke

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

hmenke avatar Nov 23 '19 02:11 hmenke

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.

ghost avatar Dec 20 '19 19:12 ghost

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.

hmenke avatar Dec 20 '19 19:12 hmenke

All I want to say is that there is the related issue.

ghost avatar Dec 20 '19 20:12 ghost

What related issue? You just repeated the original issue.

hmenke avatar Dec 21 '19 00:12 hmenke

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

ghost avatar Dec 21 '19 01:12 ghost

It's the same issue.

hmenke avatar Dec 21 '19 01:12 hmenke

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

ghost avatar Dec 21 '19 01:12 ghost

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}

Qrrbrbirlbel avatar Jul 29 '24 10:07 Qrrbrbirlbel