[Tex/LaTex] Line breaks in underlined citations

biblatexsoululem

I've been looking for a solution to automatically highlight citations to the works of a specific author using biblatex, but the question is still unanswered and I'm lacking time at the moment to investigate it myself.

Anyway, I've been doing it manually by underlining the citations I want to highlight (author names are printed in small caps, so I can't just emphasize them). However, this causes overfull lines as the underlining doesn't allow line breaks in the citations. I've used \underline, \uline from the ulem package ; both don't break lines.
ul from the soul package causes an error, due to interference with biblatex ?

Is there a way to underline citations that allows line breaks ?

MWE:

 \documentclass{article}
 \usepackage[latin9]{inputenc}
 %\usepackage{soul}
 \usepackage{ulem}

 \usepackage[style=authoryear-comp,natbib=true,%
 backend=biber]{biblatex}

 \usepackage{filecontents}
 \begin{filecontents}{\jobname.bib}
 @Book{Darwin.84,
   author =      {C. D\"{a}rwin},
   title =   {The different forms of flowers on plants of the same species},
   publisher =   {John Murray},
   address =      {London},
   edition =      2,
   year =    1884}

 @ARTICLE{Davies.pnas04,
 AUTHOR = {Davies, T. J. AND Barraclough, T. G. AND Chase, M. W. AND Soltis, P. S. AND Soltis, D. E. AND D\"{a}rwin, C.},
 TITLE = {D\"{a}rwin's abominable mystery: {Insights} from a supertree of the angiosperms.},
 JOURNAL = {Proc. Natl. Acad. Sci. U.S.A.},
 VOLUME = {101},
 PAGES = {1904--1909},
 YEAR = {2004},
 MONTH = Feb,
 NUMBER = {7}
 }

 @ARTICLE{Vamosi.el10,
 AUTHOR = {Vamosi, J. C. AND Vamosi, S. M.},
 TITLE = {Key innovations within a geographical context in flowering plants: towards resolving {D\"{a}rwin}'s abominable mystery.},
 JOURNAL = {Ecol. Lett.},
 VOLUME = {13},
 PAGES = {1270--1279},
 YEAR = {2010},
 MONTH = Oct,
 NUMBER = {10}
 }

 \end{filecontents}
 \addbibresource{\jobname.bib}


 \makeatother

 \begin{document}


 \citet{Davies.pnas04,Vamosi.el10} cite \uline{\citet{Darwin.84}}.

 %\citet{Davies.pnas04,Vamosi.el10} cite \ul{\citet{Darwin.84}}.

 \printbibliography

 \end{document}

Best Answer

Underlining is very hard for TeX. In particular \underline can never break. The commands \uline and \ul (from ulem and soul) lift this restriction, but at a cost of requiring their arguments to be comparatively simple. Complicated macros like \cite either don't allow for line breaks (because they contain grouping) or don't work at all.

The only way I see to solve this is to use LuaTeX to underline text using Paul Isambert's \underline. See also How to underline whole bibitem in biblatex?

The MWE must be compiled with LuaLaTeX

\documentclass{article}

\usepackage[style=authoryear-comp, backend=biber]{biblatex}
\addbibresource{biblatex-examples.bib}

\usepackage{kantlipsum}
\usepackage[normalem]{ulem}
\usepackage{soul}

\newattribute{\ulattr}

\usepackage{luacode}
\begin{luacode}
local HLIST = node.id("hlist")
local RULE = node.id("rule")
local GLUE = node.id("glue")
local KERN = node.id("kern")
local ULATTR = luatexbase.attributes["ulattr"]

function get_lines(head)
  for line in node.traverse_id(HLIST, head) do
    underline(line.list, line.glue_order,
      line.glue_set, line.glue_sign)
  end
  luatexbase.remove_from_callback("post_linebreak_filter",
                                  "get_lines")
  return head
end

local function good_item(item)
  if item.id == GLUE and
    (item.subtype == node.subtype("leftskip")
     or item.subtype == node.subtype("rightskip")
     or item.subtype == node.subtype("parfillskip")) then
      return false
  else
    return true
  end
end

function underline(head, order, ratio, sign)
  local item = head
  while item do
    if node.has_attribute(item, ULATTR)
      and good_item(item) then
        local item_line = node.new(RULE)
        item_line.depth = tex.sp("1.4pt")
        item_line.height = tex.sp("-1pt")
        local end_node = item
        while end_node.next and
          good_item(end_node.next) and
          node.has_attribute(end_node.next, ULATTR) do
            end_node = end_node.next
        end
        item_line.width = node.dimensions
          (ratio, sign, order, item, end_node.next)
        local item_kern = node.new(KERN, 1)
        item_kern.kern = -item_line.width
        node.insert_after(head, end_node,        
                          item_kern)
        node.insert_after(head, item_kern,
                          item_line)
        item = end_node.next
    else
      item = item.next
    end
  end
end
\end{luacode}

\newcommand{\luaunderline}[1]{%
  \quitvmode
  \setattribute{\ulattr}{1}%
  #1%
  \unsetattribute{\ulattr}%
  \directlua{%
    luatexbase.add_to_callback("post_linebreak_filter",
                               get_lines, "get_lines")}%
}

\newcommand{\luaunderlineswitch}{%
  \quitvmode\setattribute{\ulattr}{1}%
  \directlua{%
    luatexbase.add_to_callback("post_linebreak_filter",
                               get_lines, "get_lines")}%
}

\begin{document}
  \textcite{sigfridsson,nussbaum} cite \underline{\textcite{sigfridsson}}.

  \textcite{sigfridsson,nussbaum} cite \uline{\textcite{sigfridsson}}.

%  \textcite{sigfridsson,nussbaum} cite \ul{\textcite{sigfridsson}}.% <- gives a error

  \textcite{sigfridsson,nussbaum} cite \luaunderline{\textcite{sigfridsson}}.

  \kant[1]
\end{document}

enter image description here