6

I was trying to get a tikz automaton to fit on the page using the standalone documentclass to precompile the figure and then using \includegraphics[width=\textwidth{} (this is outlined at Tikz automaton placed too far to the right). I made the mistake though of nesting the tikzpicture inside a center environment, which inserted a blank page in front of the automaton. Consequently \includegraphics{} only included the blank first page. Why should the inclusion of a center environment cause an extra page in standalone?

Here is the original problematic mostly minimal MWE:

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows,automata,positioning}

\begin{document}

\begin{center}
\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=2.8cm,
                semithick]


\node[initial,state, accepting, align = center] (A)                    {*\textsc{NonHigh}\\Id-hi \\ Id-low \\ Id-hi\& low};

\path (A)   edge [loop right, align=center] node {a:i \\ {$ \langle 0, 1, 1, 1 \rangle $} } (A)
        edge [loop above, align=center] node {a:e \\ {$ \langle 1, 0, 1, 0 \rangle $}} (A)
    edge [loop below, align=center] node {a:a \\ {$\langle 2, 0, 0, 0\rangle$}} (A);            
    \foreach \looseness/\label [count=\n] in {8/e:e \\ {$ \langle 1, 0, 0, 0 \rangle $}, 12/i:e \\ {$ \langle 1, 1, 0, 0 \rangle $}}
        \path [->] (A) edge [
            loop above, align = center,
            every loop/.append style={
                looseness=\looseness,
                in=60-0.8*\looseness,
                out=120+0.8*\looseness
            }] node {\label} ();


        \foreach \looseness/\label [count=\n] in {10/e:i \\ {$\langle 0, 1, 0, 0\rangle$}, 15/i:i \\{ $\langle 0, 0, 0, 0 \rangle$} }
        \path [->] (A) edge [
            loop right, align = center,
            every loop/.append style={
                    looseness=\looseness,
                    in=330-0.8*\looseness,
                    out=30+0.8*\looseness
            }] node {\label} ();


        \foreach \looseness/\label [count=\n] in {8/e:a \\ {$ \langle 2, 0, 1, 0 \rangle $}, 12/i:a \\ {$\langle 2, 1, 1, 1\rangle$} }
        \path [->] (A) edge [
                loop below, align = center,
                every loop/.append style={
                    looseness=\looseness,
                    in=240-0.8*\looseness,
                    out=300+0.8*\looseness
        }] node {\label} ();

\end{tikzpicture}
\end{center}

\end{document}
  • I can understand how from the perspective of an expert, it would be obvious that a package author can ignore or fail to ignore an environment. :) From a primarily end-user perspective, center just means "put this in the center", so the addition of extra pages is mysterious/frustrating and warrants some explanation. Ideally a quick discussion of redundancy and clipping would help here. The question stands a good chance of being useful in-so-far as it documents something odd and its solution. Further clarification of the issues in the answer section can't hurt anyone. – sautedman Jun 29 '15 at 21:14
  • 1
    @cfr edited to avoid further confusion. – sautedman Jun 29 '15 at 21:28
1

The explanations of why the center environment makes no sense here are good, but they do not explain why you get a blank page rather than, say, the environment being silently or noisily ignored or an error.

Here's a way to get some sense of why you get a blank page rather than the center environment just being ignored.

etoolbox defines some commands which are useful for investigating the meanings of macros. The crucial background bit of information is that environments are really just matching pairs of commands. So for any \begin{envname}... \end{envname}, there is a \envname... \endenvname which is how LaTeX implements the environment under the hood. Hence, we want to look for the meaning of \center.

\documentclass[tikz]{standalone}
\usepackage{etoolbox}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\begin{document}

\verb|\begin{center}| is defined in terms of a command \verb|\center|\dots

What does \verb|\center| mean?

\csmeaning{center}

% Second run using information obtained on first run
OK.
What does \verb|\trivlist| mean?

\csmeaning{trivlist}

And \verb|\centering|?

\csmeaning{centering}

\dots
\end{document}

meaning of <code>center</code> environment

As you can see, starting a center environment does a bunch of stuff. You can trace the results further by feeding additional macros to \csmeaning{} if you wish.

So basically, a bunch of stuff gets put on the first page of the document when you start the center environment. Admittedly, it is basically just space but space is stuff just like letters and numbers and pictures and things.

Now tikzpicture is a default environment recognised by standalone. You can set non-default environments using \standaloneenv{} and they will be treated the same way. Each time such a 'special' environment is started, standalone does a bunch of things. In particular, it makes sure that the contents are typeset on a separate page. Since there is already stuff on the page started by the center environment, standalone starts a new page for the tikzpicture.

At least, I think so. That's my current understanding. Maybe somebody can suggest corrections/improvements to this answer.

4

The center environment is redundant with the standalone class, since this one clips anything outside of the picture you're creating.

Therefore it's not needed, the picture will always be centred. Removing the environment when you're using this class will fix the issue.

  • I could be mistaken but, as I understand the question, the OP already knows this. The question is why standalone doesn't just ignore the spurious environment. I'm not sure this is answerable, mind. It seems to require knowledge of the package author's intentions and design rationale. – cfr Jun 29 '15 at 19:19
  • I had figured out that removing the center environment will fix the problem, but the redundancy issue is new to me (and still not very well understood). – sautedman Jun 29 '15 at 20:45
  • @sautedman standalone doesn't work like preview class. It actually parses the file. And without going into surgery center environment does nontrivial adjustments. Put a single . before the center environment and you'll see it on the first page. When it cannot find a proper bounding box, standalone falls back to defaults. – percusse Jun 29 '15 at 21:35
  • @sautedman The point is that when you have a page, A4 paper and so on, it makes sense to center because you have a blank space of arbitrary size where the picture must be placed and it's not centered. However, with the standalone class you don't have a blank space anymore, since the pdf will only show the picture itself, by itself (and so, standalone). If you had a printed page with something on it, you could see it was not centered, but if you cut it with scissors from the rest of the page, "center" would become a meaningless concept. – Alenanno Jun 29 '15 at 22:20
  • My take on "why does it create a blank page" is that such a use is not taken into account because, again, something that is by itself is already at the "center". – Alenanno Jun 29 '15 at 22:23
1

That the first page is caused by environment center is already explained. Thus the fix of the bounding box remains, which is too large because of the control points of the loops.

The bounding box is determined by the four nodes. Unhappily the node with start does not have a name. But since it's the first node, the actual left bounding box border is used.

The \foreach loops are already sorted in the order, that the outer node comes last. Thus a temporary name (tmp) is given to the node and the outside border is remembered in (bbnorth), (bbeast), and (bbsouth).

At the end the final coordinates (bbll) and (bbur) are constructed, which contain the left lower corner and the upper right corner of the final bounding box. Since nodes have an inner sep with default value 0.3333em, the bounding box is corrected accordingly.

Then \pgfresetboundingbox throws the current bounding box away and [use as bounding box] enables the bounding box recording, which is established by the lower left corner (bbll) and the upper right corner (bbur).

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows,automata,positioning}

\begin{document}
\begin{tikzpicture}[
  ->,
  >=stealth',
  shorten >=1pt,
  auto,
  node distance=2.8cm,
  semithick,
]
  \node[initial,state, accepting, align = center] (A)
    {*\textsc{NonHigh}\\Id-hi \\ Id-low \\ Id-hi\& low};
  \coordinate (bbwest) at (current bounding box.west);

  \path (A) edge [loop right, align=center]
    node {a:i \\ {$ \langle 0, 1, 1, 1 \rangle $} } (A)
    edge [loop above, align=center]
    node {a:e \\ {$ \langle 1, 0, 1, 0 \rangle $}} (A)
    edge [loop below, align=center]
    node {a:a \\ {$\langle 2, 0, 0, 0\rangle$}} (A);

  \foreach \looseness/\label [count=\n] in {%
    8/e:e \\ {$ \langle 1, 0, 0, 0 \rangle $},
    12/i:e \\ {$ \langle 1, 1, 0, 0 \rangle $}}
  \path [->] (A)
    edge [
      loop above,
      align = center,
      every loop/.append style={
        looseness=\looseness,
        in=60-0.8*\looseness,
        out=120+0.8*\looseness
      }
    ]
  node (tmp) {\label} ();
  \coordinate (bbnorth) at (tmp.north);

  \foreach \looseness/\label [count=\n] in {%
    10/e:i \\ {$\langle 0, 1, 0, 0\rangle$},
    15/i:i \\{ $\langle 0, 0, 0, 0 \rangle$}}
  \path [->] (A)
    edge [
      loop right,
      align = center,
      every loop/.append style={
        looseness=\looseness,
        in=330-0.8*\looseness,
        out=30+0.8*\looseness
    }]
    node (tmp) {\label} ();
  \coordinate (bbeast) at (tmp.east);

  \foreach \looseness/\label [count=\n] in {%
    8/e:a \\ {$ \langle 2, 0, 1, 0 \rangle $},
    12/i:a \\ {$\langle 2, 1, 1, 1\rangle$}}
  \path [->] (A)
    edge [
      loop below,
      align = center,
      every loop/.append style={
        looseness=\looseness,
        in=240-0.8*\looseness,
        out=300+0.8*\looseness
    }]
    node (tmp) {\label} ();
  \coordinate (bbsouth) at (tmp.south);

  \path
    (bbwest |- bbsouth) ++(.3333em, .3333em) coordinate (bbll)
    (bbeast |- bbnorth) ++(-.3333em, -.3333em) coordinate (bbur)
    \pgfextra{\pgfresetboundingbox}
    [use as bounding box]
    (bbll) (bbur)
  ;
\end{tikzpicture}
\end{document}

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.