3

I was trying to highlight some text, which contains \x, using the \hl command from the soul package, where \x is simply defined as \def\x{\mathbf{x}}.

However, I've found that \x has already been defined in \hl. As a result, the TeX compiler wrongly interprets \hl{How to define $f(\x_i)$?}, where \x actually takes as the value define.

Can I know how to enforce the global definition of \x inside \hl? Thanks.

\documentclass[10pt]{article}

\usepackage{color}
\usepackage{soul}

\def\x{\mathbf{x}}

\begin{document}
\title{}
\author{}
\date{}
\maketitle

How to define $\x$?

\hl{How to define $\x$?}

\end{document}
New contributor
mintaka is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • 2
    \def\x{\mathbf{x}} will bite you in the end ... or more precisely now, because you get into troubles... – Christian Hupfer Feb 11 at 13:48
  • 1
    Exactly which error do you get? Using my TexLive 2019, I get no errors with your example. Note: I agree with Christian: a normal user should never use \def – daleif Feb 11 at 13:48
  • On a simpler note why dont you change the \x definition in your document? – Raaja Feb 11 at 13:49
  • @daleif There is no error, but the output is not as expected. It shows 'How to define $define$' and not 'How to define $\mathbf{x}$' – moewe Feb 11 at 13:49
  • 1
    well it is imho a rather bad idea from soul to use \x as a scratch command, but there is not much you can do beside complaining to the maintainer. So don't use \x yourself. – Ulrike Fischer Feb 11 at 13:51
2

It's very unfortunate that the author of soul misunderstood the usage of \x, which should be

\begingroup\edef\x{\endgroup<material>}\x

instead of

\edef\x{<material>}\x

The former only redefines \x in a group and a possible definition of \x is irrelevant; when the redefined \x is executed, the group ends and the redefinition vanishes.

You can cure the disease by changing \x into a different scratch macro, here I used \SOUL@x.

\documentclass[10pt]{article}

\usepackage{color}
\usepackage{soul}
\usepackage{regexpatch}

\makeatletter
\xpatchcmd*{\SOUL@flushcomma}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@flushapo}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@flushgrave}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@addgroup}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@addmath}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@addprotect}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@addtoken}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\soulregister}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@doword}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@dosyllable}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@gettoken}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@puttoken}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@nexttoken}{\x}{\SOUL@x}{}{}
\xpatchcmd*{\SOUL@soeverytoken}{\x}{\SOUL@x}{}{}
\makeatother


\newcommand\x{\mathbf{x}}

\begin{document}
\title{}
\author{}
\date{}
\maketitle

How to define $\x$?

\hl{How to define $\x$?}

\end{document}

enter image description here

1

soul uses the name \x internally as a scratch command to temporarily store stuff all over the place. (Just search for \x or \edef\x in http://mirrors.ctan.org/macros/latex/contrib/soul/soul.dtx.) The way the package is written there is little to no chance to get it to stop doing that easily (short of replacing every occurence of \x in the source with \soul@tempa), so I guess you should

  1. Complain to the author of soul and suggest he use an 'internal' name as scratch command.
  2. Use a macro name other than \x for your \textbf{x}. Make it semantic. You could for example say

    \newcommand*{\vector}[1]{\mathbf{#1}}
    

    and then use \vector{x} or if you want one command

    \newcommand*{\vector}[1]{\mathbf{#1}}
    \newcommand*{\vecx}{\vector{x}}
    

    and use \vecx.

It is usually safer to steer clear of one-letter commands. Even though they are very handy (at least superficially) many are already taken and redefining those could lead to catastrophic consequences.

It wouldn't have helped here, but it could help in other cases and is therefore a good practice if you use LaTeX to use \newcommand instead of \def. \def just overwrites an existing command, while \newcommand will throw an error if you try to do that.

Your Answer

mintaka is a new contributor. Be nice, and check out our Code of Conduct.

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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