4

I would like to define a command for highlighting in the following style. enter image description here Some people do this on paper and I would like to mimic that on a particular document. How could I achieve this? I thought of using the package tcolorbox, but I am at a loss as to how to approach it using the package and as it is simple perhaps it could be done without using this package. I would like the command to receive as arguments the colour of the highlighting and the content to be highlighted. I would like this to work with XeLaTeX.

EDIT: I've tested @abcdefg's solution and the following problem arose. enter image description here How can I make the rectangle be always at the same level? It would be nice if it could begin a little bellow the line base and advance up to the middle height of the characters. It would also be nice if the behaviour of the macro were favorable to line breaks.

Tera
  • 97

2 Answers2

7

tcolorbox is arguably one of the most powerful option if you seek extensions later on.

\documentclass{article}
\usepackage{tcolorbox}
\tcbuselibrary{skins}
\usetikzlibrary{calc}
\tcbset{twilight/.style={enhanced,hbox,colback=white,
underlay={\begin{tcbclipinterior}
\fill[#1] let \p1=($(interior.north)-(interior.south)$) in
([yshift={0.5*\y1}]interior.south west) rectangle 
(interior.south east);
\end{tcbclipinterior}}},twilight/.default=purple!50,
tight/.style={on
line,boxsep=0pt,left=#1,right=#1,top=#1,bottom=#1,arc=0pt,boxrule=0pt,colframe=white},
tight/.default=0pt}
\begin{document}

One wishes to highlight \begin{tcolorbox}[tight,twilight] this expression \end{tcolorbox} in a sentence. \end{document}

enter image description here

  • 1
    In this use case it probably seems better to write a macro; something like \halful{<text>}. – Werner Nov 18 '20 at 19:46
  • @Werner You mean something like One wishes to highlight \tcbox[tight,twilight]{this expression} in a sentence.? This already works with the current version of the answer, i.e. it is aready taken care of by tcolorbox which indeed provides users with a macro version. –  Nov 18 '20 at 19:49
  • 1
    Sure. I'm thinking more along the lines of \newcommand{\halful}[1][]{\tcbox[tight,twilight,#1]} (as suggested here, since it provides context in the macro name). – Werner Nov 18 '20 at 19:57
  • @Werner Sure, that works. Note, however, that tcolorbox has the \newtcbox command (see p. 16 of the manual) for this which comes with some additional advanced options, but also allows you to define a macro along the lines you suggest. –  Nov 18 '20 at 20:01
  • E.g. `\newtcbox{\halffull}[1][]{tight,twilight,#1}

    One wishes to highlight \halffull{this expression} in a sentence.`

    –  Nov 18 '20 at 20:05
  • Hi, @abcdefg. Thanks for the answer. I'll edit the question to display an image of a problem that arose. – Tera Nov 18 '20 at 20:41
  • Besides, in the spirit of what @Werner draw attention to, how could a set the \halffull receive also the name of the colour to be used? – Tera Nov 18 '20 at 20:42
  • @Tera This is also already included. `\newtcbox{\halffull}[1][]{tight,twilight,#1,before upper=\strut}

    One wishes to highlight \halffull[twilight=blue!50]{this expression} in a \halffull{sentence}.. I added a\strut` to address the problem in the updated question.

    –  Nov 18 '20 at 20:48
  • \strut will make the box always begin at the lowest level, won't it? as if there was a phantom "p" or other letter which extends downwards. I'm using the font Libertinus and the "tails" of p's and q's are rather long. This makes this fix look rather awkward. I'm searching the tcolorbox package trying to understand how to set the rectangle at a level just above the lowest level. – Tera Nov 18 '20 at 21:24
  • Also, is there a way to make colback transparent instead of white?, for when the page color is not really white. – Tera Nov 18 '20 at 21:24
  • 1
    @Tera Yes, this is all possible. However, as this is an evolving question I stop evolving the answer. It isn't too entertaining for me to get the requirements told afterwards, and I also cannot quite understand why Werner's comment is so much highlighted. In short, I write answers to answer questions in their original form, and I am not interested in playing reputation or other games. –  Nov 19 '20 at 00:46
  • I understand. Perhaps I am to be blamed for not having anticipated some of the issues too be avoided and requirements or not having made them more explicit from the start. Thank you for your answers, they were helpful and I learned from them. – Tera Nov 19 '20 at 03:36
4

Here I use \ooalign to get the rule, and a tokencycle to achieve line breaking (however, hyphenation is lost, which may require sloppypar to remedy, in some cases, such as the MWE).

EDITED to use \discretionary in the \Spacedirective, to avoid hanging spaces when linebreaking.

REEDITED to add some glue to assist with justification.

\documentclass[10pt]{article}
\usepackage{xcolor,tokcycle}
\newlength\replength
\newcommand\ruleht{-1.5pt}% ELEVATION OF RULE
\newcommand\rulewidth{4pt}% THICKNESS OF RULE
\def\rulecolor{purple!30}% COLOR OF RULE
\newcommand\sphl[1]{\sbox0{#1}\ooalign{\makebox[0pt][l]{%
  \smash{\color{\rulecolor}\rule[\ruleht]{\wd0}{\rulewidth}}}\cr#1}}
\newcommand\myul[2]{%
  \resettokcycle
  \Characterdirective{\addcytoks{\nobreak\hspace{0pt minus.6pt}%
    \sphl{##1}}}%
  \Spacedirective{\addcytoks{\nobreak\hspace{0pt minus .6pt}%
    \discretionary{}{}{\sphl{\ }}}}%
  \cytoks{}%
  \def\rulecolor{#1}%
  \tokcyclexpress{#2}%
  \the\cytoks%
}
\begin{document}
\begin{sloppypar}
Now I will try my special underlining \myul{purple!25}{%
This is a test, we will
  see if word wrapping occurs automatically or not
This is a test, we will
  see if word wrapping occurs automatically or not
This is a test, we will
  see if word wrapping occurs automatically or not
This is a test, we will
  see if word wrapping occurs automatically or not
This is a test, we will
  see if word wrapping occurs automatically or not
This is a test, we will
  see if word wrapping occurs automatically or not} back to normal text.
\end{sloppypar}

\noindent\hrulefill \end{document}

enter image description here

  • Hi, @Steven B. Segletes! Thank you for your answer. What did you mean by "line breaks will end on an explicit space". I've checked the rule breaks in this case: The rule is \myul{not\ whole}. It results as The rule is \myul{not} \myul{whole}. – Tera Nov 18 '20 at 21:29
  • 1
    @Tera What I meant was, with my original answer, there would be an underlined empty space hanging off the right end of the line break. Now, as you see, with the \hrulefill added to provide a comparison to the textwidth, the underlined text goes flush up to each (left and right) margins. – Steven B. Segletes Nov 18 '20 at 21:36
  • 1
    @Tera Put another way, at linebreaks, the space should be "eaten", showing neither at the prior line-end nor the new line-start. It was not eaten with the original implementation...with \discretionary, it is now properly eaten at line breaks. – Steven B. Segletes Nov 18 '20 at 21:38
  • Your explanation is very clear! I had interpreted your sentence way wrongly. – Tera Nov 18 '20 at 21:51
  • your solutions works perfectly! I could not however adjust it to produce a command of the type \myul{<color>}{<content to be highlighted>}. I tried changing the definitions of \sphl and \myul to make them receive two arguments but must've made some mistake for the content ended up appearing repeatedly on the pdf. What is the proper way to make \myul receive such two arguments without interfering in the tokcycle mechanism? – Tera Nov 18 '20 at 22:13
  • 1
    @Tera Try this change to the macro: \newcommand\myul[2]{% \resettokcycle \Characterdirective{\addcytoks{\sphl{##1}}}% \Spacedirective{\addcytoks{\discretionary{}{}{\sphl{\ }}}}% \cytoks{}% \def\rulecolor{#1}% \tokcyclexpress{#2}% \the\cytoks% } – Steven B. Segletes Nov 18 '20 at 22:29
  • @Tera I added a further edit, to add some negative glue, which will assist with justification for extended underlining passages. – Steven B. Segletes Nov 19 '20 at 00:47