获得透明、可嵌套、可包裹的背景

获得透明、可嵌套、可包裹的背景

我喜欢该包启用彩色文本背景的方式,soul因为它:

  • \hl{}在ed 文本周围不添加填充(\colorbox除非我们\fboxsep=0cm在周围的组中设置)
  • 启用换行(不同于\colorbox不可破坏的)

但是,它不支持:

  • 透明背景着色
  • 嵌套突出显示的文本(如果背景是透明的,则这样做是有意义的)

换句话说,我正在寻找一个神奇的命令,它允许我定义自定义\mhl突出显示命令,以便:

\documentclass{standalone}

\newcommand{\mhl}[1]{\whichCommandIsThat{black}{.2}{#1}}

\begin{document}

\begin{minipage}{3.4cm}
here is a \mhl{weird \mhl{nested, wrappable} weird} text
\end{minipage}

\end{document}

将产生:

在此处输入图片描述

任何想法?

答案1

编辑:请参阅最后更新的完整解决方案。

我确实通过使用包得到了部分答案tcolorbox,其中可以实现嵌套和透明:

\documentclass{article}
\usepackage{tcolorbox}
\tcbuselibrary{skins,breakable,xparse}
\newcommand{\mhl}[1]{%
   \tcbox[tcbox raise base, 
  left=0mm,right=0mm,top=0mm,bottom=0mm,boxsep=0.5pt,arc=0mm,
  boxrule=0pt,opacityfill=0.3,enhanced jigsaw,colback=gray!85!white,
   before=\relax,after=\relax]{#1}
}
\begin{document}
I say \mhl{Hello World} !
This box has a no \mhl{defined \mhl{height}} as you can see. 
The total \mhl{colored box is \mhl{shrunk to the 
\mhl{dimensions} of the \mhl{upper} part}. There} should be  no title. 
\end{document}

导致: 在此处输入图片描述 但它不能跨行拆分。也许可以通过xstring逐字处理文本来模拟拆分功能……

编辑: 更好的解决方案是使用较新的listofitems包,该包允许将 的内容拆分\mhl为单词或内部\mhl,然后逐个处理它们。为此,将以前的宏\mhl调用\tcbox重铸为内部宏\mhl@int。换行在 \mhl 的第一级有效,但在嵌套的级中无效。

新代码:

\documentclass{article}
\usepackage{tcolorbox}
\usepackage{trimspaces}
\usepackage{listofitems}
\tcbuselibrary{skins,breakable}
%
\makeatletter
\newcommand{\trim}[1]{\trim@spaces@noexp{#1}}
\newlength{\mhl@spacelen}
\settowidth{\mhl@spacelen}{\ }
\def\mhl@space{\kern\mhl@spacelen}
\def\mhl@backspace{\kern-1.1\mhl@spacelen}
%
\newcommand{\mhl@int}[1]{%
\mhl@backspace%
\tcbox[tcbox raise base,
left=0mm,right=0mm,top=0mm,bottom=0mm,boxsep=0pt,arc=0mm,boxrule=0pt,
opacityfill=0.3,enhanced jigsaw,colback=gray!85!white,
before=\relax,after=\relax]{\trim{#1}}
}
%
\newcommand{\mhl}[1]{%
\setsepchar{ }
\ignoreemptyitems
\readlist\phrase{#1}
\foreachitem\mot\in\phrase{\mhl@int{\strut\mot\mhl@space}}
}
%
\makeatother
%
\begin{document}
I say \mhl{Hello World}! This box has a no \mhl{defined \mhl{height}} 
as you can see. The total colored \mhl{box is shrunk to 
the\mhl{dimensions} of the upper part. \mhl{There} should be 
no lower part and no title.}
\end{document}

新结果: 在此处输入图片描述

进一步的改进可能会使用递归调用来mhl跟踪级别,以摆脱一些额外的空格,并将可破坏性推入嵌套的突出显示的句子中。

编辑:完整解决方案

经过一段时间,我终于得到了这个问题的完整解决方案。它仍然依赖于tcolorbox为背景着色并使用解析文本listofitems。由于嵌套tcolorbox不可破坏,因此程序循环处理句子,逐字突出显示,跟踪级别,并尽可能小心地处理空格。

这是 MWE(抱歉,是法语单词,phrase=sentence,mot=word):

\documentclass{standalone}
\usepackage{listofitems}
\usepackage{xstring}
\usepackage{tcolorbox}
\tcbuselibrary{skins,breakable,xparse}
%
\makeatletter
\newlength{\mhl@spacelen}
\settowidth{\mhl@spacelen}{\space}
\def\mhl@space{\hspace*{\mhl@spacelen}}
\def\mhl@sep{\hspace{\z@}}
\newcounter{nesthl}
\newif\ifmhlstart \mhlstartfalse
\newif\ifmhlend \mhlendfalse
%

\newcommand{\mhl@int}[2]{%
\ifcase#1\def\col{black!10!white}\or\def\col{black!10!white}\or\def\col{black!50!white}\or\def\col{black!85!white}\fi%
\tcbox[tcbox raise base, spartan, left=0mm,right=0mm,top=0mm,bottom=0mm,boxsep=0pt,arc=0mm,
boxrule=0pt,before=\relax,after=\relax, opacityfill=0.35,colback=\col
]{\strut #2}}

\newcommand{\mhl}[1]{%
\setcounter{nesthl}{1}%
\def\beforeskip{}%
\setsepchar{ }\ignoreemptyitems\readlist*\phrase{#1}%
\foreachitem\mot\in\phrase{%
    \IfBeginWith{\mot}{+}{\mhlstarttrue}{\mhlstartfalse}%
    \IfEndWith{\mot}{+}{\mhlendtrue}{\mhlendfalse}%
    \ifmhlstart \StrBehind{\mot}{+}[\nmot]\else\edef\nmot{\mot}\fi%
    \ifmhlend\StrBefore{\nmot}{+}[\nnmot]\else\edef\nnmot{\nmot}\fi%
    \ifmhlstart\addtocounter{nesthl}{1}\fi%
    \ifmhlend \ifnum\thenesthl>1 \def\beforeskip{\mhl@space}\fi
    \mhl@int{\thenesthl}{\nnmot}\mhl@sep\addtocounter{nesthl}{-1}%
    \else\mhl@int{\thenesthl}{\beforeskip\nnmot\mhl@space}\mhl@sep\def\beforeskip{}\fi%
    }
}
\makeatother

\begin{document}
\framebox{
\begin{minipage}{3.7cm}
here is a  \mhl{weird nested, +wrappable, +dummy blob+ and nice+} text
\end{minipage}
}
\end{document}

结果: 在此处输入图片描述

此解决方案的关键思想在于不使用\mhl会阻止换行的嵌套命令,而是在命令中使用简单的类似 wiki 的标记\mhl,即+*如果 、 和可能的标点符号未启用,它也可以使用)。以 开头的单词+(无空格)会初始化一个新级别,以 结尾的单词会+关闭此级别。 的数量+必须是偶数,并且它们的相对位置很重要。

最大嵌套深度实际上没有限制,但要使用比这里使用的 3 级更大的深度,就必须修改宏\mhl@int以扩大可用的阴影数量(第一行)以及opacityfill盒子的参数。

相关内容