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}
5
  • 1
    Really interesting question, but I guess a counter question is necessary: how can you tell all those commands which are incompatible? Oct 18, 2013 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, 2013 at 18:02
  • 1
    Maybe with \soulregister\ref{7}?
    – Robert
    Oct 18, 2013 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, 2013 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. Jul 25, 2017 at 20:06

3 Answers 3

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

7
  • 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, 2013 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 7, 2015 at 23:20
  • 1
    Or one can use {} like {\ref{sec}}. This doesn't require to use \souregister\ref7 command :-D
    – Khaaba
    Sep 10, 2015 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, 2016 at 0:35
  • 3
    @jbaums not with reasonable effort, I'm afraid. You'll have to put these citations in an \mbox.
    – Robert
    Feb 19, 2016 at 4:00
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}
5
  • Nice & simple solution.
    – Themis
    Dec 17, 2018 at 15:16
  • 1
    does not work for me. same bug Oct 20, 2019 at 22:00
  • @kevinkayaks It works with me without a problem. What is the error message you are getting?
    – Khaaba
    Oct 27, 2019 at 8:36
  • 1
    I don't recall exactly, but I learned it works with \citep{person2018} but not with \citep[e.g.,][]{person2018} which (unfortunately for trackchanges) is a construction I often use. Oct 28, 2019 at 0:07
  • I'm getting Package soul Error: Reconstruction failed. Mar 6, 2023 at 16:19
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.

You must log in to answer this question.

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