[Tex/LaTex] Xparse’s new e-type argument (replacement for k-type argument)

macrosoptional argumentsxparse

Accoring to Joseph Wright's answer at Optional Parameters in xparse: \IfBooleanTF vs \IfNoValueTF

The k-type argument has recently been adjusted: you now want e-type

Questions:

  1. What is the functionality of the new e-type argument and how does it differ from the previous k-type argument?

  2. The 2016-11-21 version of the xparse documentation does not mention the k-type argument at all. Is the plan to leave the earlier k functionality intact (but deprecated so no documentation) or will it eventually be removed and any usage of that should eliminated? If the plan is for it to be removed, how long will the older k-type argument functionality be kept in xparse.

Code:

Example of the k-type argument from
Xparse t argument type (underscore with optional parameter). Would be useful to see how this would be modified to use the new e-type argument.

\documentclass{article}

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

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

\begin{document}

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

Without any subscript: $\MyMacro$ 

\end{document}

Best Answer

The k argument type is not available any longer.

There is a big difference between the old k and the new e type. With

e{ABC}

(here A, B and C represent any three distinct tokens) the macro will look for any sequence of tokens in the form A{x}B{y}C{z}, but the order is arbitrary, so

A{x}B{y}C{z}
B{y}A{x}C{z}
C{z}B{y}A{x}

will result in the same token list to be passed in the macro replacement text as #<n>. Repeating one of the stated tokens will result in stopping the search for the next, so

A{x}A{Ouch}B{y}C{z}

will be the same as passing just A with argument {x} and nothing for the other two tokens.

The argument is normalized with respect to the order and #<n> will represent a sequence of braced token lists, with -NoValue- for the missing ones. For instance

\NewDocumentCommand{\test}{ e{ABC} }{%
  \showtokens{#1}%
}

with the input

\test
\test A{x}
\test A{x}B{y}C{z}
\test B{y}C{z}A{x}
\test B{y}A{x}C{z}
\test A{x}B{y}
\test C{z}

will result in showing

> {-NoValue-}{-NoValue-}{-NoValue-}.
> {x}{-NoValue-}{-NoValue-}.
> {x}{y}{z}.
> {x}{y}{z}.
> {x}{y}{z}.
> {x}{y}{-NoValue-}.
> {-NoValue-}{-NoValue-}{z}.

The consequence is that you should pass #1 to another macro for subsequent processing, even if there is only one embellishment prefix token; such a macro must have the required number of mandatory arguments.

\documentclass{article}

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

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

\begin{document}

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

Without any subscript: $\MyMacro$

\end{document}

Note that no braces should surround #1 in the code for \MyMacro. This is the normal procedure for “processed arguments”.

Update June 2017

The newer versions of xparse made a breaking change related to the e and E argument types. Now e<tokens> returns one argument in the replacement text for each token in <tokens>, so the code for this case must become

\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}

The argument(s) will contain -NoValue- (testable with \IfNoValueTF) if the corresponding token is not found.

Related Question