我在看LaTeX 中的酷炫文本突出显示,正如我的 MWE (如下)所示:
... 第一部分,以 突出显示soul
,\hl
在[cmyk]{xcolor}
使用 时会失败。 上面链接中接受的答案使用tikz
,并且该解决方案确实适用于 CMYK - 但我对褪色文本问题感到非常恼火,我只能部分解决它。
基本上,我希望突出显示适用于 CMYK、段落中的多条连字符,并且不会淡化文本(突出显示在文本的“背景”/“后面”)。 如果有更简单的方法,那就太好了 - 否则,这里有一些关于tikz
MWE 中修改后的方法的讨论,以防可以更改它以使其完全发挥作用。
第一个想法是,由于该方法还使用了soul
的机制来获取连字过程中的音节,我们可以在运行突出显示\phantom
时为音节插入 s soul
- 同时将音节连接/附加到部分句子中,我们将在突出显示的顶部进行渲染(这必然必须在幻影上绘制) - 从而避免褪色的文本问题。
问题是:如果你给出soul
某个\box
ed,比如 a \phantom
,那么连字/换行引擎的其余部分就会出错;如果你尝试绘制白色字母,也会发生同样的情况,例如通过\textcolor{white}{#text}
。因此,我们必须在第一次运行中打印音节;然后唯一要做的就是使突出显示背景不透明(以便它覆盖第一运行字母),然后在其上打印连接的句子。如上所示,这种方法并不是那么糟糕 - 但是,调试版本(在要点中)测试.tex它使用lua-visual-debug
(和透明高亮背景)揭示了更多信息:
请注意,彼此叠放在一起的“双”字母往往会扰乱 PDF 阅读器中的选择过程(至少在 PDF 阅读器中是这样evince
- 但有点奇怪的是,当突出显示不透明时,这种情况并不那么明显?!)
基本上,覆盖文本被放置在一个tikz
节点中,该节点被“拉伸”以覆盖tikz
突出显示背景(a \fill
rectangle
),然后text align=
将设置为justify
以拉伸节点内的文本;显然,这并不总是会导致为各个空间生成相同的粘合大小。其次,当 TeX 引擎决定使用连字符并断开行尾时,我们不会-
在处理程序中获得相应的连字符soul
;因此,该连字符仅包含在首次运行的文本中,因此被不透明背景覆盖。
此 MWE 使用将音节内容连接到命令/宏变量中;然而,在调试代码中,还有一个连接到框的测试(另见访问 LaTeX 框的子内容(附加/连接 TeX 框材料)?)。 那里的问题是,框总是以.\pdfcolorstack 0 pop
框列表末尾的 结尾,这是一个问题,因为如果部分句子以空格结尾,它会弄乱覆盖文本的大小 - 并且由于.\pdfcolorstack
,我们不能使用\unskip
从框列表中删除此类尾随粘连(空格)(当使用“字符串”“变量”时,\unskip
字符串末尾的 将有助于删除可能的尾随空格)。
以下是代码:
% see also: https://gist.github.com/anonymous/999426bbae600abb9e74
\documentclass{book}
\usepackage[cmyk]{xcolor}
\usepackage{soulutf8}
\usepackage{trace}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{fit}
\usepackage{etoolbox} % \providerobustcmd
\makeatletter
\gdef\highlight@Tcontent{}
\global\newsavebox{\highlight@box}
\newcommand{\defhighlighter}[3][]{%
\tikzset{every highlighter/.style={color=#2, fill opacity=#3, #1}}%
}
% \defhighlighter{yellow!30}{.5} % transparent, to show the text below
\defhighlighter{yellow!30}{1} % fully solid/opaque, to hide the text below
\newcommand{\highlight@DoHighlight}{
\path let
\p1=($(begin highlight)+(0,8pt)$),
\p2=($(end highlight)+(0,-3pt)$),
\p3=($(\p2)-(\p1)$)
in \pgfextra %
\global\highlight@previous=\x3 %
\endpgfextra %
[fill,%
every highlighter,%
this highlighter,%
]%
(\p1) rectangle (\p2) ;%
\unskip\ignorespaces%
\node%
[anchor=south west,inner sep=0pt, outer sep=0pt, minimum size=0pt,
% hand tuned for best position:
fit={($(begin highlight)+(0pt,0pt)$)($(end highlight)+(0,-2pt)$)},
% align goes after fit;
% https://tex.stackexchange.com/questions/213105/forcing-left-text-alignment-in-a-fit-tikz-node
text width=\highlight@previous, %if it is set, align=left may break, align=justify doesn't
align=justify, %
]%
%at ($(begin highlight)+(0,2.5pt)$) % don't use at() if using fit!
{\ignorespaces\highlight@Tcontent\unskip\ignorespaces}%
;
\gdef\highlight@Tcontent{}% erase here for next round
}
\newcommand{\highlight@BeginHighlight}{
\coordinate (begin highlight) at (0,0) ;
}
\newcommand{\highlight@EndHighlight}{
\coordinate (end highlight) at (0,0) ;
}
\def\highlight@appendTcontent#1{%
% do the append to a "string"
\xdef\highlight@Tcontent{\highlight@Tcontent#1}%
% output the syllable characters:
#1%
% \hbox{#1}, \phantom{#1} makes main line breaking calc wrong ;
% an outer box probably messes up hyphenation algorithm
% (in #1 we get the syllable, but not the '-' at end if it gets hyphenated)
}
\newdimen\highlight@previous %y!
\newdimen\highlight@current %y!s
\DeclareRobustCommand*\highlight[1][]{%
\tikzset{this highlighter/.style={#1}}%
\SOUL@setup%
%
\def\SOUL@preamble{%
\begin{tikzpicture}[overlay, remember picture]%
\highlight@BeginHighlight%
\highlight@EndHighlight%
\end{tikzpicture}%
}%
%
\def\SOUL@postamble{%
\begin{tikzpicture}[overlay, remember picture]%
\highlight@EndHighlight%
\highlight@DoHighlight%
\end{tikzpicture}%
}%
%
\def\SOUL@everyhyphen{%
\discretionary{%
\SOUL@setkern\SOUL@hyphkern%
\SOUL@sethyphenchar%
\tikz[overlay, remember picture] \highlight@EndHighlight ;%
}{%
}{%
\SOUL@setkern\SOUL@charkern%
}%
}%
%
\def\SOUL@everyexhyphen##1{%
\SOUL@setkern\SOUL@hyphkern%
%\hbox{##1}% don't output raw anymore; only append it to the box
\highlight@appendTcontent{\hbox{##1}}%
\discretionary{%
\tikz[overlay, remember picture] \highlight@EndHighlight ;%
}{%
}{%
\SOUL@setkern\SOUL@charkern%
}%
}%
%
\def\SOUL@everysyllable{%
\begin{tikzpicture}[overlay, remember picture]%
\path let \p0 = (begin highlight), \p1 = (0,0)
in \pgfextra
\global\highlight@previous=\y0
\global\highlight@current =\y1
\endpgfextra (0,0);%
\ifdim\highlight@current < \highlight@previous%
\highlight@DoHighlight%
%\gdef\highlight@Tcontent{}%
\highlight@BeginHighlight%
\fi%
\end{tikzpicture}%
%\the\SOUL@syllable% don't output raw; only append it to the box
\highlight@appendTcontent{\the\SOUL@syllable}%
\tikz[overlay, remember picture] \highlight@EndHighlight ;%
}%
% must define for spaces too:
\def\SOUL@everyspace##1{%
%##1\space% "The macro should at least do {#1\space}."% don't output raw; only append it to the box
\highlight@appendTcontent{##1\space}%
}
%
\unskip\ignorespaces% this to avoid doubling spaces at start!
%
\SOUL@%
}
\makeatother
\begin{document}
\noindent\hl{Highlighting} text feels good.
You can draw attention of people to a \hl{word} or perhaps
\hl{even a whole sentence that spans across multiple lines
in such a way that hyphenation etc. are not affected.}
% the highlights will render wrong if there is no space before them!
Lorem ipsum and the again %
\highlight{dolor sit amet, consectetur adipis-icing elit, sed do
eiusmod tempor} incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation
\highlight[red]{ullamco $laboris$ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit}
in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Lorem ipsum %
\highlight{dolor sit amet, consectetur adipis-icing elit, sed do
eiusmod tempor} incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation
\highlight[red]{ullamco $laboris$ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit}
in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
\end{document}
答案1
以下解决方案提供了一种解决无法使用\usepackage[cmyk]{xcolor}
该包突出显示文本的问题的方法soul
。
xcolor
提供将核心颜色模型定义为类选项xcolor
(例如:)\usepackage[rgb]xcolor
。但是,使用\usepackage[cmyk]xcolor
会破坏文本突出显示功能soul
。
指定核心颜色模型的另一种方法是将其纳入颜色定义中。这是通过使用定义颜色模型来完成的,\definecolor[type]{name}{model-list}{spec-list}
可以<model-list>
将其写为等<core model>:model1/model2
。此格式提供了将核心模型定义为 rgb 和将颜色规范定义为 cmyk 的能力(请参阅手册第 2.3.1 节xcolor
)。
使用这种方法,MWE 逐步完成了几个示例,这些示例演示了 svgnames color 的正确和不正确渲染CornflowerBlue
。该测试重现了众所周知的问题,即使用 定义颜色cmyk
可能无法正确渲染颜色(参见下面的示例 4 和 5)。该测试表明,使用 cmyk 颜色规范来突出显示命令的正确语法soul
是使用\definecolor{colourname}{rgb:cmyk}{spec-list}
。
然后,MWE 将相同的解决方案应用于 OP 描述的问题,分别使用\definecolor{rred}{rgb:cmyk}{0,1,1,0}
和\definecolor{yyellow}{rgb:cmyk}{0,0,1,0}
提供红色和黄色突出显示。
MWE 使用\hlc
来自这里的@Gumbo 的命令:LaTeX 中的酷炫文本突出显示。
\documentclass[a4paper,12pt]{article}
\usepackage[lmargin=2.5cm,rmargin=2.5cm,tmargin=2.5cm,bmargin=2.5cm]{geometry}
\usepackage[dvipsnames,svgnames]{xcolor}
\usepackage{soul}
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt}
% CornflowerBlue definitions
\definecolor{CB}{RGB}{100,149,237}
\definecolor{cba}{rgb}{0.392,0.584,0.929}
\definecolor{cbb}{cmyk}{0.58,0.37,0,0.07}
\definecolor{cbc}{cmyk:rgb}{0.392,0.584,0.929}
\definecolor{cbd}{rgb:cmyk}{0.58,0.37,0,0.07}
% colour defintions for red and yellow
\definecolor{rred}{rgb:cmyk}{0,1,1,0}
\definecolor{yyellow}{rgb:cmyk}{0,0,1,0}
\newcommand{\hlc}[2][yellow]{ {\sethlcolor{#1} \hl{#2}} }
\begin{document}
\begin{enumerate}
\item \textbf{CornFlowerBlue (an svgname) - correct}
\hlc[CornflowerBlue]{Lorem ipsum dolor sit amet, consectetur adipiscing elit.}
\item \textbf{\{RGB\}\{100,149,237\} - correct}
\hlc[CB]{Lorem ipsum dolor sit amet, consectetur adipiscing elit.}
\item \textbf{\{rgb\}\{0.392,0.584,0.929\} - correct}
\hlc[cba]{Lorem ipsum dolor sit amet, consectetur adipiscing elit.}
\item \textbf{\{cmyk\}\{0.58,0.37,0,0.07\} - incorrect}
\hlc[cbb]{Lorem ipsum dolor sit amet, consectetur adipiscing elit.}
\item \textbf{\{cmyk:rgb\}\{0.392,0.584,0.929\} - incorrect }
\hlc[cbc]{Lorem ipsum dolor sit amet, consectetur adipiscing elit.}
\item \textbf{\{rgb:cmyk\}\{0.58,0.37,0,0.07\} - correct }
\hlc[cbd]{Lorem ipsum dolor sit amet, consectetur adipiscing elit.}
\end{enumerate}
\hlc[yyellow]{Highlighting} text feels good.
You can draw attention of people to a \hlc[yyellow]{word} or perhaps
\hlc[yyellow]{even a whole sentence that spans across multiple lines
in such a way that hyphenation etc. are not affected.}
% the highlights will render wrong if there is no space before them!
Lorem ipsum and the again %
\hlc[rred]{dolor sit amet, consectetur adipis-icing elit, sed do
eiusmod tempor} incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation
\hlc[rred]{ullamco $laboris$ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit}
in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Lorem ipsum %
\hlc[rred]{dolor sit amet, consectetur adipis-icing elit, sed do
eiusmod tempor} incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation
\hlc[rred]{ullamco $laboris$ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit}
in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
\end{document}
请注意,此解决方案在何时\usepackage[cmyk]{xcolor}
使用以及何时\setcolormodel
使用时都会失效。