我希望我的列表的顶层没有缩进,即具有与周围段落相同的左边距,并且有足够的空间容纳最宽的标签:
Paragraph text
1. Item
2. Item
3. Item
...
10. Item
Paragraph text
我已经使用包对itemize
和做了类似的事情:description
enumitem
\usepackage{enumitem}
\setlist[itemize]{leftmargin=*}
\setlist[description]{leftmargin=*}
但显然enumerate
在确定标签宽度方面存在一些问题。它从一个不可靠的假设开始,将小标签推得太靠右,如果枚举足够大,则会超出左边距(我知道 10000 这个值太荒谬了,这只是为了让我的观点更明显):
\documentclass[twocolumn]{scrbook}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\newcommand{\justsometext}{Just enough text to make the line break so we get to see a second line.}
\begin{document}
\justsometext
\begin{enumerate}
\item \justsometext
\begin{enumerate}
\item Nested. \justsometext
\end{enumerate}
\item \justsometext
\addtocounter{enumi}{9997}
\item \justsometext
\end{enumerate}
\justsometext
\end{document}
包装enumitem
给了我一半的路程,但它要求我标明最宽的标签
\usepackage{enumitem}
\setlist[enumerate]{leftmargin=*}
% ...
\begin{enumerate}[widest=10000]
% ...
但是,有没有办法可以enumerate
自动检测最宽标签的宽度,而不必为每个单独的列表设置它?我觉得一定有办法,只是我无法从文档中找出方法enumitem
……
(我尝试了paralist
带有选项的包alwaysadjust
,以及compactenum
来自同一个包的包;两者都比我从中获得的更糟糕enumitem
:首先假设一些标签宽度 - 从左边距推动“1。”和“2。” - 然后当 10000 个标签将其项目推到右边时完全破坏对齐......)
答案1
这是一种使用引用并因此至少进行两次编译的方法。它需要使用labelwidth
而不是widest
。首先,介绍一些背景知识...
itemize
显然,提供解决方案的动机description
是,前者 ( itemize
) 使用单个元素(符号)来表示列表项,所有列表项的宽度都相同(默认情况下)。将此默认值覆盖为除单个元素(符号)以外的任何元素,将导致项目错位,或项目标签突出边距线:
\begin{itemize}
\item An item
\item[qwerty] An item
\item An item
\end{itemize}
这是由于项目符号具有左对齐的特性。另一个原因是列表是“动态”排版的,甚至允许项目之间分页。因此,为了在开始时知道最宽的项目,enumerate
必须在内存中读取/解析整个环境主体,然后确定最宽,然后排版 - 默认情况下并非如此。后者(description
)有效,因为它使用右对齐方法来排版项目符号,并且默认情况下对标签和项目内容进行段落样式排版。
使用的解决方案enumerate
需要设置以下内容enumitem
列表的选项:
labelindent=0pt
:具有齐平的左边距;labelwidth=\widthof{\ref{last-item}}
:这需要calc
包裹测量列表中最后一项的标签设置\ref{last-item}
位置的宽度;last-item
label=\arabic*.
:标签将采用阿拉伯语,后跟句点.
;itemindent=1em
:标签与物品之间的间隔/空间;以及leftmargin=!
leftmargin
:根据上面提供的参数自动计算应该是什么(这是 3.0 版的新功能enumitem
)。
这是一个突出显示结果的简单示例:
\documentclass{article}
\usepackage{enumitem}% http://ctan.org/pkg/enumitem
\usepackage{calc}% http://ctan.org/pkg/calc
\begin{document}
\noindent Just enough text to make the line break so we get to see a second line.
\begin{enumerate}[labelindent=0pt,labelwidth=\widthof{\ref{last-item}},label=\arabic*.,itemindent=1em,leftmargin=!]
\item An item
\item An item
\item An item \addtocounter{enumi}{9997}
\item An item \label{last-item}
\end{enumerate}
Just enough text to make the line break so we get to see a second line.
\end{document}
答案2
这是一个简单的技巧,但我不确定它是否适用\include
:
\def\maxenumi{0}
\def\saveenumi{0}
\makeatletter
\AtEndDocument{%
\immediate\write\@auxout{%
\string\gdef\string\maxenumi{\saveenumi}}}
\makeatother
\usepackage{enumitem}
\setlist[enumerate,1]{%
leftmargin=*,
widest=\maxenumi,
after=\ifnum\value{enumi}>\saveenumi\xdef\saveenumi{\the\value{enumi}}\fi}
更新。请参阅下面 Werner 的回答,这个答案更好,但需要\label
在最后一项中明确说明(另一方面,可以移至after
)。
答案3
可以使用以下包完成enumerate
:
\documentclass{article}
\usepackage{enumerate}
\begin{document}
\noindent The quick brown fox jumps over the lazy dog.
\begin{enumerate}[ 1.]
\item First item.
\item Second item.
\setcounter{enumi}{9}
\item Tenth item.
\end{enumerate}
\end{document}
但我不确定这个解决方案有多么强大。