# How to use the global definition of a variable in a command where that variable has already been defined?

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}

• \def\x{\mathbf{x}} will bite you in the end ... or more precisely now, because you get into troubles... – user31729 Feb 11 at 13:48
• 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
• 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

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

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


\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*{\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}


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 or trying to patch the package to the same effect), 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.
