4

After digging into the output of \tracingmacros=1 during a while, I'll ask here... I am trying to add a bit of introspection to pgf shapes. The idea is to be able to "extract" a \savedmacro of a shape.

To be more specific: is it possible to define the following \whatamI macro so that it expands to the shape (passed as argument) internal \Iam?

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\pgfdeclareshape{myA}{
    \savedmacro{\Iam}{\edef\Iam{A}}
    \anchor{center}{\pgfpointorigin}
    \behindbackgroundpath{
        \pgfnode{circle}{center}{\Iam}{}{\pgfusepath{stroke}}
    }
}
\pgfdeclareshape{myB}{
    \savedmacro{\Iam}{\edef\Iam{B}}
    \anchor{center}{\pgfpointorigin}
    \behindbackgroundpath{
        \pgfnode{rectangle}{center}{\Iam}{}{\pgfusepath{stroke}}
    }
}
\def\whatamI#1{%
    % extract the saved macro \Iam definition
    % return \relax or -NoItem- or whatever if not defined in the shape
    % ???
}
\begin{document}
    They works: \begin{tikzpicture}
        % \tracingmacros=1
        \node [myA](A) at(0,0) {};
        % \tracingmacros=1
        \node [myB](B) at(1,0) {};
        % ...more code
        \edef\nodeAis{\whatamI{A}} % so now I can do different things dinamically
        \node [draw, rectangle,red,right] at (2,0) {%
            Node A is \nodeAis};
    \end{tikzpicture}

\end{document}

Output from the MWE above

Notice that I really do not need to retrieve the instance-specific savedmacro of a shape through its label/name. Even being able to retrieve the last one specified or to retrieve the value in the shape text would suffice to me.

  • Try \def\whatamI#1{\csname pgf@sh@ma@#1\endcsname\message{^^J^^J I am \Iam^^J^^J}}. – Symbol 1 Jul 25 '19 at 9:51
3
+100

It seems the main problem is that you do not know where are the saved things. For macros, they are in \pgf@sh@ma@NAMEOFNODE where NAMEOFNODE is to be replaced with the name of the node.

For instance, if I insert \show\pgf@sh@ma@A in your code, I get

> \pgf@sh@ma@A=macro:
->\def \Iam {A}.

If, instead, I insert \show\pgf@sh@ma@B, I get

> \pgf@sh@ma@B=macro:
->\def \Iam {B}.

There will be multiple things if there are more than one saved macros. For example for the shape regular polygon from shapes.geometric, there are its saved macros

> \pgf@sh@ma@NAMEOFPOLYGON=macro:
->\def \sides {5}\def \anglestep {72.0}\def \calculateradii {\def \radius {5.82619pt}\def \anchorradius {6.07338pt}}\def \startangle {90.0}.

Back to your question. To extract the \Iam of node (A), just execute \pgf@sh@ma@A and then \Iam will be defined to be A. Similarly if you execute \pgf@sh@ma@B then \Iam will be defined to be B.

So the following works

\begin{tikzpicture}
    \node [myA](A) at(0,0) {};
    \node [myB](B) at(1,0) {};
    \node [draw, rectangle,red] at (3,0) {%
        Node A is \pgf@sh@ma@A\Iam};
    \node [draw, rectangle,green,right] at (5,0) {%
        Node B is \pgf@sh@ma@B\Iam};
\end{tikzpicture}

P.S. Here is a list

  • pgf@sh@ns@#1: "node shape", such as rectangle or circle.
  • pgf@sh@np@#1: saved anchors and dimensions.
  • pgf@sh@nt@#1: transformation applied to the node; this affects the position of anchors so it is worth remembering.
  • pgf@sh@pi@#1: the picture id; this is used for remember picture etc.
  • pgf@sh@ma@#1: saved macros as in this answer.

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.