33

I'm trying to get a description's list hanging indent to lie flush with the first line of text. I have a description list such as the following:

\begin{description}
 \item[Label the first] Lorem ipsum dolor sit amet, consectetur adipisicing
                        elit, sed do eiusmod tempor incididunt ut labore et
                        dolore magna aliqua.
 \item[The longest label] Ut enim ad minim veniam, quis nostrud exercitation
                          ullamco laboris nisi ut aliquip ex ea commodo
                          consequat.
 \item[Shrtlbl] Duis aute irure dolor in reprehenderit in voluptate velit esse
                cillum dolore eu fugiat nulla pariatur.
\end{description}

This produces the following output:

Bad hanging indent.

I would like to have each paragraph indented so that the following lines are flush with the first letter of the list item's text, the way it's laid out in my TeX. For instance, the "s" of "sectetur" should be right under the "L" of "Lorem". I've tried looking through the documentation of the enumitem package, but I can't seem to find a good option. I tried specifying [leftmargin=3cm, style=sameline], but this results in the following:

Slightly better hanging indent.

This isn't quite right: I'm trying to get each item lined up differently, so that the "L" of "Lorem" is not necessarily flush with the "U" of "Ut" or the "D" of "Duis". Does anybody know a good way to do this?

5
  • One way to work around this would be to customize your own description environment. Section 3.3 of "The LaTeX Companion" offers an in-depth explanation with several example solutions.
    – Jimi Oke
    Commented Dec 13, 2010 at 3:21
  • @Jimi: That sounds like a viable option, honestly; I'll check it out, thanks. If only I owned The LaTeX Companion :-) Commented Dec 13, 2010 at 3:30
  • yeah, sorry I don't have time to dig into it right now. If I finish my work, I'll get to it but a couple years ago, I dug in and fixed up my own solution that I have used ever since. However, that is not quite what you want. All my items are aligned to the same margin but you want them aligned differently...ok, I'll just go ahead and post an answer.
    – Jimi Oke
    Commented Dec 13, 2010 at 3:36
  • From a typographical point of view I'd say: Don't do it unless you have a very good reason. Commented Dec 13, 2010 at 13:37
  • @Hendrik: Yes, I concur. I'm poking at it for two reasons. First, because I think there are some cases where it'd look nice (mostly involving nested lists); I might be wrong, but I can't tell unless I can see it. And second, because right now, I'm trying to fit lots of stuff onto a note sheet for an exam, so I'm paying less attention to the normal rules of typography :) Commented Dec 13, 2010 at 15:51

5 Answers 5

26

Here's a solution which allows you to just write

\begin{DESCRIPTION}
 \item[Label the first] Lorem ipsum dolor sit amet, consectetur adipisicing
                        elit, sed do eiusmod tempor incididunt ut labore et
                        dolore magna aliqua.
 \item[The longest label] Ut enim ad minim veniam, quis nostrud exercitation
                          ullamco laboris nisi ut aliquip ex ea commodo
                          consequat.
 \item[Shrtlbl] Duis aute irure dolor in reprehenderit in voluptate velit esse
                cillum dolore eu fugiat nulla pariatur.
\end{DESCRIPTION}

and obtain

Result of the code

It works with arbitrary text inside the {DESCRIPTION} and can be nested with other lists.

\documentclass{article}

\usepackage{calc}

\makeatletter
\newcommand{\DESCRIPTION@original@item}{}
\let\DESCRIPTION@original@item\item
\newcommand*{\DESCRIPTION@envir}{DESCRIPTION}
\newlength{\DESCRIPTION@totalleftmargin}
\newlength{\DESCRIPTION@linewidth}
\newcommand{\DESCRIPTION@makelabel}[1]{\llap{#1}}%
\newcommand{\DESCRIPTION@item}[1][]{%
  \setlength{\@totalleftmargin}%
       {\DESCRIPTION@totalleftmargin+\widthof{\textbf{#1 }}-\leftmargin}%
  \setlength{\linewidth}
       {\DESCRIPTION@linewidth-\widthof{\textbf{#1 }}+\leftmargin}%
  \par\parshape \@ne \@totalleftmargin \linewidth
  \DESCRIPTION@original@item[\textbf{#1}]%
}
\newenvironment{DESCRIPTION}
  {\list{}{\setlength{\labelwidth}{0cm}%
           \let\makelabel\DESCRIPTION@makelabel}%
   \setlength{\DESCRIPTION@totalleftmargin}{\@totalleftmargin}%
   \setlength{\DESCRIPTION@linewidth}{\linewidth}%
   \renewcommand{\item}{\ifx\@currenvir\DESCRIPTION@envir
                           \expandafter\DESCRIPTION@item
                        \else
                           \expandafter\DESCRIPTION@original@item
                        \fi}}
  {\endlist}
\makeatother

\begin{document}

\begin{DESCRIPTION}
 \item[Label the first] Lorem ipsum dolor sit amet, consectetur adipisicing
                        elit, sed do eiusmod tempor incididunt ut labore et
                        dolore magna aliqua.
 \item[The longest label] Ut enim ad minim veniam, quis nostrud exercitation
                          ullamco laboris nisi ut aliquip ex ea commodo
                          consequat.
 \item[Shrtlbl] Duis aute irure dolor in reprehenderit in voluptate velit esse
                cillum dolore eu fugiat nulla pariatur.
\end{DESCRIPTION}

\end{document}

The code work by resetting the relevant list settings at each \item instead of just at the start of the list.

1
  • 1
    Brilliant! Thanks for looking at this ancient question—and for such a thorough fix. Commented May 9, 2011 at 22:52
8

A Plain version which may or may not help:

\def\tabdesc#1: #2\cr{% notice the space.
  \setbox0=\hbox{\bf#1:\enspace}% take note about the width of the label.
  \global\dimen0=\wd0% why it needs to be global, I've no clue.
  \box0\cleartabs&\vtop{% clear the tab-position after the label.
    \hsize=.5\hsize% imaginary desclistwidth.
    \advance\hsize by-\dimen0% substract the width of the label from hsize.
    \raggedright\noindent#2}% raggedright when paragraphs are narrower.
  \cr\medskip% a little skip after an entry.
}
\settabs2\columns
\+ \tabdesc Label the first: Lorem ipsum dolor sit amet, consectetur
  adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
  aliqua.\cr
\+ \tabdesc The longest label: Ut enim ad minim veniam, quis nostrud
  exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\cr
\+ \tabdesc Shrtlbl: Duis aute irure dolor in reprehenderit in voluptate
  velit esse cillum dolore eu fugiat nulla pariatur.\cr
\bye

output of code

3

The solution below is copied directly from page 850 of The LaTeX Companion (Second Edition). This will not give you exactly what you want; it aligns each item to the same margin but it's something to work with:

\usepackage{calc}
\newenvironment{altDescription}[1][\quad]
  {\begin{list}{}{
   \renewcommand\makelabel[1]{\hfil\textsf{##1}}
   \settowidth\labelwidth{\makelabel{#1}}
   \setlength\leftmargin{\labelwidth+\labelsep}}}
  {\end{list}}

The default indentation for each item is \quad. By passing the widest entry of your list as an optional argument after \begin{altDescription}, for instance, \begin{altDescription}[The longest label], you can line up all your items with headings aligned right. Moving \hfil from its current position to right after \textsf{##1} will align your headings left.

Nevertheless, the authors (Mittelbach, Goosens, et al, p.149) argue that the above is not the typographically acceptable solution because it could be awkward to have varying list indentations for several lists. Thus, if you want to align the items to a fixed width, you can adjust \labelwidth and \leftmargin accordingly by adding extra lengths, for instance \setlength\leftmargin{\labelwidth+\labelsep + 2em}}} and then passing [Return values] as your optional argument after \begin{altDescription}.

However, if you still want a solution that aligns each item to the width of the heading, you will probably want a \hangindent fix but I've played around with that and I could not figure out. Another alternative is to tinker with the example I've given. There must be some way to pass the optional width argument as a variable that is determined by the width of each heading but that is beyond my knowledge for now.

1

This is somewhat old, but I had the same problem. Here's the solution I came up with:

\usepackage{calc}%% Make sure to include this in your preamble

%%% Use the following code in a \renewenvironment or whatever: 

\begin{list}{}{
\setlength{\leftmargin}{2cm}%% Make sure to pick a fixed value here. 
\setlength{\itemindent}{0cm}
\setlength{\labelwidth}{\leftmargin-\labelsep}
}

\end{list}
1
  • 3
    calc provides infix arithmetic for lengths by redefining macros like \setlength which is great. If you only do a couple of (or small) calculations, it is also possible to do this using (say) \setlength{\labelwidth}{\dimexpr\leftmargin-\labelsep\relax} - here \dimexpr denotes an expression relating to dimensions, and \relax stops the calculation input.
    – Werner
    Commented Nov 13, 2011 at 2:25
0

Have you tried just using the tabular environment? Just enter each [description] as the first column, and each paragraph field in the second column.

e.g. \begin{tabular}{l p{5.5in}}

Just a thought.

1
  • welcome to tex.sx. this would give a uniform indent to all items, whereas what is wanted is an indent tailored to the width of the item label. Commented Oct 11, 2017 at 13:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .