似乎\hl
soul 包中的命令无法处理逃逸空间。一个最小的非工作示例是
\documentclass{article}
\usepackage{xcolor, soul}
\colorlet{mycolor}{red!30}
\sethlcolor{mycolor}
\begin{document}
\hl{can\ we\ highlight}
\end{document}
错误信息是
包灵魂错误:重建失败。
一些帖子(例如,这里和这里) 建议使用\mbox
(或\hbox
)来换行,或者使用\protect
。虽然这些方法有效,但它们有一些缺点:
- 如果
\mbox
使用,长文本将无法正常换行。 - 如果
\protect
使用,文本的背景颜色将会消失。
如何更加优雅的解决这个问题?
编辑
Skillmon 分享的解决方案适用于英语,但不适用于中文。下面的 MWE 将对此进行说明。
\documentclass{ctexart}
\usepackage{xcolor, soul}
\usepackage{xparse}
\let\hlORIG\hl
\colorlet{mycolor}{red!30}
\sethlcolor{mycolor}
\ExplSyntaxOn
\tl_new:N \l_jdhao_hlx_tl
\RenewDocumentCommand \hl { +m }
{
\tl_set:Nn \l_jdhao_hlx_tl { #1 }
\tl_replace_all:Nnn \l_jdhao_hlx_tl { \ } { ~ }
\exp_args:NV \hlORIG \l_jdhao_hlx_tl
}
\ExplSyntaxOff
\begin{document}
\hl{test\ test} %% pass!
\hl{测试\ 测试} %% fail!
\end{document}
有趣的是,英文测试通过了,中文测试却失败了,错误信息是一样的。
答案1
使用辅助宏将所有显式空间(\
)转换为普通空间,这是可能的(我重新定义了\hl
宏,以便您不必更改任何其他内容):
\documentclass{article}
\usepackage{xcolor, soul}
\usepackage{xparse}
\let\hlORIG\hl
\colorlet{mycolor}{red!30}
\sethlcolor{mycolor}
\ExplSyntaxOn
\tl_new:N \l_jdhao_hlx_tl
\RenewDocumentCommand \hl { +m }
{
\tl_set:Nn \l_jdhao_hlx_tl { #1 }
\tl_replace_all:Nnn \l_jdhao_hlx_tl { \ } { ~ }
\exp_args:NV \hlORIG \l_jdhao_hlx_tl
}
\ExplSyntaxOff
\begin{document}
\hl{can\ we\ highlight}
\end{document}
编辑:使用中文输入,但破坏自动连字功能(您仍然可以使用 进行手动连字\-
):
\documentclass{ctexart}
\usepackage{xcolor, soul}
\usepackage{xparse}
%\usepackage[chinese,main=english]{babel}
\let\hlORIG\hl
\colorlet{mycolor}{red!30}
\sethlcolor{mycolor}
\ExplSyntaxOn
\tl_new:N \l_jdhao_hlx_tl
\RenewDocumentCommand \hl { m }
{
\tl_set:Nn \l_jdhao_hlx_tl { #1 }
\tl_replace_all:Nnn \l_jdhao_hlx_tl { \ } { ~ }
\regex_replace_all:nnN { [^\s\c{-}] } { \c{hbox} \0 } \l_jdhao_hlx_tl
\exp_args:NV \hlORIG \l_jdhao_hlx_tl
}
\ExplSyntaxOff
\begin{document}
% for comparison of hyphenating
\rule{.9\textwidth}{1pt}possibility\ to\ highlight
\rule{.9\textwidth}{1pt}\hl{possibility\ to\ highlight}
\rule{.9\textwidth}{1pt}\hl{pos\-sibility\ to\ highlight}
\rule{.9\textwidth}{1pt}\hlORIG{possibility to highlight}
\hl{汤面}
\hl{汤面}
\hl{测试\ 测试}
%\hlORIG{汤面}
\end{document}
编辑2:
还有另一个版本允许您在 的参数中使用括号和其他内容\hl
。请注意,此版本和第二个版本都会破坏 的参数中的数学运算\hl
。您可以更改用作 的第一个参数的正则表达式来\regex_replace_all:nnN
解决您面临的更多问题,我不愿意花更多时间去摆弄它。
\documentclass{ctexart}
\usepackage{xcolor, soul}
\usepackage{xparse}
%\usepackage[chinese,main=english]{babel}
\let\hlORIG\hl
\colorlet{mycolor}{red!30}
\sethlcolor{mycolor}
\ExplSyntaxOn
\tl_new:N \l_jdhao_hlx_tl
\RenewDocumentCommand \hl { m }
{
\tl_set:Nn \l_jdhao_hlx_tl { #1 }
\tl_replace_all:Nnn \l_jdhao_hlx_tl { \ } { ~ }
\regex_replace_all:nnN { \c[^CBEMTPUDA]\S } { \c{hbox} \0 } \l_jdhao_hlx_tl
\exp_args:NV \hlORIG \l_jdhao_hlx_tl
}
\ExplSyntaxOff
\begin{document}
% for comparison of hyphenating
\rule{.9\textwidth}{1pt}possibility\ to\ highlight
\rule{.9\textwidth}{1pt}\hl{possibility\ to\ highlight}
\rule{.9\textwidth}{1pt}\hl{pos\-sibility\ \textbackslash{} to\ highlight}
\rule{.9\textwidth}{1pt}\hlORIG{possibility\textbackslash{} to highlight}
\hl{汤面}
\hl{汤面}
\hl{测试\ 测试}
\end{document}