5

The listings syntax highlighting for OCaml breaks whenever the OCaml literal character '"' appears in the source.

It's not possible to let the language definition treat single quotes as a delimiter for string literals because single quotes are also used for type variables (e.g. 'a list)

The following document shows the problem. On the last line of the output the let keyword should be in bold. This doesn't happen because listings thinks it is inside a string literal. If we treat single quotes as string literal delimiters then first line breaks the rendering of the subsequent lines.

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[scaled]{beramono}
\usepackage{listings}
\lstset{
 language=caml,
 columns=[c]fixed,
 basicstyle=\small\ttfamily,
 keywordstyle=\bfseries,
 upquote=true,
 commentstyle=,
 breaklines=true,
 showstringspaces=false}
\begin{document}
 \begin{lstlisting}
 type 'a t = ..
 let double_quote = '"'
 let broken_highlight = ()
 \end{lstlisting}
\end{document}

Is there a way to configure the listings package for OCaml so that this problem doesn't happen ?

1
  • Also I tried to add morekeywords={'"'} but that doesn't work. Apr 3, 2019 at 22:22

3 Answers 3

4

In this particular case you can use the literate option which doesn't break with double-quoted strings or other highlighting:

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
%\usepackage[scaled]{beramono}
\usepackage{listings}
\usepackage{xcolor}

\lstset{
 language=caml,
 columns=[c]fixed,
% basicstyle=\small\ttfamily,
 keywordstyle=\bfseries,
 upquote=true,
 commentstyle=,
 breaklines=true,
 showstringspaces=false,
 stringstyle=\color{blue},
 literate={'"'}{\textquotesingle "\textquotesingle}3
}

\begin{document}
 \begin{lstlisting}
 type 'a t = ..
 let double_quote = "foo"
 let double_quote = '"'
 let double_quote = 'a'
 let double_quote = "'"
 let broken_highlight = ()
 \end{lstlisting}
\end{document}

enter image description here

1
  • Thanks works as advertised. More specificially the interested OCaml typsetter may want to add: literate={'"'}{\textquotesingle "\textquotesingle}3 {'\\"'}{\textquotesingle\textbackslash "\textquotesingle}4 Apr 5, 2019 at 15:08
3

You could consider switching to minted, which handles this input correctly. There is a black and white style available with the option style=bw.

MWE:

\documentclass{article}
\usepackage{minted}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[scaled]{beramono}

\begin{document}
\begin{minted}{ocaml}
type 'a t = { name : string; mutable info : 'a};;
let p = { name = "John"; info = 23 };;
let double_quote = '"'
let broken_highlight = ()
\end{minted}

\begin{minted}[style=bw]{ocaml}
type 'a t = { name : string; mutable info : 'a};;
let p = { name = "John"; info = 23 };;
let double_quote = '"'
let broken_highlight = ()
\end{minted}

\end{document}

Result:

enter image description here

1
  • I wasn't aware of this package, my only gripe is that it relies on external software. But thanks for the suggestion. Apr 5, 2019 at 15:09
2

The package piton handles this input without problem. The package piton requires LuaLaTeX but does not use any exterior software.

\documentclass{article}
\usepackage{piton,xcolor}

\begin{document}

\begin{Piton}[language=ocaml]
type 'a t = { name : string; mutable info : 'a};;
let p = { name = "John"; info = 23 };;
let double_quote = '"'
let broken_highlight = ()
\end{Piton}

\end{document}

Output of the above code

You must log in to answer this question.

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