定义一个带有参数的命令,如果不带参数调用则具有行为

定义一个带有参数的命令,如果不带参数调用则具有行为

是否可以定义一个类似\Sign如下方式工作的命令?

  • \Sign\mathsf{Sign}
  • \Sign{foo}\mathsf{Sign}\left(foo\right)

我特别希望函数能实现这一点:宏的参数是函数的参数,不带括号的宏写函数的名称(即,删除左边并写上括号)。

编辑:我明确表示我想使用括号,而不是[]可选参数。

答案1

这是有可能的,但是强烈反对。

为什么不使用更自然的语法,例如

\Sign
\Sign(a)

还可以容纳可选的尺寸参数?

\documentclass{article}
\usepackage{amsmath,mathtools}

\DeclareMathOperator{\Signop}{\mathsf{Sign}}

\DeclarePairedDelimiter{\parens}{(}{)}

\NewDocumentCommand{\Sign}{sO{}d()}{%
  \IfNoValueTF{#3}
    {{\Signop}}% just the function name as ordinary symbol
    {\SignArg{#1}{#2}{#3}}% the more complex construction
}

\NewDocumentCommand{\SignArg}{mmm}{%
  \Signop % the operator
  \IfBooleanTF{#1}
   {% extensible delimiter
    \parens*{#3}%
   }
   {% sized delimiter
    \parens[#2]{#3}%
   }
}

\begin{document}

Ordinary: $a+\Sign+x$

\bigskip

With argument: $a+\Sign(b)+x$

\bigskip

With argument and size: $a+\Sign[\Big](b)+x$

\bigskip

With extensible fences: $a+\Sign*(\dfrac{1}{2})+x$

\end{document}

在此处输入图片描述

为什么要避免无条件的\left\right?考虑一下

$\Sign*(\hat{X})$ versus $\Sign(\hat{X})$ or $\Sign[\big](\hat{X})$

其中*-version 使用\left\right

在此处输入图片描述


仅供参考,正如我所说可以使用括号,但是

  1. 它已被弃用
  2. 这其实并不是更好的输入
\documentclass{article}
\usepackage{amsmath,mathtools}
\usepackage{xparse}

\DeclareMathOperator{\Signop}{\mathsf{Sign}}

\DeclarePairedDelimiter{\parens}{(}{)}

\NewDocumentCommand{\Sign}{sO{}g}{%
  \IfNoValueTF{#3}
    {{\Signop}}% just the function name as ordinary symbol
    {\SignArg{#1}{#2}{#3}}% the more complex construction
}

\NewDocumentCommand{\SignArg}{mmm}{%
  \Signop % the operator
  \IfBooleanTF{#1}
   {% extensible delimiter
    \parens*{#3}%
   }
   {% sized delimiter
    \parens[#2]{#3}%
   }
}

\begin{document}

Ordinary: $a+\Sign+x$

\bigskip

With argument: $a+\Sign{b}+x$

\bigskip

With argument and size: $a+\Sign[\Big]{b}+x$

\bigskip

With extensible fences: $a+\Sign*{\dfrac{1}{2}}+x$

\end{document}

答案2

您可以使用\futureletTeX 原语:

\def\Sign{\mathop{\mathsf{Sign}}\futurelet\next\SignA}
\def\SignA{\ifx \next\bgroup \expandafter\SignB \fi}
\def\SignB #1{\mathopen{}\left(#1\right)\mathclose{}}

%% test:
$\Sign X, \Sign{X+Y}$

相关内容