3

This is a follow up question from Box highlighting of text with rounded corners (soul-based). The desired end result is a sort of "circled text", as one would do if annotating a text with a pencil.

I answered that question myself, based on Antal Spector-Zabusky's approach in Cool Text Highlighting in LaTeX. The result is cool enough, but one important limitation is that it does not allow for page breaks. It doesn't because the approach relies on soul for providing coordinates and lets tikz do all the drawing. That was needed in Antal's answer because the desired irregularity of the path, to make sense in a drawing, depended on the decorations from tikz.

Well, I'm looking for something "less cool" and would be satisfied with straight lines above and below the text. And for that, I could rely on soul rather than tikz to draw them, thus retaining page breaking capabilities. And then, use tikz to draw the corners only.

I started from the same idea, but tried it from scratch, based on the soul driver for \ul. The code below gets close, but not quite. I cannot convince \SOUL@everyspace to draw the line above as well.

The crux of the matter seems to lie in:

\def\SOUL@tceveryspace#1{%
  \SOUL@ulcolor{
    #1%
    \SOUL@tcleaders
    \hskip\spaceskip
  }%
  \null
}

where \SOUL@tcleaders does the actual drawing with an \hrule:

\def\SOUL@tcleaders{%
  \leaders\hrule\@depth\SOUL@tcdp\@height\SOUL@tcht\relax
}

Is there a way to draw both (bottom and top) hrules in this step?

The full code is:

\documentclass[12pt]{scrartcl}
\usepackage{soulutf8}
\usepackage{tikz}

\usetikzlibrary{calc,decorations.pathmorphing}

\newlength\LineWidth
\setlength\LineWidth{1pt}

\newlength\baseliney
\setlength\baseliney{.45ex}

\newlength\heighty

\newcommand\opac{0.35}

\colorlet{HLcolor}{gray}

\setul{.325ex}{\LineWidth}
\colorlet{ulcolor}{gray!35}
\setulcolor{ulcolor}

\makeatletter

\newdimen\SOUL@tcdp
\newdimen\SOUL@tcht
\newdimen\SOUL@tchdp
\newdimen\SOUL@tchht

\def\SOUL@tcleaders{%
  \leaders\hrule\@depth\SOUL@tcdp\@height\SOUL@tcht\relax
}
\def\SOUL@tcheaders{%
  \leaders\hrule\@depth\SOUL@tchdp\@height\SOUL@tchht\relax
}

\def\SOUL@tcunderline#1{{%
    \setbox\z@\hbox{#1}%
    \dimen@=\wd\z@
    \dimen@i=\SOUL@uloverlap
    \advance\dimen@2\dimen@i
    \rlap{%
      \null
      \kern-\dimen@i
      \SOUL@ulcolor{\SOUL@tcleaders\hskip\dimen@}%
    }%
    \rlap{%
      \null
      \kern-\dimen@i
      \SOUL@ulcolor{\SOUL@tcheaders\hskip\dimen@}%
    }%
    \unhcopy\z@
  }}

\def\SOUL@tcpreamble{%
  \setlength{\heighty}{\f@size pt}%
  \SOUL@tcdp=\SOUL@uldepth
  \SOUL@tcht=-\SOUL@tcdp
  \advance\SOUL@tcdp\SOUL@ulthickness
  \SOUL@tchdp=-\heighty
  \advance\SOUL@tchdp\SOUL@tcdp
  \advance\SOUL@tchdp-\SOUL@ulthickness
  \SOUL@tchht=-\SOUL@tchdp
  \advance\SOUL@tchdp\SOUL@ulthickness
  \spaceskip\SOUL@spaceskip
  \begin{tikzpicture}[decoration={bent,aspect=.3}, overlay]
    \draw[decorate,HLcolor,line width=\LineWidth,opacity=\opac]  ($(0,-\baseliney)$) -- ($(0,-\baseliney+\heighty)$) ;
  \end{tikzpicture}%
}
\def\SOUL@tceverysyllable{%
  \SOUL@tcunderline{%
    \the\SOUL@syllable
    \SOUL@setkern\SOUL@charkern
  }%
}
\def\SOUL@tceveryspace#1{%
  \SOUL@ulcolor{
    #1%
    \SOUL@tcleaders
    \hskip\spaceskip
  }%
  \null
}
\def\SOUL@tceveryhyphen{%
  \discretionary{%
    \unkern
    \SOUL@tcunderline{%
      \SOUL@setkern\SOUL@hyphkern
      \SOUL@sethyphenchar
    }%
  }{}{}%
}
\def\SOUL@tceveryexhyphen#1{%
  \SOUL@setkern\SOUL@hyphkern
  \SOUL@tcunderline{#1}%
  \discretionary{}{}{%
    \SOUL@setkern\SOUL@charkern
  }%
}
\def\SOUL@tcpostamble{%
  \begin{tikzpicture}[decoration={bent,aspect=.3}, overlay]
    \draw[decorate,HLcolor,line width=\LineWidth,opacity=\opac]  ($(0,-\baseliney+\heighty)$) -- ($(0,-\baseliney)$) ;
  \end{tikzpicture}%
}
\def\SOUL@tcsetup{%
  \SOUL@setup
  \let\SOUL@preamble\SOUL@tcpreamble
  \let\SOUL@everysyllable\SOUL@tceverysyllable
  \let\SOUL@everyspace\SOUL@tceveryspace
  \let\SOUL@everyhyphen\SOUL@tceveryhyphen
  \let\SOUL@everyexhyphen\SOUL@tceveryexhyphen
  \let\SOUL@postamble\SOUL@tcpostamble
}
\DeclareRobustCommand*\textcirc{\SOUL@tcsetup\SOUL@}

\makeatother


\begin{document}

\vspace*{15cm}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus
elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur
dictum gravida mauris. \textcirc{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. Curabitur auctor semper nulla. \textcirc{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,
\textcirc{fringilla a, euismod sodales, sollicitudin vel}, wisi. Morbi
auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae,
ultricies et, tellus. \textcirc{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. \ul{Pellentesque a nulla.} \textcirc{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 thus far is:

enter image description here

enter image description here

That is, everything is in place, except the lines above the spaces. Any ideas on how to get them?

7
  • I certainly do not understand you code, but you're saying that you "use tikz to draw the corners only". I am wondering what's wrong with connecting these corners with lines (if you are using TikZ anyway).
    – user121799
    Apr 17, 2018 at 15:42
  • @marmot Well, that's what Antal Spector-Zabusky's answer does, but doesn't allow for page breaks (at least as far as the answer lays). This code is based on the definitions of the soul driver for underlining, I just adapted it.
    – gusbrs
    Apr 17, 2018 at 15:58
  • But can't you just add a line all the way to the boundary of current page text area (tikzpagenode package) in the case of a page break?
    – user121799
    Apr 17, 2018 at 16:27
  • @marmot, Mmh, I'm not sure I grasp your idea. But, if I do, we would have to know beforehand the line at which the page break occurs. Otherwise the coordinates to end of the line would have to be supplied from soul. Antal Spector-Zabusky's approach gets this coordinate syllable by syllable with the help of soul. How could we decide on the fly when not to do it and use instead current page text area? Or am I missing something from your suggestion?
    – gusbrs
    Apr 17, 2018 at 16:41
  • Not necessarily. You could run the line always to either the closing corner or the boundary of current page text area, whatever comes first. One possible way to achieve this is to run a white line from the corners to the boundary of current page text area whenever you issue the closing brackets.
    – user121799
    Apr 17, 2018 at 16:57

1 Answer 1

3

You did all the work already. I only changed \SOUL@tceveryspace (and did not read the rest of the code at all to be honest). The command uses essentially \leaders\hrule\hskip\spaceskip, which means "make a horizontal rule that otherwise behaves like glue of length \spaceskip". In particular that glue allows line breaks and is removed when there is a line break (just like normal spaces do). To have lines above and below, I just used one leader, one negative space to go back to the original place and another leader on top. You can see that everything stretches properly in my first line after \begin{document}.

\documentclass[12pt]{scrartcl}
\usepackage{soulutf8}
\usepackage{tikz}

\usetikzlibrary{calc,decorations.pathmorphing}

\newlength\LineWidth
\setlength\LineWidth{1pt}

\newlength\baseliney
\setlength\baseliney{.45ex}

\newlength\heighty

\newcommand\opac{0.35}

\colorlet{HLcolor}{gray}

\setul{.325ex}{\LineWidth}
\colorlet{ulcolor}{gray!35}
\setulcolor{ulcolor}

\makeatletter

\newdimen\SOUL@tcdp
\newdimen\SOUL@tcht
\newdimen\SOUL@tchdp
\newdimen\SOUL@tchht

\def\SOUL@tcleaders{%
  \leaders\hrule\@depth\SOUL@tcdp\@height\SOUL@tcht\relax
}
\def\SOUL@tcheaders{%
  \leaders\hrule\@depth\SOUL@tchdp\@height\SOUL@tchht\relax
}

\def\SOUL@tcunderline#1{{%
    \setbox\z@\hbox{#1}%
    \dimen@=\wd\z@
    \dimen@i=\SOUL@uloverlap
    \advance\dimen@2\dimen@i
    \rlap{%
      \null
      \kern-\dimen@i
      \SOUL@ulcolor{\SOUL@tcleaders\hskip\dimen@}%
    }%
    \rlap{%
      \null
      \kern-\dimen@i
      \SOUL@ulcolor{\SOUL@tcheaders\hskip\dimen@}%
    }%
    \unhcopy\z@
  }}

\def\SOUL@tcpreamble{%
  \setlength{\heighty}{\f@size pt}%
  \SOUL@tcdp=\SOUL@uldepth
  \SOUL@tcht=-\SOUL@tcdp
  \advance\SOUL@tcdp\SOUL@ulthickness
  \SOUL@tchdp=-\heighty
  \advance\SOUL@tchdp\SOUL@tcdp
  \advance\SOUL@tchdp-\SOUL@ulthickness
  \SOUL@tchht=-\SOUL@tchdp
  \advance\SOUL@tchdp\SOUL@ulthickness
  \spaceskip\SOUL@spaceskip
  \begin{tikzpicture}[decoration={bent,aspect=.3}, overlay]
    \draw[decorate,HLcolor,line width=\LineWidth,opacity=\opac]  ($(0,-\baseliney)$) -- ($(0,-\baseliney+\heighty)$) ;
  \end{tikzpicture}%
}
\def\SOUL@tceverysyllable{%
  \SOUL@tcunderline{%
    \the\SOUL@syllable
    \SOUL@setkern\SOUL@charkern
  }%
}
\def\SOUL@tceveryspace#1{%
  \SOUL@ulcolor{
    #1%
    \SOUL@tcleaders
    \hskip\spaceskip
    \hskip-\spaceskip
    \SOUL@tcheaders
    \hskip\spaceskip
  }%
  \null
}
\def\SOUL@tceveryhyphen{%
  \discretionary{%
    \unkern
    \SOUL@tcunderline{%
      \SOUL@setkern\SOUL@hyphkern
      \SOUL@sethyphenchar
    }%
  }{}{}%
}
\def\SOUL@tceveryexhyphen#1{%
  \SOUL@setkern\SOUL@hyphkern
  \SOUL@tcunderline{#1}%
  \discretionary{}{}{%
    \SOUL@setkern\SOUL@charkern
  }%
}
\def\SOUL@tcpostamble{%
  \begin{tikzpicture}[decoration={bent,aspect=.3}, overlay]
    \draw[decorate,HLcolor,line width=\LineWidth,opacity=\opac]  ($(0,-\baseliney+\heighty)$) -- ($(0,-\baseliney)$) ;
  \end{tikzpicture}%
}
\def\SOUL@tcsetup{%
  \SOUL@setup
  \let\SOUL@preamble\SOUL@tcpreamble
  \let\SOUL@everysyllable\SOUL@tceverysyllable
  \let\SOUL@everyspace\SOUL@tceveryspace
  \let\SOUL@everyhyphen\SOUL@tceveryhyphen
  \let\SOUL@everyexhyphen\SOUL@tceveryexhyphen
  \let\SOUL@postamble\SOUL@tcpostamble
}
\DeclareRobustCommand*\textcirc{\SOUL@tcsetup\SOUL@}

\makeatother


\begin{document}

\vspace*{15cm}

\hbox to 200pt{Lorem ipsum \textcirc{dolor sit} amet}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus
elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur
dictum gravida mauris. \textcirc{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. Curabitur auctor semper nulla. \textcirc{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,
\textcirc{fringilla a, euismod sodales, sollicitudin vel}, wisi. Morbi
auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae,
ultricies et, tellus. \textcirc{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. \ul{Pellentesque a nulla.} \textcirc{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}
3
  • Oh, that's beautiful! Thank you very much! I had tried to retreat with a \kern there, but somehow it didn't work. As I mentioned to marmot in the chat, soul's code is way out of my league, it's no wonder I was stumbling. Thanks!
    – gusbrs
    Apr 18, 2018 at 2:20
  • 1
    \kern, contrarily to \hskip, does not allow breaks, so TeX would treat the combination of a leader, a kern, and a leader as somewhat similar to a space, a letter, and a space. Instead, what I do gives a space, a space, a space, all of which are deleted when there is a line-break. Apr 18, 2018 at 4:40
  • I wouldn't have guessed that... I suppose it's time I start my studies on "The TeX Book", ain't it? :)
    – gusbrs
    Apr 18, 2018 at 10:03

You must log in to answer this question.

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