# Command to make comma separated commands

I'm trying to create a command, called \newcscommand, that lets me define commands with values separated by commas.

Here's what I have so far

\documentclass{article}
\usepackage{xparse}

\newcommand{\newcscommand}[3]{
\NewDocumentCommand{ #1 }{ >{\SplitArgument{#2 - 1}{,}}m }{\csname aux\endcsname##1} % the auxiliary command should be named 'auxtest' instead of just aux
\newcommand{\aux}[#2]{#3} % same here
}

\newcscommand{\test}{3}{#1 is #2 a #3.}
\begin{document}
\test{This, just, test}
\end{document}


I use an auxiliary command to split the comma separated list, which should be called 'aux + the name of the command', however I couldn't get it to work so I left it as 'aux' in the MWE, which is if of course wrong because if I call newcscommand twice I'll get an error.

I know that I have to use csname and endcsname somehow, but I haven't figured it out.

How can I get this to work? Is there a totally different and better way to do this that I don't know about?

Your idea is good, but proper expl3 programming is better:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\newcscommand}{mO{0}m}
{
\NewDocumentCommand{#1}{ >{\SplitArgument{#2-1}{,}}m }
{
\use:c { __noibe_\cs_to_str:N #1:\prg_replicate:nn{#2}{n} } ##1
}
\cs_new:cn { __noibe_\cs_to_str:N #1:\prg_replicate:nn{#2}{n} } { #3 }
}

\ExplSyntaxOff

\newcscommand{\test}[3]{#1 is #2 a #3.}

\begin{document}

\test{This, just, test}

\end{document}


Note that the syntax of \newcscommand is similar to \newcommand.

The trick is indeed to create a macro with the correct number of arguments in its signature.

A variant that avoids calling \use:c and \prg_replicate:nn each time \test is executed, because the control sequence name is built at definition time thanks to \exp_not:c.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\newcscommand}{mO{0}m}
{
\exp_args:Nnne \NewDocumentCommand{#1}{ >{\SplitArgument{#2-1}{,}}m }
{
\exp_not:c { __noibe_\cs_to_str:N #1:\prg_replicate:nn{#2}{n} } ##1
}
\cs_new:cn { __noibe_\cs_to_str:N #1:\prg_replicate:nn{#2}{n} } { #3 }
}
\exp_args_generate:n { nne }

\ExplSyntaxOff

\newcscommand{\test}[3]{#1 is #2 a #3.}

\begin{document}

\test{This, just, test}

\end{document}

• Thanks for the feedback. How can I extend this to a renewcscommand command? I tried simply copy-pasting it, with the substitution \exp_args:Nnne \NewDocumentCommand -> \exp_args:Nnne \RenewDocumentCommand, but that didn't work too well. – noibe Nov 2 '19 at 0:13
• @noibe Change also \cs_new:cn into \cs_set:cn – egreg Nov 2 '19 at 0:24

This doesn't check for list length, but that can be done. Likewise, the arguments can be added to a \foreachitem loop.

\documentclass{article}
\usepackage{listofitems}
\newcommand\test[1]{%
\mylist[1] is \mylist[2] a \mylist[3].
}
\begin{document}
\test{This, just, test}
\end{document}


Here's an example where number of arguments may vary, yet be accounted for:

\documentclass{article}
\usepackage{listofitems}
\newcommand\test[1]{%
There are \mylistlen{} arguments:
\foreachitem \z \in \mylist[]{\ifnum\zcnt=1\relax\else, \fi(\zcnt) \z}.
}
\begin{document}
\test{This, just, test}

\test{This, just, test, today, Hallelujah}
\end{document}


I figured it out eventually:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\newcommand{\newcscommand}[3]{
\NewDocumentCommand{ #1 }{ >{\SplitArgument{#2 - 1}{,}}m }{\csname aux\cs_to_str:N #1\endcsname##1}
\expandafter\newcommand\csname aux\cs_to_str:N #1\endcsname[#2]{#3}
}

\ExplSyntaxOff

\newcscommand{\test}{3}{#1 is #2 a #3.}
\begin{document}
\test{This, just, test}
\end{document}