7

Is it possible to write a macro that detects whether there is a | character in its arguments, and expands that to something else?

In concrete terms, I want to be able to use the following definitions simultaneously:

\def\P(#1){\Pr\left( #1 \right)}
\def\P(#1|#2){\Pr\left( #1 \mid #2 \right)}

Whenever in the text I write a probability $\P(X)$, the first definition should be used, whereas $\P(X|Y)$ should use the second.

If possible, a simple TeX/LaTeX solution is preferred, since many journals put restrictions on usable packages.

I know this could be achieved using simply two different macros. The reason for this question is that the abstract of a paper often ends up printed in plain text (think the arXiv email), and I would like it to be as readable as possible.

2

This can differentiate the argument as you requested.

\documentclass{article}
\def\P(#1){\Phelper#1|\relax\Pchoice(#1)}
\def\Phelper#1|#2\relax{\ifx\relax#2\relax\def\Pchoice{\Pone}\else\def\Pchoice{\Ptwo}\fi}
\def\Pone(#1){\Pr\left( #1 \right)}
\def\Ptwo(#1|#2){\Pr\left( #1 \mid #2 \right)}
\def\Pr{\mathbf{Pr}}
\begin{document}
$\P(A)$ or $\P(A|B)$
\end{document}

enter image description here

If your arguments are always short, then a simpler \def\P(#1){\Pr(#1)} may be sufficient for your need. But since you are using \left(...\right), it might be the case that you want to handle tall arguments. In that case, I would replace \mid with \,\middle|\, so that you could achieve the following, which works in both text style and display style:

\documentclass{article}
\def\P(#1){\Phelper#1|\relax\Pchoice(#1)}
\def\Phelper#1|#2\relax{\ifx\relax#2\relax\def\Pchoice{\Pone}\else\def\Pchoice{\Ptwo}\fi}
\def\Pone(#1){\Pr\left( #1 \right)}
\def\Ptwo(#1|#2){\Pr\left( #1 \,\middle|\, #2 \right)}
\def\Pr{\mathbf{Pr}}
\begin{document}
\centering$\P(A)$ or $\P(A|B)$

\[\P(\displaystyle\frac{x}{2}>1 | x>0) = 0.5\]
\end{document}

enter image description here

  • Perfect, thank you. It's necessary to differentiate the argument because the non-\mid vertical bar does not look right. – user53911 Jun 3 '14 at 13:11
6

I don't think you gain too much by having \P(A|B) in the source rather than \P{A|B}. Also, redefining \P is not a good idea.

Anyway, here's a redefinition of \Pr, which exploits mathtools so it can receive an optional size argument or the * that denotes automatic resizing.

\documentclass{article}
\usepackage{mathtools,xparse}

\RenewDocumentCommand\Pr{sO{}r()}{%
  \operatorname{Pr}%
  \begingroup
  \IfBooleanTF{#1}
    {\PrInn*{#3}}
    {\PrInn[#2]{#3}}%
  \endgroup
}

\DeclarePairedDelimiterX\PrInn[1](){%
  \activatebar
  #1%
}

\newcommand{\activatebar}{%
  \begingroup\lccode`~=`|
  \lowercase{\endgroup\def~}{\;\delimsize\vert\;}%
  \mathcode`|=\string"8000
}

\begin{document}
\[
\Pr(a)\quad
\Pr(x|y)\quad
\Pr[\big](x|y)\quad
\Pr*(\frac{X}{2}|\frac{Y}{2})
\]
\end{document}

enter image description here

2

Here is my take on this

\usepackage{mathtools}
\providecommand\given{} % so it exists
\DeclarePairedDelimiterX\PH[1](){
   \renewcommand\given{\nonscript\:\delimsize\vert\nonscript\:}
   #1
}
\newcommand\Prop{\operatorname{Pr}\PH}

Then use

\[
    \Prop{ A } \qquad \text{or}\qquad \Prop{ A \given B}
\]

this include auto scaling of () and \vert if you use \Prop*. The very recent mathtools has a macro to make \Prop at one go.

Note I do not make the () a part of the syntax, and I perfer space around the |

  • @ daleif: Why not simply DeclarePairedDelimiter\Prob[1](){\providecommand\given{\nonscript\:\delimsize\vert\nonscript\:}#1 }? – Bernard Jun 3 '14 at 13:48
  • (1) my bad, has to be \DeclarePairedDelimiterX, (2) yours is not enough, you cannot get the Pr in front. That is what the \DeclarePairedDelimiterXPP from the latest very mathtools can do. – daleif Jun 3 '14 at 13:52
  • 1
    (1) yes, sorry for the typo. Thanks for the information about \DeclarePairedDelimiterXPP. – Bernard Jun 3 '14 at 14:13
1

I wouldn't use \left ..\mid ...\right in this simple case:

\documentclass{article}
\makeatletter
\def\P(#1){\expandafter\P@i#1||\@nil}
\def\P@i#1|#2|#3\@nil{\ifx\relax#2\relax \Pr(#1)\else\Pr( #1|#2 )\fi}
\def\Pr{\mathbf{Pr}}
\makeatother
\begin{document}

$\P(A)$ or $\P(A|B)$

\end{document}

enter image description here

  • This is a nice succinct macro to achieve the desired result, thanks. However, I prefer the extra spacing when using \mid, that's why I did not just write \Pr(A|B) in the first place. – user53911 Jun 3 '14 at 14:07
  • 1
    Feel free to use it. Changing the above code is easy – user2478 Jun 3 '14 at 14:27
0

If your main interest is to replace | with \mid if it exists, you can perform a search-and-replace via etoolbox's \patchcmd:

enter image description here

\documentclass{article}
\usepackage{mleftright,etoolbox,xparse}

\makeatletter
\DeclareDocumentCommand{\Pr}{R(){}}{%
  % \patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>}
  \def\pr@arg{#1}\patchcmd{\pr@arg}{|}{\mid}{}{}%
  \mathbf{Pr}\mleft(\pr@arg\mright)%
}
\makeatother

\begin{document}

$\Pr(A)$ or $\Pr(A|B)$ or $\Pr(\frac{1}{2}|\frac{2}{3})$

\end{document}

Note that \displaystyle will typically cause problems with the vertical size of | (or \mid). Perhaps a replacement could also be \,\middle|\,.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy