61

The soul package provides a useful command \hl for highlighting text. However, \cite, \ref, and some other commands (maybe equations too) must be placed within an \mbox in order for \hl to work properly.

Is there any way to make this automatic? Meaning that to modify \hl (and other commands provided by soul) to put everything except plain text in an \mbox?

\documentclass[12pt]{article}
\usepackage{soul}
\begin{document}

\section{1}\label{sec}
This is to show that \textbackslash{hl} fails to highlight texts containing citations or reference!

\hl{ This is one line containing a citation \mbox{\cite{}}}

\hl{ This is one line containing a reference \mbox{\ref{sec}}}


\end{document}
M.Reza
  • 3,237
  • 1
    Really interesting question, but I guess a counter question is necessary: how can you tell all those commands which are incompatible? – Sean Allred Oct 18 '13 at 17:49
  • @Sean, good question! So far I have noticed that \cite, \ref and some inline equations are incompatible. Putting everything except a plain text in a \mbox would not be a good idea since some commands need text wrapping! For a preliminary solution, maybe defining a list of incompatible commands and automatically place them inside an \mbox (if they are used in \hl) would help! – M.Reza Oct 18 '13 at 18:02
  • 1
    Maybe with \soulregister\ref{7}? – Robert Oct 18 '13 at 18:59
  • Thanks, Yes indeed, it was quite helpful! By using \soulregister\X{7}, where X is the command name, \hl encloses that command in braces. – M.Reza Oct 18 '13 at 20:08
  • 1
    This is really only useful if you use numeric citation and never use the optional argument to \cite. Anything longer, like author-year format will eventually cause a serious H&J problem. – Peter Flynn Jul 25 '17 at 20:06

3 Answers3

58

You can (ab)use \soulregister with the identifier 7. While this command is meant to be used to register font switching commands (with identifier 0 or 1), a look in the implementation part of the documentation reveals that it also accepts other numbers: 9 for accents, 8 for \footnote and, the one that's interesting here, 7 for "\textsuperscript or similar commands". Obviously, \cite, \ref and friends are similar enough.

When a command is registered this way, soul will first expand it (including the argument), and then feed the result as a whole to its scanner, just like \mbox would do. Note that while this is good enough for highlighting, striking out and underlining, it also means that it won't work in letterspaced text - there's no error, but no letterspacing either (which, I would guess, is probably the reason why these commands are not registered by default).

\documentclass[12pt]{article}
\usepackage{soul,color}
\soulregister\cite7
\soulregister\ref7
\soulregister\pageref7
\begin{document}
\st{This is a line containing a citation \cite{}.}

\hl{This is a line containing a reference \ref{sec} on page \pageref{sec}.}

\so{This reference: \ref{sec}, is not letterspaced.}

\setcounter{section}{122}
\section{1}\label{sec}
\end{document}

soul output

Robert
  • 14,181
  • 1
  • 52
  • 77
  • 1
    Thanks for the useful answer! I found out that if \xspace is defined this way, it won't function well. – M.Reza Oct 21 '13 at 10:19
  • 3
    I'll add for the sake of others like me who found this to work half-way: if you're using \citep or \citet, you'll need to add a line for each: \soulregister\citep7 and \soulregister\citet7. – jvriesem May 07 '15 at 23:20
  • 1
    Or one can use {} like {\ref{sec}}. This doesn't require to use \souregister\ref7 command :-D – Khaaba Sep 10 '15 at 13:22
  • Can this be modified to allow prefix/suffix options of \citep? For example, \hl{Things were said \citep[e.g.,][]{author2016}.}, which renders as "Things were said (?)e.g.,][]author2016". – jbaums Feb 19 '16 at 00:35
  • 3
    @jbaums not with reasonable effort, I'm afraid. You'll have to put these citations in an \mbox. – Robert Feb 19 '16 at 04:00
  • Ohhh, YES !!!!! – Vincent Fourmond Jun 19 '19 at 08:12
  • This doesn't really work for e.g. citations which have a line break (the highlighting spills outside the line), whereas \mbox{\textcite{citation}} would. – Toivo Säwén Mar 06 '23 at 16:17
14

Another option using curly braces {} around \ref, \cite or \pagerefcommands may be:

\documentclass[12pt]{article}
\usepackage{soul,color}

\begin{document}
\st{This is a line containing a citation {\cite{}}.}

\hl{This is a line containing a reference {\ref{sec}} on page {\pageref{sec}}.}

\so{This reference: {\ref{sec}}, is not letterspaced.}

\setcounter{section}{122}
\section{Section \# 123}\label{sec}
\end{document}
Khaaba
  • 1,848
  • 1
  • 22
  • 34
0

Now that the LaTeX 3 programming layer and xparse have become part of LaTeX, another option is using regular-expression replace. I think, this should be as robust as manually placing incompatible commands in \mbox.

\documentclass{article}
\usepackage{hyperref, soul, xcolor}

\ExplSyntaxOn % comma-separated list of commands that require protection \clist_const:Nn \l_soul_protect_clist { cite , citep , ref , eqref } \NewDocumentCommand{\robusthl}{m}{ \tl_set:Nn \l_tmpa_tl { #1 } % replace \cmd with \mbox{\cmd} for all \cmd in the % list of protected commands (\l_soul_protect_clist) \clist_map_inline:Nn \l_soul_protect_clist { \regex_replace_all:nnN { (\c{##1}[^{}]{[^{}]}) } % { \c{mbox}{\1} } \l_tmpa_tl } \hl\l_tmpa_tl } \ExplSyntaxOff

\begin{document}

\section{Start Here} \label{sec:start-here}

Lorem ipsum dolor sit amet \robusthl{(see Section~\ref{sec:start-here})}, consectetuer adipiscing elit. % \robusthl{Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis~\cite[et al.]{lamport94, lamport94}.}

\begin{thebibliography}{999} \bibitem{lamport94} Leslie Lamport, \emph{\LaTeX: A Document Preparation System}. Addison Wesley, Massachusetts, 2nd Edition, 1994. \end{thebibliography}

\end{document}

Output:

A screenshot of the output with highlighted \ref and \cite

It might be possible to apply this fix to a macro shared by the different soul commands so that it automatically also works for strikeout and underline, but I have not explored this yet.

alexurba
  • 1,648