Verbatim/Lstlisting environment with background color highlighting

colorcolorboxhighlightinglistingsverbatim

Use case: Currently we are reporting security findings using MS Word. These findings contain large parts of code snippets, command outputs and HTML code. We highlight relevant parts of this code so the client knows where to look. I'm trying to convert this to latex.

Problem: I cannot find a way to perform highlighting in a verbatim environment, each of the solutions I have found on this site have a drawback. The requirements are:

  • Highlighting using a background color (not changing the text color).
  • The highlighting should work across line breaks.
  • The highligted text should have the same style as the rest of the verbatim environment.
  • The highlighted text should be able to contain special characters.
  • The highlighting should work correctly, even if the verbatim environment has a background.
  • Highlighting should work correctly across pages

The following is what I would like the end result to look like: (screenshot from MS Word).
Screenshot from MS Word

I have the following latex document:

\documentclass{article}
\usepackage{color}

\definecolor{codebg}{RGB}{217,217,217}
\definecolor{highlight}{RGB}{255,255,0}

%Listings
\usepackage{listings}
\usepackage{mdframed} %For background and frame
\newcommand{\listingstyle}{\ttfamily\fontsize{8pt}{9pt}\selectfont}
\lstset{
    basicstyle={\listingstyle},
    breakatwhitespace=false,
    escapeinside={*@}{@*},
    breaklines=true,
    keepspaces=true,
    xleftmargin=-5pt,
    xrightmargin=-5pt,
    aboveskip=0pt,
    belowskip=0pt,
}
\lstnewenvironment{code}{
    \mdframed[backgroundcolor=codebg,linecolor=black,linewidth=1pt]
}{
    \endmdframed
}

\begin{document}
\begin{code}
!@#$%^&*(){}[]\|
test$${{highlight!@#$%^&*(){}[]\|}}$$abcd
\end{code}
\end{document}

The result of the latex document is as follows:
Latex document

I would like the text between $${{ and }}$$ highlighted. It is okay if different separators have to be used, but these separators is what we currently use in our tooling.

I have tried many solutions on this site, notably:

Best Answer

If you are willing to use LuaLaTeX, you can do this with my lua-ul package. Basically you can define a command which enables highlighting for the rest of the current group by copying the definition of \highLight from lua-ul while omitting outer braces, then that command can be used with moredelims=** to enable delimiters which can be combined with other style elements:

\documentclass{article}
\usepackage{color}
\usepackage{plex-mono}% To make bold more visible in the exmple

\definecolor{codebg}{RGB}{217,217,217}
\definecolor{highlight}{RGB}{255,255,0}

%Listings
\usepackage{listings}
\usepackage{mdframed} %For background and frame

\usepackage{luacolor,lua-ul}% LuaLaTeX based improved color and underlining/highlighting support

\newcommand{\listingstyle}{\ttfamily\fontsize{8pt}{9pt}\selectfont}

% By default, lua-ul's \highLight has to be used as \highLight[color]{text}, 
% but moredelim=** needs a command which gets used as {\highLight[color] text}
% Therefore we define \highLightSwitch as such a variant
\makeatletter
\DeclareDocumentCommand\highLightSwitch{m}{%
  \luaul@setcolor{#1}%
  \@highLight
}
\makeatother

\lstset{
    basicstyle={\listingstyle},
    breakatwhitespace=false,
    escapeinside={*@}{@*},
    breaklines=true,
    keepspaces=true,
    xleftmargin=-5pt,
    xrightmargin=-5pt,
    aboveskip=0pt,
    belowskip=0pt,
    language=C, % To demonstrate keyword highlighting
    moredelim=**[is][\highLightSwitch{yellow}]{$$\{\{}{\}\}$$}, % Tell listings about our markers
                                                                % ** indicate that it should be combined with other styles.
}
\lstnewenvironment{code}{
    \mdframed[backgroundcolor=codebg,linecolor=black,linewidth=1pt]
}{
    \endmdframed
}

\begin{document}
\begin{code}
!@#$%^&*(){}[]\|
test$${{highlight!@#$%
  ^&*(){}[]\|}}$$abcd
\end{code}
\begin{code}
int main(int argc, char **argv) {
  $${{int ret = 42}}$$;
  return 42;
}
\end{code}
\end{document}

enter image description here