7

Is it in a way possible to preserve parts of a preamble of a standalone document? For example when I have a savebox or a macro inside it and don't want to repeat it in the preamble of my main document. Here a mini example mypicture.tex:

\documentclass[tikz,border=5pt]{standalone}
\newsavebox\mybox
\savebox\mybox{
  \begin{tikzpicture}
    \draw[->] (0,0) -- (1,1);
  \end{tikzpicture}
}
\begin{document}
  \begin{tikzpicture}
    \node[draw] (a) at (0,0) {A};
    \node[draw] (b) at (0,2) {\usebox\mybox};
    \draw[->] (a) -- (b);
  \end{tikzpicture}
\end{document

So when I include this file inside my main document I don't want to reassign my savebox but instead reuse the one from the standalone file.

\documentclass{report}
\usepackage{standalone}
% No redeclaration of the savebox here
\begin{document}
  \input{mypicture.tex}
\end{document}

I didn't found any mechanism in the standalone manual but perhaps there is an easy solution to this problem.

  • Would it help to put the \newsavebox after \begin{document}? Or asked in another way: Is there a reason why it must be in the preamble? – knut Feb 3 '14 at 7:53
  • as far as I understand is this not possible because nesting of environments is disallowed (and gives a missing \endgroup error) – Reza Feb 3 '14 at 7:55
  • See my answer. It works with your MWE. – knut Feb 3 '14 at 11:27
5

The standalone package has a subpreambles option that preserves the preambles. Your MWE seems to have a couple of small issues (it is missing a } in \end{document} and you never load the tikz package. Fixing those two issues and adding the package option

\documentclass{report}
\usepackage[subpreambles=true]{standalone}
% No redeclaration of the savebox here
\begin{document}
  \input{mypicture.tex}
\end{document}

and

\documentclass[tikz,border=5pt]{standalone}
\usepackage{tikz}
\newsavebox\mybox
\savebox\mybox{
  \begin{tikzpicture}
    \draw[->] (0,0) -- (1,1);
  \end{tikzpicture}
}
\begin{document}
  \begin{tikzpicture}
    \node[draw] (a) at (0,0) {A};
    \node[draw] (b) at (0,2) {\usebox\mybox};
    \draw[->] (a) -- (b);
  \end{tikzpicture}
\end{document}
  • Thanks that is in a way what I was looking for. But there's no fine grained control, to allow parts of the sub preambles to be included in the main preamble? – Reza Feb 4 '14 at 7:27
  • @Reza \ifstandalone may be able to give you the control that you need, but it is not clear from your MWE what you are trying to do. – StrongBad Feb 4 '14 at 10:24
1

My recommendation in my comment works with your MWE.

When you put the \newsavebox after \begin{document} it works:

There are some minor additional errors:

mypicture.tex missed the closing } in \end{document}:

\documentclass[tikz,border=5pt]{standalone}

\begin{document}

\newsavebox\mybox
\savebox\mybox{
  \begin{tikzpicture}
    \draw[->] (0,0) -- (1,1);
  \end{tikzpicture}
}

  \begin{tikzpicture}
    \node[draw] (a) at (0,0) {A};
    \node[draw] (b) at (0,2) {\usebox\mybox};
    \draw[->] (a) -- (b);
  \end{tikzpicture}
\end{document}

your mainfile missed the \usepackage{tikz}:

\documentclass{report}
\usepackage{tikz}
\usepackage{standalone}
\begin{document}
  \input{mypicture.tex}
\end{document}

Update: I detected a problem when I run mypicture.tex. This version solved the problem, but I think a better solution (without code repetition) should be possible:

\documentclass[tikz,border=5pt]{standalone}
 \ifstandalone
    \newsavebox\mybox
    \savebox\mybox{
      \begin{tikzpicture}
        \draw[->] (0,0) -- (1,1);
      \end{tikzpicture}
    }
\fi
\begin{document}
 \ifstandalone
 \else
    \newsavebox\mybox
    \savebox\mybox{
      \begin{tikzpicture}
        \draw[->] (0,0) -- (1,1);
      \end{tikzpicture}
    }
\fi
\begin{tikzpicture}
    \node[draw] (a) at (0,0) {A};
    \node[draw] (b) at (0,2) {\usebox\mybox};
    \draw[->] (a) -- (b);
  \end{tikzpicture}
\end{document}
  • Strange your example gives me an missing \endgroup inserted error. – Reza Feb 3 '14 at 13:00
1

The most recommended solution by me only for the best practitioners.

Step 1: Create a package

Put everything you use across many input files in a single package, e.g., mygraphiclib.sty.

% mygraphiclib.sty
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{mygraphiclib}[2014/02/03 v0.01 LaTeX package for my graphic library]
\RequirePackage{tikz}

% mybox
\newsavebox\mybox
\savebox\mybox{%
  \begin{tikzpicture}
    \draw[->] (0,0) -- (1,1);
  \end{tikzpicture}
}

% myBox
\newcommand\myBox{%
  \begin{tikzpicture}
    \draw[->] (0,0) -- (1,1);
  \end{tikzpicture}}

\endinput
% mygraphiclib.sty

Use \newcommand so you can avoid defining the same macro name accidentally.

Step 2: Create child input files

You can separate each diagram into its own input file by using standalone class. This input file of course needs the mygraphiclib.sty if you want to make use of the macros in mygraphiclib.sty.

% child.tex
\documentclass[tikz,border=12pt]{standalone}
\usepackage{mygraphiclib}
\begin{document}
    \begin{tikzpicture}
        \node[draw] (a) at (0,0) {A};
        \node[draw] (b) at (0,2) {\usebox\mybox};
        \draw[->] (a) -- (b);
    \end{tikzpicture}
\end{document}

During the development phase, you might need to recompile this input file many times so separation of concern really helps you to reduce the compilation time. Imagine if you put all graphic code in the main input file, you will waste much time to compile a bunch of diagrams every time you modify just a single diagram.

Step 3: Create the main input file

The main input file just needs to load mygraphiclib.sty and standalone (or docmute) to make use the child input files.

% main.tex
\documentclass{article}
\usepackage{mygraphiclib}
\usepackage{standalone}% or \usepackage{docmute}

\begin{document}
\input{child}
\end{document}

Simulation all in one

The following input file simulates all of the steps given above as a single input file.

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{mygraphiclib.sty}
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{mygraphiclib}[2014/02/03 v0.01 LaTeX package for my graphic library]
\RequirePackage{tikz}

% mybox
\newsavebox\mybox
\savebox\mybox{%
  \begin{tikzpicture}
    \draw[->] (0,0) -- (1,1);
  \end{tikzpicture}
}

% myBox
\def\myBox{%
  \begin{tikzpicture}
    \draw[->] (0,0) -- (1,1);
  \end{tikzpicture}}

\endinput
% mygraphiclib.sty
\end{filecontents*}

\begin{filecontents*}{child.tex}
\documentclass[tikz,border=12pt]{standalone}
\usepackage{mygraphiclib}
\begin{document}
    \begin{tikzpicture}
        \node[draw] (a) at (0,0) {A};
        \node[draw] (b) at (0,2) {\usebox\mybox};
        \draw[->] (a) -- (b);
    \end{tikzpicture}
\end{document}
\end{filecontents*}

\usepackage{mygraphiclib}
\usepackage{standalone}

\begin{document}
\input{child}
\end{document}
0

First file:

%% mypicture.tex
\documentclass[tikz,border=5pt]{standalone}
\usepackage{tikz}
\usepackage{filecontents}
\begin{filecontents*}{temp.tex}
    \tikz\draw[->] (0,0) -- (1,1);
\end{filecontents*}

\begin{document}

\begin{tikzpicture}
    \node[draw] (a) at (0,0) {A};
    \node[draw] (b) at (0,2) {\input{temp}};
    \draw[->] (a) -- (b);
\end{tikzpicture}

\end{document}

Second file:

%%% myfile.tex
\documentclass{report}
\usepackage{tikz}
\usepackage{standalone}
\begin{document}
  \input{mypicture.tex}
\end{document}

Running mypicture.tex and myfile.tex has the output myfile.pdf:

enter image description here

  • Thanks! But this approach is not working with savebox. Nesting of environments causes an error. – Reza Feb 3 '14 at 7:30
  • @Reza: Make a complete example, which shows what exactly you want. It is also possible to create the standalone file from within another file. – user2478 Feb 3 '14 at 8:59
  • @Herbert Ok I adjusted my example, hope it's clear now – Reza Feb 3 '14 at 10:51
  • @Reza: see my edited answer – user2478 Feb 3 '14 at 11:55
  • Good idea, but it's not working with a \savebox inside the temp.tex file – Reza Feb 3 '14 at 13:09

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.