14

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

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.

  • 1
    1) this should really be part of the documentation, which right now makes anybody get stuck grasping how the 'e'-type arguments work, and 2) was the indirection through another macro needed? Couldn't the embellishment values simply be passed to the main command as #1 #2 #3 etc... after normalizing the order? – gigabytes Mar 3 '17 at 10:29
  • 1
    Also, why is a transition path not available? I realize the 'k' argument type was marked as experimental, but a period of availability of both with a deprecation warning would have been appreciated. I have tons of documents where I use a macro defined in this way that do not compile anymore (and I have lot of coauthors, less proficient in LaTeX, that get stuck much more than me when trying to compile them) – gigabytes Mar 3 '17 at 10:33
1

Since I spent some time to apply the answer of egreg with several parameters I provide another MWE which I used:

\documentclass{article}
\usepackage{xparse}
\usepackage{xstring}

\NewDocumentCommand\Median{O{s} m e{_}}{%
  \MyMedian{#1}{#2}#3%
}
\NewDocumentCommand\MyMedian{m m m}{%
  \IfNoValueTF{#3}{\gdef\temp{0,5}}{\gdef\temp{0,5;#3}}%
  \IfSubStr{s}{#1}{#2_{\temp}}{}%
  \IfSubStr{e}{#1}{\uppercase{#2}_{\temp}}{}%
}

\begin{document}
$$\Median{x}$$      % x_{0.5}   median of a sample
$$\Median{x}_i$$    % x_{0.5,i} median of subgroup i in a sample
$$\Median[e]{x}$$   % X_{0.5}   sample median (random variable)
$$\Median[e]{x}_i$$ % X_{0.5,i} sample median of subgroup i (random variable)
\end{document}
  • It should be \MyMedian{#1}{#2}#3 I believe. – Manuel Mar 15 '17 at 13:33

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.