4

This answer provides a nice solution to Highlight text in code listing while also keeping syntax highlighting which is improved in another answer. The point is the former works like a charm with the beamer class but, as shown by the following MCEs, not the latter (nothing is highlighted).

How to make the latter solution work with beamer?

(Note that other answers, e.g. this nice one, provide solutions that are working with beamer.)

Former answer which is working with beamer

\documentclass{beamer}
\usepackage{listings,xcolor,tikz}
\newcommand\bh{\tikz[remember picture]
  \node (begin highlight) {};
}
\newcommand\eh{\tikz[remember picture]
  \node (end highlight) {};
  \tikz[remember picture, overlay]
  \draw[yellow,line width=10pt,opacity=0.3] (begin highlight) -- (end
  highlight);
}


\begin{document}

\begin{frame}[fragile]
\bh abc bce bde bde \eh

\begin{lstlisting}[escapechar=@,language=SQL]
WHERE name=@\bh@UNION SELECT@\eh@
\end{lstlisting}
\end{frame}

\end{document}

enter image description here

Latter answer which is not working with beamer

\documentclass{beamer}

% required packages
\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);}}{}}}

\begin{document}

\begin{frame}[fragile]
Works in \bh{}plain text too\eh{} (but not across line breaks).

\begin{lstlisting}[escapechar=@, language=SQL, basicstyle=\sffamily, columns=fullflexible]
SELECT name, password FROM users WHERE name='@\bh@' UNION SELECT "10", 1 #@\eh@';
\end{lstlisting}
\end{frame}

\end{document}

enter image description here

  • When you say that the second method works also in plain text, why is the output not highlighted? – user121799 Mar 14 '18 at 13:39
  • @marmot Sorry, it's not my claim, but the one from the author of the original solution (which works indeed in plain text for the article class but not for beamer) that I reproduced verbatim. Is is worth editing the question in order to avoid the confusion? – Denis Bitouzé Mar 14 '18 at 13:48
  • I see. And your question is not to repair the code (as there are already plenty of working alternatives) but really why it does not work, right? – user121799 Mar 14 '18 at 13:50
  • @marmot Indeed. – Denis Bitouzé Mar 14 '18 at 14:14
  • 2
    I guess what is going on is that beamer uses its own shipouts, and the additional one ends up on a lower layer. The fact that the code compiles when you do not load atbegshi supports this. But I guess only @samcarter can tell. – user121799 Mar 14 '18 at 14:39
3

@marmots analysis of the problem was correct. The highlighting in the second example works perfectly fine, it is just below the background layer. If you change the background colour from its default white to empty you can see the highlighting:

\documentclass{beamer}

% required packages
\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);}}{}}}

\setbeamercolor{background canvas}{bg=}

\begin{document}

\begin{frame}[fragile]
Works in \bh{}plain text too\eh{} (but not across line breaks).

\begin{lstlisting}[escapechar=@, language=SQL, basicstyle=\sffamily, columns=fullflexible]
SELECT name, password FROM users WHERE name='@\bh@' UNION SELECT "10", 1 #@\eh@';
\end{lstlisting}
\end{frame}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.