[Tex/LaTex] Inline verbatim with line breaks, colored font and highlighting

colorhighlightingverbatim

I'd like to be able to use inline verbatim text with the following features:

  1. Line breaks, as provided for example by package spverbatim, command \spverb;
  2. Colored font, as provide by package color;
  3. Highlighting (text with colored background), like soul's package \hl command.

By "inline" I mean that the verbatim part is within the normal text (not an environment with its own paragraph), and by "verbatim" I mean that special symbols like \, _ etc are not be interpreted by LaTeX.

What I'd like to achieve looks like this (using blue as font color and grey as highlighting color), but it should allow a line break if the verbatim part requires one.

enter image description here

I have tried packages color, newverbs, spverbatim and soul, but I haven't been able to combine all the above features. The closest I've got is:

  • Tweaking spverbatim's definition of spverb to include colored font. That way I get features 1 and 2, but not 3:

    \gdef\myVerb{%
      \bgroup
      \color{fgColor}%
      \let\spverb@ve=\verb@egroup
      \def\verb@egroup{\spverb@ve\egroup}%
      \def\@xobeysp{\mbox{}\space}%
      \verb
    }
    

    Apparently \myVerb defined this way can't be chained with soul's package hl to use \hl{\myVerb{verbatim text}} (LaTeX complains LaTeX Error: \verb illegal in command argument.). Is there any way to combine them? For example, is there something analogous to \hl that can be added after \color{fgColor} in the code above to achieve highlighting?

  • Using the newverbs package to define

    \newverbcommand{\myVerb}
    {\color{fgColor}\begin{lrbox}{\verbbox}}
    {\end{lrbox}\colorbox{bgColor}{\usebox{\verbbox}}}
    

    This produces the font colored in fgColor and the highlighting with bgColor, so I get 2 and 3; but not 1: it doesn't allow line breaks. I guess that's because of lrbox or \colorbox, but I don't know how to modify this to allow line breaks. Is there any way to do it?

  • I can of course use

    \newcommand{\myVerb}[1]{{\ttfamily\color{fgcolor}{\hl{#1}}}}
    

    with hl as per soul package. With this I get 1, 2 and 3 but it's not verbatim, so I have to escape all special characters.

So, is there any way to achieve what I want? Either by solving what's missing in any of the above approaches, or by using a different approach? Perhaps there's a package that supports all the features I want off the shelf?

Best Answer

While not exactly what the OP asks, it may suffice. First, it uses \detokenize, not verbatim, which means 1) that braces {} must be balanced, 2) that the % symbol is still interpreted as a comment, 3) that a space is inserted after all detokenized macro names, and 4) Hash marks # are doubled in number.

Also, I just \allowbreak between words, using the \fboxsep of the colorbox to create the interword spaces.

EDITED to use \ttfamily for the \mytokens macro.

EDITED to fix line height, since the combination of a \strut and \fboxsep blew the allowed baselineskip budget.

Originally, I was not using interword space but allowed the \fboxsep to suffice. But this caused margin issues, as nothing could stretch. So, upon RE-EDIT, I insert a space of 0pt minus \fboxsep between words, which seems to allow enough compression to address the margin issues, while still leaving enough space between words (otherwise 2\fboxsep).

I also rearranged the \grayspace and allowbreak, upon RE-EDIT, so that a linebreak would not occur before trailing punctuation.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\newcommand\mytokens[1]{\mytokenshelp#1 \relax\relax}
\def\mytokenshelp#1 #2\relax{\allowbreak\grayspace\tokenscolor{#1}\ifx\relax#2\else
 \mytokenshelp#2\relax\fi}
\newcommand\tokenscolor[1]{\colorbox{gray!20}{\textcolor{blue}{%
  \ttfamily\mystrut\smash{\detokenize{#1}}}}}
\def\mystrut{\rule[\dimexpr-\dp\strutbox+\fboxsep]{0pt}{%
 \dimexpr\normalbaselineskip-2\fboxsep}}
\def\grayspace{\hspace{0pt minus \fboxsep}}
\begin{document}
Here is my leading text
\mytokens{Fie Fi Fo Fum, I smell the $#@*& blood of an \Englishman.
I will continue this text to observe the margins. 
Fie Fi Fo Fum, I smell the \textbf{blood} of an Englishman.}
and my trailing text. And here is more text to find where the margin end
really should be.

Standard MATLAB formats are allowed, such as \mytokens{1.2}, \mytokens{-.2i},
\mytokens{1.}, \mytokens{-1.2e3}, \mytokens{+.2E-3j}.  \mytokens{i} and 
\mytokens{j} denote...
\end{document}

enter image description here

SUPPLEMENT

In response to a comment request, here is a version that takes the background color as an optional argument.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\newcommand\mytokens[2][gray!20]{\mytokenshelp{#1}#2 \relax\relax}
\def\mytokenshelp#1#2 #3\relax{\allowbreak\grayspace\tokenscolor[#1]{#2}\ifx\relax#3\else
 \mytokenshelp{#1}#3\relax\fi}
\newcommand\tokenscolor[2][gray!20]{\colorbox{#1}{\textcolor{blue}{%
  \ttfamily\mystrut\smash{\detokenize{#2}}}}}
\def\mystrut{\rule[\dimexpr-\dp\strutbox+\fboxsep]{0pt}{%
 \dimexpr\normalbaselineskip-2\fboxsep}}
\def\grayspace{\hspace{0pt minus \fboxsep}}
\begin{document}
Here is my leading text
\mytokens{Fie Fi Fo Fum, I smell the $#@*& blood of an \Englishman.
I will continue this text to observe the margins. 
Fie Fi Fo Fum, I smell the \textbf{blood} of an Englishman.}
and my trailing text. And here is more text to find where the margin end
really should be.

Standard MATLAB formats are allowed, such as \mytokens{1.2}, 
  \mytokens{-.2i}, \mytokens[red!40]{1.}, \mytokens{-1.2e3}, 
  \mytokens{+.2E-3j}.  \mytokens[cyan!30]{i} and 
  \mytokens[green!20]{j} denote...
\end{document}

enter image description here