6

For using a TikZ matrix as part of a nested tikzpicture, I define the former in advance and store it in a savebox.
However, when I add a second column, compilation fails. It seems to be due to the & (see MWE below). The log notably says: ! Package pgf Error: Single ampersand used with wrong catcode.

Question: How to define a TikZ matrix with multiple columns in a savebox?


\documentclass{article}
    \usepackage{tikz}

    \newsavebox{\testsbox}
    \savebox{\testsbox}{
        \begin{tikzpicture} [borders/.style={draw, help lines}]
            \matrix[borders]{
                \node [borders] {11};
%           &
%               \node [borders] {12};
            \\
            };
        \end{tikzpicture}
    }

\begin{document}
    This example stops working as soon as you add a second column (i.e. uncomment lines 9 and 10).
    \begin{tikzpicture}
        \node {\usebox{\testsbox}};
    \end{tikzpicture}
\end{document}
ebosi
  • 11,692

2 Answers2

10

TikZ changes the category code of & to be an active character to process the matrix. But the tikzpicture is used as argument for \savebox. When TeX parses an argument, then the text is tokenized with the current category code settings. Then, when TikZ changes the category code, it does not have an effect, because & is already tokenized.

LaTeX provides the environment lrbox as alternative to the commands \savebox or \sbox. In the environment form, the contents is not read as argument and category changes work:

\documentclass{article}
\usepackage{tikz}

\newsavebox{\testsbox}
\begin{lrbox}{\testsbox}
    \begin{tikzpicture} [borders/.style={draw, help lines}]
        \matrix[borders]{
            \node [borders] {11};
        &
            \node [borders] {12};
        \\
        };
    \end{tikzpicture}
\end{lrbox}

\begin{document}
    \begin{tikzpicture}
        \node {\usebox{\testsbox}};
    \end{tikzpicture}
\end{document}

Result

The environment lrbox also removes spaces at the begin and at the end of the body in opposite to \savebox/\sbox.

Heiko Oberdiek
  • 271,626
8

Use the ampersand replacement to replace & by an arbitrary command (most people choose \&).

\documentclass{article}
    \usepackage{tikz}

    \newsavebox{\testsbox}
    \savebox{\testsbox}{%
        \begin{tikzpicture} [borders/.style={draw, help lines}]
            \matrix[borders,ampersand replacement=\&]{
                \node [borders] {11};
            \&
                \node [borders] {12};
            \\
            };
        \end{tikzpicture}%
    }

\begin{document}
    This example stops working as soon as you add a second column (i.e. uncomment lines 9 and 10).
    \begin{tikzpicture}
        \node {\usebox{\testsbox}};
    \end{tikzpicture}
\end{document}

enter image description here

egreg
  • 1,121,712
Henri Menke
  • 109,596
  • Great! I should have read the PGF manual more carefully, since it is all detailed in ยง20.5 Considerations Concerning Active Characters (v3.0.1a)! โ€“ ebosi Apr 08 '17 at 01:46
  • 1
    The spaces by line ends after \savebox{\testsbox} and \end{tikzpicture} matter and go into the horizontal box \testsbox. โ€“ Heiko Oberdiek Apr 08 '17 at 02:15
  • @HeikoOberdiek nice catch! I should have commented the ends of line. โ€“ ebosi Apr 08 '17 at 02:39