How to use showexpl with an external class?

The code must be compiled externally. Loading the code of article.cls and all sorts of packages in the beamer run would lead to chaos. But theoretically if --shell-escape is active it is possible to trigger this external run on-the-fly during the compilation of the beamer run and then to include the resulting pdf with the graphic-option of showexpl. The main problem I see is that you probably don't want to include a complete page but only a part of it (e.g. to show the section). I think it would be difficult to write a good and flexible interface to choose this part.


This is not a 'fully worked up' solution for all cases, but I hope is enough of an answer to show how things can be done in a reasonably flexible way. The code in showexpl is pretty long, and so breaking into it to add the ability to use an external compilation is a bit tricky. Instead, I'm using some code I've adapted from the listings sources in my own packages, and adding an additional ability to that. As a result, you don't get all of the bells and whistles of showexpl out of the box, although you could add them:

\documentclass{beamer}
\usepackage{ifplatform}
\usepackage{listings}
\makeatletter
\lst@RequireAspects{writefile}
\newbox\LaTeXdemo@box
\newbox\LaTeXdemo@graphics
\lstnewenvironment{LaTeXdemo}[1][code-and-example]{%
  \global\let\lst@intname\@empty
  \ifcsname LaTeXdemo@#1@end\endcsname
    \expandafter\let\expandafter\LaTeXdemo@end
      \csname LaTeXdemo@#1@end\endcsname
    \csname LaTeXdemo@#1\expandafter\endcsname
  \else
    \ERROR
  \fi
}{%
  \LaTeXdemo@end
}
\newcommand*{\LaTeXdemo@common}{%
  \setkeys{lst}{%
    basewidth    = 0.51 em,
    basicstyle   = \small\ttfamily ,
    gobble       = 2,
    keywordstyle = \color{blue},
    language     = [LaTeX]{TeX},
    moretexcs    =
      {
        % Add list of additions here, e.g.
        email
      }
  }%
}
\newcommand*{\LaTeXdemo@input}{%
  \catcode`\^^M=10\relax
  \small
  \begingroup
    \leavevmode
    \input{\jobname.tmp}%
  \endgroup
}

\@namedef{LaTeXdemo@code-and-example}{%
  \setbox\LaTeXdemo@box=\hbox\bgroup
    \lst@BeginAlsoWriteFile{\jobname.tmp}%
    \LaTeXdemo@common
}
\@namedef{LaTeXdemo@code-and-example@end}{%
    \lst@EndWriteFile
  \egroup
  \begin{center}
    \ifdim\wd\LaTeXdemo@box>0.48\linewidth\relax
      \hbox to\linewidth{\box\LaTeXdemo@box\hss}%
        \begin{minipage}{\linewidth}
          \LaTeXdemo@input
        \end{minipage}
    \else
      \begin{minipage}{0.48\linewidth}
        \LaTeXdemo@input
      \end{minipage}
      \hfill
      \begin{minipage}{0.48\linewidth}
        \hbox to\linewidth{\box\LaTeXdemo@box\hss}%
      \end{minipage}
    \fi
  \end{center}
}

\expandafter\let\csname LaTeXdemo@code-and-external\expandafter\endcsname
  \csname LaTeXdemo@code-and-example\endcsname
\@namedef{LaTeXdemo@code-and-external@end}{%
    \lst@EndWriteFile
  \egroup
  \immediate\write18{pdflatex -jobname \jobname-demo 
    "\unexpanded\expandafter{\LaTeXdemo@documentclass@move}
     \noexpand\input \jobname.tmp"}%
  \begin{center}
    \ifdim\wd\LaTeXdemo@box>0.48\linewidth\relax
      \hbox to\linewidth{\box\LaTeXdemo@box\hss}%
        \begin{minipage}{\linewidth}
          \includegraphics{\jobname-demo}%
        \end{minipage}
    \else
      \begin{minipage}{0.48\linewidth}
        \includegraphics{\jobname-demo}%
      \end{minipage}
      \hfill
      \begin{minipage}{0.48\linewidth}
        \hbox to\linewidth{\box\LaTeXdemo@box\hss}%
      \end{minipage}
    \fi
  \end{center}
  \immediate\write18{\ifwindows del\else rm\fi \jobname-demo.pdf}%
}
\begingroup
  \catcode`\#=12 %
  \gdef\LaTeXdemo@documentclass@move{%
    \let\LaTeXdemodocumentclass\documentclass
    \renewcommand{\documentclass}[2][]{%
      \let\documentclass\LaTeXdemodocumentclass
      \begingroup
      \edef\x{%
        \endgroup
        \noexpand\documentclass[class=#2,varwidth,#1]{standalone}%
      }%
      \x
    }%
  }
\endgroup
\makeatother

\begin{document} 
\begin{frame}[fragile] 
\frametitle{An example in the beamer class} 
\begin{LaTeXdemo} 
  \section{foobar}
  \begin{itemize} 
    \item foo 
    \item bar
  \end{itemize} 
\end{LaTeXdemo} 
\end{frame}

\begin{frame}[fragile] 
\frametitle{An example in the article class} 
\begin{LaTeXdemo}[code-and-external]
  \documentclass{article}
  \begin{document}
  \section{foobar}
  \begin{itemize} 
    \item foo 
    \item bar
  \end{itemize} 
  \end{document}
\end{LaTeXdemo} 
\end{frame}
\end{document}

The idea in the above is to provide different ways of printing examples: I've included only 'code plus demo' and 'code plus externally-compiled demo', but 'code only' and 'code plus floating demo' are easy enough to do: I can add in if there is interest. (I guess also 'code plus floating externally-compiled demo', if really wanted!) As it stands, the code assumes the aim is a 'side by side' presentation but does no scaling if that won't fit, instead placing the output below the code. That can easily be adjusted, but perhaps would be best as a separate (linked) question.

The tricky part is getting a 'tight' page around the output using an external compilation (assuming that is what is required). The method I've used is to really use the standalone class, but to pass the 'required' class as an argument to that using a bit of trickery in the auxiliary compilation.

Note that some of this is a bit low-level (for example the box stuff) and some of that could be moved 'higher up'. Also note that at least restricted \write18 is required, and that I've not added mutli-pass, BibTeX or similar support, but that this could be done with a bit of effort (probably using a keyval approach for the optional argument).