1

I'm trying to highlight a text with a strikeout word by defining a new command as explained in the docs of ulem. Unfortunately, that moves down the strikeout line a few points, which looks strange compared to non-highlighted text. How to avoid/fix this?

Here is an MWE:

\documentclass{article}
\usepackage{xcolor}
\usepackage{ulem}
\newcommand\hl{\bgroup\markoverwith{\textcolor{yellow}{\rule[-.5ex]{.1pt}{2.5ex}}}\ULon}
\begin{document}
Lorem Ipsum is simply dummy text of the printing \sout{and typesetting} industry.

\hl{Lorem Ipsum is simply dummy text of the printing \sout{and typesetting} industry.}
\end{document}

enter image description here

2 Answers2

1

That's an interesting observation and here comes an overkill answer based on TikZ.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{tikzpagenodes}
\usepackage{ulem}
\newcommand\HighLight{\bgroup\markoverwith{\textcolor{yellow}{\rule[-.5ex]{.1pt}{2.5ex}}}\ULon}

\tikzset{StrikeOut/.style={thick,-}}


\makeatletter
\newcommand{\gettikzxy}[3]{% from https://tex.stackexchange.com/a/58590/121799
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \global\edef#2{\the\pgf@x}%
  \global\edef#3{\the\pgf@y}%
}
\makeatother
\newcommand{\StrikeOut}[2][2pt]{%
\tikz[remember picture,overlay, baseline=(Begin.base)]{%
\node[anchor=base,inner sep=0pt,outer sep=0pt] (Begin) {\strut};}#2%
\tikz[remember picture,overlay, baseline=(End.base)]{%
\node[anchor=base,inner sep=0pt,outer sep=0pt] (End) {\strut};}%
\begin{tikzpicture}[overlay,remember picture]
\gettikzxy{($(Begin.north)-(current page.south west)$)}{\BeginxN}{\BeginyN}
\gettikzxy{($(End.north)-(current page.south west)$)}{\EndxN}{\EndyN}%\typeout{\BeginyN\space\EndyN}
\pgfmathtruncatemacro{\mytest}{\EndyN-\BeginyN}
\ifnum\mytest=0\relax% begin and and in the same line %\typeout{begin and end in the same line}
% \draw[thick,-] ($(Begin.north)-(#1,0)$) -- ($(Begin.south)-(#1,0)$)
% -- ($(End.south)+(#1,0)$) -- ($(End.north)+(#1,0)$) -- cycle;
\draw[StrikeOut] (Begin) -- (End);
\else% \typeout{end below begin}
\path (current page text area.north west) -- (current page text area.south west)
node(WestLine)[left]{};
\path (current page text area.north east) -- (current page text area.south east)
node(EastLine)[right]{};
\gettikzxy{($(End.north)-(current page.south west)$)}{\EndxN}{\EndyN}
\gettikzxy{($(Begin.south)-(current page.south west)$)}{\BeginxS}{\BeginyS}
\pgfmathtruncatemacro{\mytest}{\BeginyS-\EndyN+1pt}% \typeout{\mytest}
\ifnum\mytest<2\relax% \typeout{end in the next line after begin}%
\pgfmathtruncatemacro{\mytest}{\BeginxS-\EndxN}% \typeout{\mytest}
\ifnum\mytest>0\relax
% \draw[thick,-] (Begin.north -| EastLine) -- ($(Begin.north)-(#1,0)$) -- 
% ($(Begin.south)-(#1,0)$) -- (Begin.south -| EastLine);
\draw[StrikeOut] (Begin) -- (Begin -| EastLine);
% \draw[thick,-] (End.south -| WestLine) -- ($(End.south)+(#1,0)$) -- 
% ($(End.north)+(#1,0)$) -- (End.north -| WestLine);
\draw[StrikeOut] (End -| WestLine) -- (End);
\else
% \draw[thick,-] ($(Begin.north)-(#1,0)$) -- ($(Begin.south)-(#1,0)$) -- 
% (Begin.south -| WestLine) -- (End.south -| WestLine)
% -- ($(End.south)+(#1,0)$) -- ($(End.north)+(#1,0)$) -- (End.north -| EastLine)
% -- (Begin.north -| EastLine) -- cycle;
\draw[StrikeOut] (Begin) -- (Begin -| EastLine);
\draw[StrikeOut] (End -| WestLine) -- (End);
\fi
\else
\pgfmathsetmacro{\LineHeight}{\the\baselineskip}
\pgfmathtruncatemacro{\NumLines}{-1+(\BeginyN-\EndyN)/\LineHeight}
\typeout{\NumLines}
\foreach \X in {1,...,\NumLines}
{
\draw[StrikeOut] ($(Begin -| WestLine)+(0,-\X*\LineHeight pt)$) -- 
($(Begin -|EastLine)+(0,-\X*\LineHeight pt)$);
}
\draw[StrikeOut] (Begin) -- (Begin -| EastLine);
\draw[StrikeOut] (End -| WestLine) -- (End);
% \draw[thick,-] ($(Begin.north)-(#1,0)$) -- ($(Begin.south)-(#1,0)$) -- 
% (Begin.south -| WestLine) -- (End.south -| WestLine)
% -- ($(End.south)+(#1,0)$) -- ($(End.north)+(#1,0)$) -- (End.north -| EastLine)
% -- (Begin.north -| EastLine) -- cycle;
\fi
\fi
\end{tikzpicture}}
\begin{document}

Lorem Ipsum is simply dummy text of the printing \StrikeOut{and typesetting} industry.

\HighLight{Lorem Ipsum is simply dummy text of the printing \StrikeOut{and typesetting} industry.}

Lorem ipsum dolor sit amet, consectetur adipiscing elit. \StrikeOut{Sed a leo ut
erat luctus scelerisque. Suspendisse auctor mauris sit amet fringilla
hendrerit.} Maecenas eu tortor eu diam fringilla scelerisque sit amet eget enim.
Nam vitae bibendum erat, sit amet scelerisque felis. \StrikeOut{Suspendisse placerat
vitae velit pharetra lobortis et marmottae.} Donec ut erat a erat porta aliquet. Nulla eget
augue sem. Proin orci neque, eleifend id eleifend id, venenatis sit amet diam.
\StrikeOut{Mauris lacus est, cursus eget sapien at, pharetra lobortis ante. Proin
tempus ipsum tellus, ut ultricies magna congue nec. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse potenti.
In posuere dapibus urna, vitae euismod magna iaculis at.} Pellentesque pretium,
lorem ut vehicula egestas, velit dolor porta nunc, id interdum ipsum purus vel
dolor.

\end{document}

enter image description here

This workaround has all sorts of drawbacks, such as the inability to deal with page breaks and that does not work when the height of the line changes inside the \StrikeOut argument. The code is based on this post. I'm only posting it here because I wanted to convince myself that it can be done in principle while not destroying the hyphenation.

  • Thank you for your answer. I've used the same command name as provided by the soul package, because before I've used the soul package, too and switched between various versions without having to change my whole document. It is simply for testing purposes/MWE. Unfortunately, \hl or \texthl from the soul package is not compatible with the changes package (which uses ulem), because the highlighting stops as soon as text or character is marked (striked/exed out, underlined, etc.). – Mathias Walter Jan 23 '18 at 07:21
  • My main aim is to get highlighting of some changes or part of changes working. I'm aware of the solution provided in Changes package - highlight and strikethrough but I don't want to replace strikethrough by highlighting and I don't want to have the drawbacks you mentioned above. – Mathias Walter Jan 23 '18 at 07:29
  • I just recognized that the original \sout isn't linebreakable either inside of \hl. I don't know however for which reason that is. – Skillmon Jan 23 '18 at 19:07
  • @Skillmon I thought it never is, i.e. even outside \hl, at least according to this post: "The one big reason in favor of soul, however, is that it's able to deal with line breaks and hyphenation:" –  Jan 23 '18 at 19:16
  • Line breaking does work (at least in between words) using \sout outside of \hl. But no hyphenation it seems. – Skillmon Jan 23 '18 at 19:19
  • @Skillmon Yes, you're right. I was not precise. I was also thinking to use these tricks in order to write a line- and word-breakable strike through in TikZ, but I am not sure if that would just be "reinventing the wheel". –  Jan 23 '18 at 19:22
  • @marmot please go ahead. I'm personally interested in this as I encountered a use case where soul doesn't work but ulem does with the restriction of no automatic hyphenation and perhaps your TikZ solution would work, too. – Skillmon Jan 23 '18 at 21:30
  • @marmot I tried to implement the stuff you provided there with underlining. The code works well outside of \hl. But inside of it, line breaking doesn't work with it (maybe my fault?!). – Skillmon Jan 24 '18 at 16:19
  • @Skillmon I can't say much because I don't see your code. I plan to write up what I'm thinking over the weekend. –  Jan 24 '18 at 16:32
  • @marmot of course you can't. And the issues with page breaks remain, too. I don't know what you intend to write up, I just wanted to warn you that it might not work out. – Skillmon Jan 25 '18 at 10:44
  • I think there is no need for \LineHeight. TikZ should understand \baselineskip. – Skillmon Jan 26 '18 at 08:53
  • Line wrapping (overfull boxes) of \StrikeOut inside \HighLight doesn't work this way. I warned you beforehand that it might not work :) – Skillmon Jan 26 '18 at 08:55
  • @Skillmon Ah, I misinterpreted what you said. BTW, if one does the highlights with the \BoxMe thingy, it will work. –  Jan 26 '18 at 13:50
1

You could let \hl redefine the \sout marco (the space in the name is important).

\documentclass{article}
\usepackage{xcolor}
\usepackage{ulem}
\newcommand\hl{%
  \bgroup
  \expandafter\def\csname sout\space\endcsname{\bgroup \ULdepth =-.8ex \ULset}%
  \markoverwith{\textcolor{yellow}{\rule[-.5ex]{.1pt}{2.5ex}}}%
  \ULon}
\begin{document}
Lorem Ipsum is simply dummy text of the printing \sout{and typesetting} industry.

\hl{Lorem Ipsum is simply dummy text of the printing \sout{and typesetting} industry.}

Lorem Ipsum is simply dummy text of the printing \sout{and typesetting} industry.
\end{document}

enter image description here


EDIT: thanks to muzimuzhiZ for letting me know that the above became outdated.

If you're using a newer version of ulem starting from 2019-11-28, the \sout macro isn't changed by the above, since it is now defined as \protected\def\sout{...} instead. You can use the following then:

\documentclass{article}
\usepackage{xcolor}
\usepackage{ulem}
\makeatletter
\newcommand\hl{%
  \bgroup
  \UL@protected\def\sout{\bgroup \ULdepth =-.8ex \ULset}%
  \markoverwith{\textcolor{yellow}{\rule[-.5ex]{.1pt}{2.5ex}}}%
  \ULon}
\makeatother
\begin{document}
Lorem Ipsum is simply dummy text of the printing \sout{and typesetting} industry.

\hl{Lorem Ipsum is simply dummy text of the printing \sout{and typesetting} industry.}

Lorem Ipsum is simply dummy text of the printing \sout{and typesetting} industry.
\end{document}
Skillmon
  • 60,462
  • Unfortunately, highlighting across line breaks won't work:

    `This is \hl{a new paragraph.

    And so} is this.`

    Could https://tex.stackexchange.com/a/247009/153215 solve this problem, too?

    – Mathias Walter Jan 25 '18 at 10:13
  • @MathiasWalter you could try. It looks good, but I won't test this myself. – Skillmon Jan 25 '18 at 10:38
  • I've tried this with the mentiond wrapper command and it works. I wonder if it's possible to integrate it into your solution. I don't have much experience in writing tex macros and stuck on the paratmeter #1. – Mathias Walter Jan 25 '18 at 10:42
  • My answer does redefine an internal command of the ulem package locally. Just using the code there with replacing every occurence of xout with hl should work (untested). – Skillmon Jan 25 '18 at 10:47
  • yes, this works. I just wanted to avoid introducing two additional commands (parhelp and hlpars which wraps your solution with helpcmd/parhelp). But anyway, it works. Thanks! – Mathias Walter Jan 25 '18 at 10:51
  • One additional problem arose in combination with chapter titles. If a chapter spans multiple pages, the chapter title is printed in the header - including the highlighted part. How can I avoid this? I tried \let\MakeUppercase=\relax. But then I get the LaTeX Error: "Not in outer par mode." – Mathias Walter Feb 05 '18 at 18:46
  • Found the answer myself: I used the optional argument of \chapter with the unmodified/undecorated text. – Mathias Walter Feb 05 '18 at 21:41
  • From ulem 2019/11/18, \sout is defined directly by \protected\def, so the \expandafter\def\csname sout\space\endcsname part should be changed to \UL@protected\def. The detailed changes of ulem 2019/11/18 can been seen here. – muzimuzhi Z Feb 28 '20 at 14:25