0

I have been slowly learning LaTeX over the past few years. I have been mostly successful in these efforts.

Recently, I stumbled across a problem, I know is probably quite simple to fix, but it has me stumped. I figure, it has to do with macro expansion. These macro expansion issues are undoubtedly one of my big remaining hangups.

Looking for any input on the problem below. I tried doing various combinations of \expandafter, \edef, etc., but I was obviously just randomly stumbling around.

I have seen some related questions, but they each appear to be trying to do something slightly different and the suggestions do not appear to help me in my situation.

MWE provided:

\documentclass[10pt]{article}

\usepackage{soul}

\def\qwerty{happy new year}

\begin{document}

\ul{happy new year}
\ul{\qwerty}

\end{document}

And the error:

! Package soul Error: Reconstruction failed.

See the soul package documentation for explanation.
Type H <return> for immediate help.
 ...

l.10 \ul{\qwerty}

I know the solution is simple. Anything to point me in the direction, which will contribute to my understanding of the problem and solution, would be greatly appreciated.

  • 1
    soul doesn't expand tokens. Try \ul{\mbox{\qwerty}}. – Phelype Oleinik Jun 21 '19 at 18:37
  • @PhelypeOleinik which effectively disables the only advantage soul has compared to \underline or similar: disabling hyphenation and line breaks. Instead, if you know that the macro you're using is fully expandable, you can use the following (if you have an up to date LaTeX installation): \expandafter\ul\expandafter{\expanded{<macro>}} (which is the case for the shown definition of \qwerty). – Skillmon likes topanswers.xyz Jun 21 '19 at 18:39
  • 1
    And welcome to TeX.SX! – Skillmon likes topanswers.xyz Jun 21 '19 at 18:40
  • related: this and this answer – schtandard Jun 21 '19 at 18:41
  • 1
    I know there should be a way to just make LaTeX expand \qwerty into its definition, and only then to handle the \ul macro. – mkd Jun 21 '19 at 19:12
3

enter image description here

\documentclass[10pt]{article}

\usepackage{soul}

\def\qwerty{happy new year}

\begin{document}

\ul{happy new year}
\expandafter\ul\expandafter{\qwerty}

\end{document}
|improve this answer|||||
  • Terrific, this is close to what I expected would be a solution; now to work on understanding why it works ;). Thank you so much! – mkd Jun 22 '19 at 17:21
  • @mkd the first expandafter expands the second expandafter which expands \qwerty so the argument to \ul is happy new year – David Carlisle Jun 22 '19 at 17:22
  • @mkd note this is a generic answer that would apply to any macro, Ulrike's is much simpler (you should probably accept that) but is specific to the workings of \ul – David Carlisle Jun 22 '19 at 17:25
3

You can let soul expand by removing the braces:

\documentclass[10pt]{article}

\usepackage{soul}

\def\qwerty{happy new year}

\begin{document}

\ul{happy new year}
\ul\qwerty

\end{document}

enter image description here

|improve this answer|||||
  • Wow that just blew my mind; to this point I wouldn't have even suspected that would make any difference whatsoever.. Just when I think I have at least the basics understood... This language never stops surprising me. Could you explain why this is the case? Or refer me to material elsewhere? I have been gradually reading TUGboat articles, I have started reading a few different books on LaTeX but I don't think anything I've read suggested the difference of omitting those brackets as above. Thank you! – mkd Jun 22 '19 at 17:26
  • Well I simply checked the documentation of soul ... – Ulrike Fischer Jun 22 '19 at 17:28
  • @mkd this wouldn't the case normally, it is only expanded because soul implemented this behaviour (with checking what the next token is). Ordinary macros defined with \newcommand\foo[1]{#1} won't expand their argument if it isn't contained in braces. – Skillmon likes topanswers.xyz Jun 22 '19 at 17:32
  • @Skillmon Thank you so much for explaining that; I thought this represented something about the language I wasn't aware of. I didn't realize it was related to soul itself; I thought this was going to apply generally. Thanks for your help! – mkd Jun 26 '19 at 3:21
0

If you don't have the \expanded primitive and the argument is fully expandable (but you don't know how many expansions it would take), you can use \edef with a temporary macro:

\documentclass[]{article}

\usepackage{soul}

\makeatletter
\newcommand\edefexp[2]
  {%
    \begingroup
      \edef\edefexp@tmp{#2}%
      \expandafter
    \endgroup
    \expandafter\edefexp@aux\expandafter{\edefexp@tmp}{#1}%
  }
\newcommand\edefexp@aux[2]
  {%
    #2{#1}%
  }
\makeatother

\newcommand\qwerty{happy new \qwertz}
\newcommand\qwertz{year}

\begin{document}
\edefexp\ul{\qwerty}
\end{document}
|improve this answer|||||
  • I will probably upgrade my distribution as you suggested before. Thank you very much for posting this! – mkd Jun 22 '19 at 17:29

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.