4

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.)

5
  • By »When using \enumerate« you mean »when using the enumerate package« I guess?
    – cgnieder
    Oct 26, 2014 at 8:48
  • 1
    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)
    – cgnieder
    Oct 26, 2014 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, 2014 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.
    – cgnieder
    Oct 26, 2014 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, 2014 at 10:04

2 Answers 2

1

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
}

\DefineEnumeration{randomenum}{
  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}

\begin{enumerate}[label=\randomenum{\arabic*} --,ref=\randomenum{\arabic*}]
\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.

enter image description here

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
}

\DefineEnumeration{randomenum}{
  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}

\begin{enumerate}[label=\randomenum{\arabic*} --,ref=\randomenum{\arabic*}]
\item\label{X} A
\item B
\item C
\end{enumerate}

Here's the reference: \ref{X}
\end{document}
4
  • 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, 2014 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, 2014 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, 2014 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, 2014 at 10:41
1

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{}%
  \forcsvlist{\listadd\@tmplist}{#2}%
  % 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
\newcounterlist{whatever}{aaa,bbb,ccc}% add more

% tell enumitem how to use the new counter representations:
\AddEnumerateCounter{\greeklabel}{\@greeklabel}{1}
\AddEnumerateCounter{\whatever}{\@whatever}{1}
\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}

enter image description here

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{}%
  \forcsvlist{\listadd\@tmplist}{#2}%
  % 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
\newcounterlist{whatever}{aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii}% add more

% adding the new counter commands to enumerate's mechanism:
\newrobustcmd*\addenumeratelabel[2]{%
  \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
}
\addenumeratelabel{g}{\greeklabel}
\addenumeratelabel{w}{\whatever}
\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}

enter image description here

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .