与 CMYK xcolor 模式兼容的文本突出显示?

与 CMYK xcolor 模式兼容的文本突出显示?

我在看LaTeX 中的酷炫文本突出显示,正如我的 MWE (如下)所示:

测试.png

... 第一部分,以 突出显示soul\hl[cmyk]{xcolor}使用 时会失败。 上面链接中接受的答案使用tikz,并且该解决方案确实适用于 CMYK - 但我对褪色文本问题感到非常恼火,我只能部分解决它。

基本上,我希望突出显示适用于 CMYK、段落中的多条连字符,并且不会淡化文本(突出显示在文本的“背景”/“后面”)。 如果有更简单的方法,那就太好了 - 否则,这里有一些关于tikzMWE 中修改后的方法的讨论,以防可以更改它以使其完全发挥作用。


第一个想法是,由于该方法还使用了soul的机制来获取连字过程中的音节,我们可以在运行突出显示\phantom时为音节插入 s soul- 同时将音节连接/附加到部分句子中,我们将在突出显示的顶部进行渲染(这必然必须在幻影上绘制) - 从而避免褪色的文本问题。

问题是:如果你给出soul某个\boxed,比如 a \phantom,那么连字/换行引擎的其余部分就会出错;如果你尝试绘制白色字母,也会发生同样的情况,例如通过\textcolor{white}{#text}。因此,我们必须在第一次运行中打印音节;然后唯一要做的就是使突出显示背景不透明(以便它覆盖第一运行字母),然后在其上打印连接的句子。如上所示,这种方法并不是那么糟糕 - 但是,调试版本(在要点中)测试.tex它使用lua-visual-debug(和透明高亮背景)揭示了更多信息:

测试.lualatex.png

请注意,彼此叠放在一起的“双”字母往往会扰乱 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使用时都会失效。

相关内容