3

I am trying to improve the current implementation (v0.1b) of the lstfiracode package. In particular, I wish to achieve the opposite of Use Fira Code font with ligatures in code listings.

Here is what I have come up with

% !TeX program = XeLaTeX
% !TeX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{fontspec}
\setmonofont{FiraCode-Regular.otf}[ % https://github.com/tonsky/FiraCode/releases
  Ligatures=Common,Contextuals=Alternate
]

\makeatletter
% Snippets of lstfiracode.sty, v0.1b
\let\lstfiracode@verbatim@nolig@list\verbatim@nolig@list
\newcommand*\ActivateVerbatimLigatures{%
  \def\verbatim@nolig@list{\do\`\do\,\do\'}%
}
\newcommand*\DeactivateVerbatimLigatures{%
  \expandafter\def\expandafter\verbatim@nolig@list\expandafter{%
    \lstfiracode@verbatim@nolig@list
    \do\w\do\*\do\/\do\:\do\=\do\!\do\~\do\[%
    \do\#\do\(\do\?\do\_\do\.\do\;\do\&\do\|%
    \do\+\do\$\do\@\do\%\do\]% Do "7B and "7D, how?
  }%
}
\makeatother

\begin{document}

\ActivateVerbatimLigatures
\begin{verbatim}
A<-www>>=B#{C|}D
\end{verbatim}

\DeactivateVerbatimLigatures
\begin{verbatim}
A<-www>>=B#{C|}D
\end{verbatim}

\end{document}

sample

As shown in the above example, I could not figure out how to \do\{ and \do\}.

As far as I know, simply \do\{ or \do\} messes up category code and the result is a big ⚠. However, the \do\# turns out just fine, even though \do@noligs has made # active before \def~{\leavevmode\kern\z@\char`#1} and before the other \do’s.

What should I do to suppress the Fira Code ligatures involving { and } (and \, just in case)?

4
  • I would say you are misusing the noligs-code (and I don't see how it should work). Why don't you simply remove the Contextuals=Alternate if you want to suppress them? Commented Dec 21, 2018 at 17:00
  • I'm afraid you can't like this: characters specified in the “nolig list” are made active, but then \end{verbatim} doesn't match the terminator sequence, which is expecting { and } with category code 12.
    – egreg
    Commented Dec 21, 2018 at 17:05
  • @UlrikeFischer I absolutely agree. In fact, to avoid ligatures all together, one should simply use Fira Mono instead. I am just wondering if a counterpart of \ActivateVerbatimLigatures is possible. Commented Dec 21, 2018 at 17:40
  • @egreg Ahhh, this is what I have suspected. It is extremely lucky that \end{verbatim} does not contain the lowercase letter w. Commented Dec 21, 2018 at 17:44

1 Answer 1

1

There's a few related questions.

Anyway, in summary,

  • if you are okay with disabling ligatures globally for Fira Mono font, just use 4th question above (if XeLaTeX/LuaLaTeX) or 5th question above (PDFLaTeX)

Otherwise, keep reading.


As mentioned by egreg in the comment, it's because of the matching of the \@xverbatim macro.

source2e screenshot

The only way I can think of is to selectively redefine \@xverbatim when needed.

% !TeX program = XeLaTeX
% !TeX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{fontspec}
\setmonofont{FiraCode-Regular.ttf}[ % https://github.com/tonsky/FiraCode/releases
Contextuals=Alternate
]

\makeatletter
% Snippets of lstfiracode.sty, v0.1b
\let\lstfiracode@verbatim@nolig@list\verbatim@nolig@list
\usepackage{precattl}
\precattlExec{
\newcommand*\ActivateVerbatimLigatures{%
  \gdef\@xverbatim##1\cO\\end\cO\{verbatim\cO\}{##1\end{verbatim}}%
  \def\verbatim@nolig@list{\do\`\do\,\do\'}%
}
\newcommand*\DeactivateVerbatimLigatures{%
  \gdef\@xverbatim##1\cO\\end\cA\{verbatim\cA\}{##1\end{verbatim}}%
  \expandafter\def\expandafter\verbatim@nolig@list\expandafter{%
    \lstfiracode@verbatim@nolig@list
    \do\w\do\*\do\/\do\:\do\=\do\!\do\~\do\[%
    \do\#\do\(\do\?\do\_\do\.\do\;\do\&\do\|%
    \do\+\do\$\do\@\do\%\do\]\do\{\do\}%
  }%
}
}
\makeatother

\begin{document}

\ActivateVerbatimLigatures
\begin{verbatim}
A<-www>>=B#{C|}D
\end{verbatim}

\DeactivateVerbatimLigatures
\begin{verbatim}
A<-www>>=B#{C|}D
\end{verbatim}

\end{document}

Of course, this monkey-patches the verbatim environment, so if at any point in time the LaTeX kernel is modified, this will break horribly.

Explanation

Basically, the normal definition of \@xverbatim is:

\gdef\@xverbatim#1\cO\\end\cO\{verbatim\cO\}{#1\end{verbatim}}

where \cO\⟨character⟩ represents a other-category token with charcode = that character.

That matches the document until the specified token list is seen.

When { and } are made active, then you want to modify the definition to:

\gdef\@xverbatim#1\cO\\end\cA\{verbatim\cA\}{#1\end{verbatim}}

where \cA\⟨character⟩ represents a active-category token with charcode = that character.


If you don't want to use my package precattl, there are other ways to insert the weird-catcode tokens in. One is to use the catcode-changing trick.

% !TeX program = XeLaTeX
% !TeX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{fontspec}
\setmonofont{FiraCode-Regular.ttf}[ % https://github.com/tonsky/FiraCode/releases
Contextuals=Alternate
]

\makeatletter
% Snippets of lstfiracode.sty, v0.1b

\let\lstfiracode@verbatim@nolig@list\verbatim@nolig@list

\begingroup \catcode `|=0 \catcode `[=1
\catcode `]=2 \catcode `\{=12 \catcode `\}=12
\catcode `\\=12
|gdef|ActivateVerbatimLigatures[%
  |gdef|@xverbatim##1\end{verbatim}[##1|end[verbatim]]%
  |def|verbatim@nolig@list[|do|`|do|,|do|']%
]

|catcode `|{|active
|catcode `|}|active
|gdef|DeactivateVerbatimLigatures[%
  |gdef|@xverbatim##1\end{verbatim}[##1|end[verbatim]]%
  |expandafter|def|expandafter|verbatim@nolig@list|expandafter[%
    |lstfiracode@verbatim@nolig@list
    |do|w|do|*|do|/|do|:|do|=|do|!|do|~|do|[%
    |do|#|do|(|do|?|do|_|do|.|do|;|do|&|do||%
    |do|+|do|$|do|@|do|%|do|]|do|{|do|}%
  ]%
]
|endgroup
\makeatother

\begin{document}

\ActivateVerbatimLigatures
\begin{verbatim}
A<-www>>=B#{C|}D
\end{verbatim}

\DeactivateVerbatimLigatures
\begin{verbatim}
A<-www>>=B#{C|}D
\end{verbatim}

\end{document}

The other is to use \lowercase trick.

% !TeX program = XeLaTeX
% !TeX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{fontspec}
\setmonofont{FiraCode-Regular.ttf}[ % https://github.com/tonsky/FiraCode/releases
Contextuals=Alternate
]

\makeatletter
% Snippets of lstfiracode.sty, v0.1b
\let\lstfiracode@verbatim@nolig@list\verbatim@nolig@list

\begingroup
\catcode`X\active
\catcode`Y\active
\lccode`[=`{
\lccode`]=`}
\lccode`X=`{
\lccode`Y=`}
\lccode`/=`\\
\lowercase{\endgroup
\newcommand*\ActivateVerbatimLigatures{%
  \gdef\@xverbatim##1/end[verbatim]{##1\end{verbatim}}
  \def\verbatim@nolig@list{\do\`\do\,\do\'}%
}
\newcommand*\DeactivateVerbatimLigatures{%
  \gdef\@xverbatim##1/endXverbatimY{##1\end{verbatim}}
  \expandafter\def\expandafter\verbatim@nolig@list\expandafter{%
    \lstfiracode@verbatim@nolig@list
    \do\w\do\*\do\/\do\:\do\=\do\!\do\~\do\[%
    \do\#\do\(\do\?\do\_\do\.\do\;\do\&\do\|%
    \do\+\do\$\do\@\do\%\do\]\do\{\do\}%
  }%
}
}

\makeatother

\begin{document}

\ActivateVerbatimLigatures
\begin{verbatim}
A<-www>>=B#{C|}D
\end{verbatim}

\DeactivateVerbatimLigatures
\begin{verbatim}
A<-www>>=B#{C|}D
\end{verbatim}

\end{document}

You must log in to answer this question.

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