How to "highlight" text/formulas with tikz?

You can give the node a name and align to the baseline of that:

enter image description here

Note:

  • This will only work for small pieces of text that do not cross line boundaries. If you need it to work across line boundaries you should consider the soul package. A good example of this can be found at Cool Text Highlighting in LaTeX.
  • As suggested by @percusse, you should also consider the mdframed package if you are interested in highlighting entire paragraphs.

Code:

\documentclass{scrartcl}

\usepackage[T1]{fontenc}
\usepackage[american,ngerman]{babel}
\usepackage{tikz}

\newcommand*{\yellowemph}[1]{%
  \tikz[baseline=(X.base)] \node[rectangle, fill=yellow, rounded corners, inner sep=0.3mm] (X) {#1};%
}

\begin{document}
Just some \yellowemph{dummy} text to see what happens.
\end{document}

Here's the code that I currently use for this. I use it mainly for highlighting (or fading) short segments of presentations, so it isn't designed to cope with long sections (though it makes a reasonable stab at it) and it almost certainly would go potty with page breaks. It's major drawback is that it doesn't automatically adjust to the size of the text because it doesn't work by putting the text in a box. Rather, it draws the highlighting under (for highlighting, over for fading) the text. So you should think of it more as getting a highlighter pen and highlighting text instead of drawing a box and filling it. Of course, you can use a thicker pen and there are keys to customise such stuff.

There are three variants: a highlighter, a fader, and a vertical highlighter. Each works by marking the start and end of the part you want marked. Then TikZ draws thick lines of the highlighter colour from the start to the end. If the displacement warrants it, the lines wrap (vertically in the case of the vertical highlighter). The difference between the highlighter and the fader is when the lines are drawn. For the highlighter, the lines emanate from the starting position, effectively placing them under the text. For the fader, the lines emanate from the ending position, placing them over the text.

Here's a sample:

simplistic highlighter code

Here's the code. I've tried to make it work with both beamer and non-beamer. In beamer, you get to do things like \highlight<2>{only on slide 2}. There are two ways to invoke the highlighting. One is to say \highlight{text to be highlighted} the other is to say \hlstart text to be highlighted \hlend. Sometimes the latter gives a bit more flexibility (the vertical highlighting in the above was done this way).

Here's the code. The amsmath package is just for the bmatrix environment. The above sample was actually produced using beamer (and uncommenting the frame environment).

\documentclass{article}
%\url{http://tex.stackexchange.com/q/46434/86}
\usepackage{amsmath}
\usepackage{tikz}

\makeatletter

%
% Highlighter code
%

\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  }
}

\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \@ifundefined{save@pt@#1}{%
    \pgfpointorigin
  }{%
  \pgfsys@getposition{\csname save@pt@#1\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}

\newcounter{highlight}
\newcommand{\hlstart}{\tikz[remember picture with id=hlstart\the\value{highlight},baseline=-0.7ex];\hl@start}
\newcommand{\hlend}{\tikz[remember picture with id=hlend\the\value{highlight},baseline=-0.7ex];\hl@end\stepcounter{highlight}}
\newcommand{\fdstart}{\tikz[remember picture with id=hlstart\the\value{highlight},baseline=-0.7ex];\fd@start}
\newcommand{\fdend}{\tikz[remember picture with id=hlend\the\value{highlight},baseline=-0.7ex];\fd@end\stepcounter{highlight}}
\newcommand{\vlstart}{\tikz[remember picture with id=hlstart\the\value{highlight},baseline=-1em];\vl@start}
\newcommand{\vlend}{\tikz[remember picture with id=hlend\the\value{highlight},baseline=0.3ex];\vl@end\stepcounter{highlight}}

\newcommand{\hl@start}[1][]{%
  \hl@draw{highlighter}{#1}{\the\value{highlight}}}

\newcommand{\hl@end}{}

\newcommand{\fd@start}[1][]{%
  \def\fd@args{#1}}

\newcommand{\fd@end}{\def\@tempa{\hl@draw{fader}}\expandafter\@tempa\expandafter{\fd@args}{\the\value{highlight}}\def\fd@args{}}

\newcommand{\vl@start}[1][]{%
  \vl@draw{highlighter}{#1}{\the\value{highlight}}}

\newcommand{\vl@end}{}


\def\hl@sets{%
  \edef\hl@sx{\the\pgf@x}%
  \edef\hl@sy{\the\pgf@y}%
}
\def\hl@sete{%
  \edef\hl@ex{\the\pgf@x}%
  \edef\hl@ey{\the\pgf@y}%
}

\@ifclassloaded{beamer}{

\def\page@node{
  \path (current page.south east)
      ++(-\beamer@rightmargin,\footheight)
  node[
    minimum width=\textwidth,
    minimum height=\textheight,
    anchor=south east
  ] (page) {};
}

}{

  \def\page@node{
    \path (current page.north west)
    ++(\hoffset + 1in + \oddsidemargin + \leftskip,\voffset + 1in + \topmargin + \headheight + \headsep)
    node[
      minimum width=\textwidth - \leftskip - \rightskip,
      minimum height=\textheight,
      anchor=north west
    ] (page) {};
  }

}

\newcommand{\hl@draw}[3]{%
  \begin{tikzpicture}[remember picture,overlay]%
  \page@node
  \tikzset{#2,highlight=#1,every path/.append style={highlight=#1}}%
  \pgfmathsetlengthmacro{\hl@width}{\the\pgflinewidth - 1pt}%
  \coordinate (hlstart) at (pic cs:hlstart#3);
  \coordinate (hlend) at (pic cs:hlend#3);
  \tikz@scan@one@point\hl@sets(pic cs:hlstart#3)
  \tikz@scan@one@point\hl@sete(pic cs:hlend#3)
  \ifdim\hl@sy=\hl@ey\relax
  \draw (hlstart) -- (hlend);
  \else
  \draw (hlstart) -- (hlstart -| page.east);
  \pgfmathsetlengthmacro{\hl@sy}{\hl@sy -\hl@width}%
  \pgfmathsetlengthmacro{\hl@ey}{\hl@ey +\hl@width}%
  \loop\ifdim\hl@sy>\hl@ey\relax
  \draw (0,\hl@sy -| page.west) -- (0,\hl@sy -| page.east);
  \pgfmathsetlengthmacro{\hl@sy}{\hl@sy -\hl@width}%
  \repeat
  \draw (hlend -| page.west) -- (hlend);
  \fi
  \end{tikzpicture}%
}

\newcommand{\vl@draw}[3]{%
  \begin{tikzpicture}[remember picture,overlay]%
  \page@node
  \tikzset{#2,highlight=#1,every path/.append style={highlight=#1}}%
  \pgfmathsetlengthmacro{\hl@width}{\the\pgflinewidth - 1pt}%
  \coordinate (hlstart) at (pic cs:hlstart#3);
  \coordinate (hlend) at (pic cs:hlend#3);
  \tikz@scan@one@point\hl@sets(pic cs:hlstart#3)
  \tikz@scan@one@point\hl@sete(pic cs:hlend#3)
  \ifdim\hl@sx=\hl@ex\relax
  \draw (hlstart) -- (hlend);
  \else
  \draw (hlstart) -- (hlstart |- page.south);
  \pgfmathsetlengthmacro{\hl@sx}{\hl@sx -\hl@width}%
  \pgfmathsetlengthmacro{\hl@ex}{\hl@ex +\hl@width}%
  \loop\ifdim\hl@sx>\hl@ex\relax
  \draw (\hl@sx,0 |- page.north) -- (\hl@sx,0 |- page.south);
  \pgfmathsetlengthmacro{\hl@sx}{\hl@sx -\hl@width}%
  \repeat
  \draw (hlend |- page.north) -- (hlend);
  \fi
  \end{tikzpicture}%
}

\tikzset{%
  highlight/.default=highlighter,
  highlight/.style={
    color=\pgfkeysvalueof{/tikz/#1 colour},
    line width=\pgfkeysvalueof{/tikz/#1 width},
    line cap=\pgfkeysvalueof{/tikz/#1 cap},
    opacity=\pgfkeysvalueof{/tikz/#1 opacity},
  },
  highlighter colour/.initial=yellow,
  highlighter width/.initial=12pt,
  highlighter cap/.initial=butt,
  highlighter opacity/.initial=1,
  fader colour/.initial=gray,
  fader width/.initial=12pt,
  fader cap/.initial=butt,
  fader opacity/.initial=.5,
}



\@ifclassloaded{beamer}{

%% Beamer variants

\setbeamercolor{highlighted text}{bg=yellow}
\setbeamercolor{faded text}{fg=gray}

\newcommand<>{\highlight}[2][]{%
  \only#3{\hlstart[#1]}#2\only#3{\hlend}}

\newcommand<>{\fade}[2][]{%
  \only#3{\fdstart[#1]}#2\only#3{\fdend}}

\newcommand<>{\vhighlight}[2][]{%
  \only#3{\vlstart[#1]}#2\only#3{\vlend}}

}{

\newcommand{\highlight}[2][]{%
\hlstart[#1]#2\hlend}

\newcommand{\fade}[2][]{%
\fdstart[#1]#2\fdend}

\newcommand{\vhighlight}[2][]{%
\vlstart[#1]#2\vlend}

}

\makeatother

\begin{document}
%\begin{frame}

This is some \highlight{highlighted} text.  With displaystyle maths, we might have to adjust the line width to get \highlight[highlighter width=24pt]{\(\displaystyle \frac12\)}.

\highlight[highlighter cap=round]{For a very long line, we get basic line wrapping.  It's a little creaky around the edges so may not be as robust as it could be.}

Sometimes, though, one wants to \fade[fader colour=white]{fade} some text.

Vertical highlighting is useful in matrices:
%
\[
  \begin{bmatrix}
  1 & \vlstart 2 & 3 \\
  4 & \vlend 5 & 6
  \end{bmatrix}
\]

%\end{frame}
\end{document}

Like Peter's answer but without adding a new name for the node

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[american,ngerman]{babel}
\usepackage{tikz}

\newcommand*{\yellowemph}[1]{%
\tikz[baseline]\node[rectangle, fill=yellow, rounded corners, inner sep=0.3mm,anchor=base]{#1};%
}
\begin{document}
Just some \yellowemph{dummy} text to see what happens.
\end{document} 

enter image description here

Tags:

Tikz Pgf