[Tex/LaTex] newcommand with comma separated argument, and optional arguments

argumentscomma-separated listmacrosoptional argumentsrobust-commands

I want to define a command (not with \def) the simplest possible way that it

  • takes arguments separated by a comma,
  • supports an optional argument (the first one).

maybe another solution with extra optional arguments which are not necessarily the firsts will be welcome in the future.

I want to have something like this: \mycmd[opt arg1, opt arg2]{arg3, arg4}.

I already saw https://tex.stackexchange.com/a/29975/92620 and https://tex.stackexchange.com/a/2860/92620.

\newcommand\mycmd[4][]{optional: #1\\ mandatory: #2 - #3 - #4}

\mycmd[optional arg]{second arg,third arg,fourth arg}

Best Answer

The following example uses \comma@parse of package kvsetkeys to parse the comma separated argument lists.

\usepackage{kvsetkeys}% provides \comma@parse
\usepackage{etexcmds}% provides \etex@unexpanded

  \expandafter\let\csname arg\romannumeral\arg@count\endcsname\comma@entry
% \mycmd[opt arg1, opt arg2]{arg 3, arg4, arg5}
\newcommand\mycmd[2][]{% Default is empty and will be configured later
  % Set default values
  \comma@parse{default1, default2}\arg@parser % Default values
  % Parse optional argument
  \ifnum\arg@count>2 %
    \@latex@error{Too many optional arguments}{%
      The macro \string\mycmd\space got \the\arg@count\space
      optional arguments,\MessageBreak
      but expected are 2 optional arguments.\MessageBreak
  % Mandatory arguments
  \ifnum\arg@count=5 %
    \@latex@error{Wrong number of mandatory arguments}{%
      The macro \string\mycmd\space got \the\numexpr\arg@count-2\relax\space
      mandatory arguments,\MessageBreak
      but expected are 3 mandatory arguments.\MessageBreak
  % Either using \argi, \argii, \argiii, \argiv, \argv
  % or
  % \@mycmd\argi\argii\argiii\argiv\argv
  % or
  optional: #1 -- #2\\
  mandatory: #3 -- #4 -- #5%

  \mycmd[optional arg]{third arg,fourth arg, fifth arg }



  • The list of optional arguments can be shorter, the omitted arguments gets default values.

  • \comma@parse trims the arguments by removing leading and trailing space.

  • \comma@parse removes empty entries. A workaround for empty arguments is using \relax or \empty.

Related Question