Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Is it possible to nest files with the standalone package? I have something like the following:

In A.tex:

\documentclass{article}
\usepackage{standalone}
\begin{document}
\input{B}
\end{document}​

B.tex:

\documentclass{standalone}
\begin{document}
\begin{table}
  \input{C}
\end{table}
\end{document}​

C.tex is

\documentclass{standalone}
\begin{document}
\begin{tabular}{ l l r r } 
    A & B & C & D
\end{tabular} 
\end{document}​

A and C compile fine, but when compiling B.tex I get errors starting with :

! LaTeX Error: Not in outer par mode.

and complaining from there.

Is what I'm trying to do -- where A.tex includes B.tex includes C.tex -- possible? Possible with floats?

share|improve this question
    
Welcome to TeX.SE. It appears that once you fix your typos (\usepackage needs to be before begin{document}) and include the required packages in the main file, and replace using the article class this compiles, but fails with standalone. –  Peter Grill Oct 7 '11 at 4:27
add comment

2 Answers 2

up vote 14 down vote accepted

Yes, you can nest standalone files, however, as with any other document which \inputs standalone files you need to load the standalone package also in this case.

Another issue is that you can't use floats like table and figure environments in normal standalone files, because of the used preview mode used. You need either switch it off using the class option preview=false or redefine the table environment to not be a float.

% B.tex
\documentclass{standalone}
\usepackage{standalone}
\renewenvironment{table}{}{}% Ignore `table` environment in standalone mode.
\begin{document}
\begin{table}
  \input{C}
\end{table}
\end{document}​

If you have a \caption you should use:

\makeatletter
\renewenvironment{table}{\def\@captype{table}}{}
\makeatother

instead, otherwise you get an error.

Update 2011/12/21

I now release standalone v1.0 which redefines floats by defaults to work inside standalone files. See the float option in the manual for more details. See also Is it possible to use the figure environment with the standalone package?

share|improve this answer
    
This comment will be deleted shortly. I sent a bug report to your e-mail. preview environment of standalone class takes the following white spaces that makes the output no longer tight. –  Please don't touch Aug 4 '12 at 17:35
add comment

Although this doesn't use the standalone package, I hope it will interest you.

I frequently use my own hack to have standalone documents that I can compile separately. I devised it before I came to know standalone, and the only drawback that I haven't solved yet is that it doesn't behave very well in presence of subfolders.

The file a.tex

Use \input{include.sty} (defined below) at the very top of the document, and directly \begin{xdocument} (note the x) and \end{xdocument} without any preamble.

\input{include.sty}
\masterdocumenttrue
\begin{xdocument}
\input{b}
\end{xdocument}

\masterdocumenttrue lets you know when the file passed to LaTeX on the command-line is the "master" document, and not a subdocument, so you can include conditionnaly stuff like the table of contents and bibliography by enclosing them in \ifmasterdocument …\fi.

The file b.tex

Same thing, but no \masterdocumenttrue here.

\input{include.sty}
\begin{xdocument}
\begin{table}
  \input{c}
\end{table}
\end{xdocument}​

The file c.tex

\input{include.sty}
\begin{xdocument}
\begin{tabular}{ l l r r } 
    A & B & C & D
\end{tabular} 
\end{xdocument}​

The file preamble.sty

This file contains the pramble to use for all files.

\documentclass{article}
%\usepackage{foo}
%\def\mycommand{bar}

Step-by-step through include.sty

This file includes the preamble only for the "main" document (the one passed on the command-line to LaTeX), inserts \begin{document} when the first \begin{xdocument} is run, and inserts \end{document} when the fisrt xdocument is closed (thus the last \end{xdocument}) if your xdocuments are properly nested, and they should be.

Since we didn't use LaTeX's \usepackage, we need to change @'s catcode ourselves:

\makeatletter

If the macro \nesteddocumentlevel is undefined, then it's the first time include.sty has been included, so it does its job, but not the rest of the time:

\ifx\nesteddocumentlevel\undefined
\def\nesteddocumentlevel{0}

We avoid using an extra counter (there are only 255 of them) by providing a command to increment any macro, by putting it in a temporary counter just to increment it, and back into the macro afterwards:

\def\addtomacrocounter#1#2{%
  \bgroup%
  \@tempcnta=#1%
  \advance\@tempcnta #2%
  \expandafter\xdef\noexpand#1{\the\@tempcnta}%
  \egroup%
}

Build an easy-to-use macro \ifdocumentlevel{level}{if-equal}{if-different} to check the current inclusion depth:

\def\ifdocumentlevel#1#2#3{
  \edef\testnesteddocumentlevel{#1}
  \ifx\nesteddocumentlevel\testnesteddocumentlevel#2\else#3\fi%
}

Build the xdocument environment:

\newenvironment{xdocument}{

It increments the inclusion depth pseudo-counter:

  \addtomacrocounter{\nesteddocumentlevel}{1}

If we're in the top-level document, insert a \begin{document}

  \ifdocumentlevel{1}{
    \document% = \begin{document}

If we have a file named main-header.tex, it will be included at the beginning of the document passed on the command-line to LaTeX, that is before b.tex's content when you compile b.tex:

    \IfFileExists{main-header.tex}{\input{main-header.tex}}{}
  }{}

If we have a file named every-header.tex, it will be included at the beginning of every (sub-)document, that is before b.tex and c.tex's contents when you compile b.tex:

    \IfFileExists{every-header.tex}{\input{every-header.tex}}{}
}{

When running the \end{xdocument}, we define a \maybeenddocument macro, that will be \expandaftered, and may output \end{document}, and include various footers.

If we have a file named every-footer.tex, it will be included at the end of every (sub-)document, that is after b.tex and c.tex's contents when you compile b.tex:

  \IfFileExists{every-footer.tex}{\input{every-footer.tex}}{}
  \ifdocumentlevel{1}{

    If we have a file named `main-footer.tex`, it will be included at the end of the document passed on the command-line to LaTeX, that is after `b.tex`'s content when you compile `b.tex`

    \IfFileExists{main-footer.tex}{\input{main-footer.tex}}{}

When we're in the top-level document, we're going to output a \end{document}:

    \def\maybeenddocument{\enddocument}
  }{

But not the rest of the time:

    \def\maybeenddocument{}
  }

Pop one level of inclusion:

  \addtomacrocounter{\nesteddocumentlevel}{-1}

And place the possible \end{document} after the very last bit of code of \end{xdocument}. If we place it earlier, it will complain about unmatched {s, beacuse their matching } will be after the \end{document}, that is, in limbo.

  \expandafter\maybeenddocument%
}

When include.sty is included for the first time, we include the preamble. preamble.sty should contain everything between your \documentclass{…} and \begin{document}, without the \begin{document} itself.

\input{preamble.sty}

And create the masterdocument conditionnal. We need to escape its name with \csname and \endcsname, otherwise TeX thinks its a real \if…, matches it with the \fi, which belonged to the \ifx\nesteddocumentlevel\undefined at the top of this file, which in turn will have no matching \fi

\expandafter\newif\csname ifmasterdocument\endcsname\masterdocumentfalse

End of the code run when include.sty is included for the first time:

\fi

And restore the behaviour of @:

\makeatother

Complete code for include.sty

\makeatletter
\ifx\nesteddocumentlevel\undefined
\def\nesteddocumentlevel{0}
\def\addtomacrocounter#1#2{%
  \bgroup\@tempcnta=#1%
  \advance\@tempcnta #2%
  \expandafter\xdef\noexpand#1{\the\@tempcnta}%
  \egroup}
\def\ifdocumentlevel#1#2#3{
  \edef\testnesteddocumentlevel{#1}
  \ifx\nesteddocumentlevel\testnesteddocumentlevel#2\else#3\fi%
}
\newenvironment{xdocument}{
  \addtomacrocounter{\nesteddocumentlevel}{1}
  \ifdocumentlevel{1}{
    \document% = \begin{document}
    \IfFileExists{main-header.tex}{\input{main-header.tex}}{}
  }{}
    \IfFileExists{every-header.tex}{\input{every-header.tex}}{}
}{
  \IfFileExists{every-footer.tex}{\input{every-footer.tex}}{}
  \ifdocumentlevel{1}{
    \IfFileExists{main-footer.tex}{\input{main-footer.tex}}{}
    \def\maybeenddocument{\enddocument}
  }{
    \def\maybeenddocument{}
  }
  \addtomacrocounter{\nesteddocumentlevel}{-1}
  \expandafter\maybeenddocument%
}
\input{preamble.sty}
\expandafter\newif\csname ifmasterdocument\endcsname\masterdocumentfalse
\fi
\makeatother
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.