# tcolorbox listing error using beamers begin{frame}

I've just started using the tcolorbox package for slides for a LaTeX course. It works nicely to box LaTeX code, interacting with the listings package. However, I ran into trouble when I tried to make a box of example code for a beamer frame, it fails.

\documentclass{beamer}
\usepackage[listings]{tcolorbox}

\begin{document}
\begin{frame}[fragile]{Example}

\begin{tcblisting}{listing only}
\begin{frame}{equation}
$a = b$
\end{frame}
\end{tcblisting}

\end{frame}
\end{document}


I get errors "undefined control sequence \end{tcblisting}" and other errors

Commenting the \end{frame} before the \end{tcblisting} outputs ok. Also, running the code inside an article documentclass instead of a beamer class is also ok.

Can anyone point out what I'm doing wrong here?

thanks

It's not you, it's beamer... :)

The frame environment is really finicky since it has to read the entire content before actually setting the frame. Why? Because when you use overlay specifications (like \pause, or \only, or \onslide, or ...) then the frame has to be broken up into different slides, each of which may require the exact same layout. So, in this instance the \end{frame} inside tcblisting is actually mistaken for the \end{frame} at the end of the document.

My suggestion, in cases like these, is to set the verbatim-like content in a box first, and then use that box wherever needed. Once the box is set, it's portable and should not affect "finicky things" (like frame):

\documentclass{beamer}% http://ctan.org/pkg/beamer
\usepackage[listings]{tcolorbox}% http://ctan.org/pkg/tcolorbox
\newsavebox{\codebox}% To store any verbatim content

\begin{document}
% Capture the verbatim content in \codebox
\begin{lrbox}{\codebox}
\begin{tcblisting}{listing only}
\begin{frame}{equation}
$a = b$
\end{frame}
\end{tcblisting}
\end{lrbox}

\begin{frame}{Example}

\usebox{\codebox}% Insert \codebox

\end{frame}
\end{document}

• good idea to save it in a box. Perhaps I should have thought of that. Thanks. – Glenn Fulford Nov 21 '13 at 10:08

Here comes another alternative.

The tcblisting environment saves the content into a file which is read afterwards as a listings or as a compiled text or both. This process can be decoupled:

• The environment tcboutputlisting saves the content into the intermediate file.

• \tcbinputlisting reads the intermediate file.

This gives:

\documentclass{beamer}
\usepackage[listings]{tcolorbox}

\begin{document}

\begin{tcboutputlisting}
\begin{frame}{equation}
$a = b$
\end{frame}
\end{tcboutputlisting}

\begin{frame}[fragile]{Example}
\tcbinputlisting{listing only}
\end{frame}

\end{document}


Just for fun, I add some madness. Since the content of the listing is a code for a beamer frame, we may like to add the compiled frame inside the outer frame ...

This can be done using the compile options of tcolorbox which do system calls. The intermediate file has to be unique for this. In the decoupled situation here, the option compilable listing cannot be used and one has to take care of the file name directly. That's the reason for

\tcbset{listing file=\jobname-listing-myslide}


in the following code:

\documentclass{beamer}
\usepackage[listings,raster,skins]{tcolorbox}

\begin{document}

\tcbset{listing file=\jobname-listing-myslide}% <-- Use a unique name

\begin{tcboutputlisting}
\documentclass{beamer}
\begin{document}
\begin{frame}{equation}
$a = b$
\end{frame}
\end{document}
\end{tcboutputlisting}

\begin{frame}[fragile]{Example}
\tcbinputlisting{
listing and comment,pdf comment,run pdflatex,% <-- These options do the trick
% the rest is just to be colorful and nice:
enhanced,oversize,
lower separated=false,
colframe=red!50!black,colback=yellow!10!white,
interior style={top color=yellow!5!white,bottom color=yellow!20!white},
listing options={style=tcblatex,texcsstyle=*\color{red!70!black}},
sidebyside,sidebyside gap=1mm,raster columns=1
}
\end{frame}

\tcbset{listing file=\jobname.listing}% <-- reset to default

\end{document}


The output is:

An alternative is to wrap the underlining frame into a newenvironment called slide.

Code:

\documentclass{beamer}
\usepackage[listings]{tcolorbox}
% define a new environment called slide with two parameters.
\newenvironment{slide}[2]{%
\begin{frame}[fragile,environment=slide]{Example}
\begin{tcblisting}{listing only}
\begin{frame}{#1}
#2
\end{frame}
\end{tcblisting}
}
{\end{frame}}

\begin{document}

\begin{slide}{equation}
{$a = b$}
\end{slide}

\end{document}