
조금 바보 같은 느낌이 들지만 왜 내 인수 안에 매크로를 넣을 수 없습니까 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}