11

This is a follow-up question to Mixing underline and strike-out. This time, I'm specifically interested in an implementation using soul (that doesn't require multiple compilations to stabilize).

I would like to use soul to create an (underline) + (strike-through) command \textulst that would combine \textul with \textst and still allow line-breaks within.

Thus far I'm unable to properly combine the two, as soul uses the same underlining for both the (regular) underline and the strike-through.

Here's my (unsuccessful) attempt at generating \textulst:

enter image description here

\documentclass{article}
\usepackage{soul}

\makeatletter
\def\SOUL@ulstunderline#1{{%
    \setbox\z@\hbox{#1}%
    \dimen@=\wd\z@
    \dimen@i=\SOUL@uloverlap
    \advance\dimen@2\dimen@i
    \rlap{% Draw underline
        \null
        \kern-\dimen@i
        \SOUL@ulcolor{\SOUL@ulleaders\hskip\dimen@}%
    }%
    \SOUL@stpreamble% Switch to draw over-strike
    \rlap{%
        \null
        \kern-\dimen@i
        \SOUL@ulcolor{\SOUL@ulleaders\hskip\dimen@}%
    }%
    \unhcopy\z@
}}
\def\SOUL@ulsteverysyllable{%
    \SOUL@ulstunderline{%
        \the\SOUL@syllable
        \SOUL@setkern\SOUL@charkern
    }%
}
\def\SOUL@ulstsetup{%
  \SOUL@ulsetup
  \let\SOUL@everysyllable\SOUL@ulsteverysyllable
}
\DeclareRobustCommand*\textulst{\SOUL@ulstsetup\SOUL@}

\makeatletter

\begin{document}
Here is \textul{some text}.

Here is \textst{some text}.

Here is \textulst{some text}.
\end{document}
2
  • What is the difference between underlining and striking text the usual way and using packages like soul and censor ? May 17, 2014 at 12:42
  • @subhamsoni: As mentioned in Mixing underline and strike-out, soul cannot handle nesting. Also, as mentioned below, censor does not handle hyphenation properly. The solution proposed in the linked question in awesome (and uses tikz, but requires multiple compiles (even first time around) to settle the references.
    – Werner
    May 17, 2014 at 13:52

2 Answers 2

5

Here's a solution based on soul:

\documentclass{article}
\usepackage{soul}

\makeatletter
\newdimen\SOUL@ulstdp
\newdimen\SOUL@ulstht
\def\SOUL@ulstleaders{%
    \leaders
    \hbox
    {%
      \rlap{\vrule\@depth\SOUL@uldp\@height\SOUL@ulht\@width.1pt\relax}%
      \vrule\@depth\SOUL@ulstdp\@height\SOUL@ulstht\@width.1pt\relax
    }%
}
\def\SOUL@ulstpreamble{%
  \SOUL@ulpreamble
  \SOUL@ulstdp=\SOUL@uldp
  \SOUL@ulstht=\SOUL@ulht
  \SOUL@stpreamble
}
\def\SOUL@ulstsetup{%
  \SOUL@ulsetup
  \let\SOUL@preamble\SOUL@ulstpreamble
  \let\SOUL@ulleaders\SOUL@ulstleaders
}
\DeclareRobustCommand*\textulst{\SOUL@ulstsetup\SOUL@}

\makeatletter

\begin{document}
Here is \textul{some text}.

Here is \textst{some text}.

Here is \textulst{some text}.
\end{document}

example output

It's based on the idea of "stacking" two rules immediately in the \leaders construction soul uses to overlay a rule. I wouldn't know how else to get two rules as soul relies heavily on \leaders especially to support stretching interword space.

The downside is that when using \leaders with a rule (as usual for \ul, \st, and \hl), the rule will just stretch as far as the dimension given as the leader length, while when using a box, the rule needs to have a predefined width, which then becomes the minimal length of the leaders construct. The box is then replicated as often as neccessary to span the given width.

I have used .1pt as the box width. That means, if soul tries to span something shorter than .1pt there will be a gap in the underline. On the other hand, using a narrower box will substantially enlarge execution time and file size.

5

I realize that this doesn't answer your question because it is not with soul, but rather this shows an alternative, using censor, based on several of my similar previous answers:

\documentclass{article}
\usepackage{censor}
\usepackage{stackengine}
\usepackage{xcolor}
\usepackage{scalerel}
\newlength\uldepth
\newlength\rlwd
\def\ulcolor{black}
\rlwd=.8pt
\censorruledepth=2.5pt
\uldepth=-2pt

\makeatletter
\def\stacktype{L}
\periodrlap=0pt\relax
\afterperiodlap=0pt\relax
\lletterlap=0pt\relax
\rletterlap=0pt\relax
\afterspacelap=1.0ex\relax

\renewcommand\censorrule[1]{%
\protect\textcolor{\ulcolor}{\stackon[0pt]%
  {\rule[\uldepth]{#1}{\rlwd}}{\rule[\censorruledepth]{#1}{\rlwd}}}%
}

\renewcommand\@cenword[1]{%
  \setbox0=\hbox{#1}%
  \stackon[0pt]{#1}{\censorrule{\wd0}}%
}

\def\censordot{\textcolor{\ulcolor}{\rlap{\@cenword{\phantom{.}}}}.}

\makeatother
\parindent 0in
\parskip 1em
\begin{document}

This shows linebreaking capability: aaa aaa aaa aaa aaa aaa aaa
\xblackout{bbb bbb bbb bbb. bbb bbb bbb bbb bbb bbb}
ccc ccc ccc ccc ccc ccc

Can this \xblackout{procedure go across paragraphs boundaries?

Why yes} it can.![enter image description here][1]

But gaps can arise if glue is stretched too far.

\afterspacelap=1.7ex\relax
\xblackout{%
This tests marking a multiline block of text.  This tests marking a multiline block of text.
This tests marking a multiline block of text.  This tests marking a multiline block of text.
This tests marking a multiline block of text.}

\end{document}

enter image description here

2
  • Does this support hyphenation? May 17, 2014 at 11:53
  • @StephanLehmke No, the censor package algorithm does not support hyphenation. May 17, 2014 at 12:27

You must log in to answer this question.

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