6

I am not understanding how to use the t type parameter with xparse's \NewDocumentCommand.

I am trying to define a macro that accepts one optional parameter, but the optional parameter is specified as a subscript using an underscore. That is I want to define something that behaves like

\def\MyMacro_#1{A_{\textcolor{red}{#1}}}

but with the subscript being optional. I need #1 to be parameter not simply a subscript added outside of the macro (i.e., \MyMacro must be the one that invokes the actual subscript)

The MWE below yields:

enter image description here

but the desired result is:

enter image description here

with the color and subscript applied by \MyMacro.

Notes:

  • The documentation states that t is

    An optional ⟨token⟩, which will result in a value \BooleanTrue if ⟨token⟩ is present and \BooleanFalse otherwise. Given as t⟨token⟩.

    but no examples are given.

Code:

\documentclass{article}

\usepackage{amsmath} \usepackage{xparse} \usepackage{xcolor}

%\newcommand*{\MyMacro}[1][]{}% Ensure we are not overwriting anything %\def\MyMacro_#1{A_{\testcolor{red}{#1}}}% <-- Want this behavior but with the _{#1} being optional

\NewDocumentCommand{\MyMacro}{t_}{% \IfBooleanTF{#1}{% A_{\textcolor{red}{#1}} }{% \mathbf{A} }% }

\begin{document}

With a subscript: $\MyMacro_{\pi}$

Without any subscript: $\MyMacro$

\end{document}

Peter Grill
  • 223,288

3 Answers3

5

Looks like an e-type argument to me

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}
\usepackage{xcolor}

\NewDocumentCommand\MyMacro{e_}{%
    \IfNoValueTF{#1}{%
        \mathbf{A}
    }{%
        A_{\textcolor{red}{#1}}
    }%
}

\begin{document}

With a subscript: $\MyMacro_{\pi}$ 

Without any subscript: $\MyMacro$ 

\end{document}
Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • If you are adding % to those lines even in math mode, you are missing two :) I like that k has been implemented. – Manuel Jul 13 '16 at 21:50
  • Works great, except that k is marked as experimental so hesitant to use it at this time. – Peter Grill Jul 13 '16 at 21:52
  • @PeterGrill Joseph is allowed to experiment with his own code though:-) – David Carlisle Jul 13 '16 at 22:32
  • @DavidCarlisle: :-). I just meant it as a reason that this was not the accepted answer. – Peter Grill Jul 13 '16 at 23:52
  • The k-type works great when things get more complicated (such as having both _ and ^ optional), so wondering when you think this will become non-experimental and be a permanent feature of xparse? – Peter Grill Jul 14 '16 at 04:46
  • @PeterGrill I personally think this is probably going to stay. It's useful in general, and definitely now that there's no handling of super/sub-scripts. For me, ideally, in the future, apart from k_ k^, it might be good to have more automation in particular for math sub/super-scripts, like i_ i^ that will check for \foo_{a}^{b} but also for \foo^{b}_{a}. But k and K are definitely useful, and are (hopefully) going to stay. – Manuel Jul 14 '16 at 06:27
  • It's down as experimental as there are some interface questions (we considered allowing a variable order of the type k{_^}, but this didn't quite feel right over all): what is needed is some testing/use cases. @Manuel The problem with allowing k^k_ to be equal to k_k^ was that it breaks the mapping between letters in the spec and the argument number, whilst allowing k{_^} has a similar concern. There's also the question of whether we really want to allow definitions emulating TeX primitive syntax (as TeX's parsing here is subtly different). One for LaTeX-L. – Joseph Wright Jul 14 '16 at 06:32
  • @JosephWright For me it's enough, and I think it's right, k_ k^ (you can even tell the users that subscript go before superscripts), but I don't think it's too complex to map i_ i^ so that \foo_{a}^{b} and \foo^{b}_{a} are read exactly the same (#1=a and #2=b). My point was to say to Peter that this is the way to go to solve this particular problem, at least this is the intended interface. – Manuel Jul 14 '16 at 06:37
  • 1
    @Manuel This type of discussion is the reason the interface is down as experimental – Joseph Wright Jul 14 '16 at 07:28
  • It's been altered and renamed to e. Now use e{_^} instead of the former k_ k^. – Bruno Le Floch Feb 12 '17 at 17:04
  • @BrunoLeFloch If we use e{_^} does that count as two arguments? Or just one with two optional tokens? How do we check to work depending of those optional tokens? I see the documentation has been updated and also accepts { m O{self referential #1} O{#2^2} } I like that :) – Manuel Feb 12 '17 at 18:15
  • @Manuel Currently as one: it's still experimental and we are still not sure what is best :) – Joseph Wright Feb 12 '17 at 19:16
3

The t argument specifier is a generalization of s that is the same as t*.

I don't think it's the right approach, but if you really want to go this way:

\NewDocumentCommand{\MyMacro}{t_}{A\IfBooleanT{#1}{\MyMacroAux}}
\NewDocumentCommand{\MyMacroAux}{m}{_{\textcolor{red}{#1}}}

Full example:

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}
\usepackage{xcolor}

\NewDocumentCommand{\MyMacro}{t_}{A\IfBooleanT{#1}{\MyMacroAux}}
\NewDocumentCommand{\MyMacroAux}{m}{_{\textcolor{red}{#1}}}

\begin{document}

With a subscript: $\MyMacro_{\pi}$

Without any subscript: $\MyMacro$

\end{document}

enter image description here

In case the first part also depends on the presence of _:

\NewDocumentCommand{\MyMacro}{t_}{%
  \IfBooleanTF{#1}
    {A\MyMacroAux}
    {\mathbf{A}}%
}
\NewDocumentCommand{\MyMacroAux}{m}{_{\textcolor{red}{#1}}}
egreg
  • 1,121,712
2

Is this what is meant?

The t_ check works, but \textcolor{red}{#1} will try to typeset _ then, so {\pi} never enters the subscript.

In my opinion, the {\pi} is an 2nd optional argument. Either use g or the G{} type to grab this.

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}
\usepackage{xcolor}

%\newcommand*{\MyMacro}[1][]{}% Ensure we are not overwriting anything
%\def\MyMacro_#1{A_{\testcolor{red}{#1}}}% <-- Want this behavior but with the _{#1} being optional

\NewDocumentCommand{\MyMacro}{t_G{}}{%
  \IfBooleanTF{#1}{%
    A_{\textcolor{red}{#2}}
  }{%
    \mathbf{A}
  }%
}

\begin{document}

With a subscript: $\MyMacro_{\pi}$ 

Without any subscript: $\MyMacro$ 

\end{document}

enter image description here