# How define LaTeX command with 2 or 3 arguments in comma-separated list

To avoid typing subscripts and extra parentheses and brackets, I want to define a command, say \disk, that may be used with a comma-separated list of either 2 or 3 arguments, like this:

$\disk{r,x}$
$\disk{r,x,d}$


that will produce, respectively, the same output as would directly typing:

$D_{r}(x)$
$D_{r}(x;d)$


[The r, x, and d could, of course, by any letter or number, etc. For example, I might use \disk{\epsilon, 0, D}, etc.]

Using xparse or otherwise, how might this be done?

Although I am aware that the two different outputs could be obtained by using an optional argument, that would require typing the 3rd, optional argument inside brackets; and in any case even for the case of only two arguments, I want to speed up typing by using just the comma-separated list {x, d} rather than {x}{d}.

You have to assume there are three items; if there aren't, the missing ones are automatically passed to the inner macro as “No Value”.

Then the inner macro can check for the value being given.

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\disk}{ >{\SplitArgument{2}{,}} m }{\printdisk#1}
\NewDocumentCommand{\printdisk}{mmm}{D_{#1}(#2\IfValueT{#3}{;#3})}

\begin{document}

$\disk{r,x}$

$\disk{r,x,s}$

\end{document}


A different implementation:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\disk}{m}
{
% split the input at commas
\seq_set_split:Nnn \l_murray_disk_input_seq { , } { #1 }
% remove the leftmost item
% print; _ is not available here
(\seq_use:Nn \l_murray_disk_input_seq { ; })
}
\seq_new:N \l_murray_disk_input_clist
\ExplSyntaxOff

\begin{document}

$\disk{r,x}$

$\disk{r,x,s}$

\end{document}

• However, typing $D_{r}(x;s)$ seems easier – egreg Aug 28 '16 at 20:07
• Not easier to type for me! Without the macro, the direct way requires a separate finger reach for _ and either typing the pair of braces around the subscript or else (in TeXShop) moving the cursor beyond the automatically supplied pair of braces. With the macro, I don't have to stop each time to think whether I want a comma or a semicolon before the 3rd item (the metric), and should I change my mind about that style, I can do it just once, within the macro definition. – murray Aug 28 '16 at 20:26
• The real trick in the Answer is that \printdisk uses the triple-m expression mmm even when I use \disk with only 2 items in the comma-separated list. – murray Aug 28 '16 at 20:28
• Oops, doesn't work for something like $\disk{\epsilon,(1,2),\rho}$. My workaround for that is $\disk{\epsilon,{(1,2)},\rho}$ -- a slight annoyance of extra braces. – murray Aug 28 '16 at 20:36
• @murray If you plan to use something like (1,2), then change the delimiter in the argument, say ; – egreg Aug 28 '16 at 20:38

We can do this at TeX primitive level without any xparse or another package. Note, there are only two lines of code.

\def\disk#1{\diskA#1,,\end}
\def\diskA#1,#2,#3,#4\end{D_{#1}\ifx,#3,(#2)\else (#2;#3)\fi}

$\disk{r,x}$

$\disk{r,x,s}$

\end


If you need to do something like this $\disk{\epsilon,(1,2),\rho}$ then add one line of code:

\def\disk#1{\diskA#1()\end}
\def\diskA#1(#2)#3\end{\ifx\end#3\end\diskB#1,,\end \else\diskA#1{(#2)}#3\end \fi}
\def\diskB#1,#2,#3,#4\end{D_{#1}\ifx,#3,(#2)\else (#2;#3)\fi}

$\disk{r,x}$

$\disk{r,x,s}$

$\disk{\epsilon,(1,2),\rho}$

\end

• Hard now for me to choose which answer to accept: your pure TeX method is nicely terse, yet the more complicated LaTeX (with xparse) seemingly leaves things at the higher level of abstraction that avoids TeX primitives. Wish I could accept both! – murray Aug 30 '16 at 20:18