4

I want to design a tikz style that will modify a node content according to some function of mine. As suggested in an answer to the original question, I can use the “execute at begin node” key for this. But it does not play well with “align” and linebreaks. Any idea why? (I suspect something related to the way \\ works, but I am not sure; replacing with \newline shows no improvement.)

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
% First picture: the align instruction works.
% The prefix word appears, as expected, on top of MyTest.
\begin{tikzpicture}
  \path node[align=left] {prefix \\ MyTest};
\end{tikzpicture}

\newcommand{\myfunction}[1]{prefix \\ #1}
% Second picture: now align has no apparent effect any more.
% The prefix word and MyTest appear together on the same line.
\begin{tikzpicture}
  \path node[align=left, execute at begin node=\myfunction] {MyTest};
\end{tikzpicture}
\end{document}
6
  • align installs a minipage you are overwriting it and making it an hbox
    – percusse
    Feb 1, 2016 at 13:42
  • @percusse Good point. I now see that this is probably explained in the pgf manual (although I don’t really understand it when it speaks about the node halign header part). I can’t find a workaround however in the manual. E.g., using a tabular inside \myfunction definition yields “Extra }, or forgotten \endgroup.”. Feb 2, 2016 at 14:58
  • Why don't you simply use node contents ?
    – percusse
    Feb 2, 2016 at 15:55
  • For consistency reasons, I’d prefer keeping the usual syntax for nodes if possible, where the “contents” go in the brackets following the nodes. This way I can change the style and not change the rest of the syntax. Here, I consider the added prefix as an element of style, which I agree is only one of the possible points of view. But you are right, node contents is certainly a viable option in absence of a solution for align. Feb 2, 2016 at 16:52
  • @percusse minipage is still there, try \node[align=left, execute at begin node=\myfunction] {MyTest\\second line};.
    – Symbol 1
    Feb 2, 2016 at 18:22

1 Answer 1

2

Go to tikz.code.tex line 3713, there is the definition of \tikz@do@fig. This is the essential part of typesetting nodes. In the definition one can see \tikz@atbegin@node at line 3736 and \tikz@halign@check at 3755.

As one might guess, \tikz@atbegin@node is the macro the stores execute at begin node-codes, and \tikz@halign@check checks if you says align=something and build up a \halign. Therefore by default your prefix is not involved in \halign-construction and hence is put aside the node content. Try

\node[align=left,execute at begin node=\myfunction]{MyTest\\aa\\bb\\cc};

to see this clearer.

To solve this, a stupid method is to rearrange the code so that \tikz@halign@check happens before \tikz@atbegin@node. A stupid instance is

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\newcommand{\myfunction}[1]{prefix \\ #1}

\makeatletter
\def\tikz@do@fig{%  
    % Ok, reset all node part boxes
    \pgfutil@for\tikz@temp:=\tikz@nodepart@list\do{%
      \expandafter\setbox\csname pgfnodepart\tikz@temp box\endcsname=\box\pgfutil@voidb@x%
    }%
    \setbox\pgfnodeparttextbox=\hbox%
      \bgroup%
        \tikzset{every text node part/.try}%
        \ifx\tikz@textopacity\pgfutil@empty%
        \else%
          \pgfsetfillopacity{\tikz@textopacity}%
          \pgfsetstrokeopacity{\tikz@textopacity}%
        \fi%
        \pgfinterruptpicture%
          \ifx\tikz@text@width\pgfutil@empty%
            \tikz@textfont%  
          \else%
            \begingroup%
                \pgfmathsetlength{\pgf@x}{\tikz@text@width}%
              \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}%
                \tikz@textfont%  
                \tikz@text@action%
          \fi%
          \bgroup%
            \aftergroup\unskip%
            \ifx\tikz@textcolor\pgfutil@empty%
            \else%
              \pgfutil@colorlet{.}{\tikz@textcolor}%
            \fi%
            \pgfsetcolor{.}%
            \setbox\tikz@figbox=\box\pgfutil@voidb@x%
            \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
            \tikz@uninstallcommands%
            \iftikz@handle@active@code%  
              \tikz@orig@shorthands%
              \let\tikz@orig@shorthands\pgfutil@empty%
            \fi%
            \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi%
            \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi%
            \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi%
            \aftergroup\tikz@fig@collectresetcolor%
            \tikz@halign@check%
            \tikz@atbegin@node%
            \ignorespaces%
}

\tikz\node[align=left,execute at begin node=\myfunction]{MyTest\\aa\\bb\\cc};

\end{document}

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.