除阿拉伯/罗马/字母等之外的数字样式的自定义符号列表

除阿拉伯/罗马/字母等之外的数字样式的自定义符号列表

使用时,\enumerate可以输入\begin{enumerate}[(a)]每个项目,并将它们编号为 (a)、(b)、(c)、(d),。\ldots同样,对于\begin{enumerate}[i)]— 可以得到 i)、ii)、iii)、iv) 等。

我正在寻找一个定义命令,类似于

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

因此当使用 时\begin{enumerate}[(g)],应该得到 (α), (β), (γ), (δ), (ε) 作为项目点。

如果有人知道如何实现这一点,我将不胜感激,如果他能告诉我如何做的话。(注意:我正在寻找一个通用的解决方案。即使有针对希腊字母的预置选项,我也希望能够针对完全任意的符号集执行此操作。

答案1

这是一个通用的枚举样式构建器。

\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}

使用时\severus_define_enumeration,第一个参数用于命名宏以及标记列表变量,该变量将包含如下数据:

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

在 的情况下。当使用宏来提取所需值randomenum时,会使用这样的标记列表。可以避免使用位,但保留它更容易。\randomenum\arabic*

在此处输入图片描述

etoolbox相同宏的基础实现:

\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}

答案2

正如我在评论中所说,一个不太困难的方法是定义新的计数器表示命令并告诉enumitem(而不是enumerate如何使用它

思路如下:可以使用\ifcase\or ...\or ...\fi类似于\@fnsymbol定义的方式来定义内部计数器命令。

为了使这比“手动”定义命令更舒服一点,我们可以定义一个宏,从 csv 列表构建计数器表示命令。etoolbox有方便的工具来简化这个任务:

\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}

在此处输入图片描述

为了将新的计数器表示命令添加到enumerate的机制中,需要重新定义。以下是通过使用的\@enloop@修补命令来实现此目的的建议:etoolbox\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}

在此处输入图片描述

相关内容