[Tex/LaTex] framebox does not work for lstlisting environment

framedlistings

I am looking a way to wrap something with a frame. I try different approaches but finally choose to use fancybox package and minipage (because I need to control the width of the frame). It works pretty good for text-only content

\usepackage{fancybox}

\begin{document}
  \fbox{%
    \begin{minipage}{\textwidth}
      \textbf{Why we use negative angle in above calculate?}\newline
       Since .... we have to ....
    \end{minipage}
  }
\end{document}

However, if we add any environment like lstlisting or verbatim, it doesn't work

  \fbox{%
    \begin{minipage}{\textwidth}
      \textbf{Why we use negative angle in above calculate?}\newline
       Since .... we have to ....
       \begin{lstlisting}
          A = x+y;
          B = x^2-2y;
       \end{lstlisting}
    \end{minipage}
  }

Is that any way to make it work?

p.s. I have created a webpage for the user to type the latex stuff inside and whatever they type, I will like to wrap that with a framebox and generated a pdf with pdflatex. I cannot control what they type, they might type text, math, environment and/or mix all of those. So any better way to frame whatever the latex stuff inside?

Best Answer

This is because listings (including verbatim content) cannot be passed as arguments to other functions/macros (without care). Boxing the content first is okay though:

enter image description here

\documentclass{article}
\usepackage{listings}% http://ctan.org/pkg/listings
\newsavebox{\codebox}% For saving code
\begin{document}
\begin{lrbox}{\codebox}
\begin{lstlisting}
A = x+y;
B = x^2-2y;
\end{lstlisting}
\end{lrbox}

\noindent
\fbox{%
  \begin{minipage}{\dimexpr\linewidth-2\fboxsep-2\fboxrule}
    \textbf{Why we use negative angle in above calculate?}\newline
      Since .... we have to .... \par
    \usebox{\codebox}
  \end{minipage}%
}
\end{document}

lrbox is an environment that takes one mandatory (box) argument which it will use to store the content in. I've made on called \codebox. Do this outside your \fbox and then use \usebox{\codebox} inside \fbox's argument.

Note the use of \noindent, occational % (see What is the use of percent signs (%) at the end of lines?) and a \dimexpr for the minipage size to avoid overfull \hbox warnings.


If you don't have control over what the user inserts and they could mix/match content, then you might be better off boxing everything and just \fbox-ing the output:

enter image description here

\documentclass{article}
\usepackage{listings}% http://ctan.org/pkg/listings
\newsavebox{\userinput}% For saving user input
\begin{document}
\begin{lrbox}{\userinput}
\begin{minipage}{\dimexpr\linewidth-2\fboxsep-2\fboxrule}
  \textbf{Why we use negative angle in above calculate?}\newline
   Since .... we have to ....

\begin{lstlisting}
A = x+y;
B = x^2-2y;
\end{lstlisting}
\end{minipage}
\end{lrbox}

\noindent
\fbox{\usebox{\userinput}}%
\end{document}

Of course, mdframed has no problem with this kind of thing, and might be a better option; it also allows for frame breaking across the page boundary:

enter image description here

\documentclass{article}
\usepackage{listings,mdframed}% http://ctan.org/pkg/{listings,mdframed}
\begin{document}
\begin{mdframed}
  \textbf{Why we use negative angle in above calculate?}\newline
   Since .... we have to ....

\begin{lstlisting}
A = x+y;
B = x^2-2y;
\end{lstlisting}
\end{mdframed}

\end{document}

See the mdframed documentation for more details on making things fancy.