enumitem \setlist 的行为

enumitem \setlist 的行为

我有一个使用 创建一些列表的包enumitem。全局更改列表参数的标准方法是使用\setlist,但如果列表是自定义列表,这有时会产生错误。这是一个最小文档。

在下面的代码中,假设自定义列表test是在包中定义的,即包的最终用户看不到\newlist\setlist命令。因此,他们会假设他们可以使用\setlist[test]{nosep}来全局设置列表间距test。但此命令失败并出现错误。

\documentclass{article}
\usepackage{enumitem}
% assume this code is in a package
\newlist{test}{enumerate}{1}
\setlist[test]{resume,leftmargin=*,label=(\arabic*)}
% end package code
% Now a user wants to adjust the list properties
\setlist[test]{nosep} % This doesn't work \setlist* is needed
%\setlist*[test]{nosep] % works and makes sense because it adds to list
%\setlist[test,1]{nosep} % But why does this work?

\begin{document}
\begin{test}
\item This is an item
\end{test}
\end{document}

有两种方法可以解决这个问题:1) 使用\setlist*或 2) 使用\setlist[test,1],即添加显式级别。这两种选择都不是普通用户所期望的。

问题

  • 为什么\setlist[test]会失败又会\setlist[test,1]起作用?
  • 有没有办法解决这个问题,这样我就不需要指导用户如何明确设置列表属性?

答案1

为什么\setlist[test]会失败又会\setlist[test,1]起作用?

其核心功能是使用 来\setlist[<arg>]保存传递给它的设置。\enit@@<slightly modified version of 'arg'>\def

因此,\setlist[test]会覆盖先前的\setlist[test],因为它们都保存到同一个宏中\enit@@test。但\setlist[test,1]不会覆盖所做\setlist[test]的,因为它保存到\enit@@testi

您的示例会失败,因为\setlist[test]{nosep}删除了先前的定义,特别是label导致新test环境没有标签的定义。

我之前没有意识到这一点,甚至不知道\setlist*,但现在我觉得这\setlist*更自然,应该是更改列表设置的首选命令。但我怀疑很多人有同样的感觉,甚至不知道\setlist*,所以这可能不是一个选择。

等等,为什么无辜的人\setlist[enumerate]{nosep}不会犯这些错误?

enumerate很特殊,因为它是在 LaTeX 内核中定义的。它的标签定义通常在文档类中设置,因此您不会遇到\setlist[enumerate]覆盖enumitem设置的麻烦。test另一方面,您的 LaTeX 是一张白纸,因此它需要标签定义。

啊哈!我们为什么不定义一个默认计数器呢?

的确

\newcounter{testi}
\renewcommand\thetesti{\arabic{testi}}
\def\labeltesti{(\thetesti)}
\newlist{test}{enumerate}{1}
\setlist[test]{resume,leftmargin=*,label=(\arabic*)}

如果稍后使用,错误就会消失\setlist[test]{nosep}。但仔细检查后我们发现,这只会节省\setlist[test]{label=(\arabic*)}。我们还必须resume,leftmargin=*自己设置。但这两个不能像设置那样容易label=(\arabic*)。你最终会enumitem在包中泄露干净的界面。

有没有解决的办法?

我从这些调查中得出的结论是,我会尝试教育用户使用\setlist*而不是\setlist。抱歉。

可以做出像\setlist[test]{label=(\arabic*)} \setlist证明这样的定义,但像更复杂的东西\setlist[test]{resume,leftmargin=*,label=(\arabic*)}需要大量额外的工作,最终可能不值得(如果可能的话,我没有检查是否可以让类似的东西resume起飞)。

相关内容