9

I am using the soul package to underline omitting the descenders. It seems that passing the following as a parameter works fine

 \textit{special text}

but if the \textit is applied indirectly via the macro \ApplyStyle then I get the error:

Argument of \ApplyStyle has an extra }.

Question:

Is it possible to allow for this indirect application of the style by changes to the \varul macro? If not, what other options are available (except of course for applying the formatting directly within the invocation of the \varul macro -- that would just be too easy :-))?

Code:

\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}
\usepackage{soul}
\usepackage{xspace}


%% ----------------------------------------------------------------
%%                https://tex.stackexchange.com/questions/36894/
%%                    underline-omitting-the-descenders
%%
%%
\makeatletter
\ExplSyntaxOn
    \cs_new:Npn \white_text:n #1
      {
        \fp_set:Nn \l_tmpa_fp {.01}
        \fp_mul:Nn \l_tmpa_fp {#1}
        \llap{\textcolor{white}{\the\SOUL@syllable}\hspace{\fp_to_decimal:N \l_tmpa_fp em}}
        \llap{\textcolor{white}{\the\SOUL@syllable}\hspace{-\fp_to_decimal:N \l_tmpa_fp em}}
      }
    \NewDocumentCommand{\whiten}{ m }
        {
          \int_step_function:nnnN {1}{1}{#1} \white_text:n
        }
\ExplSyntaxOff

\NewDocumentCommand{ \varul }{ D<>{5} O{0.2ex} O{0.1ex} +m } {%
\begingroup
\setul{#2}{#3}%
\def\SOUL@uleverysyllable{%
   \setbox0=\hbox{\the\SOUL@syllable}%
   \ifdim\dp0>\z@
      \SOUL@ulunderline{\phantom{\the\SOUL@syllable}}%
      \whiten{#1}%
      \llap{%
        \the\SOUL@syllable
        \SOUL@setkern\SOUL@charkern
      }%
   \else
       \SOUL@ulunderline{%
         \the\SOUL@syllable
         \SOUL@setkern\SOUL@charkern
       }%
   \fi}%
    \ul{#4}%
\endgroup
}%
\makeatother
%% ----------------------------------------------------------------

\newcommand{\ApplyStyle}[1]{\textit{#1}}%

\begin{document}
\varul{\textit{special text}\xspace}%      Works!!

\varul{\ApplyStyle{special text}\xspace}%  Does NOT work
\end{document}
  • On the side, your definition of \ApplyStyle could be simplified to \let\ApplyStyle\textit... – Werner Jul 23 '13 at 23:44
  • @Werner: Yep for the MWE that make sense, but my style selection process is more complicated -- hope that that doesn't introduce any further complications. – Peter Grill Jul 23 '13 at 23:47
  • You could add \ApplyStyle to the \SOUL@cmds: \SOUL@cmds\expandafter{\the\SOUL@cmds\\1\ApplyStyle} (or with the interface-macro \soulregister{\ApplyStyle}{1}, see comment below). The 1 denotes in both cases a font-changing macro that takes an argument. – Qrrbrbirlbel Jul 23 '13 at 23:50
  • Tell soul to leave your command alone with \soulregister\ApplyStyle{1}. – Robert Jul 23 '13 at 23:52
  • @Qrrbrbirlbel I first wrote the comment, then I saw yours, then I wrote the answer, then I saw your edit to the comment. Now I hope you weren't preparing an answer yourself... – Robert Jul 24 '13 at 0:39
10

soul scans the text token by token, a process which can easily be messed up when the input stream also contains macros. The package already knows that it should leave font switching commands alone -- therefore \textit works in your case -- but fails with the unknown macro \ApplyStyle. Fortunately, there is an interface to make soul acquainted with new macros: \soulregister<command><identifier>, where <identifier> can be either 0 or 1 for the number of arguments (see section 5.2 in the documentation; also see this answer for an extension of \soulregister to accept more, and possibly optional, arguments).

Your example runs fine when adding

\soulregister\ApplyStyle{1}

to the preamble.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.