5

What way do you recommend to access the

  • the label text

of a named node later in the same tikzpicture?

Small example:

\begin{tikzpicture}   
    \node (curve0) at (0,0) [] {curve $C_0$}; 
    \node (alaternodeinwhichlabeltextofcurveoughttobeused) at (0,2) { The following is a label text of a node we already defined: (curve0.label text) };
\end{tikzpicture}

where, of course, the above use of "(curve0.label text)" is not permissible, but in analogy to existing features like "(curve0.center)".

This must be very usual, but is escaping my reading of the literature.

Feel free to correct if "label text" is not the correct technical term for this particular entity (I am taking it from a certain error message produced by tikz).

Edit: Like recommended in the comments, a workaround is to use a separate macro. For example:

\begin{tikzpicture}   
    \newcommand{\labeltextofcurve0}{curve $C_0$};
    \node (curve0) at (0,0) [] {\labeltextofcurve0}; 
    \node (alaternodeinwhichlabeltextofcurve0oughttobeused) at (0,2) { An isotopy from \labeltextofcurve0 to the curve $C_\infty$ is the following: ... };
\end{tikzpicture}

However, there are at least two issues with this:

  • Quantitative: this solution requires one separate line of code for each label text. (In the problem motivating this question, there are many nodes, each of whose label text I would like to access. Imagine (curve0), (curve1), ... , (curve 17), and having one separate \newcommand{\labeltextof...} for each...) It appears more natural to define the label text in the content of the node.

  • Qualitative: there is a decision to be made where to place the \newcommmand{\labeltextofcurve0}. Sure, immediately before the definition of (curve0) seems a canonical choice, but there are issues with 'scopes', that appear too complicated and cofusing to describe here.

Therefore, wouldn't it be better to have a way to say (curve0.label text), and have it work whenever (curve0) is defined somewhere else in the code?

An opinion on whether using the additional

  \newcommand{\labeltextofcurve0}{curve $C_0$};

is to be preferred over trying to get a "(curve0.label text)"-feature would be appreciated.

  • Do you mean "label" in the sense of a \label/\ref pair? If so, what should the \ref return? Or do you mean to have a way to save the text of a label in a macro that can be called elsewhere? – Steven B. Segletes May 16 '17 at 11:01
  • So you mean {label $x$} in this case (why the extra braces, by the way?) – Torbjørn T. May 16 '17 at 11:05
  • Thanks. The "label $x$" is meant to be the label text of the node, the use of the word label is not referring to a keyword. So a clearer way to put the question would be to replace "label $x$" by e.g. "manifold $M_0$". – Peter Heinig May 16 '17 at 11:14
  • No reason for the extra braces except a personal habit of adding this extra layer of braces, due to some experiences with tikz where it seemed to help to do so. I cannot make this more precise. I now remove these superfluous braces from the question, thanks. – Peter Heinig May 16 '17 at 11:16
  • 4
    I don't think it is very common, at least I cannot remember any previous questions here about it. The obvious workaround is of course \newcommand\textofmyfirstnode{label $x$}, and use \textofmyfirstnode in both nodes. Somewhat related question: https://tex.stackexchange.com/questions/332215 Note the first sentence of the answer. – Torbjørn T. May 16 '17 at 11:19
  • In view of existing features like "(vertex.north west)", wouldn't one expect there to be something like "(vertex.label text)", returning the content of the braces {}? – Peter Heinig May 16 '17 at 11:45
  • 1
    Not really, the dot notation is only for referring to anchors of the nodes, used as a coordinate specification, it is not for getting generic properties of a node. (And by the way, I'm not notified of your comments, you need to write @<username> to ping a user, see https://meta.stackexchange.com/questions/43019 You are always notified, because it's your post.) – Torbjørn T. May 16 '17 at 12:10
  • 1
    Note that the node in question doesn't have a label. I think you mean the content of the node or the node's text. To label it, you'd use e.g. label=below:label of node in the options. Forest can do this, but that isn't much help unless you are drawing a tree. – cfr May 16 '17 at 12:15
  • @cfr: Thanks. Then, is there a way to access the content of a node? I.e., is there a way to do this without replacing "[]" in the example code snippet of the question by something more complicated. I.e., is there are way to do this without adding options? – Peter Heinig May 16 '17 at 12:25
  • 2
    I don't think it is a question of access. I am not sure if TikZ even knows the content of the node at that point. That is, it must know it in some sense, but I don't know if it knows it as a piece of data distinct from other things. Maybe it does. As far as I know, you can't access it, though. But I'm not a PGF expert, which is what you need, if it can be done at all. As I say, Forest does make this information accessible. But why can't you use a macro, as suggested? That would be the standard way to handle it. – cfr May 16 '17 at 15:02
  • @cfr: Thanks. A macro can be used, as pointed out in the edited question. I am wondering whether it should be used. – Peter Heinig May 17 '17 at 05:17
  • @cfr: Re the use of the term "label": do you think the term "label" should be removed from the question? You say that the node does not have a label. Is it nevertheless correct that it has a "label text"? The reason for thinking that it has one is: if you define a node by \node (a) at (0,0) []; then tikz gives the error message "A node must have a (possibly empty) label text." Of course, strictly logically speaking, this does not imply (at least not in constructive logic) that what is inside {} is to be referred to as a "label text", but nevertheless strongly suggests that it should. – Peter Heinig May 17 '17 at 09:29
  • 1
    Then the error message is confusing, too, because nodes can, optionally, have labels and the natural thing to say about the text in any label is that it is the 'label text'. But if the programme is itself misleading, I don't know what to say. – cfr May 17 '17 at 13:38
  • 1
    How do you want to capture the content of a node with side effects (as \refstepcounter for example)? – Paul Gaborit May 23 '17 at 05:00

2 Answers2

8

You can hack into the TikZ code and just capture the node content in a macro.

\documentclass{article}
\usepackage{tikz}
\makeatletter
\protected\def\tikz@fig@main#1{%
  \expandafter\gdef\csname labeltextof@\tikz@fig@name\endcsname{#1}%
  \iftikz@node@is@pic%
    \tikz@node@is@picfalse%
    \tikz@subpicture@handle{#1}%
  \else%
    \tikz@@fig@main#1\egroup%
  \fi}
\makeatother

\newcommand\labeltextof[1]{\csname labeltextof@#1\endcsname}
\begin{document}

\begin{tikzpicture}
  \node (curve0) at (0,0) [] {curve $C_0$}; 
    \node (alaternodeinwhichlabeltextofcurve0oughttobeused) at (0,2) {
      An isotopy from \labeltextof{curve0} to the curve
      $C_\infty$ is the following: ... };
\end{tikzpicture}

\end{document}

enter image description here

Henri Menke
  • 109,596
5

TikZ, when parsing the node syntax, gets the brace pair content puts it in a hbox or a minipage and forgets it. So it will not remember the contents. This remembering is tough because it can be anything including tables or images. Thus assigning to a key is by no means that straightforward.

But you can use macros as comments and Henri's answer mentioned or using node contents,name and at keys to define the node.

\documentclass{article}
\usepackage{tikz}

\tikzset{nodelist/.is family,
nadd/.code 2 args= {%
    \tikzset{node contents=#1,name=#2}%
    \begingroup\globaldefs=1\relax%
    \pgfkeyssetvalue{/nodelist/#2}{#1}%
    \endgroup%
  }
}
\begin{document}    
\begin{tikzpicture}[]
  \node[nadd={My text}{a},at={(4,2)}]; % Add this to "my remembered nodes list"
  \node[draw] at (1,1) {\pgfkeysvalueof{/nodelist/a}};
\end{tikzpicture}
\end{document}

enter image description here

Note however, if you use node contents key then you won't use the brace syntax for the contents and TikZ uses a different way lloking for arguments. Hence you get a little different behavior. But still in my opinion, this is not as productive as you would think in the long run.

percusse
  • 157,807