3

I am setting up a template for a presentation on some sort of code. Thus I would like to have an environment that holds a frame (done with \usepackage{environ}) within which I have a lstlisting environment.

The minimal working example, not defined as a new environment would be the following:

\documentclass{beamer}

\usepackage{listings}

\begin{document}

\begin{frame}[fragile]
\begin{center}
\begin{minipage}{0.9\linewidth}
\begin{lstlisting}
for i=1:2:10
    do something
end
\end{lstlisting}
\end{minipage}
\end{center}
\end{frame}
\end{document}

Now what I would like to achieve is something like this:

\NewEnviron{TFListing}[1][]{
  \begin{frame}[fragile]{#1}
     \begin{center}
        \begin{minipage}{0.9\linewidth}
            \begin{lstlisting}
               \BODY
            \end{lstlisting}
         \end{minipage}
      \end{center}
   \end{frame}
}

Which I could then use as:

\begin{TFListing}[Title]
    for i=1:2:10
       do something
    end
\end{TFListing}

However, the main problem is that latex does not allow reading the \BODY argument signalizing the content of the newly defined environment, since it is escaped by the \begin{lstlisting}. The benefit of such an environment would be that about eight lines of code per frame could be spared.

Thanks for all of your help in advance.

  • This is hard, but, isn't this already a build in feature of the tcolorbox package, amongst all the other things that package can do? – daleif Feb 4 '18 at 21:27
  • With \NewEnviron you lose line breaks, for instance; but the most important aspect is that the contents is absorbed as the argument to a command, so listings can no longer do its job. – egreg Feb 4 '18 at 21:28
4

There are a few problems with your approach:

  1. With \NewEnviron, line breaks are lost.
  2. The contents of such an environment is absorbed as the argument to a command and lstlisting can never appear in the argument to a command.
  3. Hiding frame is bad programming anyway.

Here's a different implementation.

\documentclass{beamer}
\usetheme{Warsaw}

\usepackage{listings}

\lstnewenvironment{tflisting}[1][]
 {%
  \lstset{
    linewidth=0.9\textwidth,
    xleftmargin=0.05\textwidth,
    #1
  }%
 }{}

\begin{document}

\begin{frame}[fragile]

\begin{tflisting}
for i=1:2:10
    do something
end
\end{tflisting}

\end{frame}

\end{document}

enter image description here

You can also use

\begin{tflisting}[<listings options>]
  • How do you mean "Hiding the frame"? Do you mean hiding it in a \NewEnviron command? – GianAndrea Müller Feb 14 '18 at 19:34
  • @GianAndreaMüller Masking frame inside another environment: I don't think you need it. – egreg Feb 14 '18 at 20:01
  • I see your point. I guess it's a question of taste :) Thanks a lot for your help! I could use your fix really well! – GianAndrea Müller Feb 14 '18 at 20:34
  • @GianAndreaMüller I don't see why obfuscating the code just for saving a few keystrokes. – egreg Feb 14 '18 at 20:48
3

As far as I understand it, this is not easily possible. But at least it can partly be achieved with:

\documentclass{beamer}

\usepackage{listings}

\lstnewenvironment{TFListing}[1][]{
 \lstset{caption={#1}}%
 \centering\minipage{.9\textwidth}%
}{
 \endminipage%
}

\begin{document}

\begin{frame}[fragile]
\begin{TFListing}[Title]
for i=1:2:10
    do something
end
\end{TFListing}
\end{frame}

\end{document}

The center environment adds some spacing, but the \centering macro does not. So, maybe you have to add some vertical spacing manually.

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.