1

I am using a lstlisting environment in several spots in some stuff I'm writing up, with the language being set to either Python or Mathematica. In both cases, the equals signs merge together to look like one long equals sign (or, if they're not actually merged, they're close enough it's annoying). How can I fix this?

My thought was just to add \, after the first equal sign when there are double equals signs, but a. lstlisting purposefully turns off LaTeX commands and b. that's tedious and annoying.

MWE:

\documentclass{article}
\usepackage{listings}
\begin{document}
\begin{lstlisting}
something == something
\end{lstlisting}
\end{document}
16
  • Have a look at latex.org/forum/viewtopic.php?t=6975
    – moewe
    Commented Jun 25, 2018 at 20:33
  • You could use a fixed-width font with basicstyle=\ttfamily, that changes the font to typewriter/fixed-width. Or you could have a look at §2.10 Fixed and flexible columns of the listings documentation. In particular columns=flexible or columns=fullflexible may be of interest. To quote the manual: "In the abstract one can say: The fixed column format ruins the spacing intended by the font designer, while the flexible formats ruin the column alignment (possibly) intended by the programmer." If you are a Python person you may want to look at minted
    – moewe
    Commented Jun 25, 2018 at 20:43
  • @moewe the problem with changing column width and such around is one of the languages I'm writing code up for, Python, relies upon indentation to work properly. I'll take a look at basicstyle=\ttfamily.
    – auden
    Commented Jun 25, 2018 at 20:44
  • @moewe hmm, the thing with basicstyle=\ttfamily is it removes the language specific formatting - is there any way to remedy this? Other than that it seems to work well.
    – auden
    Commented Jun 25, 2018 at 20:46
  • As far as I can see columns=flexible and columns=fullflexible do preserved some amount of indentation, but I'm not sure if that is what you need. It seems to me you are between a rock and a hard place: columns=flexible gives bad results with fonts that have no fixed character widths, the simple solution would be to use basictstyle=\ttfamily in that case (all characters have the same width, everything is tickety boo). If you don't want \ttfamily you need to switch to a different columns format to avoid the letters running into each other.
    – moewe
    Commented Jun 25, 2018 at 20:48

2 Answers 2

2

Have a look at §2.10 Fixed and flexible columns of the listings documentation.

In the MWE you are using columns=fixed with a variable-width font. That means that the different glyphs/characters of the font have a different width. If you were to write a line of ls and a line of Ms, the 'l's and 'M's would not line up. So to maintain the proper indentation and alignment of the code listings has to do some tricks.

[T]he fixed format puts n characters into a box of width n × ‘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. [...]

If you don’t need or like this, you should use a flexible format. All characters are typeset at their natural width. In particular, they never overlap. If a word requires more space than reserved, the rest of the line simply moves to the right. The difference between the three formats is that the full flexible format cares about nothing else, while the normal flexible and space-flexible formats try to fix the column alignment if a character string needs less space than ‘reserved’.

The documentation explains

In the abstract one can say: The fixed column format ruins the spacing intended by the font designer, while the flexible formats ruin the column alignment (possibly) intended by the programmer.

Since the equal signs are quite long it just so happens that the space between them is shrunken to such as degree that the two equal signs merge together.

So what can you do to solve this problem?

  1. Use a fixed-width typewriter font. In those fonts all characters have the same width making it unnecessary to stretch and shrink spaces a lot. Everything aligns naturally.

    basicstyle=\ttfamily
    

    If you want to keep bold and italic/slanted markup you will have to find typewriter font that supports bold and slanted. The default Computer Modern \ttfamily has no bold version (Using \ttfamily with \bfseries (or how to enable bold in fixed-width font)). Latin Modern (\usepackage{lmodern}) has a bold font, which is quite similar to the regular variant, so you may want to try lighttt (in which case you need to be aware of italic font in lmodern-lighttt).

    <code>basicstyle=\ttfamily,</code>

  2. You can increase the basewidth parameter. That makes the box into which the glyphs need to fit wider allowing for a bit of space around the equal signs. Of course all other words will suffer from increased letter spacing.

    <code>basicstyle=\normalfont, basewidth=0.7em</code>

    The default value for fixed mode is 0.6em, for flexible mode 0.45em. In the example here it has been increased to 0.7em. The space is still quite faint, so one might be tempted to increase the width further, but of course that drags the other letters even further apart from each other.

  3. Use columns=flexible

    <code>basicstyle=\normalfont, columns=flexible</code>

    or columns=fullflexible

    <code>basicstyle=\normalfont, columns=fullflexible</code>

    While it may not be easy to count the exact number of spaces with here, the fact that the second line is indented is still very clearly visible. Indentation levels don't get lost with these settings only the exact number of spaces can be hard to figure out.

\documentclass{article}
\usepackage[lighttt]{lmodern}
\usepackage{listings}
\lstset{%
  basicstyle=\ttfamily,
  language=python,
}
\begin{document}
\begin{lstlisting}
if something == something:
    somethingelse(something)
\end{lstlisting}

\begin{lstlisting}[basicstyle=\normalfont, basewidth=0.7em]
if something == something:
    somethingelse(something)
\end{lstlisting}

\begin{lstlisting}[basicstyle=\normalfont, columns=flexible]
if something == something:
    somethingelse(something)
\end{lstlisting}

\begin{lstlisting}[basicstyle=\normalfont, columns=fullflexible]
if something == something:
    somethingelse(something)
\end{lstlisting}
\end{document}
0
1

If you want to use the standard font for the listings, I suggest to set flexible or full flexible columns; if you prefer fixed columns (at the cost of obnoxious interletter spaces), increase the width (this depends on the document font).

\documentclass{article}
\usepackage{listings}

\lstset{
  basewidth={0.7em,0.5em},
}

\begin{document}

\begin{lstlisting}[language=C]
something == something
\end{lstlisting}

\begin{lstlisting}[language=C,columns=flexible]
something == something
\end{lstlisting}

\begin{lstlisting}[language=C,columns=fullflexible]
something == something
\end{lstlisting}

\end{document}

enter image description here

You must log in to answer this question.

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