customised Symbol-list for Numberstyles other than arabic/roman/alpha, etc

When using \enumerate one can enter \begin{enumerate}[(a)] and each item will be numbered (a), (b), (c), (d), \ldots. Similarly for \begin{enumerate}[i)] — one gets i), ii), iii), iv), etc.

I am looking for a defining command, something like

\newenumlistcounter{g}{$\alpha$,$\beta$,$\gamma$,$\delta$,$\epsilon$,…,$\omega$}


so that when using \begin{enumerate}[(g)], one should get (α), (β), (γ), (δ), (ε), as the item-points.

If someone knows, how to achieve this, I would be grateful, if the same would show me how. (NOTE: I am looking for a GENERAL solution. Even if there be a pre-built-in option for Greek letters, I would like to be able to do this for completely arbitrary symbol sets.)

• By »When using \enumerate« you mean »when using the enumerate package« I guess? – clemens Oct 26 '14 at 8:48
• The easiest way may be to use the enumitem package which provides \AddEnumerateCounter (see tex.stackexchange.com/questions/118445) in a combination with custom counter representation commands (see tex.stackexchange.com/questions/124980) – clemens Oct 26 '14 at 8:52
• Sorry, this does not help. With this, one can only play with \alpha,\roman,\arabic. One cannot via this way, generate one’s OWN lists. The only thing I can think of is something that works with Footnote: one can define ones own symbol-set via \DefineFNsymbols*{foo}{q,w,e,r,t,y,u,i,o,p,…,m}, and then one sets \setfnsymbol{foo}, which is able to convert a counter-value to a symbol in the defined list. I am hoping for something similar for enumerate. – Severus Oct 26 '14 at 9:23
• In order to show you that my suggestion does work I could add an answer using it for Greek letters if you like. – clemens Oct 26 '14 at 9:36
• Thanks, cg nieder! egreg has answered below, though there remains one question --- whether one can compactify the command usage as one can with i=roman, a=alpha. – Severus Oct 26 '14 at 10:04

Here's a general enumeration style builder.

\documentclass{article}
\usepackage{enumitem,xparse}

\ExplSyntaxOn
\int_new:N \l_severus_temp_int

\cs_new_protected:Npn \severus_enumeration:nn #1 #2
{
\int_case:nvF { #2 } { g_severus_enum_#1_tl } { \use:c { @ctrerr } }
}
\cs_generate_variant:Nn \int_case:nnF { nv }

\cs_new_protected:Npn \severus_define_enumeration:nn #1 #2
{
\tl_new:c { g_severus_enum_#1_tl }
\int_zero:N \l_severus_temp_int
\clist_map_inline:nn { #2 }
{
\int_incr:N \l_severus_temp_int
\tl_put_right:cx { g_severus_enum_#1_tl }
{
{\int_to_arabic:n { \l_severus_temp_int }}
{\exp_not:n { ##1 }}
}
}
}

\NewDocumentCommand{\DefineEnumeration}{mm}
{
\cs_new_protected:cpn { #1 } ##1 { \severus_enumeration:nn { #1 } { ##1 } }
\severus_define_enumeration:nn { #1 } { #2 }
}

\ExplSyntaxOff

\DefineEnumeration{greekenum}{
$\alpha$,$\beta$,$\gamma$,$\epsilon$,$\zeta$,% go on
}

Alpher, Bethe, Gamow
}

\begin{document}
\begin{enumerate}[label=(\greekenum{\arabic*})]
\item\label{alpha} a
\item b
\item c
\end{enumerate}

Here's the reference: \ref{alpha}

\item\label{X} A
\item B
\item C
\end{enumerate}

Here's the reference: \ref{X}
\end{document}


With \severus_define_enumeration, the first argument is used for naming a macro and also a token list variable, that will contain data such as

{1}{Alpher}{2}{Bethe}{3}{Gamow}


in the case of randomenum. Such a token list is used when the \randomenum macro is used for extracting the desired value. The \arabic* bit might be avoided, but it's easier leaving it.

An etoolbox based implementation of the same macros:

\documentclass{article}
\usepackage{enumitem,etoolbox}

\makeatletter
\newcommand{\DefineEnumeration}[2]{%
\expandafter\newrobustcmd\csname #1\endcsname[1]{%
\severus@enumeration{#1}{##1}%
}%
\severus@define@enumeration{#1}{#2}%
}
\newcommand{\severus@enumeration}[2]{%
\ifcase#2\expandafter\expandafter\expandafter\relax\csname severus@#1@list\endcsname
}
\newcommand{\severus@define@enumeration}[2]{%
\renewcommand{\do}[1]{\csappto{severus@#1@list}{\or##1}}%
\docsvlist{#2}%
\csappto{severus@#1@list}{\else\@ctrerr\fi}
}
\makeatother

\DefineEnumeration{greekenum}{
$\alpha$,$\beta$,$\gamma$,$\epsilon$,$\zeta$,% go on
}

Alpher, Bethe, Gamow
}

\begin{document}
\begin{enumerate}[label=(\greekenum{\arabic*})]
\item\label{alpha} a
\item b
\item c
\end{enumerate}

Here's the reference: \ref{alpha}

\item\label{X} A
\item B
\item C
\end{enumerate}

Here's the reference: \ref{X}
\end{document}

• Super! Thanks! And is there a way to compactify the usage, so that one can e. g. simply enter \begin{enumerate}[(g):]? (Similar to how one can use i, a, etc. for roman, alpha, etc. – Severus Oct 26 '14 at 10:01
• @Severus I'd favor enumitem over enumerate; it would be possible to do that, but it requires substantial work. I think that the enumitem way is much clearer. – egreg Oct 26 '14 at 10:03
• Okay, somehow I am getting hiccups with xparse… Is there a way to do this, encasing the macros within \makeatletter … \makeatother and using \@… type definitions? – Severus Oct 26 '14 at 10:15
• @Severus I added the code. However you should update your TeX distribution, since you probably have older versions of expl3. – egreg Oct 26 '14 at 10:41

As I said in comments a not so difficult way is to define new counter representation commands and tell enumitem (rather than enumerate) how to use it.

The idea is as follows: the internal counter command can be defined using \ifcase\or ...\or ...\fi similar to how \@fnsymbol is defined.

In order to make this a little bit more comfortable than defining the commands “by hand” we can define a macro that builds the counter representation commands from a csv list. etoolbox has handy tools to ease this task:

\documentclass{article}
\usepackage{enumitem,etoolbox}

\makeatletter
\newrobustcmd\csapptocmd[2]{%
\expandafter\apptocmd\expandafter{\csname#1\endcsname}{#2}{}{}%
}

\newrobustcmd\newcounterlist[2]{%
\def\@tmplist{}%
% build the internal counter command:
\csdef{@#1}##1{\ifcase##1}%
\def\do##1{\csapptocmd{@#1}{\or##1}}%
\dolistloop\@tmplist
\csapptocmd{@#1}{\else\@ctrerr\fi}%
% define the counter interface command:
\csdef{#1}##1{\expandafter\csname @#1\expandafter\endcsname\csname c@##1\endcsname}%
}

% new counter lists:
\newcounterlist{greeklabel}{$\alpha$,$\beta$,$\gamma$}% add more

% tell enumitem how to use the new counter representations:
\makeatother

\begin{document}

\begin{enumerate}[label=(\greeklabel*)]
\item first item
\item second item \label{beta}
\item third item
\end{enumerate}

\begin{enumerate}[label=\itshape\whatever* ---,ref=\whatever*]
\item first item
\item second item
\item third item \label{ccc}
\end{enumerate}

see \ref{beta} and \ref{ccc}

\end{document}


For adding new counter representation commands to enumerate's mechanism one needs to redefine \@enloop@. Below is a suggestion that does it via patching the command with etoolbox's \patchcmd:

\documentclass{article}
\usepackage{enumerate,etoolbox}

\makeatletter
\newrobustcmd\csapptocmd[2]{%
\expandafter\apptocmd\expandafter{\csname#1\endcsname}{#2}{}{}%
}

\newrobustcmd\newcounterlist[2]{%
\def\@tmplist{}%
% build the internal counter command:
\csdef{@#1}##1{\ifcase##1}%
\def\do##1{\csapptocmd{@#1}{\or##1}}%
\dolistloop\@tmplist
\csapptocmd{@#1}{\else\@ctrerr\fi}%
% define the counter interface command:
\csdef{#1}##1{\expandafter\csname @#1\expandafter\endcsname\csname c@##1\endcsname}%
}

% new counter lists:
\newcounterlist{greeklabel}
{$\alpha$,$\beta$,$\gamma$,$\delta$,$\epsilon$,$\zeta$,$\eta$,$\iota$,$\theta$}% add more

% adding the new counter commands to enumerate's mechanism:
\patchcmd\@enloop@
{\ifx 1\@entemp \def\@tempa{\@enLabel\arabic}\else}% search
{%
\ifx 1\@entemp \def\@tempa{\@enLabel\arabic}\else
\ifx #1\@entemp \def\@tempa{\@enLabel#2}\else
}% replace
{}% success
{}% failure
\patchcmd\@enloop@
{\fi}% search
{\fi\fi}% replace
{}% success
{}% failure
}
\makeatother

\begin{document}

\tracingmacros=1

\begin{enumerate}[(g)]
\item first item
\item second item \label{beta}
\item third item
\end{enumerate}

\begin{enumerate}[\itshape w ---]
\item first item
\item second item
\item third item \label{ccc}
\end{enumerate}

see \ref{beta} and \ref{ccc}

\end{document}


• Why \csapptocmd instead of the simplest \csappto (that's predefined)? – egreg Oct 26 '14 at 10:54
• @egreg \appto doesn't like macros with parameters – clemens Oct 26 '14 at 11:13
• I see; sorry, I thought it was a parameterless macro. – egreg Oct 26 '14 at 11:17