TransWikia.com

How can I process each element of SplitArgument succinctly?

TeX - LaTeX Asked by Grayscale on May 13, 2021

I am trying to create some functions that handle conditional probability nicely. So far, I have the following:

usepackage{xparse}

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

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

This seems to work nicely. Now, I want to write a new function problm which does the same thing as prob, but it wraps each of the (1 or possibly 2) arguments in texttt. (The lm in problm indicates language model; when writing probabilities in the context of language models, I want to skip having to write texttt around all the inputs to prob.)

In trying to do this, I tried the following:

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

However, this does not work. Why does this fail? And how can I accomplish what I am trying to do in a clean, succinct way? Ideally the solution would only use default or xparse commands, though if there is a much simpler solution with an entirely different tool set then that could be useful too!

By the way, I know that I could just write a new function problmc which looks almost like probc but has some texttts inserted, but I would like to reuse the underlying probc function.

2 Answers

Your ProcessList isn't evaluated before probc, so as arguments probc takes ProcessList and {#1}, which obviously isn't what you want. Instead, you can introduce another wrapper macro that will put texttt around your input.

documentclass[]{article}

usepackage{xparse}
usepackage[]{amssymb}

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

NewDocumentCommand probc { m m }
  {mathbb{P}!left(#1IfValueT{#2}{;middlevert;#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}

enter image description here

Answered by Skillmon on May 13, 2021

I would define a generic command, to which we can pass the “decoration” for the real arguments we want.

It seems more complicated than you expect, because I really don't like using left and right unconditionally.

You can follow the various cases to see how the size of the parentheses and of the middle delimiter is chosen.

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|}}#4mathclose{#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*{bigcuplimits_{gin B_j}g(R)}$; this uses the
dreaded verb|limits|, but even without it the result is not optimal:
compare $prob*{bigcup_{gin B_j}g(R)}$ with $prob[big]{,bigcup_{gin B_j}g(R)}$
and judge for yourself.
begin{gather*}
prob{x}neprob{x|y}

prob[Big]{x}neprob[bigg]{x|y}

prob*{frac{x}{2}}neprob*{frac{x}{2}|y}

problm{x}neproblm{x|y}

problm[Big]{x}neproblm[bigg]{x|y}

problm*{frac{x}{2}}neproblm*{frac{x}{2}|y}
end{gather*}
Inspiring picture at texttt{https://math.stackexchange.com/q/4038452/62967}

end{document}

Of course, the last line doesn't really make sense, it's just for illustration.

The paragraph before the displayed equations shows why automatic sizing is not the best. I believe that the example is self-explanatory. In the formula using big, a thin spaces was needed. Typesetting is not simple, but with some experience, these clashes will be seen even before looking at the printout.

What about ensuremath? You just lose semantics in exchange of two keys.

Most important: how does prob not have an argument? Because its definition consists of genericprob{} and the rest of the arguments are grabbed by this more general macro. This avoids code duplication: we can define problm and other commands with different “decorations”.

enter image description here

Answered by egreg on May 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP