我编写了一个宏来表示傅里叶变换(花括号 F 本身)或函数的傅里叶变换(花括号 F 后跟一个函数并括在 \left( 和 \right) 中)。它通过测试参数是否等于 void 来实现这一点:
\newcommand*{\fourier}[1]{\ensuremath{\mathscr{F}\ifthenelse{\equal{#1}{}}{}{\!\left({#1}\right)}}}%
所以
\fourier{}
或者
\fourier{f(\omega t)}
给出预期结果。
我想对一个函数应用 \fourier 两次,因此写了
\fourier{\fourier{f}}(x)
但是,我遇到了! Missing \endcsname inserted.
错误。我应该如何修改我的宏以使其允许嵌套?我猜是因为构造\ifthenelse
?
答案1
如同斯基尔蒙原创回答,但假装mathtools
并坚持强制参数。带星号的版本使用\left
/ \right
,无星号的版本有一个可选参数\big
/ \Big
/...
采取往返\left
的\right
方法马特乌斯·阿劳若的回答\left 和 \right 周围的间距在...的帮助下菲利普·斯蒂芬尼(谢谢张瑞熙对于评论中的建议)
\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{amsmath}
\usepackage{mathrsfs}
\usepackage{ifthen}
\makeatletter
\DeclareRobustCommand{\fourier}{%
\mathscr{F}%
\@ifstar
\fourier@paren@star
\fourier@paren@expl}
\newcommand{\fourier@paren@star}[1]{%
\if\relax\detokenize{#1}\relax
\else
\mathopen{}\mathclose{\left(#1\right)}%
\fi}
\newcommand{\fourier@paren@expl}[2][]{%
\if\relax\detokenize{#2}\relax
\else
\mathopen{#1(}#2\mathclose{#1)}%
\fi}
\makeatother
\begin{document}
\[ \fourier{} \]
\[ \fourier{f(\omega t)} \]
\[ \fourier{\fourier{f}}(x) \]
\[ \fourier*{\fourier*{\frac{f^2}{2\pi}}}(x) \]
\end{document}
答案2
我将使用以下内容:
- 不要使用
\ensuremath
它,因为它会混淆源代码 - 不要用来
\ifthenelse
检查空参数,但是\if\relax\detokenize{#1}\relax
(可扩展,加上个人偏好) - 使用可选参数作为可选参数
我犯了一个错误因此前面的代码错误地获取了参数。下面的代码使用xparse
更强大的方式获取参数。因此它不使用测试\if\relax\detokenize{#1}\relax
而是xparse
使用\IfValueT
。
结果:
\documentclass[]{article}
\usepackage{mathrsfs}
\usepackage{xparse}
\NewDocumentCommand \fourier { o }
{%
\mathscr{F}\IfValueT{#1}{\!\left(#1\right)}%
}%
\begin{document}
$\fourier[\fourier[f]](x)$
\end{document}