How do I create a description list where the item text is automatically indented to the width of the widest label?
This is the same question as Description list with aligned descriptions but I would like the width of the widest label to be automatically calculated.
For example, I'd like the following output:
to be produced by the following input:
\documentclass{article}
\usepackage{calc}
\usepackage{enumitem}
\usepackage{lipsum}
\usepackage[margin=1em,papersize={4in,2.2in}]{geometry}
\newenvironment{mydescription}{%
\begin{description}[
leftmargin=!,
labelwidth=\magicgoeshere,
]%
}{%
\end{description}%
}
\newcommand{\text}{long long long long long long long long long long
long long long long long long long long long long long long long
long long long long long long long text}
\begin{document}
\begin{mydescription}
\item[The longest label] text
\item[Short] \text
\end{mydescription}
\hrule
\begin{mydescription}
\item[Medium label] text
\item[Short] \text
\end{mydescription}
\end{document}
Best Answer
Solution
Here is a solution that uses the
eqparbox
package to measure item label widths. It avoids some of the limitations of the solution described in Gonzalo Medina's answer (see the bottom of this post) because it doesn't typeset the entire list twice. The trade-off is that it requires an additional compilation run because widths measured during one run will only become available for the next one.You can declare a version of the description environment that does what you want by adding the following lines to your preamble. (Only works for enumitem v3.7+, see below.)
What this does is put the description item labels in in
\eqmakebox
es so that their widths are written to the aux file. From the second run onwards, all such boxes in the same list will be given the same width (largest among them) and this width will be used as the list'slabelwidth
.If you're using a version of
enumitem
that is older than v3.7 (which was released on 2019-01-04), you can still make this work by adding the following lines:(N.B. Using the
before
key for this wouldn't work because the code would be run too late.)Application to your MWE
Here is my solution applied to your MWE (version for
enumitem
v3.7+).How this works
\newlist
instead of\newenvironment
to define themydescription
environment and\setlist
to customise it. You could of course also forego the\newlist
and modify the normaldescription
environment instead.enumitem
sformat
key is used to put every item label in yourmydescription
environment in an\eqmakebox
. All\eqmakebox
es with the same tag will be given the same dimensions (after the second run). They're centred by default, but I provided[l]
as an option to make them left-aligned.\eqmakebox
includes\EnumitemId
, which is a unique identifier for the current list environment and is provided byenumitem
.\eqboxwidth
and used as thelabelwidth
for that list.leftmargin
, as in your MWE.The documentation for
enumitem
andeqparbox
can be found here and here respectivelyNotes
labelwidth
you can simply remove both instances of\EnumitemId
in my code snippet.\newlist{mydescription}{description}{n}
for withn
greater than 1.\mydescriptionlabel
can be replaced by\mydescriptionlabel[r]
,\mydescriptionlabel[c]
or\mydescriptionlabel[s]
respectively.\mydescriptionlabel
with other text formatting commands, but they should precede\mydescriptionlabel
and none of them should take an argument (so\itshape
is okay, but\textit
is not).The item labels themselves are still typeset twice and assignments made within them will thus still be performed twice, which I feel is unlikely to be a problem. This could be avoided, but not without making the preamble significantly longer.
The labels themselves are still typeset twice, and definitions in the labels will thus still be applied twice as well. This can be avoided but this is less likely to be a problem than typesetting the entire list twice.
tabular
environment, but I don't think that's much of a restriction since I can't think anything not allowed in atabular
that is allowed in an item label.Comparison to the other solution
Gonzalo Medina's answer will work well in most circumstances, but it's a bit heavy-handed and has a few limitations:
\NewEnviron
has a few subtle problems and restrictions;Downsides of my answer: