5

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

5
  • When you say that the second method works also in plain text, why is the output not highlighted?
    – user121799
    Mar 14, 2018 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? Mar 14, 2018 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, 2018 at 13:50
  • @marmot Indeed. Mar 14, 2018 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, 2018 at 14:39

1 Answer 1

4

@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
\tikzset{highlighter/.style={
  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

You must log in to answer this question.

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