# Command defined with \NewDocumentCommand and specifiers {O{strict} m} not receiving all of the mandatory parameter

I defined a command using \NewDocumentCommand with specifiers {O{strict} m}. I expected #1 to default to strict when calling the command with only a parameter enclosed in {}, and to pick up all of the text in {} for #2. What is happening instead is that the \strictn command is receiving only the first character of the second parameter unless I specify it with double braces, e.g., \strictn[*]{{star}}.

A secondary problem is that the test of a trailing hyphen in #1 (the optional parameter) is failing.

\documentclass{article}
\usepackage{mathtools}
\usepackage{xparse}

\ExplSyntaxOn

% Render underscored with some variation of strict
\NewDocumentCommand{\strictn}{O{strict} m}
{
\str_if_eq:nnTF {\str_item:nn {#1} {-1}} {-}
{
\show_strict:nn {{#1}strict} {#2}
}
{
\show_strict:nn {#1} #2
}
}

\cs_new:Npn \show_strict:nn #1 #2
{
\msg_term:n {show_strict \ P1 \ = \ #1}
\msg_term:n {show_strict \ P2 \ = \ #2}
\str_if_eq:nnTF {#1} {*}
{\underset{\mathrm {(semi-strict,strict)}{#2}}}
{\underset{\mathrm {{#1}}{#2}}}
}

\ExplSyntaxOff

\begin{document}

\begin{enumerate}
\item Test $\strictn{default}$
\item Test $\strictn[semi-]{hyphen}$
\item Test $\strictn[*]{star}$
\end{enumerate}

\end{document}

I didn't initially give the intended appearance because I was asking about the tokenization rather than about the rendering. For the curious, it depends on the optional parameter. In all cases the macro is used in math mode and only the text set under the mandatory is upright.

1. Optional parameter missing: underset with (semi-strict,strict)
2. Optional parameter ends in hyphen (-): underset with #1 concatenated with strict
3. Optional parameter present and doesn't end with hyphen: underset with #1
• You seem to be missing a pair of braces here: \show_strict:nn {#1} #2 – Werner Jan 25 '19 at 0:08
• With braces around the parameter numbers I get "! Illegal parameter number in definition of \show_strict:nn. <to be read again> 1 l.665 \cs_new:Npn \show_strict:nn {#1 } {#2}" – shmuel Jan 25 '19 at 20:53

The main problem is the wrong syntax in \underset: if you want both parts to be typeset upright, it should be

\underset{\textrm{#1}}{\textrm{#2}}

You're trying to use a single \textrm which is not going to work. The problem is masked by the fact that you're missing a pair of braces in \show_strict:nn {#1} #2 that should be \show_strict:nn {#1} {#2}.

\documentclass{article}
\usepackage{mathtools}
\usepackage{xparse}

\ExplSyntaxOn

% Render underscored with some variation of strict
\NewDocumentCommand{\strictn}{O{strict} m}
{
\str_if_eq:eeTF {\str_item:nn {#1} {-1}} {-}
{
\show_strict:nn {{#1}strict} {#2}
}
{
\show_strict:nn {#1} {#2}
}
}

\cs_new_protected:Npn \show_strict:nn #1 #2
{
\iow_term:n {show_strict ~ P1 ~ = ~ #1}
\iow_term:n {show_strict ~ P2 ~ = ~ #2}
\str_if_eq:nnTF {#1} {*}
{\underset{\textrm {(semi-strict,strict)}}{\textrm{#2}}}
{\underset{\textrm {{#1}}}{\textrm{#2}}}
}

\ExplSyntaxOff

\begin{document}

\begin{enumerate}
\item Test $\strictn{default}$
\item Test $\strictn[semi-]{hyphen}$
\item Test $\strictn[*]{star}$
\end{enumerate}

\end{document}

• I don't want both parts to be set upright. Also, I see that you silently changed the code to use \cs_new_protected:Npn instead of \cs_new:Npn, and that's what is relevant. – shmuel Jan 25 '19 at 21:53
• There's still a problem with recognizing a trailing hyphen. – shmuel Jan 25 '19 at 21:55
• @shmuel I tried to guess from the input you gave. Did you perhaps specify what the appearance should be? I'll fix the hyphen in a moment, but for the final appearance you need to help. – egreg Jan 25 '19 at 21:59
• @shmuel The protected is not relevantl; that function should be, according to the guidelines. The code would work the same with \cs_new:Nn, it's just the wrong type of definition. – egreg Jan 25 '19 at 22:02
• I ran a test; it works with \cs_new_protected:Nnn but not with \cs_new:Nn. – shmuel Jan 25 '19 at 22:19