1

Preparing a book where I use JetBrains Mono (Github Repo) (JBM) for code I noticed that in all the listings the * characters where rendered far to deep (on the baseline) and quite big. Also the *** ligature came out as three (fallen) * glyphs.

At this point JBM was declared as a new family:

\newfontfamily\JBMmdfamily{JetBrains Mono}[
  UprightFont    = *-Regular,
  ItalicFont     = *-Italic,
  BoldFont       = *-Bold,
  BoldItalicFont = *-BoldItalic
]

After fiddling around a bit I found that adding {*}{*}1 {***}{{***}}3 entries to a literate key in \lstset{} seemed to work. So I exchanged those characters by themselves which is funny but it works. Sort of. Looking closer I noticed that in the output spaces after those characters disappeared. Adding the keepspaces setting remedied that, so:

\lstset{
  keepspaces        = true,
%   showspaces        = false,
  literate  = {*}{*}1 {***}{{***}}3
}

(showspaces = truea lets other funny things happen but that is out of scope here.)

Later I noticed that just using

\setmonofont{JetBrains Mono}[…]

instead of

\newfontfamily\JBMmdfamily{JetBrains Mono}[…]

with the same body solved all those issues, no other \foo needed. I just don’t understand how that works. Someone care to explain?

My new problem now is, I need \texttt (etc.) to switch to the text typewriter type.

Here’s sort of a MWE:

    %!TEX TS-program = lualatex
\documentclass{article}
\usepackage{fontspec,listings}

\setmonofont{JetBrains Mono}[ UprightFont = -Regular, ItalicFont = -Italic, BoldFont = -Bold, BoldItalicFont = -BoldItalic, ]

\newfontfamily\JBMmdfamily{JetBrains Mono}[ UprightFont = -Regular, ItalicFont = -Italic, BoldFont = -Bold, BoldItalicFont = -BoldItalic, ]

\parskip=3mm \parindent=0pt \begin{document}

\subsection*{Both bindings seem to function:}

ttfamily: {\ttfamily xy z + a *** b }

JBMmdfamily: {\JBMmdfamily xy z + a *** b }

\subsection{listings needs either \textbackslash{}ttfamily:} lstlisting/ttfamily: \lstinline[basicstyle = \ttfamily]! xy * z + a *** b !

lstlisting/JBMmdfamily: \lstinline[basicstyle = \JBMmdfamily]! xy z + a *** b !

\begin{lstlisting}[basicstyle = \ttfamily] \ttfamily: xy z + a *** b \end{lstlisting}

\begin{lstlisting}[basicstyle = \JBMmdfamily] \JBMmdfamily: xy z + a *** b \end{lstlisting}

\subsection{… or keepspace & literate:} \lstset{ keepspaces = true, % showspaces = true, literate = {}{}1 {}{{*}}3 }

lstlisting/ttfamily: \lstinline[basicstyle = \ttfamily]! xy z + a *** b !

lstlisting/JBMmdfamily: \lstinline[basicstyle = \JBMmdfamily]! xy z + a *** b !

\begin{lstlisting}[basicstyle = \ttfamily] \ttfamily: xy z + a *** b \end{lstlisting}

\begin{lstlisting}[basicstyle = \JBMmdfamily] \JBMmdfamily: xy z + a *** b \end{lstlisting}

\end{document}

Result

Any ideas? Thanks for all nudges and pointers …

Just corrected the source and added a picture of my result. There were a few errors, sorry for that.

Mafsi
  • 664

1 Answers1

1

The listings package uses \textasteriskcentered when it finds *; if the font has the character at U+2217, it uses it and, lo and behold, the character in the JetBrains Mono font at that slot is a lowered big asterisk. Unless the family is \ttdefault.

In the package we find

\lst@ProcessOther {"2A}{\lst@ttfamily*\textasteriskcentered}

which exactly means what I described above.

It turns out, however, that if the definition is changed to use \lst@ttfamily**, the ligature only works in \lstinline and not in a full fledged lstlisting environment (characters are treated in different ways). Thus literate is needed anyway.

Note: font selection is slightly different because I don't have the fonts available in the system, so I need to call them by file name.

\documentclass{article}
\usepackage{fontspec,listings}

\setmonofont{JetBrainsMono}[ Extension = .ttf, UprightFont = -Regular, ItalicFont = -Italic, BoldFont = -Bold, BoldItalicFont = -Bold-Italic, ]

\newfontfamily\JBMmdfamily{JetBrainsMono}[ Extension = .ttf, UprightFont = -Regular, ItalicFont = -Italic, BoldFont = -Bold, BoldItalicFont = -Bold-Italic, ]

\makeatletter \lst@CCPutMacro\lst@ProcessOther{"2A}{\lst@ttfamily**}@empty\z@@empty \makeatother

\lstset{ keepspaces = true, % showspaces = true, % literate = {*}{{*}}3, }

\begin{document}

The wrong character:{\ttfamily x\textasteriskcentered y}

\bigskip

ttfamily: {\ttfamily xy z + a *** b }

JBMmdfamily: {\JBMmdfamily xy z + a *** b }

lstlisting/ttfamily: \lstinline[basicstyle = \ttfamily]! xy z + a *** b !

lstlisting/JBMmdfamily: \lstinline[basicstyle = \JBMmdfamily]! xy z + a *** b !

\begin{lstlisting}[basicstyle = \ttfamily] \ttfamily: xy z + a *** b \end{lstlisting}

\begin{lstlisting}[basicstyle = \JBMmdfamily] \JBMmdfamily: xy z + a *** b \end{lstlisting}

\end{document}

enter image description here

Uncommenting the literate line yields, instead

enter image description here

egreg
  • 1,121,712
  • Thanks for your answer, but … I know. ;-) You even don’t have to define \threestar, as literate = {*}{*}1 {***}{{***}}3 works perfectly—I just don’t understand why or how. It seems that \texttt does a few things that macros produced by \newfontfamily don’t which in turn makes only \texttt work with listings (without using esoteric tricks like those above ;-). – Moss_the_TeXie Jun 28 '21 at 16:51
  • @Moss_the_TeXie Reworked. – egreg Jun 28 '21 at 17:34