# "Nestable" description environment that automatically finds the widest label width at each level?

I'm excited to have found a way to adjust the label width for a description list automatically according to the widest label (from Gonzalo Medina's answer to this question). Here's the code Gonzalo Medina wrote:

\documentclass{article}
\usepackage{enumitem}
\usepackage{environ}

\newlength\widest
\makeatletter
\NewEnviron{ldescription}{%
\vbox{%
\global\setlength\widest{0pt}%
\def\item[##1]{%
\settowidth\@tempdima{\textbf{##1}}%
\ifdim\@tempdima>\widest\global\setlength\widest{\@tempdima}\fi%
}%
\setbox0=\hbox{\BODY}%
}
\begin{description}[
leftmargin=\dimexpr\widest+0.5em\relax,
labelindent=0pt,
labelwidth=\widest]
\BODY
\end{description}%
}
\makeatother

\begin{document}

\begin{ldescription}
\item[Short] text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
\item[A really really long label] text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
\end{ldescription}

\begin{ldescription}
\item[Short] text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
\item[A medium label] text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
\end{ldescription}

\end{document}


I was wondering, though, whether it's possible to make this environment "nestable." Simply trying to nest it as I would "description" or "enumerate" did not work:

\documentclass{article}
\usepackage{enumitem}
\usepackage{environ}

\newlength\widest
\makeatletter
\NewEnviron{ldescription}{%
\vbox{%
\global\setlength\widest{0pt}%
\def\item[##1]{%
\settowidth\@tempdima{\textbf{##1}}%
\ifdim\@tempdima>\widest\global\setlength\widest{\@tempdima}\fi%
}%
\setbox0=\hbox{\BODY}%
}
\begin{description}[
leftmargin=\dimexpr\widest+0.5em\relax,
labelindent=0pt,
labelwidth=\widest]
\BODY
\end{description}%
}
\makeatother

\begin{document}

\begin{ldescription}
\item[Short] text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
\item[A label with a nested list] I would like a nested list here.
\begin{ldescription}
\item[Short] text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
\item[A long label] text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
\end{ldescription}
\end{ldescription}

\end{document}


Particularly:

(1) I would like each list/nested list to have its own label width, equal to the width of the widest label in that particular list (not taking into account any label from its parent list or any label from a list nested in it); and

(2) I would like to be able to change the alignment of the labels (i.e. be able to choose between "align=left" and "align=right") for each list/nested list.

I would not mind having to define multiple environments (as long as I don't have to specify how many nested levels the document is going to have (i.e., as long as the process is automated)); my primary goal is to have this done automatically.

• welcome to tex.sx. i would be concerned that the accumulated width of labels would end up leaving too little (reasonable) space for the text following the labels Jan 23 '17 at 22:56
• @barbara beeton Thank you for your comment. In most cases, I'm going to be using labels such as a combination of digits and punctuation (e.g., 3-1 or 3.1.14) or a word or two. Jan 24 '17 at 6:13

\documentclass{article}
\usepackage{enumitem}
\usepackage{environ}

\newlength\widest
\let\saveditem\item
\makeatletter
\NewEnviron{ldescription}{%
\dimen0=\widest
\let\item\saveditem
\vbox{%
\global\setlength\widest{0pt}%
\def\item[##1]{%
\settowidth\@tempdima{\textbf{##1}}%
\ifdim\@tempdima>\widest\global\setlength\widest{\@tempdima}\fi%
}%
\setbox0=\vbox{\BODY}%
}
\begin{description}[
leftmargin=\dimexpr\widest+0.5em\relax,
labelindent=0pt,
labelwidth=\widest]
\BODY
\end{description}%
\global\widest\dimen0
}
\makeatother

\begin{document}

\begin{ldescription}
\item[Short] text text text text text text text text text text text
text text text text text text text text text text text text text
text text text text text text text text
\item[A label with a nested list] I would like a nested list here.
\begin{ldescription}
\item[Short] text text text text text text text text text text
text text text text text text text text text text text text text
text text text text text text text text text
\item[A long label] text text text text text text text text text
text text text text text text text text text text text text text
text text text text text text text text text text
\end{ldescription}
\end{ldescription}

\end{document}

• Fantastic! Thank you. I don't think I described very clearly the other thing I would like to do in my original post, but I was wondering also how I can make the new environment (ldescription) take an optional argument ([align=left] or [align=right], which aligns the item labels--not the texts). Additionally (this I did not ask in my original post; if it merits a new post, I'd be happy to make one), I was wondering if I could make multiple lists across the entire document that are nested at the same level take the same label width, maybe using something like a [resume] option. Jan 24 '17 at 6:00
• @JacobP. it was clear enough but midnight so I ignored that bit:-) for alignment you just want to add an argument that passes down an optional argument to enumitem argument \begin{description}[....] for whole-documenent width I would not start from Gonzalo's code (which uses a box) I would do (as I'd have done for the original) of a two pass version which write the width in theaux file for use next time. Jan 24 '17 at 8:57
• Sleeping is important =) Anyway, I'm not sure if I understood your comment correctly (and in any case, I couldn't figure out how to do what I think you mean). Are you saying I can achieve both the things I described without using a box? And it sounds like what you're describing would let me achieve the additional thing that I described in my previous comment as well (e.g., the list nested under the first item of the parent list and the list nested under the second item of the parent list having the same label width). What should I look for to find an answer? Jan 26 '17 at 7:11