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

  • By »When using \enumerate« you mean »when using the enumerate package« I guess? – clemens Oct 26 '14 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) – 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
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}
  • 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
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

  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.