如何定义一个使用圆括号括住其参数的命令?

如何定义一个使用圆括号括住其参数的命令?

我定义了一个概率分布的命令,例如:

\usepackage{amsmath}
\usepackage{xstring}

\DeclarePairedDelimiterX{\RoundBrackets}[1]{(}{)}{#1}
\newcommand{\p}[1]{\RoundBrackets{\StrSubstitute[0]{#1}{|}{\mid}}}

这可以用作\p{x|y}。但是,我想将其用作\p(x|y)。是否有一些 TeX 魔法可以实现这一点?

答案1

xparse使得定义具有不同类型的强制参数分隔符要求的宏变得相当容易。下面r()就是这样做的。

在此处输入图片描述

\documentclass{article}

\usepackage{mathtools,xparse,etoolbox}

\DeclarePairedDelimiterX{\RoundBrackets}[1]{(}{)}{#1}

\NewDocumentCommand{\pr}{ r() }{%
  \def\prArg{#1}% Capture argument in macro
  \patchcmd{\prArg}{|}{\mid}{}{}% Replace | with \mid
  \RoundBrackets{\prArg}% Set argument in round brackets
}

\begin{document}

$\pr(a|b)$

\end{document}

etoolbox用于|替换\mid

答案2

这也支持以下常用选项\DeclarePairedDelimiter

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{mleftright}

\ExplSyntaxOn

\NewDocumentCommand{\p}{sO{}r()}
 {
  \IfBooleanTF{#1}
   {
    \mleft(
    \danijar_middlevert:
    #3
    \mright)
   }
   {
    \group_begin:
    \danijar_sizedvert:n {#2}
    \mathopen{#2(}
    #3
    \mathclose{#2)}
    \group_end:
   }
 }

\cs_new_protected:Nn \danijar_middlevert:
 {
  \char_set_active_eq:NN | \__danijar_middle:
  \mathcode`|="8000 \scan_stop:
 }
\cs_new_protected:Nn \__danijar_middle:
 {
  \;\middle\vert\;
 }

\cs_new_protected:Nn \danijar_sizedvert:n
 {
  \tl_set:Nn \l__danijar_size_tl { #1 }
  \char_set_active_eq:NN | \__danijar_mid:
  \mathcode`|="8000 \scan_stop:
 }
\cs_new_protected:Nn \__danijar_mid:
 {
  \mathrel{\l__danijar_size_tl\vert}
 }

\ExplSyntaxOff

\begin{document}

$\p(x) \neq \p(x|y)$
\qquad
$\p[\big](x) \neq \p[\big](x|y)$
\qquad
$\p[\Big](x) \neq \p[\Big](x|y)$
\qquad
$\p*(\dfrac{a}{b})\neq \p*(\dfrac{a}{b}|y)$

\end{document}

在此处输入图片描述

这个想法是在本地使|数学活跃起来,并有一个适当的定义,即\;\middle\vert\;在声明自动调整大小时,或者\mathrel{<size>\vert}在选择手动调整大小时。

如果要添加代表“概率”的“P”:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{mleftright}

\ExplSyntaxOn

\NewDocumentCommand{\p}{sO{}r()}
 {
  \operatorname{P}
  \IfBooleanTF{#1}
   {
    \mleft(
    \danijar_middlevert:
    #3
    \mright)
   }
   {
    \group_begin:
    \danijar_sizedvert:n {#2}
    \mathopen{#2(}
    #3
    \mathclose{#2)}
    \group_end:
   }
 }

\cs_new_protected:Nn \danijar_middlevert:
 {
  \char_set_active_eq:NN | \__danijar_middle:
  \mathcode`|="8000 \scan_stop:
 }
\cs_new_protected:Nn \__danijar_middle:
 {
  \;\middle\vert\;
 }

\cs_new_protected:Nn \danijar_sizedvert:n
 {
  \tl_set:Nn \l__danijar_size_tl { #1 }
  \char_set_active_eq:NN | \__danijar_mid:
  \mathcode`|="8000 \scan_stop:
 }
\cs_new_protected:Nn \__danijar_mid:
 {
  \mathrel{\l__danijar_size_tl\vert}
 }

\ExplSyntaxOff

\begin{document}

$\p(x) \neq \p(x|y)$

$\p[\big](x) \neq \p[\big](x|y)$

$\p[\Big](x) \neq \p[\Big](x|y)$

$\p*(\dfrac{a}{b})\neq \p*(\dfrac{a}{b}|y)$

\end{document}

在此处输入图片描述

答案3

大概@Werner 的回答是可行的方法(健壮且易于修改),但在这种情况下,纯 TeX 似乎也可以工作:

\documentclass{article}

\def\pr(#1|#2){(#1 \mid #2)}

\begin{document}

$\pr(a|b)$
$\pr(a_r|b^2)$

\end{document}

结果输出

相关内容