newcommand: 매크로를 인수로 포함할 수 없습니다.

newcommand: 매크로를 인수로 포함할 수 없습니다.

조금 바보 같은 느낌이 들지만 왜 내 인수 안에 매크로를 넣을 수 없습니까 newcommand? 확장된 매크로를 수동으로 작성하면 확실히 작동하는데 왜 내 매크로가 환경 \pra내에서는 작동 하지 않습니까 ?align

내 매크로(확률을 나타냄):

\newcommand*{\pr}[2][]{\ifthenelse{\equal{#1}{}}{\Pr[\,#2\,]}{\Pr_{#1}[\,#2\,]}}

그러면 다음과 같은 결과가 나올 것으로 예상됩니다.

여기에 이미지 설명을 입력하세요

이것은 작동합니다:

\pr[b \leftarrow \{0,1\}]{a = 0 \mid b = 0} 

실패합니다.

\pr[\substack{a \leftarrow \{0,1\}}]{a = 0 \mid b = 0}

오류가 발생했습니다.

ERROR: Use of \\pr doesn't match its definition.

--- TeX said ---
\new@ifnextchar ...served@d = #1\def \reserved@a {
                                                  #2}\def \reserved@b {#3}\f...l.18 ...k{a \leftarrow \{0,1\}}]{a = 0 \mid b = 0}
                                                  \]

그리고 더 이상한 점은 방정식 내에서 작동했던 매크로 align버전이 이제 실패하는 반면, 모든 것을 수동으로 작성하면 작동한다는 것입니다...\pr

감사해요!

MWE:

\documentclass[]{article}

\usepackage{amsmath}
\usepackage{ifthen}
\setlength{\parindent}{0pt}

\newcommand*{\pr}[2][]{\ifthenelse{\equal{#1}{}}{\Pr[\,#2\,]}{\Pr_{#1}[\,#2\,]}}

\newcommand*{\pra}[2][]{\ifthenelse{\equal{#1}{}}{\Pr[\,#2\,]}{\Pr_{\substack{#1}}[\,#2\,]}}

\begin{document}
This works:
\[\pr{a = 0 \mid b = 0}\]
\[\pr[b \leftarrow \{0,1\}]{a = 0 \mid b = 0}\]
\[\Pr_{\substack{a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}}} [a = 0 \mid b = 0]\]
This fails:
% \[\pr[\substack{a \leftarrow \{0,1\}}]{a = 0 \mid b = 0}\]
% \[\pr[\substack{a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}}]{a = 0 \mid b = 0}\]

But if I put substack inside, it works:
\[\pra[a \leftarrow \{0,1\}]{a = 0 \mid b = 0}\]
\[\pra[a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}]{a = 0 \mid b = 0}\]

Now, it's still stranger: if I put the full expression without my macro, it works inside an align:
\begin{align}
  \Pr_{\substack{a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}}}[a = 0 \mid b = 0]
\end{align}
But if I use the macro that was used before, it fails:

% \begin{align}
%   \pra[a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}]{a = 0 \mid b = 0}
% \end{align}

% even if I use protect:
%\begin{align}
%  \pr[\protect\substack{a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}}]{a = 0 \mid b = 0}
%\end{align}

\end{document}

답변1

일반적으로 매크로를 인수로 제공할 수 있지만 이러한 인수를 사용하여 수행하는 작업에 약간 주의해야 할 수도 있습니다. 모든 매크로가 모든 입력을 동일하게 처리할 수 있는 것은 아닙니다.

\ifthenelse와 같은 복잡한 짐승에는 그다지 만족하지 않는 것 같습니다 \substack. 내 생각에 의 테스트 \ifthenelse\equal비교하는 문자열을 확장하려고 하는데 \substack확장이 불가능하기 때문에 잘못된 것 같습니다. 이 경우 \protect확장할 수 없는 콘텐츠 이전에 건전한 작업을 수행하는 것이 도움이 될 수 있지만 시간이 지나면 지루해질 수 있습니다.

나는 확장을 하지 않으므로 여기와 같은 복잡한 작업을 처리하는 데 추가 도움이 필요하지 않은 's \ifthenelse{\equal{#1}{}}로 대체하겠습니다 .etoolbox\ifblank{#1}\substack

\documentclass[]{article}
\usepackage{amsmath}
\usepackage{etoolbox}

\newcommand*{\pr}[2][]{%
  \ifblank{#1}
    {\Pr[\,#2\,]}
    {\Pr_{#1}[\,#2\,]}}

\begin{document}
\begin{align}
  \pr[\substack{a \leftarrow \{0,1\}\protect\\b \leftarrow \{0,1\}}]{a = 0 \mid b = 0}
\end{align}
\end{document}

\ifblank주장을 확장하지 않는다는 사실은 \equal두 테스트의 동작에 차이가 있음을 의미합니다.

비교하다

\documentclass[]{article}
\usepackage{amsmath}
\usepackage{etoolbox}
\usepackage{ifthen}

\newcommand*{\imblank}{}

\begin{document}
\ifthenelse{\equal{\imblank}{}}
  {T}
  {F}

\ifblank{\imblank}
  {T}
  {F}
\end{document}

답변2

테스트 \ifthenelse가 좀 취약하네요. 빈 선택적 인수에 대처하는 훨씬 더 좋은 방법이 있습니다.

xparse나타나지 않는 선택적 인수에 대한 테스트는 인수 유형을 사용하여 가능 합니다 o. 필요할 때 \pr*삽입하기 위해 다른 명령 대신 사용하면 훨씬 더 나은 정의가 가능하기 때문에 내가 주석 처리한 "쉬운 정의"를 참조하십시오.\substack

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}

%%% Easy version
%\NewDocumentCommand{\pr}{om}{%
%  \IfNoValueTF{#1}
%   {% no optional argument
%    \Pr[\,#2\,]%
%   }
%   {% optional argument is expressed
%    \Pr_{#1}[\,#2\,]%
%   }%
%}
%%% Better version
\NewDocumentCommand{\pr}{som}{%
  % * = use substack
  % #2 = optional
  % #3 = mandatory
  \Pr\IfValueT{#2}{_{\IfBooleanTF{#1}{\substack{#2}}{#2}}}[\,#3\,]
}

\begin{document}

\begin{gather*}
\pr{a = 0 \mid b = 0}
\\
\pr[b \leftarrow \{0,1\}]{a = 0 \mid b = 0}
\\
\pr*[a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}]{a = 0 \mid b = 0}
\end{gather*}

\end{document}

무슨 일이야? 선택적 인수가 나타나지 않으면 \IfNoValueTF실제 분기를 반환하고, 그렇지 않으면 거짓 분기를 반환합니다. 이는 으로 반전됩니다 \IfValueTF. 여기서는 \IfValueT선택적 인수가 누락된 경우 아무 작업도 수행할 필요가 없기 때문에 로 축약할 수 있습니다.

이 조건부 텍스트 내에서는 또 다른 조건부를 사용합니다. *뒤에 존재하는 \pr경우 \IfBooleanTF실제 분기를 반환하고 선택적 인수는 으로 둘러싸여 있습니다 \substack. 그렇지 않으면 일반 인수가 사용됩니다.

여기에 이미지 설명을 입력하세요

답변3

[ 사용되는 경우] 선택적 인수가 \protect필요 합니다 .\substack\ifthenelse

\documentclass[]{article}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{ifthen}
\setlength{\parindent}{0pt}

\newcommand*{\pr}[2][]{\ifthenelse{\equal{#1}{}}{\Pr[\,#2\,]}{\Pr_{#1}[\,#2\,]}}

\newcommand*{\pra}[2][]{\ifthenelse{\equal{#1}{}}{\Pr[\,#2\,]}{\Pr_{\substack{#1}}[\,#2\,]}}

\begin{document}
This works:
\[\pr{a = 0 \mid b = 0}\]
\[\pr[b \leftarrow \{0,1\}]{a = 0 \mid b = 0}\]
\[\Pr_{\substack{a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}}} [a = 0 \mid b = 0]\]
This [no longer] fails with \verb|\protect|:
 \[\pr[\protect\substack{a \leftarrow \{0,1\}}]{a = 0 \mid b = 0}\]
 \[\pr[\protect\substack{a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}}]{a = 0 \mid b = 0}\]

But if I put substack inside, it works:
\[\pra[a \leftarrow \{0,1\}]{a = 0 \mid b = 0}\]
\[\pra[a \leftarrow \{0,1\}\\b \leftarrow \{0,1\}]{a = 0 \mid b = 0}\]

\end{document}

여기에 이미지 설명을 입력하세요

관련 정보