7

NOTE: I am searching for a LaTeX solution. The ConText code was offered, which is a good answer, but that doesn't fit my purpose.

I want to underline some words in text to show the parts of sentence. As mentioned in the comments, only words, not spaces between them should be underlined. Keeping hyphenation is preferable. Unfortunately, there is no dash-dotted style presented in the ulem package.

Here is the solution using TikZ (taken from Underlining with dash-dotted line)

\documentclass{article}

\usepackage{tikz}
\usepackage{lipsum}

\newcommand{\mydash}[1]{%
\tikz[baseline=(todotted.base)]{
\node[inner sep=1pt,outer sep=0pt] (todotted) {\strut #1};
\draw[dash dot] ([yshift=3pt]todotted.south west) -- ([yshift=3pt]todotted.south east);
\draw[dashed] ([yshift=2pt]todotted.south west) -- ([yshift=2pt]todotted.south east);
}%
}%

\begin{document}

\mydash{doguble line}
\lipsum[2]

\mydash{double line double line double line double line double line double line double line }
\lipsum[2]

\end{document}

No line breaking is allowed, which is bad. I want a solution that will not affect other text (will not widen the vertical space between lines, i. e. the dash-dotted line should have zero height) and will allow linebreaking.

Here Raise or lower \hrulefill some ways to create lines were discussed. egreg provided the following MWE:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\xhrulefill}{O{}}
{
    \group_begin:
    \severin_xhrulefill:n { #1 }
    \group_end:
}

\keys_define:nn { severin/xhrulefill }
{
    height .dim_set:N    = \l_severin_xhrule_height_dim,
    thickness .dim_set:N = \l_severin_xhrule_thickness_dim,
    fill .skip_set:N     = \l_severin_xhrule_fill_skip,
    height .initial:n    = 0pt,
    thickness .initial:n = 0.4pt,
    fill .initial:n      = 0pt plus 1fill,
}

\cs_new_protected:Nn \severin_xhrulefill:n
{
    \keys_set:nn { severin/xhrulefill } { #1 }
    \leavevmode
    \leaders\hrule 
    height \dim_eval:n { \l_severin_xhrule_thickness_dim + \l_severin_xhrule_height_dim }
    depth  \dim_eval:n { -\l_severin_xhrule_height_dim }
    \skip_horizontal:N \l_severin_xhrule_fill_skip
    \kern 0pt
}
\ExplSyntaxOff

\setlength{\textwidth}{6cm} % just for the test

\begin{document}

    abc\hrulefill

    abc\xhrulefill

    abc\xhrulefill[height=-3pt]

    abc\xhrulefill[height=-2pt,thickness=1pt,fill=3cm]

    abc\xhrulefill[height=-3pt,thickness=1pt]

    abx\xhrulefill[height=0pt,thickness=1ex]

\end{document}

I wonder if it can be modified with xparse of expl3 for my needs.

6
  • Is breaking hyphenation acceptable in a solution? Is it OK if the words, but not the inter-word spaces are dot-dashed underlined? Commented Jun 22, 2017 at 19:52
  • I would like the hyphenation to work, but it is not mandatory. I add to the questions that only words should be underlined. Commented Jun 22, 2017 at 19:54
  • Well ulem does provide \dashuline which, as far as I can see, meets most of the requirements (except that it underlines also the spaces). In which respects is it not sufficient for you?
    – gusbrs
    Commented Jun 22, 2017 at 20:19
  • @gusbrs it underlines with dashed line, not dash-dotted. That is the main requirement. Commented Jun 22, 2017 at 20:24
  • If a solution with dash-dotted line, respecting hyphenation, but underlining also the spaces could be found, would this be of interest?
    – gusbrs
    Commented Jun 22, 2017 at 20:29

2 Answers 2

5
+50

This is another TikZ solution (actually a TikZ + soul solution), based in Gonzalo Medina's variation (https://tex.stackexchange.com/a/52336/105447) of Antal Spector-Zabusky's answer (https://tex.stackexchange.com/a/6029/105447) to "Cool Text Highlighting in LaTeX".

It essentially uses soul and some soul internals to supply coordinates to a TikZ drawing (my terms, see Antal's answer for a more detailed and knowledgeable explanation) using remember picture, which will require two compilations to get things in place. Lines are drawn with overlay so typesetting should not be disturbed at all. Linebreaks and hyphenation should work fine, but not pagebreaks. Alas, spaces between words will also be underlined.

\documentclass{article}
\usepackage{soul}
\usepackage{tikz}
\usetikzlibrary{calc}


\newlength\LineWidth
\setlength\LineWidth{0.7pt}

\newlength\baseliney
\setlength\baseliney{-1.5pt}

\colorlet{HLcolor}{black}

\makeatletter

\newcommand\highlight@DoHighlight{%
    \draw[dash dot, HLcolor,line width=\LineWidth,opacity=.5]  ($(begin highlight)+(0,\baseliney)$) -- ($(end highlight)+(0,\baseliney)$) ;
}

\newcommand{\highlight@BeginHighlight}{
    \coordinate (begin highlight) at (0,0) ;
}

\newcommand{\highlight@EndHighlight}{
    \coordinate (end highlight) at (0,0) ;
}

\newdimen\highlight@previous
\newdimen\highlight@current

\DeclareRobustCommand*\dashdotuline[1][]{%
    \tikzset{this highlighter/.style={#1}}%
    \SOUL@setup
    %
    \def\SOUL@preamble{%
        \begin{tikzpicture}[overlay, remember picture]
        \highlight@BeginHighlight
        \highlight@EndHighlight
        \end{tikzpicture}%
    }%
    %
    \def\SOUL@postamble{%
        \begin{tikzpicture}[overlay, remember picture]
        \highlight@EndHighlight
        \highlight@DoHighlight
        \end{tikzpicture}%
    }%
    %
    \def\SOUL@everyhyphen{%
        \discretionary{%
            \SOUL@setkern\SOUL@hyphkern
            \SOUL@sethyphenchar
            \tikz[overlay, remember picture] \highlight@EndHighlight ;%
        }{%
    }{%
    \SOUL@setkern\SOUL@charkern
}%
}%
%
\def\SOUL@everyexhyphen##1{%
    \SOUL@setkern\SOUL@hyphkern
    \hbox{##1}%
    \discretionary{%
        \tikz[overlay, remember picture] \highlight@EndHighlight ;%
    }{%
}{%
\SOUL@setkern\SOUL@charkern
}%
}%
%
\def\SOUL@everysyllable{%
    \begin{tikzpicture}[overlay, remember picture]
    \path let \p0 = (begin highlight), \p1 = (0,0) in \pgfextra
    \global\highlight@previous=\y0
    \global\highlight@current =\y1
    \endpgfextra (0,0) ;
    \ifdim\highlight@current < \highlight@previous
    \highlight@DoHighlight
    \highlight@BeginHighlight
    \fi
    \end{tikzpicture}%
    \the\SOUL@syllable
    \tikz[overlay, remember picture] \highlight@EndHighlight ;%
}%
\SOUL@
}
\makeatother


\begin{document}
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
    vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida
    mauris. \dashdotuline{Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.
        Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus
        et netus et malesuada fames ac turpis egestas.} Mauris ut leo. Cras viverra
    metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus
    eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium
    quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean
    faucibus. Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Cur-
    abitur auctor semper nulla. \dashdotuline{Donec varius orci} eget risus. Duis nibh mi, congue
    eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim
    rutrum.

    Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi \dashdotuline{dashing
    auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae, ultricies et,
    tellus. Donec aliquet, tortor sed accumsan bibendum,} erat ligula aliquet magna,
    vitae ornare odio metus a mi. Morbi ac orci et nisl hendrerit mollis. Suspendisse
    ut massa. Cras nec ante. Pellentesque a nulla. \dashdotuline{Cum sociis natoque penatibus et
        magnis dis parturient montes, nascetur ridiculus mus.} Aliquam tincidunt urna. Nulla ullamcorper vestibulum turpis. Pellentesque cursus luctus mauris.

\end{document}

The result is:

enter image description here

The apparent difference in linewidth is a viewer artifact.

Update: Using egreg's solution in https://tex.stackexchange.com/a/267558/105447, it is also possible to suppress the underline in spaces between words. With:

\ExplSyntaxOn
\NewDocumentCommand{\dashdotulwbyw}{m}
 {
  \seq_set_split:Nnn \l_tmpa_seq { ~ } { #1 }
  \seq_map_inline:Nn \l_tmpa_seq { \dashdotuline{##1}~ } \unskip
 }
\ExplSyntaxOff

This requires \usepackage{xparse} and creates a \dashdotulwbyw which stands for dash-dot-underline-word-by-word. I haven't tried this extensively, but given egreg's explanation of how this works, I don't see a reason why it should not work fine with the previously defined \dashdotuline.

1
  • @cfr, you once asked me for some more. Well, there you go! ;-)
    – gusbrs
    Commented Jun 22, 2017 at 21:41
7

\underdashes and \underdots are available in ConTeXt out-of-the-box. An \underdashdots can be easily made with some MetaFun.

\startuseMPgraphic{rules:under:dashdot}
    draw
        ((0,RuleDepth) -- (RuleWidth,RuleDepth))
        shifted (0,RuleFactor*RuleOffset)
        dashed dashpattern(on RuleFactor/2 off RuleFactor/2 on RuleThickness off RuleFactor/2)
        withpen pencircle scaled RuleThickness
        withcolor RuleColor ;
    setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
\stopuseMPgraphic

\definebar[underdashdot] [undergraphic][mp=rules:under:dashdot]
\definebar[underdashdots][underdashdot][continue=yes]

\starttext

\underdashes{
  \input knuth
}

\underdots{
  \input knuth
}

\underdashdots{
  \input knuth
}

\stoptext

enter image description here

1
  • Unfortunately I am searching for LaTeX solution. Commented Jun 12, 2017 at 18:01

You must log in to answer this question.

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