嵌套宏的问题

嵌套宏的问题

我编写了一个宏来表示傅里叶变换(花括号 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

我将使用以下内容:

  1. 不要使用\ensuremath它,因为它会混淆源代码
  2. 不要用来\ifthenelse检查空参数,但是\if\relax\detokenize{#1}\relax(可扩展,加上个人偏好)
  3. 使用可选参数作为可选参数

我犯了一个错误因此前面的代码错误地获取了参数。下面的代码使用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}

在此处输入图片描述

相关内容