[Tex/LaTex] Problems with column alignment in the `lstlisting` environment

listings

I'm having some problems with the column alignment in the lstlisting environment provided by listings.sty.

In fixed-width column alignment mode, whatever the typeface being used, listings are supposed to be presented with one character per column, where the columns have uniform widths (which may be set by the author). However, I find this not actually to be the case with certain input.

Minimal example:

\documentclass{article}
\usepackage{listings}
\begin{document}

\begin{lstlisting}[columns=fixed]
columnar alignment maligned multiple narrow characters?
1234 6789 1234 6789 1234 6789 1234 6789 1234 6789 1234
\end{lstlisting}

\end{document}

Result:

result of lstlisting environment with improper column alignment

Note that the second line is exactly one character shorter than the first, which is observed at the far right-hand side. However, the alignment in the middle is somewhat ruined at the occurance of every l character (ambiguous alignment of u in columnar with 3 or 4; ambiguous alignment of i, g, and n in alignment with 1, 2, 3, and 4; etc.). This problem is not helped by tweaking the alignment, by e.g. replacing fixed with {[l]fixed} for the column alignment.

Is this a known problem? Is there any fix for it?

Best Answer

This is the expected/default output for columns=fixed in an lstlisting environment. From the listings package documentation:

Now, the fixed format puts n characters into a box of width n x base width, where the base width is 0.6em in the example. The format shrinks and stretches the space between the characters to make them fit the box.

That is, the alignment is not meant to consistent across lines within the listing. Rather, the chunks of code is placed in boxes and the spacing is modified with no regard for anything else except the box width. Even the example presented in the documentation (page 19) exhibits this behaviour:

Listings package documentation example

Notice the misaligned i in write (line 1) and print (line 2) due to the wider w.

Even if you modified your minimal example to the following:

\documentclass{article}
\usepackage{listings}
\begin{document}

\begin{lstlisting}[columns=fixed]
colu mnar alig nmen tmal igne dmul tipl enar rowc hara cters?
1234 6789 1234 6789 1234 6789 1234 6789 1234 6789 1234
\end{lstlisting}

\end{document}

attempting to align the listing column-wise, the output looks better, but still has the same issues you mention:

Modified listings example

Notice the misalignment between mnar and 6789 (due to m); tmal and 1234 (again due to m); rowc and 6789 (due to w), etc.

The only way around this is to use a mono-spaced font for your entire listing, using (say) basicstyle=\ttfamily:

Basicstyle=ttfamily in listings