5

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)?
  • I just experimented with basewidth=0.51em, option of {lstlisting} - that seems to fix the behavior of cmtt -- but then messes up the behavior of pcr (in escaped vs unescaped in columns=fixed)! So that's not the answer... – sdaau Jul 19 '14 at 11:57
  • 1
    cmtt is definitely a fixed-width font. this can be checked by looking at the width values in the .tfm file -- tftopl cmtt10. the width of every character is reported as (CHARWD R 0.524996). so something else is going on here. – barbara beeton Jul 19 '14 at 12:58
  • Thanks for that @barbarabeeton - good to know that; cheers! – sdaau Jul 19 '14 at 14:26
1

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.

0

Ok, I managed to get somewhere, but not sure how correct it is. Basically, it's all about setting basewidth=, but to a correct value, which I've obtained by using \widthof from package calc. Now, the problem is that we must have an expandable macro for basewidth= - and also, I think when basewidth= is processed, the {lstlisting} environment still doesn't "know" what \lst@basicstyle has been set to. This means, that this length has to be calculated before the {lstlisting} starts, and the arguments that will be used as basicstyle= have to be retyped there. For that, below I use a newcommand.

So, not to paste the whole example, these are the most substantial changes at the start:

\documentclass{article}

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

\newlength{\tlen}
% \xdef\etlen{}
\makeatletter
\newcommand{\getMyLen}[1]{%
%   \setlength{\tlen}{\widthof{{\lst@basicstyle W}}}%
  \setlength{\tlen}{\widthof{#1}}%
%   \xdef\etlen{\the\tlen}%
%   \etlen% return
  \the\tlen% return
}
\makeatother
\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};
\getMyLen{\scriptsize\ttfamily W}.

\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,
basewidth=\tlen,
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}
...
\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};
\getMyLen{\scriptsize\ttfamily W}.
...

... and otherwise add basewidth=\tlen, for all {lstlisting}; the end result is this:

test01b.png

... and, so to speak, looks good enough to me in either font. Of course, the question on determining if a font is really fixed-width is still open...

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.