我有以下定义数学符号的宏:
\newcommand{\myX}[2]{x_{#1}^{#2}}
根据上下文,符号 x 应该用 a\widetilde
或 a修饰\widehat
,或者保持未修饰。
伪代码可能看起来像:
\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
我已经为许多符号定义了一份宏,并且也在我的文本中使用它们(根本没有装饰器),因此一个不需要在文本和宏中进行太多更改的解决方案就很棒了。
实现这一目标的最佳做法是什么?
答案1
如果“上下文”指的是环境,那么它只是正确定义宏的问题:
\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}}
如果您更喜欢像示例中的声明性样式:
\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}}
的目的是什么\@firstofone
?它只是删除了括号,因为它的定义基本上是
\newcommand\@firstofone[1]{#1}
因此,当这是的值时\decorate
,\myX{a}{b}
您首先会得到
\decorate{x}_{a}^{b}
进而
x_{a}^{b}
答案2
\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}}}
答案3
我现在采用如下解决方案,欢迎评论:
\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}