2

For example, if I want to define a command produces functions with given name, I use the following code:

\NewDocumentCommand \fun { m e{\sp\sb} O{} } 
  { 
    \operatorname{\mathrm{#1}}
    \IfNoValueTF{#2}{}{\sp#2}
    \IfNoValueTF{#3}{}{\sb#3}
    \ifblank{#4}{}
      {\left(#4\right)} 
  }

or the following one:

\NewDocumentCommand \fun { m e{^_} O{} } 
  { 
    \operatorname{\mathrm{#1}}
    \IfNoValueTF{#2}{}{\sp#2}
    \IfNoValueTF{#3}{}{\sb#3}
    \ifblank{#4}{}
      {\left(#4\right)} 
  }

However, they have problems: the first one only accepts one character as the argument #2 and #3, while the latter makes all following characters (including those that should be viewed as argument #4) as the argument #2 or #3.

How to fix this?

1 Answer 1

2

You need to enclose the arguments in braces, otherwise TeX will only use the first one in the sub/superscript. Also, \IfValueT{#2}{\sp{#2}} is easier than \IfNoValueTF{#2}{}{\sp{#2}}, and I also defined a \IfBlankTF using expl3:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new_eq:NN \IfBlankTF \tl_if_blank:nTF
\ExplSyntaxOff
\NewDocumentCommand \fun { m e{^_} O{} }
  {%
    \operatorname{#1}%
    \IfValueT{#2}{\sp{#2}}%
    \IfValueT{#3}{\sb{#3}}%
    \IfBlankTF{#4}{}
      {\left(#4\right)}%
  }
\begin{document}
\(\fun{blub}_{foo}^{bar}[zzz]\)
\end{document}

enter image description here

Also, with the next xparse update (TL'20), when you define a token as delimiter, like in:

\NewDocumentCommand \fun { e{\sp\sb} } { ... }

then the e argument will only match if you have the literal tokens \sp and \sb in the document (that is, \fun\sp{arg1}\sb{arg2}), but not if you have some token with the same meaning, like \fun^{arg1}_{arg2}. Same thing if you define:

\NewDocumentCommand \fun { e{^_} } { ... }

then the function will match \fun^{arg1}_{arg2} but not \fun\sp{arg1}\sb{arg2}.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .