Defining a command that accepts multiple but non-determined in total number of parameters

(edit) 2017: since xint 1.1 (2014/10/28) one needs here \usepackage{xinttools}. Code updated for that to replace \usepackage{xint} of initial answer.

This code is short but not for the faint of heart (1). Its key tool is the command \xintApplyUnbraced from package xint which applies a given macro to each successive braced thing of a list of such braced things, such as {stuff}{more}{yet}{other}.

(1) but edited version is simpler and better.

The sole effect of \xintApplyUnbraced here is to insert \myitemhelpera commands everywhere; and this macro is defined (thanks to TeX delimited macros) to fetch the data 2 by 2, producing a description item with its heading and description content.

\documentclass{article}
\usepackage{xinttools}

% The space in \myitemhelper will be swallowed during
% the action of \xintApplyUnbraced, and prevents further
% expansion (at a too premature time)

% edited. This is simpler and moreover allows use of [ and ] in the 
% contents of the description texts
\def\myitemhelper #1{ \myitemhelpera {#1}}
\def\myitemhelpera #1\myitemhelpera #2{\item [#1]#2}

% earlier, more complicated and less efficient method:
% \def\myitemhelper #1{ \myitemhelpera[#1]}
% \def\myitemhelpera {\let\myitemhelpera\myitemhelperb \item}
% \def\myitemhelperb [#1]{#1\let\myitemhelpera\myitemhelperA}
% \let\myitemhelperA\myitemhelpera


% \xintApplyUnbraced just has the effect here to insert
%  \myitemhelpera in-between all the braced pairs

\newcommand{\myitem}[2]{\item #1
  \begin{description}
  \xintApplyUnbraced\myitemhelper {#2}
  \end{description}}

\begin{document}
\begin{enumerate}
\myitem{Producers}{% This percent sign is optional
    {Vision:}{abc ...}
    {Contribution:}{def ...}
    {Anticipation:}{g[h]k ...}
    {Participation:}{lmn ...}
    {Conclusion:}{not [yet].}% This percent sign is optional
  }
    \myitem{Example}{%
    {A}{a}
    {B}{b}
    {C}{c}
    {D}{d}%
  }
  \myitem{Example}{%
    {A}{a}%
  }
 \end{enumerate}
\end{document}

variable-number-of-param


No guarantees but this works with the syntax outlined in the question:

\documentclass{article}
\makeatletter
% place \item and check if a description follows:
\newcommand\myitem[1]{%
  \item #1\@myitem@check@description
}
% if an opening brace follows start description:
\def\@myitem@check@description{%
  \@ifnextchar\bgroup
    {\@myitem@startdescription}
    {}%
}
% start description environment, place the first item
% and see if another item follows:
\def\@myitem@startdescription#1#2{%
  \begin{description}%
  \item[#1] #2%
  \@myitem@check@description@item
}
% end description environment:
\def\@myitem@enddescription{%
  \end{description}%
}
% if an item follows place it and check if there is
% another one; else end the description
\def\@myitem@check@description@item{%
  \@ifnextchar\bgroup
    {\@myitem@description@item}
    {\@myitem@enddescription}%
}
% place item and check for the next one:
\def\@myitem@description@item#1#2{%
  \item[#1] #2%
  \@myitem@check@description@item
}

\makeatother
\begin{document}

\begin{enumerate}
  \myitem{Producers}
    {Vision:}{abc ...}
    {Contribution:}{def ...}
    {...}{...}
  \myitem{Example}
    {A}{a}
    {B}{b}
    {C}{c}
    {D}{d}
  \myitem{Example}
  \myitem{Example}
    {A}{a}
\end{enumerate}

\end{document}

enter image description here


A modification of cgnieder's that catches also loners.

\documentclass{article}
\makeatletter
\newcommand\myitem[1]{%
  \item #1
  \@ifnextchar\bgroup{\begin{description}\@myitem@desc}{}
}
\newcommand{\@myitem@desc}[1]{%
  \item[#1]
  \@ifnextchar\bgroup{\@myitem@desc@item}{\@myitem@warning\end{description}}
}
\newcommand{\@myitem@desc@item}[1]{%
  #1
  \@ifnextchar\bgroup{\@myitem@desc}{\end{description}}
}
\newcommand\@myitem@warning{\@latex@warning{Lonely label without text}}
\makeatother
\begin{document}

\begin{enumerate}
  \myitem{Producers}
    {Vision:}{abc ...}
    {Contribution:}{def ...}
    {...}{...}
  \myitem{Example}
    {A}{a}
    {B}{b}
    {C}{c}
    {D}{d}
  \myitem{Example}
    {A loner}
  \myitem{Example}
    {A}{a}
\end{enumerate}

\end{document}

However, I'd better see a different syntax:

\documentclass{article}
\newcommand{\myitem}[2]{%
  \item #1
  \begin{description}
  #2
  \end{description}
}
\newcommand{\II}[2]{%
  \item[#1] #2
}

\begin{document}

\begin{enumerate}
  \myitem{Producers}{
    \II{Vision:}{abc ...}
    \II{Contribution:}{def ...}
    \II{...}{...}
  }
  \myitem{Example}{
    \II{A}{a}
    \II{B}{b}
    \II{C}{c}
    \II{D}{d}
  }
  \myitem{Example}{
    \II{A}{a}
  }
\end{enumerate}

\end{document}

Not much more difficult to type, surely cleaner and more structured.

Tags:

Macros