I would like to define a macro for defining further macros to display sequences/lists/tuples of elements by specifying the following parameters:
- The name of the new command.
- What to display for an empty sequence/list/tuple.
- How to open a singleton sequence/list/tuple.
- How to close a singleton sequence/list/tuple.
- How to open a sequence/list/tuple with more than one element.
- How to close a sequence/list/tuple with more than one element.
- What to display as separating object between two elements in the sequence/list/tuple.
I had a look at the following questions and corresponding answers:
- When to use \edef, \noexpand, and \expandafter?
- What exactly do \csname and \endcsname do?
- Defining a newcommand, with variable name, inside another newcommand
- variable-name \newcommand with parameters within another \newcommand
So I tried to code my command and came up with the following two versions (the second one is outcommented in the code below). Unfortunately, none of them works and I cannot figure out what the problem is:
\documentclass{article}\makeatletter \newcommand{\definelistcommand}[7]{%\expandafter\newcommand\csname @start#1\endcsname{\expandafter\@ifnextchar\csname @stop#1\endcsname{#2\csname @end#1\endcsname}{\csname @first#1\endcsname}}%\expandafter\newcommand\csname @first#1\endcsname[1]{\expandafter\@ifnextchar\csname @stop#1\endcsname{#3##1#4\csname @end#1\endcsname}{#5##1\csname @next#1\endcsname}}%\expandafter\newcommand\csname @next#1\endcsname[1]{#7##1\expandafter\@ifnextchar\csname @stop#1\endcsname{#6\csname @end#1\endcsname}{\csname @next#1\endcsname}}%\expandafter\newcommand\csname @end#1\endcsname[1]{}% consumes the \stop command\expandafter\newcommand\csname #1\endcsname[1]{\csname @start#1\endcsname##1\csname @stop#1\endcsname}%}\makeatother% \makeatletter % \edef\definelistcommand#1#2#3#4#5#6#7{%% \noexpand\newcommand\expandafter\noexpand\csname @start#1\endcsname{\noexpand\@ifnextchar\expandafter\noexpand\csname @stop#1\endcsname{#2\expandafter\noexpand\csname @end#1\endcsname}{\expandafter\noexpand\csname @first#1\endcsname}}%% \noexpand\newcommand\expandafter\noexpand\csname @first#1\endcsname[1]{\noexpand\@ifnextchar\expandafter\noexpand\csname @stop#1\endcsname{#3##1#4\expandafter\noexpand\csname @end#1\endcsname}{#5##1\expandafter\noexpand\csname @next#1\endcsname}}%% \noexpand\newcommand\expandafter\noexpand\csname @next#1\endcsname[1]{#7##1\noexpand\@ifnextchar\expandafter\noexpand\csname @stop#1\endcsname{#6\expandafter\noexpand\csname @end#1\endcsname}{\expandafter\noexpand\csname @next#1\endcsname}}%% \noexpand\newcommand\expandafter\noexpand\csname @end#1\endcsname[1]{}% consumes the \stop command% \noexpand\newcommand\expandafter\noexpand\csname #1\endcsname[1]{\expandafter\noexpand\csname @start#1\endcsname##1\expandafter\noexpand\csname @stop#1\endcsname}%% }% \makeatother\definelistcommand{mylist}{empty}{[}{]}{(}{)}{,}\begin{document}\mylist{{a}{b}{c}}\mylist{{a}{b}}\mylist{a}\mylist{{b}}\mylist{}\end{document}
The desired output would be:
(a,b,c)(a,b)[a][b]empty
For the first version, I get this error message:
! Missing \endcsname inserted.<to be read again> \letl.27 \mylist{{a}{b}{c}}
For the second version, I get this:
! Undefined control sequence.l.27 \mylist {{a}{b}{c}}
What are the errors in my commands and how would a correct solution work?
EDIT (to point future readers to the fact that the accepted answer is not the only interesting one):Although I accepted the answer by Christian Hupfer (since it contains an explanation and fix for my attempt), the other answers also contain valuable contributions. In particular, I will use egreg's solution as it allows a key-value pair specification of my desired parameters. Unfortunately, I cannot accept two answers.