4

I am currently writing a 200 pages book with many code extracts (around 100). I like to display them in a lstlisting environment (within a black frame). I have some very short code extracts (one line) and some longer ones (up to 50 lines). I often come across the case where the lstlisting frame has the top or bottom frame border alone on a page. I would like this border to be shown on the same page as the rest of the code.

enter image description here

I read many people advising to put the lstlisting environment into a float. But that wouldn't work for me as I have some long codes. I don't want these codes to be far away from my text, nor my text to have huge blank space at the end of a page as I force the float on the next page.

Isn't it a way to say to latex to take a bit of extra space from the page margin to avoid these border to be left alone?

Below a MWE (I am new to this forum so let me know if I missed anything)

\documentclass[14pt]{extreport}
\usepackage{lipsum} 
\usepackage{listings}
\lstset{ 
  basicstyle=\footnotesize,        
  breakatwhitespace=false,         
  breaklines=true,                 
  captionpos=b,                    
  frame=single,
  extendedchars=true,             
  language=Python,                 
  numbers=left,                   
  numbersep=5pt,                  
  showspaces=false,                
  showstringspaces=false,          
  showtabs=false,                  
  stepnumber=1,                   
  tabsize=2,                       
  title=\lstname,                   
  belowskip=-1em,
  aboveskip=1em,
  belowcaptionskip=0em,
  }
\begin{document}
\lipsum[2-4]
\begin{lstlisting}
dummy
dummy
dummy
dummy
\end{lstlisting}
\end{document}
  • Weclome to the site, Your MWE looks like a good MWE but unless I missed something it is not an example of the problem, which means it can't be used to test answers? – David Carlisle Jul 16 '18 at 19:45
  • ah, I see it's just a markdown error, I'lll fix:-) – David Carlisle Jul 16 '18 at 19:46
  • are you looking for fully automatic solutions or manual correction, for example \enlargethispage{5pt}\begin{lstlisting} fixes the posted example if manual insertion of \enlargethispage is acceptable. – David Carlisle Jul 16 '18 at 19:52
  • I have unfortunately a book of 200 pages. So if I can find something automated that would be perfect. Thank you for your corrections – Nicolas Jul 16 '18 at 20:32
  • well... automated is more tricky (and more likey to clash with some other loaded package) if it were me I'd leave it until each chapter finished and then manually adjust either with enlargethispage or by shrinking some other space on that page, or making a paragraph take one less line (\looseness=-1) or some other human judgement, but someone will post an automated version, then you'll have the options... - – David Carlisle Jul 16 '18 at 20:36
2

It is possible to avoid a widow rule:

\documentclass[14pt]{extreport}
\usepackage{lipsum} 
\usepackage{listings}
\lstset{ 
  basicstyle=\footnotesize,        
  breakatwhitespace=false,         
  breaklines=true,                 
  captionpos=b,                    
  frame=single,
  extendedchars=true,             
  language=Python,                 
  numbers=left,                   
  numbersep=5pt,                  
  showspaces=false,                
  showstringspaces=false,          
  showtabs=false,                  
  stepnumber=1,                   
  tabsize=2,                       
  title=\lstname,                   
  belowskip=-1em,
  aboveskip=1em,
  belowcaptionskip=0em,
  }
%\showoutput

\makeatletter
\gdef\lst@frameExit{%
    \lst@frameSpreadV\lst@framexbottommargin
    \lst@frameH B\lst@framebshape
    \ifvoid\z@\else
        \everypar{}\par\nobreak\lst@parshape\nointerlineskip\noindent\box\z@
    \fi}
\makeatother
\begin{document}
\lipsum[2-4]
%\enlargethispage{5pt}
\begin{lstlisting}
dummy
dummy
dummy
dummy
\end{lstlisting}
\end{document}

but like preventing widow lines in normal paragraphs, this doesn't always give the best result, here for example it simply takes the last line over to page 2 so there is a line and a rule on the second page.

A better result here would be achieved by a manual correction

\documentclass[14pt]{extreport}
\usepackage{lipsum} 
\usepackage{listings}
\lstset{ 
  basicstyle=\footnotesize,        
  breakatwhitespace=false,         
  breaklines=true,                 
  captionpos=b,                    
  frame=single,
  extendedchars=true,             
  language=Python,                 
  numbers=left,                   
  numbersep=5pt,                  
  showspaces=false,                
  showstringspaces=false,          
  showtabs=false,                  
  stepnumber=1,                   
  tabsize=2,                       
  title=\lstname,                   
  belowskip=-1em,
  aboveskip=1em,
  belowcaptionskip=0em,
  }
%\showoutput

\begin{document}
\lipsum[2-4]
\enlargethispage{5pt}
\begin{lstlisting}
dummy
dummy
dummy
dummy
\end{lstlisting}
\end{document}

in other cases the bad break could be avoided by shrinking vertical space on the page, or forcing a paragraph on the page to take one less like (by prefixing it with \looseness=-1 or even by re-wording a paragraph.

Given the time it takes to write a book, spending a few minutes hand tuning bad page breaks is often worth it....

  • Perfect and is there a way to shrink a page in the case of which i have only the top frame in one page? Something similar to \enlargethispage{5pt} – Nicolas Jul 17 '18 at 7:43

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.