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.

  • 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: tex.stackexchange.com/questions/332215 Note the first sentence of the answer. – Torbjørn T. May 16 '17 at 11:19
  • 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 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
  • 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
  • 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
6

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

4

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.