6

I wanted to build an environment that allows to save tikz pictures as boxes. This is the code that I tried:

\documentclass{standalone}

\usepackage{tikz}

\begin{document}

\newenvironment{tikzcomponent}[1]
{
  \newsavebox{#1}%
  \begin{lrbox}{#1}
    \begin{tikzpicture}%
    }
    {
    \end{tikzpicture}%
  \end{lrbox}
}

\begin{tikzcomponent}{\abox}
  \draw (0,0) -- (1,1) node {Hello world};
\end{tikzcomponent}

\usebox\abox

\end{document}

It compiles without errors, but the result is empty. Why is that?

8

The issue is that your box is only local. (If you are not familiar with the notions global and local, you may want to look at section 10 of TeX by topic, texdoc texbytopic.) So you may want to make it global (or at least smuggle it out of the group). This can be achieved more easily with the environ package.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{environ}
\NewEnviron{tikzcomponent}[1]{\newsavebox{#1}%
  \begin{lrbox}{#1}%
  \begin{tikzpicture}
    \BODY
  \end{tikzpicture}%
  \end{lrbox}%
  \global\setbox#1\box#1% <- globalize the box
}
\begin{document}

\begin{tikzcomponent}{\abox}
  \draw (0,0) -- (1,1) node {Hello world};
\end{tikzcomponent}
\usebox\abox
\end{document}

enter image description here

1

Package xsavebox could be an option.

Its boxes are global, and they are addressed by name, rather than by command. Standard saveboxes have local scope. In the present case, the scope is limited by the environment tikzcomponent.

There is some freedom in choosing box names. They may be built from any non-active characters (letters, digits, space, punctuation marks). More importantly, the box content (PDF code) is embedded only once in the PDF output, which may save some file size in the case of repeated insertions, such as watermarks or logos.

\documentclass{standalone}

\usepackage{tikz}
\usepackage{xsavebox}

\newenvironment{tikzcomponent}[1]{%
  \begin{xlrbox}{#1}
  \begin{tikzpicture}
}{
  \end{tikzpicture}
  \end{xlrbox}%
}

\begin{document}

\begin{tikzcomponent}{a box?}
  \draw (0,0) -- (1,1) node {Hello world};
\end{tikzcomponent}%
%
\xusebox{a box?}

\end{document}

enter image description here

  • Thanks, xsavebox looks useful! Do you know if xsavebox also shares the 256 (or 32768 with etex) box limit? – bennofs Oct 22 at 9:23
  • @bennofs The package uses only 2 TeX box registers in total. Thus, no limit and no danger at all. – AlexG Oct 22 at 9:25
0

An alternative to storing in boxes, save directly in memory using the scontents package:

\documentclass{standalone}
\usepackage{tikz}
\usepackage[store-env=tikz]{scontents}
\begin{document}
\begin{scontents}
\begin{tikzpicture}
  \draw (0,0) -- (1,1) node {Hello world};
\end{tikzpicture}
\end{scontents}
\getstored[1]{tikz}
\end{document}

enter image description here

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.