0

When we have a blank line between text in the LaTeX source, we have a paragraph break.

The fact of the paragraph breaking itself seems to be respected with a lstlisting environment. Specifically, if there is a blank line between the end of the environment and the text, we get a new paragraph indent. Else, not.

\end{lstlisting}
There is no paragraph start indent here; all good!
\end{lstlisting}

There \emph{is} a paragraph start indent here; all good!

However, now I have set an actual gap with:

\setlength{\parskip}{1em}

This is not respected by the lstlisting environment, although it tentatively seems to be respected by other environments. Specifically, although a new paragraph can be started with a blank line, there is no additional space below the listing. A similar problem is present at the top of the environment, with no additional space regardless of whether there is a blank line or not.

Vertical space \emph{after} this paragraph is the same,
regardless of whether there is a blank line :(

\begin{lstlisting}
\end{lstlisting}

Vertical space \emph{before} this paragraph is the same,
regardless of whether there is a blank line :(

I really want the spacing to be configurable in this way. Sometimes a listing is its own separate thing, and should be set apart from the text, but sometimes it's just a quick line of code that semantically shouldn't break the flow of the paragraph, or even sentence.

One disambiguates these choices by line spacing, but the lstlisting environment appears not to respect this. How can I get what I want?


It should be noted that there are keys aboveskip and belowskip, which I think are the promising avenues for making this happen. They seem expected to take constants, but (inspired by this) also able to take macros. I tried something like:

aboveskip={\ifvmode 1em \else 0em \fi},
belowskip={\ifvmode 1em \else 0em \fi},

. . . but this did not have the desired effect; the zero case never happens. I don't know enough to try much else.

1 Answer 1

0

Behold: my terrible, brittle, cargo-cult, no-good, very-evil redefinition of lstlisting to improve vertical spacing. It kindof mostly respects different values of \parskip, at least in my testing (from 0 to 4em). It also adds a keyval break=false / break=true to control whether the environment breaks at page boundaries:

\usepackage{ifthen}

\makeatletter
\let\lstlisting\@undefined
\let\lstlisting@\@undefined
\define@key{lst}{break}{\def\lstbreak{#1}}
\lstnewenvironment{lstlisting}[1][]{
    \csname\@lst @SetFirstNumber\endcsname
    \def\lstbreak{true}
    \lstset{aboveskip={0pt},belowskip={0pt},#1}
    \ifthenelse{\equal{\lstbreak}{true}}{
        \ifhmode\\\vspace{-0.7\baselineskip}\else\addvspace{\parskip}\addvspace{0.3\baselineskip}\fi
    }{
        \ifhmode\endgraf\vspace{-\parskip}\else\fi
        \vspace{\baselineskip}
        \noindent
        \minipage{\linewidth}
    }
}{
    \ifthenelse{\equal{\lstbreak}{true}}{
        \vspace{-\parskip}\vspace{0.3\baselineskip}\noindent
    }{
        \vspace{0.4\baselineskip}\endminipage\vphantom{(p}
    }%
    \csname\@lst @SaveFirstNumber\endcsname%
}
\makeatother

My hope is that this is so ultra-cursed that someone who knows more than me can tell me how to do it right. For now, this is going straight to production.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .