Underline just words, not the space between them
Let's make soul
work less:
\documentclass{article}
\usepackage{xparse,soul}
\ExplSyntaxOn
\NewDocumentCommand{\ulns}{m}
{
\seq_set_split:Nnn \l_tmpa_seq { ~ } { #1 }
\seq_map_inline:Nn \l_tmpa_seq { \ul{##1}~ } \unskip
}
\ExplSyntaxOff
\begin{document}
\ulns{The quick brown fox jumped} over the lazy dog.
\end{document}
Basically, the argument is split at spaces; every fragment is fed to \ul
and a space is added. The last one is removed by \unskip
.
Package soul
provides an underlining macro \textul
/\ul
with the same depth. The following example copies the driver to \textulw
/\ulw
and leaves the spaces without underline:
\documentclass{article}
\usepackage{soul}
\makeatletter
\DeclareRobustCommand*{\textulw}{%
\SOUL@ulwsetup
\SOUL@
}
\newcommand*{\SOUL@ulwsetup}{%
\SOUL@setup
\let\SOUL@preamble\SOUL@ulpreamble
\let\SOUL@everysyllable\SOUL@uleverysyllable
% \let\SOUL@everyspace\SOUL@uleveryspace % \SOUL@ulsetup
\let\SOUL@everyhyphen\SOUL@uleveryhyphen
\let\SOUL@everyexhyphen\SOUL@uleveryexhyphen
}
\let\ulw\textulw
\makeatother
\begin{document}
\ulw{The quick brown fox jumped over the lazy dog}.
\end{document}
Here's a LuaLaTeX-based solution. It doesn't require loading the soul
package.
The user macro is called \ulow
-- short for "underline only words". With \ulow
, all non-letter glyphs, and not just whitespace, are exempt from being underlined.
The input is assumed to be UTF8-encoded. (ASCII is a proper subset of UTF8; thus, if your input file is pure ASCII, it's UTF8 automatically.)
If the argument of \ulow
contains letters with descenders (g, j, p, q, or y), the lines below all words will be set with a generous amount of vertical whitespace. Conversely, if no letters with descenders are present, the spacing will be set more tightly. If you want the more generous spacing in all cases, simply replace the five-line if
construct in the lua function with s = unicode.utf8.gsub (s, "(%a+)" , "\\underline{%1\\vphantom{p}}" )
. (Even if you don't know Lua syntax, you may be able to guess that the term %a+
"captures" entire words, where a "word" can be any contiguous groups of uppercase and lowercase letters.)
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Latin Modern Roman} % set main document font
%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function ulow ( s )
if unicode.utf8.find ( s, "[gjpqy]") then -- any letters with descenders?
s = unicode.utf8.gsub (s, "(%a+)" , "\\underline{%1\\vphantom{p}}" )
else
s = unicode.utf8.gsub (s, "(%a+)" , "\\underline{%1}" )
end
return ( tex.sprint ( s ) )
end
\end{luacode}
%% TeX-side code
\newcommand\ulow[1]{\directlua{ ulow ( \luastring {#1} ) }}
\begin{document}
\frenchspacing
\ulow{The quick brown fox jumps over the lazy dog.}
\bigskip
\ulow{El rápido zorro marrón saltó sobre el perro perezoso.}
\bigskip
\ulow{And, but; let: show? that. where (now), èéà äöü ÄÖÜß!}
\end{document}