如何使 \hl(突出显示)自动将不兼容的命令放置在 \mbox 中?

如何使 \hl(突出显示)自动将不兼容的命令放置在 \mbox 中?

soul包提供了一个有用的命令\hl来突出显示文本。但是,\cite\ref和一些其他命令(可能还有方程式)必须放在 中\mbox才能\hl正常工作。

有什么方法可以实现自动化?意思是要修改\hl(以及 提供的其他命令soul)以将除纯文本之外的所有内容放入\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}

答案1

您可以 (滥用) 使用\soulregister标识符7。虽然此命令旨在用于注册字体切换命令(使用标识符01),但查看文档的实现部分会发现它还接受其他数字:9用于重音符号,8用于\footnote和,这里有趣的是,7用于“\textsuperscript或类似命令”。显然,\cite\ref朋友足够相似。

当以这种方式注册命令时,soul将首先扩展它(包括参数),然后将结果作为一个整体提供给其扫描仪,就像\mbox会做的那样。请注意,虽然这对于突出显示、删除和下划线来说已经足够了,但这也意味着它不会在字母间距文本中工作 - 没有错误,但也没有字母间距(我猜,这可能是这些命令默认未注册的原因)。

\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}

灵魂输出

答案2

{}使用花括号\ref, \cite或命令的另一种选择\pageref可能是:

\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}

答案3

现在 LaTeX 3 编程层和xparse已成为 LaTeX 的一部分,另一种选择是使用正则表达式替换。我认为这应该与手动将不兼容的命令放入 中一样强大\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}

输出:

突出显示 \ref 和 \cite 的输出屏幕截图

可能可以将此修复应用于由不同soul命令共享的宏,以便它也自动适用于删除线和下划线,但我还没有探索过这一点。

相关内容