4

I have a long sentence, where I want different parts of the sentence to have different transparency. The entire sentence should, however, be wrappen within a colorbox:

\documentclass{article}

\usepackage{soul,xcolor}
\usepackage{transparent}
\sethlcolor{red}
\begin{document}

\hl{This is}%
\transparent{0.1}{\hl{\strut a great sentence. }}%
\transparent{0.5}{\hl{\strut a great sentence}}

\end{document}

Technicallly this works, but in the PDF I see some vertical red lines:

enter image description here

What are these artefacts and can they be removed?


EDIT: Is it possible to only make the colorbox transparent, and not the text itself?

  • 1
    My guess is the artifacts are related to glue and kerning gaps. My guess is they cannot be removed using the current technique (\hl + transparency). I'll await other wiser comments. Let me ask though, is this really what you want it to look like (other than the artifacts)? – Steven B. Segletes Jul 25 '18 at 11:38
  • @StevenB.Segletes Thanks. Ideally I only want the color to vary in transparency, the text should not vary – N08 Jul 25 '18 at 11:44
  • 1
    To follow up on your comment, against a white-page background, the change in transparency color of the colorbox is indistinguishable from a color change to the colorbox. Is there actually a need for transparency per se, or would a simple color change to the box be sufficient? – Steven B. Segletes Jul 25 '18 at 11:49
  • 1
    @StevenB.Segletes In that case a color change would do just fine – N08 Jul 25 '18 at 11:49
8

In the comments with the OP, it would appear that transparency was just the means, but not the ends of the question. I propose merely using different colorbox colors as the means. It does not have the adverse affect of changing the text blackness, and eliminates the artifacts.

Now if linebreaking is needed, something more will be required.

\documentclass{article}
\usepackage{xcolor}
\begin{document}
\fboxsep=0pt\relax
\colorbox{red}{\strut This is }%
\colorbox{red!50}{\strut a great sentence. }%
\colorbox{red!10}{\strut a great sentence}
\end{document}

enter image description here

For the issue of line breaking, a method can be used to parse the argument in search of interword spaces and allow a break between words. However, inside a box, no glue will be added (and hyphenation will not work). So such a method really only makes sense with \raggedright (or \sloppy) set. See ADDENDUM below for how to tackle full justification.

\documentclass{article}
\usepackage[showframe,pass]{geometry}% ONLY USED TO SHOW MARGINS
\usepackage{xcolor}
\newcommand\bcolorbox[2]{\bcbaux{#1}#2 \endbcb}
\def\bcbaux#1#2 #3\endbcb{%
  \colorbox{#1}{\strut#2}%
  \ifx\relax#3\relax\def\next{}\else%
    \colorbox{#1}{ \strut}%
    \allowbreak%
    \def\next{\bcbaux{#1}#3\endbcb}%
  \fi%
  \next%
}
\begin{document}
\raggedright
\fboxsep=0pt\relax
\bcolorbox{red}{This is }%
\bcolorbox{red!50}{a great sentence. }%
\bcolorbox{red!10}{a great sentence...}%
\bcolorbox{red!30}{Now we can test for the ability to line break. }%
\bcolorbox{blue!20}{Will this ability to break lines continue
  as I continue in several such boxes?}
\end{document}

enter image description here

ADDENDUM

Looking into making the above linebreaking solution work with full justification, I realized that instead of adding the interword space as a \colorbox (which does not stretch), I could add it as a soul highlight (\hl), which does glue-stretch.

The first problem was that the soul \hl macro is of a different height than \baselineskip I found two references, make soul highlight span lines and How to customize the highlight height with soul, which showed how to adjust that.

And it almost worked out of the box, except that the strut-sized boxes of \colorbox and \hl were vertically offset by a small amount (I found this very strange and unexpected...it would seem that the first argument to \setul has no effect, at least in my preamble change to \SOUL@hlpreamble).

Originally, I was able to compensate for this strange behavior with two kludges:

  1. Instead of adding a \strut to the \colorbox, I had to add a slightly shifted \mystrut to the box.

  2. I had to \smash the \colorbox, because it's unusual shift now stretched the line spacing.

However, I since have discovered it as a bug in soul and found the way to workaround it. The cited references above advocate editing \SOUL@hlpreamble to reset the dimensions of the highlight via \setul. However, the first of those dimensions passed to \setul, the depth, is immediately destroyed by the invocation of \SOUL@stpreamble.

So my 2nd adjustment to soul was to modify \SOUL@stpreamble so as not to reset \SOUL@uldepth. I don't presume that my fix is universal, but it is clearly a bug, since the call to \setul in \SOUL@hlpreamble has no effect on the \SOUL@uldepth, even though it should.

The MWE, demonstrating full justification:

\documentclass{article}
\usepackage[showframe,pass]{geometry}% ONLY USED TO SHOW MARGINS
\usepackage{xcolor,soul}
\newcommand\bcolorbox[2]{\leavevmode\bcbaux{#1}#2 \endbcb}
\def\bcbaux#1#2 #3\endbcb{%
  \colorbox{#1}{\strut#2}%
  \ifx\relax#3\relax\def\next{}\else%
    \sethlcolor{#1}%
    \hl{ }%
    \def\next{\bcbaux{#1}#3\endbcb}%
  \fi%
  \next%
}
\makeatletter
\def\SOUL@hlpreamble{%
    \setul{-\ht\strutbox}{\baselineskip}% 1ST ARGUMENT REPLACED IN \SOUL@stpreamble
    \let\SOUL@stcolor\SOUL@hlcolor
    \SOUL@stpreamble% OVERWRITES 1ST ARGUMENT TO \setul
}
\def\SOUL@stpreamble{%
    \dimen@\SOUL@ulthickness
    \dimen@i=-.5ex
    \advance\dimen@i-.5\dimen@
%    \edef\SOUL@uldepth{\the\dimen@i}% THIS OVERWRITES PRIOR SPECIFIED VALUE
    \let\SOUL@ulcolor\SOUL@stcolor
    \SOUL@ulpreamble
}
\makeatother

\begin{document}

\fboxsep=0pt\relax
\bcolorbox{red}{This is }%
\bcolorbox{red!50}{a great sentence. }%
\bcolorbox{red!10}{a great sentence...}%
\bcolorbox{red!30}{Now we can test for the ability to line break. }%
\bcolorbox{blue!20}{Will this ability to break lines continue
  as I continue in several such boxes?}
\end{document}

enter image description here

  • This is just great! – N08 Jul 25 '18 at 11:59
  • 1
    @N08 My answer mentions the inability to linebreak. I'll see if I can piece something together... – Steven B. Segletes Jul 25 '18 at 14:02
  • 1
    @N08 Please see my edit. – Steven B. Segletes Jul 25 '18 at 14:14
  • 1
    @N08 You are welcome. I just made a small change to handle spaces better...that is, to not artificially insert them at the end of each argument. – Steven B. Segletes Jul 25 '18 at 14:20
  • 1
    @N08 Please see my ADDENDUM if full justification is desirable. – Steven B. Segletes Jul 25 '18 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.