我正在尝试定义一些新命令,以便能够为一些我将反复使用的东西定义默认值,以便集中定义样式和使用的典型字母的位置。
到目前为止,我遇到的一些麻烦的事情如下
\newcommand{\Prob}[1]{%
\IfEqCase{#1}{%
{1}{p}%
{2}{q}%
{3}{r}%
}[#1]%
}%
\newcommand{\RandomVar}[1]{%
\IfEqCase{#1}{%
{1}{X}%
{2}{Y}%
{3}{Z}%
}[#1]%
}%
使用示例如下
$p_{\RandomVar1, \RandomVar2}$, $\Prob{p_{\RandomVar1,\RandomVar2}}$
所有这些的目的是能够为概率分布提供默认值,为随机变量提供默认值,并且还能够在需要时提供与默认值不同的值。这里第一个代码有效并产生 $p_{X,Y}$,第二个代码无效并产生以下错误
I've run across a `}' that doesn't seem to match anything. For example, `\def\a#1{...}' and `\a}' would produce this error.
我认为这个问题类似于这个帖子但我无法解决问题,我尝试在事情周围加括号,但并没有真正理解我在做什么。任何帮助都会受到欢迎。
完整示例
\documentclass{article}
\usepackage{xstring}
\newcommand{\Prob}[1]{%
\IfEqCase{#1}{%
{1}{p}%
{2}{q}%
{3}{r}%
}[#1]%
}%
\newcommand{\RandomVar}[1]{%
\IfEqCase{#1}{%
{1}{X}%
{2}{Y}%
{3}{Z}%
}[#1]%
}%
\begin{document}
$\Prob1$, $\Prob2$, $\Prob{p_{X,Y}}$, $p_{\RandomVar1, \RandomVar2}$
$\Prob{p_{\RandomVar1,\RandomVar2}}$
\end{document}
该文件的第一行显示
$p$, $q$, $p_{X,Y}$, $p_{X,Y}$
最后一行应该输出
$p_{X,Y}$
但反而给出了一个错误。
答案1
似乎通过定义 via\NewDocumentCommand
而不是 来使命令变得强大就可以\newcommand
了。
\documentclass{article}
%\usepackage{xparse}
\usepackage{xstring}
\NewDocumentCommand{\Prob}{m}{%
\IfEqCase{#1}{%
{1}{p}%
{2}{q}%
{3}{r}%
}[{#1}]%
}%
\NewDocumentCommand{\RandomVar}{m}{%
\IfEqCase{#1}{%
{1}{X}%
{2}{Y}%
{3}{Z}%
}[{#1}]%
}%
\begin{document}
$\Prob1$, $\Prob2$, $\Prob{p_{X,Y}}$, $p_{\RandomVar1, \RandomVar2}$
$\Prob{p_{\RandomVar1,\RandomVar2}}$
\end{document}
最后一行产生结果p_{\RandomVar1,\RandomVar2}
,进而产生结果p_{X,Y}
。
更好的方法可能是使用可扩展的\str_case:nnTF
:
\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \Prob #1 {%
% \exp_args:Ne fully expands the argument passed to \str_case:nnTF.
\exp_args:Ne
\str_case:nnTF {#1}
{
{1} {p}
{2} {q}
{3} {r}
}
{}
{#1}
}
\cs_new:Npn \RandomVar #1 {%
% \exp_args:Ne fully expands the argument passed to \str_case:nnTF.
\exp_args:Ne
\str_case:nnTF {#1}
{
{1} {X}
{2} {Y}
{3} {Z}
}
{}
{#1}
}
\ExplSyntaxOff
\begin{document}
$\Prob1$, $\Prob2$, $\Prob{p_{X,Y}}$, $p_{\RandomVar1, \RandomVar2}$
$\Prob{p_{\RandomVar1,\RandomVar2}}$
\end{document}
答案2
您可以使用可扩展的 TeX 原语非常简单地定义您\Prob
的:\RandomVar
\ifcase
\def\Prob #1{\ifcase 0#1\or p\or q\or r\fi}
\def\RandomVar #1{\ifcase 0#1\or X\or Y\or Z\fi}
答案3
问题在于如何xstring
处理它的命令,使用全面扩张除非另有明确说明。
这就是失败的原因\Prob{p_{\RandomVar{1},\RandomVar{2}}}
,因为xstring
试图充分扩张\RandomVar{1}
却无法生存\edef
。
\str_case:nnF
中的函数没有expl3
这个问题。由于您似乎想以类似的方式定义几个命令(当参数合适时从选项列表中返回,或返回完整参数),因此抽象似乎很有用。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\definechoicemacro}{mm}
{% #1 = macro name, #2 = choices
\NewDocumentCommand{#1}{m}
{
\str_case:nnF { ##1 } { #2 } { ##1 }
}
}
\ExplSyntaxOff
\definechoicemacro{\Prob}{
{1}{p}
{2}{q}
{3}{r}
}
\definechoicemacro{\RandomVar}{
{1}{X}
{2}{Y}
{3}{Z}
}
\begin{document}
$\Prob1$, $\Prob2$, $\Prob{p_{X,Y}}$, $p_{\RandomVar1, \RandomVar2}$
$\Prob{p_{\RandomVar1,\RandomVar2}}$
\end{document}
如果你希望单独定义宏,
\documentclass{article}
\ExplSyntaxOn
\cs_new_eq:NN \choosefromordefault \str_case:nnF
\ExplSyntaxOff
\newcommand{\Prob}[1]{%
\choosefromordefault{#1}{
{1}{p}
{2}{q}
{3}{r}
}{#1}%
}
\newcommand{\RandomVar}[1]{%
\choosefromordefault{#1}{%
{1}{X}
{2}{Y}
{3}{Z}
}{#1}%
}
\begin{document}
$\Prob1$, $\Prob2$, $\Prob{p_{X,Y}}$, $p_{\RandomVar1, \RandomVar2}$
$\Prob{p_{\RandomVar1,\RandomVar2}}$
\end{document}