# Decorate a symbol depending on the context

I have the following macro defining a mathematical symbol:

\newcommand{\myX}[2]{x_{#1}^{#2}}


Depending on the context, the symbol x should be decorated with a \widetilde or a \widehat or stay undecorated.

A pseudocode could look like:

\hatcontext
Hello $\myX{1}{2}$ % x has a hat
\tildecontext
Hello $\myX{1}{2}$ % x has a tilde
\nodecoratorcontext
Hello $\myX{1}{2}$ % x is undecorated


I have already defined the macros for many of those symbols, and I also use them in my text (with no decorators at all), so a solution that doesn't need too much change in the text and in the macros would be great.

What's the best practice to achieve that?

If by “context” you mean an environment, it's just a matter of defining correctly the macro:

\newenvironment{decotilde}{\let\decorate\widetilde}{}
\newenvironment{decohat}{\let\decorate\widehat}{}
\makeatletter
\newenvironment{deconone}{\let\decorate\@firstofone}{}
\newcommand\decorate{\@firstofone} % default
\makeatother

% now we can define macros based on \decorate
\newcommand{\myX}[2]{\decorate{x}_{#1}^{#2}}


If you prefer a declarative style like in your example:

\newcommand{\hatcontext}{\let\decorate\widehat}
\newcommand{\tildecontext}{\let\decorate\widetilde}
\makeatletter
\newcommand{\nodecoratorcontext}{\let\decorate\@firstofone}
\makeatother

\nodecoratorcontext % start up with no decoration

% now we can define macros based on \decorate
\newcommand{\myX}[2]{\decorate{x}_{#1}^{#2}}


What’s the purpose of \@firstofone? It simply removes the braces, because its definition is basically

\newcommand\@firstofone[1]{#1}


so, when this is the value for \decorate, from \myX{a}{b} you first get

\decorate{x}_{a}^{b}


and then

x_{a}^{b}

• Thanks, that seems nice. What I don not understand: What's the purpose of \@firstofone? I can not quite find a good explanation. – Michael May 28 '18 at 6:21
• @Michael Explanation added – egreg May 28 '18 at 8:10
• While it works basically, it seems to make trouble when done inside the argument of another macro. Is that possible? I'm currently trying to understand it better, but it's not easy with LaTeX... – Michael May 28 '18 at 13:22
• @Michael What do you mean? I can't understand what you're trying to achieve. Anyway, context depending macros are evil. Use \tilde when you want a tilde, \hat when you want a hat. – egreg May 28 '18 at 13:23
\def\hatcontext{\def\myX##1##2{\hat{x}_{##1}^{##2}}}
\def\tildecontext{\def\myX##1##2{\tilde{x}_{##1}^{##2}}}
\def\nodecoratorcontext{\def\myX##1##2{x_{##1}^{##2}}}


I now use the following solution, comments are welcome:

\documentclass{article}
\usepackage{amsmath}

\usepackage{environ}

\NewEnviron{decotilde}{%
\renewcommand{\decorateme}[1]{\widetilde{##1}}
\BODY
}

\NewEnviron{decohat}{%
\renewcommand{\decorateme}[1]{\widehat{##1}}
\BODY
}

\NewEnviron{deconone}{%
\renewcommand{\decorateme}[1]{##1}
\BODY
}

\begin{document}

\newcommand{\decorateme}[1]{#1}
\newcommand{\mya}{\decorateme{a}}

\begin{deconone}
It's $\mya$.
\end{deconone}

\begin{decohat}
It's $\mya$.
\end{decohat}

\begin{decotilde}
It's $\mya$.
\end{decotilde}

\end{document}

• Why \NewEnviron? – egreg May 27 '18 at 21:01
• @egreg: I'm mostly a beginner, so I just searched how to create an own environment, and that's what I found. Would there be a better solution? – Michael May 27 '18 at 21:17
• Yes: \newenvironment is the key; \NewEnviron is a rather advanced tool, which can bite you in several ways. But see my other approach. – egreg May 27 '18 at 21:23