6

In my Sphinx project, I have description lists that start with either a paragraph or a list. Since I want the description term to be on its own line, I use enumitem with {style=nextline}. The problem is that this causes an extra line of space to appear after the term if an itemize list follows. Being auto-generated by Sphinx, though, I'm limited to setting options in the preamble to fix it. Does such a fix exist that prevents the extra space?

\documentclass{article}
\usepackage{enumitem}
\setlist[description]{style=nextline}

\begin{document}

\begin{description}
\item[{This is a term.}] \leavevmode
This is a description of the term, usually spanning multiple lines,
which should start on its own line.
\end{description}

\begin{description}
\item[{This is a term containing an itemize list.}] \leavevmode
\begin{itemize}
\item {} 
This is an item with too much space between it and the term above.
\end{itemize}
\end{description}

\end{document}

Update: To solve the problem at hand I have the Makefile applying karlkoeller's fix across the entire file. However, this post on changing behaviour depending on environment helped me come up with this solution that almost works.

\documentclass{article}
\makeatletter
\def\ifenv#1{
   \def\@tempa{#1}%
   \ifx\@tempa\@currenvir
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
   \fi
}
\makeatother

\usepackage{enumitem}
\setlist[description]{style=nextline}
\setlist[itemize]{before=\ifenv{description}{\vspace*{-1.5\baselineskip}}{\ldots}}

\begin{document}

\begin{description}
\item[{This is a term.}] \leavevmode
This is a description of the term, usually spanning multiple lines, which should start on its own line.
\end{description}

\begin{description}
\item[{This is a term containing an itemize list.}] \leavevmode
\begin{itemize}
\item {} 
This is an item with too much space between it and the term above.
\end{itemize}
\end{description}

Text in between
\begin{itemize}
\item {} 
This is a bare itemize.
\end{itemize}

\end{document}

What's supposed to happen is the code passed to before is run wherever an itemize list starts to determine if it's inside a description, and apply the fix if necessary. However, it's returning the false condition (\ldots) each time because the code is being evaluated in the preamble, rather than the document itself. I figure expandafter is the answer, but I couldn't get it to work.

2
  • Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. Nov 27, 2013 at 21:50
  • 1
    The code is actually being evaluated inside the itemize, inside the description. At that point, \@currenvir is "itemize", so the comparison to "description" is false. You might ask the description environment to record its name and nesting level in some macros, and then itemize can test those macros to see if (1) it is inside a description and (2) its own nesting level is one greater than the description's.
    – Dan
    Nov 28, 2013 at 7:02

2 Answers 2

5

No better ideas at the moment...

You can add

\setlist[itemize]{before=\vspace*{-1.5\baselineskip}}

in the preamble.

Beware that this will affect all itemize environments...

Complete code:

\documentclass{article}
\usepackage{enumitem}
\setlist[description]{style=nextline}
\setlist[itemize]{before=\vspace*{-1.5\baselineskip}}

\begin{document}

\begin{description}
\item[{This is a term.}] \leavevmode
This is a description of the term, usually spanning multiple lines,
which should start on its own line.
\end{description}

\begin{description}
\item[{This is a term containing an itemize list.}] \leavevmode
\begin{itemize}
\item {}
This is an item with too much space between it and the term above.
\end{itemize}
\end{description}

\end{document} 

Output:

enter image description here

2
  • Didn't know about before, so that's helpful. Is there any way to conditionally apply a command if, say, the itemize comes after \leavevmode or is inside a description?
    – Eric3
    Nov 27, 2013 at 23:08
  • @Eric3 I'm afraid I don't know any way. Nov 28, 2013 at 5:55
2

I've solved it programatically by following Dan's suggestion of having the description set a macro \indesc indicating it's active, and having the itemize apply the fix if it's true. The itemize then resets \indesc globally to prevent the fix from being applied to subsequent lists within the description. The only caveat I can see is if the description text has text appearing before the list.

\documentclass{article}
\def\indesc{FALSE}
\makeatletter
\def\ifdesc{
  \def\@istrue{TRUE}%
  \ifx\indesc\@istrue
    \vspace*{-1.0\baselineskip}
    \gdef\indesc{FALSE}
  \fi
}
\makeatother

\usepackage{enumitem}
\setlist[description]{style=nextline,before=\def\indesc{TRUE},after=\def\indesc{FALSE}}
\setlist[enumerate]{before=\ifdesc}
\setlist[itemize]{before=\ifdesc}

\begin{document}

\begin{description}
\item[{This is a term.}] \leavevmode
This is a description of the term, usually spanning multiple lines,
which should start on its own line.
\end{description}

\begin{description}
\item[{This is a term containing two itemize lists.}] \leavevmode
\begin{itemize}
\item {}
This is an itemize list with the extra space above removed.
\end{itemize}
Some text in between.
\begin{itemize}
\item {}
This is an itemize list left untouched.
\end{itemize}
\end{description}

Some text after the description.
\begin{itemize}
\item {}
This is another itemize list left untouched.
\end{itemize}

\end{document}
1
  • Accepted your answer because it got me to a fix that worked without potential side effects.
    – Eric3
    Nov 30, 2013 at 17:41

You must log in to answer this question.

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