# lstlistings: framed code [closed]

I use lstlistings to write Pascal Code. I'd like my code to be numbered and framed. Here is what I have as of now :

\lstset{numbers=left, numberstyle=\small, numbersep=8pt, frame = single, language=Pascal, framexleftmargin=15pt}

\begin{lstlisting}
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{lstlisting}


My problem is that the frame is the width of the page, so I get a big frame with lot of useless empty space on the right. I'd like the frame to be the width of the code I actually wrote.

Any hints?

Edit: I don't want to have to manually set the linewidth. I'd like the width to be calculated based on the longest line of code in the listing.

Edit: To rephrase the question - "is there a way that the current version of the listings package can be applied, possibly in combination with other packages and/or auxiliary macros, to eliminate the need for manual adjustment of the line width?"

-

## closed as off-topic by Jubobs, Peter Jansson, Martin Schröder, Svend Tveskæg, cmhughesMar 1 at 20:19

• This question does not fall within the scope of TeX, LaTeX or related typesetting systems as defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

This question appears to be off-topic because it is about a feature request for listings. –  Jubobs Mar 1 at 18:52
The question is on-topic: it is not requesting a new listings feature, but simply a way to achieve a typesetting goal: i.e., a tightly-wrapped box around a listing. @Daniel's answer below, for example, gives one possible solution to this question that doesn't involve changing the listings package. –  davidg Jul 3 at 12:28
@davidg non-of the solutions below (with auto-adjustment of width) work for verbatim that extends over one page. The text is chopped off if it is longer than one page. –  Nasser Aug 27 at 20:03
As you can see below, the ground of missing for the accusation that the question is a request for a new feature for listings. Oh, well... –  Yossi Gil Sep 12 at 9:18

Another option is to use the linewidth option for lstlisting to control the width:

\documentclass{article}
\usepackage{listings}

\lstset{
numbers=left,
numberstyle=\small,
numbersep=8pt,
frame = single,
language=Pascal,
framexleftmargin=15pt}

\begin{document}

\begin{lstlisting}
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{lstlisting}

\begin{lstlisting}[linewidth=5.4cm]
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{lstlisting}

\end{document}​


-
Thank you both for your solution. However, I'd like the horizontal space to be computed automatically. I have lots of codes to be framed and dont want to have to adjust manually the size of my minipage or my linewidth. –  guigui Sep 4 '12 at 20:35
@guigui That would require two passes, so what you're asking for is essentially a feature request for listings. –  Jubobs Mar 1 at 18:52

tcolorbox package provides environments for framed and colored boxes. One of its libraries is designed to interact with listings package and one of its capture modes hbox automatically adjust frames to their contents. Combining both elements it's easy to create framed listings with adjusted width.

And, of course, you can decorate your listings with all other enhancements provided by tcolorbox.

Update: Although OP doesn't mention it, it's not possible to automatically break long listings between pages when using hbox.

\documentclass{article}
\usepackage{tcolorbox}
\tcbuselibrary{listings,skins}

\lstdefinestyle{mystyle}{
numbers=left,
numberstyle=\small,
numbersep=8pt,
language=Pascal
}

\newtcblisting{mylisting}[2][]{
arc=0pt, outer arc=0pt,
listing only,
listing style=mystyle,
title=#2,
#1
}

\begin{document}

\begin{mylisting}{}
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{mylisting}

\begin{mylisting}[hbox]{}
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{mylisting}

PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{mylisting}

\end{document}​


-
fyi, this solution does not work, as it chops off any verbatim if it is over one page long. –  Nasser Aug 27 at 20:01

The frame= key of the listings package always typesets the frame with respect to the current line width. Hence, I suggest to use another command or environment to draw the frame.

A basic solution (without further packages) would be to render the listing inside an \fbox, which, however, as a macro does not accept verbatim material as argument. So the listing has to by typesetted in an lrbox first.

Alternatively, some framing environment may be used (in the example below I use adjustbox, but you literally have dozens of possibilities here), which would not require the detour over an lrbox.

Finally (not presented below) you my define your own PASCAL environment with \lstnewenvironment{PASCAL}{<begin code>}{<end code>} (see listings documentation) that combines either method with the listings environment to gain maximum comfort.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{listings}

\usepackage{adjustbox} % For Option 2 only

\begin{document}
\lstset{numbers=left, numberstyle=\small, numbersep=8pt, language=Pascal}

% Option 1: Typeset in an LR-box and use \fbox{} to draw the frame
\newsavebox{\Lst}

\begin{lrbox}{\Lst}
\begin{lstlisting}
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{lstlisting}
\end{lrbox}

% draw frame an Listing. The \hskip enlarges the box to have numbers within the frame
\noindent\fbox{\hskip15pt\usebox{\Lst}}

% Option 2: Use some framing environment. There are lots of possibilities!
% I have just use adjustbox, which is a kind of swiss army knife for boxing
\begin{lstlisting}
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{lstlisting}

\end{document}


-
@Chris: Does this solve your problem? –  Daniel Oct 23 '12 at 15:11
fyi, this solution does not work, as it chops off any verbatim if it is over one page long. –  Nasser Aug 27 at 20:01

You should place the entire lstlisting inside an environment that restricts the horizontal width, like a minipage:

\documentclass{article}
\usepackage{listings}% http://ctan.org/pkg/listings
\begin{document}
\lstset{numbers=left, numberstyle=\small, numbersep=8pt, frame = single, language=Pascal, framexleftmargin=15pt}

\begin{lstlisting}
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{lstlisting}

\noindent\begin{minipage}{.5\linewidth}
\begin{lstlisting}
PROGRAM afficher_bonjour;
BEGIN WRITE('Bonjour');
END.
\end{lstlisting}
\end{minipage}
\end{document}​

-
Thank you both for your solution. However, I'd like the horizontal space to be computed automatically. I have lots of codes to be framed and dont want to have to adjust manually the size of my minipage or my linewidth. –  guigui Sep 4 '12 at 20:35