是否可以定义一个类似\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
。
仅供参考,正如我所说是可以使用括号,但是
- 它已被弃用
- 这其实并不是更好的输入
\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
您可以使用\futurelet
TeX 原语:
\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}$