Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question

closed as off-topic by Jubobs, Peter Jansson, Martin Schröder, Svend Tveskæg, cmhughes Mar 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.

    
Same problem exactly. Have you found a solution? Thanks in advance. Christophe –  user21240 Oct 22 '12 at 17:17
4  
This question appears to be off-topic because it is about a feature request for listings. –  Jubobs Mar 1 at 18:52
1  
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

4 Answers 4

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

enter image description here

share|improve this answer
    
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

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{adjustbox}{padding=15pt 0pt 0pt 0pt, fbox}
\begin{lstlisting}
PROGRAM afficher_bonjour; 
BEGIN WRITE('Bonjour'); 
END.
\end{lstlisting}
\end{adjustbox}

\end{document}

enter image description here

share|improve this answer
    
@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

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.

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

\begin{mylisting}[hbox,enhanced,drop shadow]{Pascal program}
PROGRAM afficher_bonjour; 
BEGIN WRITE('Bonjour'); 
END.
\end{mylisting}

\end{document}​

enter image description here

share|improve this answer
    
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:

enter image description here

\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}​
share|improve this answer
1  
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

Not the answer you're looking for? Browse other questions tagged or ask your own question.