[Tex/LaTex] Follow-up: Underline + strike-through using soul

formattingsoultext-decorations

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}

Best Answer

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.