4

I naively thought that this would be a simple fix for highlighting text -- yes, there are ulem.sty and soul.sty but they impose some restrictions with which I would prefer not to deal.

I assumed it would be useful to use something like tikzmarks. And so it is, except that the shading rectangles, though to all appearances on a background layer, actually overprint the text they should be highlighting.

Can this work? What have I missed? (Using TexLive2022, updated yesterday with Aquamacs/Skim). I should point out that this will always be used on a single page.

\documentclass{article}

\usepackage[papersize={5.5in,8.5in},margin=0.6in]{geometry}
\usepackage{tikzpagenodes}

\usetikzlibrary{backgrounds}

%% |=====8><-----| %%

\newcounter{shadenum}

\NewDocumentCommand{\btshadepar}{}{%
    \stepcounter{shadenum}%
    \leavevmode
    \begin{tikzpicture}[remember picture,overlay]
        \node[inner sep=0pt](bps-\theshadenum){\strut};
    \end{tikzpicture}%
}%

\NewDocumentCommand{\etshadepar}{}{%
    \begin{tikzpicture}[remember picture,overlay]
    \node[inner sep=0pt,outer sep=-3pt](eps-\theshadenum){\strut};
    \begin{scope}{on background layer}
        \fill[yellow!20] ([yshift=3pt]bps-\theshadenum.north) rectangle
            (bps-\theshadenum.south -| current page text area.east);% first line
        \fill[yellow!20] ([yshift=3pt]eps-\theshadenum.north) rectangle
            (eps-\theshadenum.south -| current page text area.west);% last line
        \fill[yellow!20] ([yshift=3pt]bps-\theshadenum.south -| current page text area.west) rectangle
            (eps-\theshadenum.north -| current page text area.east);% body of paragraph
    \end{scope}
    \end{tikzpicture}%
}%

\begin{document}

\thispagestyle{empty}

This is a gigantic paragraph that means \emph{absolutely} nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a \tikz{\draw[fill=red] (0,0) rectangle (1ex,1ex);} gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. \[x^2+y^2=z^2\] This is a \textbf{gigantic} paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all.

\btshadepar This is a gigantic paragraph that means \emph{absolutely} nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a \tikz{\draw[fill=red] (0,0) rectangle (1ex,1ex);} gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. \[x^2+y^2=z^2\] This is a \textbf{gigantic} paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all.\etshadepar

\end{document}

updated screenshot

Update

I've altered the text to indicate the general sort of issues with which the code must cope (display math, a small tikz object). All of the replies thus far (@samcarter_is_at_topanswers.xyz and @Qrrbrbirlbel) cope perfectly with this.

0

3 Answers 3

3

Instead of trying to put your tikzpicture into the background, you can leave it on top of the text and change the blend mode so that the text is still visible:

\documentclass{article}

\usepackage[papersize={5.5in,8.5in},margin=0.6in]{geometry}
\usepackage{tikzpagenodes}

\usetikzlibrary{backgrounds}

%% |=====8><-----| %%

\newcounter{shadenum}

\NewDocumentCommand{\btshadepar}{}{%
    \stepcounter{shadenum}%
    \leavevmode
    \begin{tikzpicture}[remember picture,overlay]
        \node[inner sep=0pt](bps-\theshadenum){\strut};
    \end{tikzpicture}%
}%

\NewDocumentCommand{\etshadepar}{}{%
    \begin{tikzpicture}[remember picture,overlay,blend mode=multiply]
    \node[inner sep=0pt,outer sep=-3pt](eps-\theshadenum){\strut};
        \fill[yellow!20] ([yshift=3pt]bps-\theshadenum.north) rectangle
            (bps-\theshadenum.south -| current page text area.east);% first line
        \fill[yellow!20] ([yshift=3pt]eps-\theshadenum.north) rectangle
            (eps-\theshadenum.south -| current page text area.west);% last line
        \fill[yellow!20] ([yshift=3pt]bps-\theshadenum.south -| current page text area.west) rectangle
            (eps-\theshadenum.north -| current page text area.east);% body of paragraph
    \end{tikzpicture}%
}%

\begin{document}

\thispagestyle{empty}

This is a gigantic paragraph that means \emph{absolutely} nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a \textbf{gigantic} paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all.

\btshadepar This is a gigantic paragraph that means \emph{absolutely} nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a \textbf{gigantic} paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all.\etshadepar

\end{document}

enter image description here

3
  • But there does seem to be something going on at the bottom of the first line and top of the last, like double highlighting
    – Chris H
    Dec 12, 2022 at 14:08
  • 1
    @ChrisH might be an artifact in converting to png. I don't see it in the pdf. Uploaded a screenshot instead of the png Dec 12, 2022 at 14:11
  • 1
    @ChrisH Yes, some artifacts from my first attempt at this which I did not notice at first -- well spotted. Easily fixed.
    – sgmoye
    Dec 12, 2022 at 14:22
6

The PGF layers only apply for the picture itself which is still put on top of the text (because you draw it at the end).

Then let's draw it before the text. And here, the tikzmark library indeed offers the helpful macro

\iftikzmark{<name>}{<true>}{<false>}

with which you can test whether <name> already exists (i.e. not on the first compilation run) and then executes the appropriate argument.

The library also provides \iftikzmarkoncurrentpage if you want to check whether the ending is maybe on another page after all …

Here I'm using only on mark at the end of the paragraph, at the start is no mark necessary we can just draw from (0, 0) directly. A \pgfmark is all that is needed because we don't do anything with this mark but to save its position. It's a bit less overhead then.

Since a \strut more or less inserts an invisible rule of height .7\baselineskip and depth .3\baselineskip I'm using this values directly in my answer. Obviously if you're using a different font (size) at the start than at the end this will not be satisfactory anymore.

Code

\documentclass{article}
\usepackage[papersize={5.5in,8.5in},margin=0.6in]{geometry}
\usepackage{tikzpagenodes}
\usetikzlibrary{tikzmark}

\newcounter{shadenum}
\NewDocumentCommand{\btshadepar}{O{yellow!20}}{%
  \stepcounter{shadenum}%
  \leavevmode
  \iftikzmark{eps-\theshadenum}{%
  \tikz[remember picture,overlay,baseline=0pt]
     \fill[#1] (0,+.7\baselineskip) rectangle
               (0,+-.3\baselineskip-|current page text area.east)
               (0,+-.3\baselineskip-|current page text area.west)
       rectangle ([yshift=+.7\baselineskip]perpendicular cs:
         horizontal line through={(pic cs:eps-\theshadenum)},
         vertical line through={(current page text area.east)})
       coordinate (@)
       (@-|current page text area.west) rectangle
       ([yshift=+-.3\baselineskip]pic cs:eps-\theshadenum);
  }{}%
}
\NewDocumentCommand{\etshadepar}{}{%
    \pgfmark{eps-\theshadenum}}%
\begin{document}
\thispagestyle{empty}

This is a gigantic paragraph that means \emph{absolutely} nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a \textbf{gigantic} paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all.

\btshadepar This is a gigantic paragraph that means \emph{absolutely} nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a \textbf{gigantic} paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all.\etshadepar
\end{document}

Output

enter image description here

2
  • A lot about which to think here. I've used -| and |- though never horizontal/vertical line through. I may have some questions shortly...
    – sgmoye
    Dec 12, 2022 at 14:24
  • @sgmoye They are the same perpendicular cs. One is the explicit version and the other is the implicit version which I had troubles with at that coordinate. The parser didn't like both the options [] and the pic cs:, maybe another set of {} would have helped but at some point it is just easier to write it down explicitly. Dec 12, 2022 at 14:52
1

If you are able to switch to lualatex, you could use the lua-ul package. This package avoids most of the restrictions of similar packages like soul or ulem.

% !TeX TS-program = lualatex

\documentclass{article}

\usepackage[papersize={5.5in,8.5in},margin=0.6in]{geometry}
\usepackage{lua-ul}
\usepackage{tikz}
\usepackage{luacolor}

\begin{document}

This is a gigantic paragraph that means \emph{absolutely} nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a \tikz{\draw[fill=red] (0,0) rectangle (1ex,1ex);} gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. \[x^2+y^2=z^2\] This is a \textbf{gigantic} paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all.

\highLight{ This is a gigantic paragraph that means \emph{absolutely} nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a \tikz{\draw[fill=red] (0,0) rectangle (1ex,1ex);} gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. \[x^2+y^2=z^2\] This is a \textbf{gigantic} paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all. This is a gigantic paragraph that means absolutely nothing at all.}

\end{document}

enter image description here

5
  • Very impressive, and a possibility to remember. Not sure that I am ready to cross over to the Dark Side ;) (LuaLaTeX) but this is really interesting. Thank you.
    – sgmoye
    Dec 12, 2022 at 14:26
  • 2
  • Absolutely wonderful!
    – sgmoye
    Dec 12, 2022 at 14:33
  • ...the cookies are absolutely delicious, can't get enough... ;)
    – sgmoye
    Dec 14, 2022 at 10:28
  • @sgmoye Save some room for the Christmas cookies :) Dec 14, 2022 at 10:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .