使用时,\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}