如何简洁地处理 \SplitArgument 的每个元素?

如何简洁地处理 \SplitArgument 的每个元素?

我正在尝试创建一些能够很好地处理条件概率的函数。到目前为止,我有以下内容:

\usepackage{xparse}

\NewDocumentCommand \prob { >{\SplitArgument{1}{|}} m } {
    \probc #1
}

\NewDocumentCommand \probc { m m } {
    \ensuremath{\mathbb{P}\!\left(#1\IfValueT{#2}{\;\middle\vert\;#2}\right)}
}

这似乎效果不错。现在,我想编写一个新函数\problm,它的功能与 相同\prob,但它包装了 中的每个(1 个或可能是 2 个)参数\texttt。(lm中的\problm表示语言模型;在语言模型的上下文中编写概率时,我希望跳过必须将\texttt所有输入写入 的步骤\prob。)

为了做到这一点,我尝试了以下方法:

\NewDocumentCommand \problm { >{\SplitArgument{1}{|}} m } {
    \probc \ProcessList{#1}{\texttt}
}

但是,这不起作用。为什么会失败?我怎样才能以干净、简洁的方式完成我想做的事情?理想情况下,解决方案只使用默认或xparse命令,但如果有一个更简单的解决方案,使用完全不同的工具集,那么它也可能很有用!

顺便说一句,我知道我可以编写一个\problmc看起来几乎像\probc\texttt插入了一些的新函数,但我想重用底层probc函数。

答案1

我将定义一个通用命令,我们可以将我们想要的真实参数的“装饰”传递给它。

它看起来比你想象的要复杂,因为我真的不喜欢无条件地使用\left\right

您可以跟踪各种情况来了解如何选择括号和中间分隔符的大小。

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

\NewDocumentCommand{\genericprob}{m s o >{\SplitArgument{1}{|}}m }{%
  % #1 = decoration, #2 = * for automatic sizing, #3 = optional size
  % #4 = argument
  \mathbb{P}
  \IfBooleanTF{#2}
    {% automatic sizing
     \!\left(%
     \genericprobaux{#1}{\;\middle|\;}#4%
     \right)%
    }%
    {% no automatic sizing
     \IfNoValueTF{#3}
       {% normal size
        (\genericprobaux{#1}{\mid}#4)%
       }
       {% optional sizing
        \mathopen{#3(}\genericprobaux{#1}{\mathrel{#3|}}#4\mathclose{#3)}%
       }%
    }%
}
\NewDocumentCommand{\genericprobaux}{mmmm}{%
  #1{#3}%
  \IfValueT{#4}{#2#1{#4}}%
}
\NewDocumentCommand{\prob}{}{\genericprob{}}
\NewDocumentCommand{\problm}{}{\genericprob{\mathtt}}

\begin{document}

First of all a paragraph to show why it is in general not advisable to
use automatic sizing; here's an example inspired from a picture in Math.SE
taken from a paper typeset with \TeX{} where \verb|\prob*| does
automatic size $\prob*{\bigcup\limits_{g\in B_j}g(R)}$; this uses the
dreaded \verb|\limits|, but even without it the result is not optimal:
compare $\prob*{\bigcup_{g\in B_j}g(R)}$ with $\prob[\big]{\,\bigcup_{g\in B_j}g(R)}$
and judge for yourself.
\begin{gather*}
\prob{x}\ne\prob{x|y}
\\
\prob[\Big]{x}\ne\prob[\bigg]{x|y}
\\
\prob*{\frac{x}{2}}\ne\prob*{\frac{x}{2}|y}
\\
\problm{x}\ne\problm{x|y}
\\
\problm[\Big]{x}\ne\problm[\bigg]{x|y}
\\
\problm*{\frac{x}{2}}\ne\problm*{\frac{x}{2}|y}
\end{gather*}
Inspiring picture at \texttt{https://math.stackexchange.com/q/4038452/62967}

\end{document}

当然,最后一行实际上没有什么意义,只是为了说明。

显示的方程式之前的段落说明了为什么自动调整大小不是最好的。我相信这个例子是不言自明的。在使用的公式中\big,需要一个细小的空格。排版并不简单,但只要有一定经验,在查看打印输出之前就会看到这些冲突。

那怎么样\ensuremath?你只是在交换两个密钥时失去了语义。

最重要的是:如何\prob没有参数?因为它的定义由 组成\genericprob{},其余参数由这个更通用的宏获取。这避免了代码重复:我们可以用\problm不同的“装饰”定义和其他命令。

在此处输入图片描述

答案2

您的\ProcessList之前未求值\probc,因此参数\probc采用\ProcessList{#1},这显然不是您想要的。相反,您可以引入另一个包装器宏来包裹\texttt您的输入。

\documentclass[]{article}

\usepackage{xparse}
\usepackage[]{amssymb}

\NewDocumentCommand \prob { >{\SplitArgument{1}{|}} m }
  {\probc #1}

\NewDocumentCommand \probc { m m }
  {\mathbb{P}\!\left(#1\IfValueT{#2}{\;\middle\vert\;#2}\right)}

\NewDocumentCommand \problm { >{\SplitArgument{1}{|}} m } 
  {\problmc#1}
% we have to test for a value here as well, otherwise the value test in `\probc` wouldn't work due to the `\texttt`.
\NewDocumentCommand \problmc { m m }
  {\IfValueTF{#2}{\probc{\texttt{#1}}{\texttt{#2}}}{\probc{\texttt{#1}}{#2}}}

\begin{document}
$\problm{language1}$
$\problm{language1|language2}$
\end{document}

在此处输入图片描述

相关内容