[Tex/LaTex] tcolorbox listing error using beamers begin{frame}

beamerlistingstcolorbox

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

Best Answer

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):

enter image description here

\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}