I would like to have my lists to have no indent for the top level, i.e. having the same left margin as the surrounding paragraph, with just enough space for the widest label to fit:
Paragraph text
1. Item
2. Item
3. Item
...
10. Item
Paragraph text
I already do something similar for itemize
and description
, using the enumitem
package:
\usepackage{enumitem}
\setlist[itemize]{leftmargin=*}
\setlist[description]{leftmargin=*}
But apparently enumerate
has some issues determining the width of its labels. It starts with a shaky assumption, which pushes small labels too far to the right, and extends beyond the left margin if the enumeration gets big enough (I know the 10000 value is ridiculous, it's just to make my point obvious):
\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}
The enumitem
package gives me half of a way around it, but it requires me to state the widest label
\usepackage{enumitem}
\setlist[enumerate]{leftmargin=*}
% ...
\begin{enumerate}[widest=10000]
% ...
However, isn't there some way to make enumerate
detect the width of its widest label automatically, instead of having to set it for each individual list? I feel like there must be some way, I just couldn't figure out how from the enumitem
doc…
(I tried the paralist
package with option alwaysadjust
, as well as compactenum
from the same package; both are worse than what I got from enumitem
: assuming some label width first – pushing the "1." and "2." from the left margin – then ruining the alignment completely when the 10000 label pushes its item to the right…)
Best Answer
Here is a way to do it using references, and consequently at least two compilations. It requires using
labelwidth
rather thanwidest
. First, some background...The obvious motivation behind
itemize
anddescription
providing solutions to this without problem is because the former (itemize
) uses a single-element (symbol) to denote list items, all of which have the same width (by default). Overriding this default to anything other than a single-element (symbol) will have misaligned items, or item labels protruding margin lines:This is due to the left-aligned nature of the itemized bullets. Another motivation is because lists are typeset "on the fly" and even allow for page breaks between items. So, in order to know the widest item at the start, the entire
enumerate
environment body would have to be read in memory/parsed before determining the widest, and then typeset - not the case by default. The latter (description
) works because it uses a right-aligned approach to typesetting the itemized bullets and has a paragraph-style typesetting of the label and item contents by default.The solution using
enumerate
requires setting the followingenumitem
options for a list:labelindent=0pt
: to have a flush left margin;labelwidth=\widthof{\ref{last-item}}
: this requires thecalc
package that measures the width of\ref{last-item}
wherelast-item
is a label set for the last item in your list;label=\arabic*.
: labels will be arabic, followed by a period.
;itemindent=1em
: separation/space between label and item; andleftmargin=!
: automatically calculate what theleftmargin
should be based on the provided parameters above (this is new to version 3.0 ofenumitem
).Here is a minimal example highlighting the result: