It's almost a year later, but as the OP has not yet accepted an answer, I still see my chance :-)
In the following, I use the same basic principle as in my other answer, that is, employ listings
moredelim=**
option to define delimiters, which styles then apply on top of all other formattings, so that the syntax formatting is kept.
However, instead of being limited to a standard font command for the delimiter style, I now use an lrbox
to grab the content of the current group. The resulting box holds the (syntax-formatted) output of listings
, which can be used to implement more fancy highlighting styles.
In the example code, the implementation of the \btHL
command employs TikZ to typeset the lrbox
into a TikZ node. Additional TikZ/PGF options to both, the tikzpicture and the node can be given in the optional argument (such as \btHL[fill=red!20,draw=red]
), which provides for pretty flexible highlighters.
(Note: when the optional argument is used inside some listings
argument, the whole \btHL[<key>=<value>,...]
command has to be put into curly braces in order to not confuse the listings
key=value parser.)
The \btHL
command can as well be used inside normal text. It does, however, not work across line breaks, which is a possible disadvantage compared to the approach that culminated from Bens answer. Insides of listings, however, this usually is not an issue.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{listings,xcolor,beramono}
\usepackage{tikz}
\makeatletter
\newenvironment{btHighlight}[1][]
{\begingroup\tikzset{bt@Highlight@par/.style={#1}}\begin{lrbox}{\@tempboxa}}
{\end{lrbox}\bt@HL@box[bt@Highlight@par]{\@tempboxa}\endgroup}
\newcommand\btHL[1][]{%
\begin{btHighlight}[#1]\bgroup\aftergroup\bt@HL@endenv%
}
\def\bt@HL@endenv{%
\end{btHighlight}%
\egroup
}
\newcommand{\bt@HL@box}[2][]{%
\tikz[#1]{%
\pgfpathrectangle{\pgfpoint{1pt}{0pt}}{\pgfpoint{\wd #2}{\ht #2}}%
\pgfusepath{use as bounding box}%
\node[anchor=base west, fill=orange!30,outer sep=0pt,inner xsep=1pt, inner ysep=0pt, rounded corners=3pt, minimum height=\ht\strutbox+1pt,#1]{\raisebox{1pt}{\strut}\strut\usebox{#2}};
}%
}
\makeatother
\lstdefinestyle{SQL}{
language={SQL},basicstyle=\ttfamily,
moredelim=**[is][\btHL]{`}{`},
moredelim=**[is][{\btHL[fill=green!30,draw=red,dashed,thin]}]{@}{@},
}
\begin{document}
A listing with {\btHL highlighting of all \textbf{important} elements} looks as follows:
\begin{lstlisting}[style=SQL]
SELECT name, password `FROM` users @WHERE@ name=@UNION SELECT@
\end{lstlisting}
One way to automatically apply the solutions form Highlight text in code listing while also keeping syntax highlighting around each lstinline
is to redefine some of the internal macros from the listings
package to include a \bh{}
at the beginning of the listing and a \eh{}
. To ensure that this only applies to inline listings, we use iftoggle
from the etoolbox
package to produce:
Known Issues:
- Highlighting does not span line breaks correctly.
Code:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{atbegshi,ifthen,listings,tikz}
% change this to customize the appearance of the highlight
\tikzstyle{highlighter} = [
yellow,
line width = \baselineskip,
]
% enable these two lines for a more human-looking highlight
%\usetikzlibrary{decorations.pathmorphing}
%\tikzstyle{highlighter} += [decorate, decoration = random steps]
% implementation of the core highlighting logic; do not change!
\newcounter{highlight}[page]
\newcommand{\tikzhighlightanchor}[1]{\ensuremath{\vcenter{\hbox{\tikz[remember picture, overlay]{\coordinate (#1 highlight \arabic{highlight});}}}}}
\newcommand{\bh}[0]{\stepcounter{highlight}\tikzhighlightanchor{begin}}
\newcommand{\eh}[0]{\tikzhighlightanchor{end}}
\AtBeginShipout{\AtBeginShipoutUpperLeft{\ifthenelse{\value{highlight} > 0}{\tikz[remember picture, overlay]{\foreach \stroke in {1,...,\arabic{highlight}} \draw[highlighter] (begin highlight \stroke) -- (end highlight \stroke);}}{}}}
%--------------------------
\makeatletter % Redefine macros from listings package:
\newtoggle{@InInlineListing}%
\togglefalse{@InInlineListing}%
\renewcommand\lstinline[1][]{%
\leavevmode\bgroup\toggletrue{@InInlineListing}\bh % \hbox\bgroup --> \bgroup
\def\lst@boxpos{b}%
\lsthk@PreSet\lstset{flexiblecolumns,#1}%
\lsthk@TextStyle
\@ifnextchar\bgroup{\afterassignment\lst@InlineG \let\@let@token}%
\lstinline@}%
\def\lst@LeaveAllModes{%
\ifnum\lst@mode=\lst@nomode
\expandafter\lsthk@EndGroup\iftoggle{@InInlineListing}{\eh{}}{}%
\else
\expandafter\egroup\expandafter\lst@LeaveAllModes
\fi%
}
\makeatother
\lstset{backgroundcolor=\color{green!10}}%
\begin{document}
The following \emph{inline} code snippet should appear
in a frame (or highlighted) if lstinline command is properly redefined above:
\lstinline´chainl1(term, "+" ^^^ Add | "-" ^^^ Sub)´Now back to regular text
\bigskip
The lstlisting environment is not affected:
\begin{lstlisting}
chainl1(term, "+" ^^^ Add | "-" ^^^ Sub)
\end{lstlisting}
\end{document}
Best Answer
It's as simple as
Version with a macro for having a background text: