6

I have a series of complicated content I'm trying to present using TikZ. The code is highly regular, so I wanted to write a simple command to handle everything. In the following code, \aelabelA and \aelabelC are not working properly at all and I don't understand why. However, \aelabelB does work. Could someone explain why the content of the boxes for scenario A and C is not visible?

\documentclass{standalone}
\usepackage{xparse}
\usepackage{tikz}

\ExplSyntaxOn
\newsavebox\aebox
\NewDocumentCommand\aelabelA{ mu{~located~at~(}u{);} }
  {
    \begin{lrbox}{\aebox}
      \begin{minipage}{1in}
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}
      \end{minipage}
    \end{lrbox}
    \node[draw] ~ at~  (#3)  ~ {\usebox{\aebox}};
  }

\NewDocumentCommand\aelabelB{ m }
  {
    \begin{lrbox}{\aebox}
      \begin{minipage}{1in}
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}
      \end{minipage}
    \end{lrbox}
    \usebox{\aebox}
  }

\ExplSyntaxOff

\def\aelabelC#1 located at (#2);{%%
    \begin{lrbox}{\aebox}
      \begin{minipage}{1in}
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}
      \end{minipage}
    \end{lrbox}%%
    \node[draw] at (#2) {\usebox{\aebox}};
  }

\begin{document}

\begin{tikzpicture}

  \coordinate (AA) at (0,0);
  \coordinate (BB) at (2,2);
  \coordinate (CC) at (4,4);

  \aelabelA {Keys} located at (AA);

  \node[draw] at (BB) {\aelabelB{Keys}};

  \aelabelC{Keys} located at (CC);

\end{tikzpicture}

\end{document}

enter image description here

  • That's indeed a bit curious. (+1) However, if you put something in your tikzpicture (but not in a node), this will be gobbled. Isn't that just what happens to the contents of the lrboxes? As you see in your example B, if you do the lrbox inside a node, it won't be gobbled. If you could explain what you really want to do, perhaps there is a way with the usual TikZ/pgf methods. – marmot Aug 30 '18 at 21:24
  • @marmot omg. that's probably the problem. thank you. write up your comment as an answer and i'll accept later when i get back to my computer and test everything out. – A.Ellett Aug 30 '18 at 21:36
4

TikZ is known to gobble ordinary stuff inside tikzpicture environments unless this stuff is in a node. You can interrupt the tikzpicture in order to evade from getting ignored, and you need a bit globalization to make it work. I fixed your first command in this fashion but left the last one as it was for pedagogical purposes.

\documentclass{standalone}
\usepackage{xparse}
\usepackage{tikz}

\ExplSyntaxOn
\newsavebox\aebox
\NewDocumentCommand\aelabelA{ mu{~located~at~(}u{);} }
  {\begin{pgfinterruptpicture}
    \begin{lrbox}{0\null\global\setbox\aebox} % from https://tex.stackexchange.com/questions/49129/lrbox-in-newenvironment/49136#49136
      \begin{minipage}{1in}
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}
      \end{minipage}
    \end{lrbox}
    \end{pgfinterruptpicture}
    \node[draw] ~ at~  (#3)  ~ {\usebox{\aebox}};
  }

\NewDocumentCommand\aelabelB{ m }
  {
    \begin{lrbox}{\aebox}
      \begin{minipage}{1in}
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}
      \end{minipage}
    \end{lrbox}
    \usebox{\aebox}
  }

\ExplSyntaxOff

\def\aelabelC#1 located at (#2);{%%
    \begin{lrbox}{\aebox}
      \begin{minipage}{1in}
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}
      \end{minipage}
    \end{lrbox}%%
    \node[draw] at (#2) {\usebox{\aebox}};
  }

\begin{document}

\begin{tikzpicture}

  \coordinate (AA) at (0,0);
  \coordinate (BB) at (2,2);
  \coordinate (CC) at (4,4);

  \aelabelA {Keys} located at (AA);

  \node[draw] at (BB) {\aelabelB{Keys}};

  \aelabelC{Keys} located at (CC);

\end{tikzpicture}

\end{document}

enter image description here

EDIT: A somewhat cleaner alternative due to @egreg (mille grazie!) with the same output.

\documentclass{standalone}
\usepackage{xparse}
\usepackage{tikz}

\ExplSyntaxOn
\newsavebox\aebox
\NewDocumentCommand\aelabelA{ mu{~located~at~(}u{);} }
  {\begin{pgfinterruptpicture}
    \begin{lrbox}{0}%
      \begin{minipage}{1in}%
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}%
      \end{minipage}%
    \end{lrbox}%
    \global\setbox\aebox=\box0
    \end{pgfinterruptpicture}
    \node[draw] ~ at~  (#3)  ~ {\usebox{\aebox}};
  }

\NewDocumentCommand\aelabelB{ m }
  {
    \begin{lrbox}{\aebox}
      \begin{minipage}{1in}
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}
      \end{minipage}
    \end{lrbox}
    \usebox{\aebox}
  }

\ExplSyntaxOff

\def\aelabelC#1 located at (#2);{%%
    \begin{lrbox}{\aebox}
      \begin{minipage}{1in}
        \Large\ttfamily\bfseries
        \centering\makebox[0pt]{#1}
      \end{minipage}
    \end{lrbox}%%
    \node[draw] at (#2) {\usebox{\aebox}};
  }

\begin{document}

\begin{tikzpicture}

  \coordinate (AA) at (0,0);
  \coordinate (BB) at (2,2);
  \coordinate (CC) at (4,4);

  \aelabelA {Keys} located at (AA);

  \node[draw] at (BB) {\aelabelB{Keys}};

  \aelabelC{Keys} located at (CC);

\end{tikzpicture}

\end{document}

A macro for creating \saveboxes inside a tikzpicture has been created in this question.

  • 2
    I suggest the cleaner \begin{lrbox}{0}...\end{lrbox}\global\setbox\aebox=\box0 – egreg Sep 3 '18 at 21:10

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.