[Tex/LaTex] Difference between fixed-width and proportional typewriter fonts in listings

fontslistingsverbatim

In the MWE below, I wonder why does the pcr (Courier) font align in both escaped and unescaped versions and for whatever column setting of {listing} – while the cmtt (Computer Modern Teletype) aligns escaped and unescaped only for fullflexible columns. The MWE is basically the same code repeated for different fonts (I would have stored it in a macro, but I'd get "Text dropped after begin of listing…" then):

\documentclass{article}

\usepackage{listings}
\usepackage{xcolor} % \pagecolor
\pagecolor{yellow!15}
\setlength{\fboxsep}{0pt}

\begin{document}


\renewcommand{\ttdefault}{pcr}

Here entering a sample paragraph with \texttt{some} words entered in
\texttt{typewriter font}, which should also be \texttt{monospaced} - or rather,
\texttt{fixed width}. It can be quite useful for showing \texttt{variables}.

\noindent\begin{minipage}[t]{.325\textwidth}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily,
caption={[short] Some instructions here; the font here is \texttt{\ttdefault}.},
escapechar=!,
showlines=true,
label=lst:ex1a,
columns=fixed,
frame=tlrb]
080484c4 <list>:
 !\fbox{\hspace{-\fboxrule}\texttt{80484c4:\fbox{ }cmd one}\linebreak}!
 80484c7: cmd two
 80484ca: cmd three, four
 80484cf: cmd five
 80484d6: cmd six, seven
 80484dd: cmd more than enough
 80484e0: cmd  not_even_joking
\end{lstlisting}
\end{minipage}
\hspace{1cm}
\noindent\begin{minipage}[t]{.325\textwidth}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily,
caption={[short] Some instructions here; the font here is \texttt{\ttdefault}.},
escapechar=!,
showlines=true,
label=lst:ex1b,
columns=fullflexible,
frame=tlrb]
080484c4 <list>:
 !\fbox{\hspace{-\fboxrule}\texttt{80484c4:\fbox{ }cmd one}\linebreak}!
 80484c7: cmd two
 80484ca: cmd three, four
 80484cf: cmd five
 80484d6: cmd six, seven
 80484dd: cmd more than enough
 80484e0: cmd  not_even_joking
\end{lstlisting}
\end{minipage}



\renewcommand{\ttdefault}{cmtt}

Here entering a sample paragraph with \texttt{some} words entered in
\texttt{typewriter font}, which should also be \texttt{monospaced} - or rather,
\texttt{fixed width}. It can be quite useful for showing \texttt{variables}.

\noindent\begin{minipage}[t]{.325\textwidth}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily,
caption={[short] Some instructions here; the font here is \texttt{\ttdefault}.},
escapechar=!,
showlines=true,
label=lst:ex2a,
columns=fixed,
frame=tlrb]
080484c4 <list>:
 !\fbox{\hspace{-\fboxrule}\texttt{80484c4:\fbox{ }cmd one}\linebreak}!
 80484c7: cmd two
 80484ca: cmd three, four
 80484cf: cmd five
 80484d6: cmd six, seven
 80484dd: cmd more than enough
 80484e0: cmd  not_even_joking
\end{lstlisting}
\end{minipage}
\hspace{1cm}
\noindent\begin{minipage}[t]{.325\textwidth}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily,
caption={[short] Some instructions here; the font here is \texttt{\ttdefault}.},
escapechar=!,
showlines=true,
label=lst:ex2b,
columns=fullflexible,
frame=tlrb]
080484c4 <list>:
 !\fbox{\hspace{-\fboxrule}\texttt{80484c4:\fbox{ }cmd one}\linebreak}!
 80484c7: cmd two
 80484ca: cmd three, four
 80484cf: cmd five
 80484d6: cmd six, seven
 80484dd: cmd more than enough
 80484e0: cmd  not_even_joking
\end{lstlisting}
\end{minipage}


\end{document}

… and the output is this:

test01a.png

Now this is the weird thing for me: for fixed columns, the escaped and unescaped listing text has completely different spacing between characters (compare the 80484c part in Listing 3) for the font cmtt, specifically; this doesn't happen for pcr.

So the conclusion I'm making from this, is that apparently pcr is a "real" fixed width font, and cmtt is "simply" a "typewriter" font, but a proportional one? But for one, cmtt doesn't look all that proportional to me – and even if it was, it should align for columns=fixed, shouldn't it?

So my questions are:

  • is there a (simple) way to determine in Latex if a font is really fixed-width? (e.g. I'd like to type something like \iffontfixedwidth{cmtt}\typeout{yes}\else\typeout{no}\fi)
  • Could I somehow get cmtt to behave the same as pcr does in {listing} (that is, have the same alignment/spacing between letters, regardless of escaped/unescaped or columns= setting)?

Best Answer

With columns=fixed and columns=flexible, the listing is built inserting each character in a box 0.6em wide for fixed and 0.45em for flexible (the default value can be changed via basewidth).

Using these two types is meaningless when the font has fixed width glyphs, like Courier or Computer Modern Typewriter, because for these fonts the interword space is the same as the width of every character, so the columns will line up automatically.

In those cases, columns=fullflexible is the best: characters are not inserted in a box and the alignment is automatic.

How to set the basewidth to a sensible value for fixed? You can exploit the fact that when basewidth is computed, the basic font has already been selected, so

basewidth=\fontcharwd\font`W,

will set this width to the one of the (usually) widest character.

Example:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{listings}
\usepackage{xcolor} % \pagecolor
\pagecolor{yellow!15}
\setlength{\fboxsep}{0pt}

\begin{document}

Here entering a sample paragraph with \texttt{some} words entered in
\texttt{typewriter font}, which should also be \texttt{monospaced} - or rather,
\texttt{fixed width}. It can be quite useful for showing \texttt{variables}.

\noindent\begin{minipage}[t]{.4\textwidth}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily,
caption={[short] Some instructions here; the font here is \texttt{\ttdefault}.},
escapechar=!,
showlines=true,
label=lst:ex2a,
columns=fixed,
basewidth=\fontcharwd\font`M,
frame=tlrb]
080484c4 <list>:
 !\fbox{\hspace{-\fboxrule}\texttt{80484c4:\_cmd one}\linebreak}!
 80484c7: cmd two
 80484ca: cmd three, four
 80484cf: cmd five
 80484d6: cmd six, seven
 80484dd: cmd more than enough
 80484e0: cmd  not_even_joking
\end{lstlisting}
\end{minipage}
\hspace{1cm}
\noindent\begin{minipage}[t]{.4\textwidth}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily,
caption={[short] Some instructions here; the font here is \texttt{\ttdefault}.},
escapechar=!,
showlines=true,
label=lst:ex2b,
columns=fullflexible,
keepspaces,
frame=tlrb]
080484c4 <list>:
 !\fbox{\hspace{-\fboxrule}\texttt{80484c4:\_cmd one}}!
 80484c7: cmd two
 80484ca: cmd three, four
 80484cf: cmd five
 80484d6: cmd six, seven
 80484dd: cmd more than enough
 80484e0: cmd  not_even_joking
\end{lstlisting}
\end{minipage}


\end{document}

enter image description here

How to determine if a font is fixed width?

\ifdim\fontcharwd\font`i=\fontcharwd\font`W
   <code for fixed width font>
\else
   <code for proportional font>
\fi

Of course \font refers to the current font.

Related Question