2

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?

3 Answers 3

3

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}
3
  • 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, 2018 at 6:21
  • 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, 2018 at 13:22
  • 1
    @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, 2018 at 13:23
0
\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}}}
0

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}
3
  • Why \NewEnviron?
    – egreg
    May 27, 2018 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, 2018 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, 2018 at 21:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .