[Tex/LaTex] xparse: Define new command with multiple optional parameters

latex3macrosxparse

I'd like to define a new command with optional parameters using the xparse package. Please consider the following example:

\documentclass{minimal}
\usepackage{xparse}

\DeclareDocumentCommand{\mycommand}{ O{mydefault} m o o o }{%
        p:#2%
        \IfNoValueTF{#3}%
            {}%
            { p:#3}%
        \IfNoValueTF{#4}%
            {}%
            { p:#4}%
        \IfNoValueTF{#5}%
            {}%
            { p:#5}
        p:#1
}
\begin{document}
\mycommand[one]{two} \par % p:two p:one
\mycommand[one]{two}[three] \par % p:two p:three p:one
\mycommand[one]{two}[three][four] \par % p:two p:three p:four p:one
\mycommand[one]{two}[three][four][five] \par % p:two p:three p:four p:five p:one
\mycommand[one]{two}[three][][five] \par % p:two p:three p: p:five p:one
\mycommand[one]{two}[][][five] % p:two p: p: p:five p:one
\end{document}

enter image description here

The problem now is that when I'm leaving some parameters empty between two others that are filled in, LaTeX also displays those empty parameters. Applied to the last example I'd like to get p:two p:five p:one.

Best Answer

You have to make an additional comparison on those arguments specified as [], which technically differ from \NoValue. And, you can't just leave them out, since subsequent optional arguments would then be used out-of-sequence. You can use the ifmtarg package:

enter image description here

\documentclass{minimal}
\usepackage{xparse}% http://ctan.org/pkg/xparse
\usepackage{ifmtarg}% http://ctan.org/pkg/ifmtarg
\makeatletter
\DeclareDocumentCommand{\mycommand}{ O{mydefault} m o o o }{%
        p:#2%
        \IfNoValueTF{#3}%
            {}%
            {\@ifmtarg{#3}{}{ p:#3}}%
        \IfNoValueTF{#4}%
            {}%
            {\@ifmtarg{#4}{}{ p:#4}}%
        \IfNoValueTF{#5}%
            {}%
            {\@ifmtarg{#5}{}{ p:#5}}
        p:#1
}
\makeatother
\begin{document}
\mycommand[one]{two} \par % p:two p:one
\mycommand[one]{two}[three] \par % p:two p:three p:one
\mycommand[one]{two}[three][four] \par % p:two p:three p:four p:one
\mycommand[one]{two}[three][four][five] \par % p:two p:three p:four p:five p:one
\mycommand[one]{two}[three][][five] \par % p:two p:three p:five p:one
\mycommand[one]{two}[][][five] % p:two p:five p:one
\end{document}
Related Question