Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Removing vertical white-space after a list

3,474 views
Skip to first unread message

Peter Flynn

unread,
Feb 26, 2013, 5:39:15 PM2/26/13
to
A user has asked me how to remove the vertical white-space above *and*
below a list when a normal paragraph precedes and follows a list.

The parskip package is used in his documents to create unindented normal
paragraphs separated by vertical white-space.

It's easy enough to redefine list environments to *start* with
\parskip=0pt, and from the latex.ltx code I can see where \endtrivlist
messes with the skips, but I can't work out what I need to adjust so
that blank lines after \end{itemize} etc cause no vertical white-space.

///Peter

Axel Berger

unread,
Feb 27, 2013, 7:13:01 AM2/27/13
to
Peter Flynn wrote:
> A user has asked me how to remove the vertical white-space above *and*
> below a list when a normal paragraph precedes and follows a list.

Try paralist.sty.
Alternatively or on top of that take a look at what
\if@noparlist
does.

I have a solution from Ulrike Fischer for another problem with it, that
I don't fully understand. I often have an introductory sentence before a
list and want no paragraph skip before but do want one after the list. I
have

\newcommand\parafterlist{\@noparlisttrue}

in a style file and invoke \parafterlist somewhere inside the list.

Lee Rudolph

unread,
Feb 27, 2013, 7:22:36 AM2/27/13
to
It's too late at night for me to have any hope of understanding
even if I looked, but I wonder whether a perusal of the coding in
paralist.sty might be helpful.

Lee Rudolph

Ulrich D i e z

unread,
Feb 27, 2013, 1:26:33 PM2/27/13
to
Vertical spacing of list-environments is configured by
\topsep, \partopsep, \itemsep, \parsep - these
lengths whose names end on the syllable "sep":

source2e.dtx, file A: ltlists.dtx:

| 56.2 Vertical Spacing (skips)
|
| \topsep: Space between first item and preceding paragraph.
| \partopsep: Extra space added to \topsep when environment starts
| a new paragraph (is called in vmode).
| \itemsep: Space between successive items.
| \parsep: Space between paragraphs within an item - the
| \parskip for this environment.

To me it seems that the lengths \topsep and \partopsep not only
form the vertical space above the text of a list but that they
also form the vertical space below a list.

Setting these lengths to 0pt in order avoid vertical space both
above and below the text of a list seems to work with the MWE
below.

Sincerely

Ulrich


\documentclass{article}
\parskip=0pt
\parindent=0pt
\begin{document}

line before list

\begin{list}{}{\topsep=0pt \partopsep=0pt \itemsep=0pt \parsep=0pt}%
\item first item
\item second item
\end{list}

line behind list

\end{document}

GL

unread,
Feb 27, 2013, 2:17:24 PM2/27/13
to
Le 27/02/2013 19:26, Ulrich D i e z a �crit :
> Peter Flynn wrote:
>
>> A user has asked me how to remove the vertical white-space above *and*
>> below a list when a normal paragraph precedes and follows a list.
>>
>> The parskip package is used in his documents to create unindented normal
>> paragraphs separated by vertical white-space.
>>
>> It's easy enough to redefine list environments to *start* with
>> \parskip=0pt, and from the latex.ltx code I can see where \endtrivlist
>> messes with the skips, but I can't work out what I need to adjust so
>> that blank lines after \end{itemize} etc cause no vertical white-space.
>
> Vertical spacing of list-environments is configured by
> \topsep, \partopsep, \itemsep, \parsep - these
> lengths whose names end on the syllable "sep":
>
> source2e.dtx, file A: ltlists.dtx:
>
> | 56.2 Vertical Spacing (skips)
> |
> | \topsep: Space between first item and preceding paragraph.
> | \partopsep: Extra space added to \topsep when environment starts
> | a new paragraph (is called in vmode).
> | \itemsep: Space between successive items.
> | \parsep: Space between paragraphs within an item - the
> | \parskip for this environment.
>
> To me it seems that the lengths \topsep and \partopsep not only
> form the vertical space above the text of a list but that they
> also form the vertical space below a list.

yes: cf. \addvspace \@topsepadd in \@endparenv in \endtrivlist.

Peter Flynn

unread,
Mar 1, 2013, 4:30:16 PM3/1/13
to
On 02/27/2013 12:13 PM, Axel Berger wrote:
> Peter Flynn wrote:
>> A user has asked me how to remove the vertical white-space above *and*
>> below a list when a normal paragraph precedes and follows a list.
>
> Try paralist.sty.

I had forgotten that one.

On 02/27/2013 06:26 PM, Ulrich D i e z wrote:
> Vertical spacing of list-environments is configured by
> \topsep, \partopsep, \itemsep, \parsep - these
> lengths whose names end on the syllable "sep":

I will experiment with both solutions. Thank you all very much.

///Peter

wexfordpress

unread,
Mar 3, 2013, 10:15:54 AM3/3/13
to
Try \vskip with a negative number. That's a plain tex trick that might
work.

Peter Flynn

unread,
Mar 20, 2013, 4:42:56 PM3/20/13
to
On 02/27/2013 06:26 PM, Ulrich D i e z wrote:
That's what I would have expected, but unfortunately it doesn't work in
a document using the standard list environments (eg itemize):

\documentclass{article}
\usepackage{lipsum}
\topsep0pt
\partopsep0pt
\itemsep0pt
\parsep0pt
\begin{document}
\lipsum[1]
\begin{itemize}
\item \lipsum[2]
\item \lipsum[3]
\end{itemize}
\lipsum[1]
\end{document}

There is still unwanted white-space before and after the list *and*
between the items.

///Peter

Peter Flynn

unread,
Mar 20, 2013, 4:48:31 PM3/20/13
to
On 03/20/2013 08:42 PM, Peter Flynn wrote:
[...]
> There is still unwanted white-space before and after the list *and*
> between the items.

Aha. You have to *redefine* \itemize etc and embed the zeroing of the
parameters in the second argument to \list. I should have known this...

///Peter

Guenter Milde

unread,
Mar 20, 2013, 7:21:05 PM3/20/13
to
Or try with the enumitem package.

Günter

Peter Flynn

unread,
Mar 20, 2013, 7:36:53 PM3/20/13
to
Thanks, that almost works. But using it with the parskip package defeats
it entirely.

(And yes, suppressing space above and below lists while still having
space between regular paragraphs *is* how the designer specified it...)

///Peter

Ulrich D i e z

unread,
Mar 21, 2013, 8:25:16 AM3/21/13
to
Sorry for not replying sooner.

This posting is submitted both to comp.text.tex and via e-mail.

(I decided to send via e-mail as well because of the considerable
time-span between this posting and the posting I'm replying to.)


On 03/20/2013 08:42 PM, Peter Flynn wrote:
[...]
>> There is still unwanted white-space before and after the list *and*
>> between the items.
>
>Aha. You have to *redefine* \itemize etc and embed the zeroing of the
>parameters in the second argument to \list. I should have known this...

Yes, setting these lengths can be done by the second argument
of the list-environment.

But when carrying out an instance of the list-environment---according
to source2e.pdf, File A: ltlists.dtx, 56.6 Default Values---default-values
for the lengths used by the list environment are set via calling one
of the commands \@listi, \@listii, \@listiii, \@listiv, ... - depending on the
current level of the list. These macros are to be defined by the
document-class.

Seems that any case one of those macros is called when the
list-environment is applied and thus your "global settings" for these
lengths (or at leasrt some of them) get overridden.

E.g., with the following minimal example, using the article-class

\documentclass{article}
\begin{document}
\makeatletter
\show\@listi
\end{document}

, I get:

| > \@listi=macro:
| ->\leftmargin \leftmargini \parsep 4\p@ \@plus 2\p@ \@minus \p@ \topsep 8\p@ \@
| plus 2\p@ \@minus 4\p@ \itemsep 4\p@ \@plus 2\p@ \@minus \p@ .
| <insert> \show\@listi

, which means that with article.cls \topsep - affecting vertical spacing above
and below the text produced by the body of a first-level-list-environment - has
a non-zero-default value...


You can probably achieve what you need by redefining these
\@list<level in lowercase roman numerals> macros ...

Seems with the article-class you need to do so via the
AtBeginDocument-hook.

Below is an example where \@listi (for lists at top-level)
is redefined. \@listii, \@listiii etc might need adjustment also
nut I omitted in order to keep the example short.

Sincerely

Ulrich


\documentclass{article}
\usepackage{lipsum}
\makeatletter
\AtBeginDocument{%
\renewcommand\@listi{%
\leftmargin \leftmargini
\topsep 0pt
\partopsep 0pt
\parsep 0pt
\itemsep 0pt
}%
}%
\makeatother
\begin{document}
\lipsum[1]
\begin{itemize}
\item \lipsum[2]
\item \lipsum[3]
\end{itemize}
\lipsum[1]
\begin{enumerate}
\item \lipsum[2]
\item \lipsum[3]
\end{enumerate}
\lipsum[1]
\end{document}

Robin Fairbairns

unread,
Mar 21, 2013, 12:18:45 PM3/21/13
to
the parskip package was written long, long, ago. i blunted some of its
sharpest edges when i still thought its style was worth having (30 years
ago, or so -- i used to use digital runoff). in the faq i suggest
you're only likely to get a totally satisfactory result by using a class
that has the structure built in from the bottom up; iirc, one of the ntg
classes does that.
--
Robin Fairbairns, Cambridge
sorry about all this posting. i'll go back to sleep in a bit.

Peter Flynn

unread,
Mar 21, 2013, 4:26:27 PM3/21/13
to
On 03/21/2013 12:25 PM, Ulrich D i e z wrote:
> Sorry for not replying sooner.

NP.

> But when carrying out an instance of the list-environment---according
> to source2e.pdf, File A: ltlists.dtx, 56.6 Default Values---default-values
> for the lengths used by the list environment are set via calling one
> of the commands \@listi, \@listii, \@listiii, \@listiv, ... - depending on the
> current level of the list. These macros are to be defined by the
> document-class.

I did eventually find these, and yes, you are perfectly correct.

> Below is an example where \@listi (for lists at top-level)
> is redefined. \@listii, \@listiii etc might need adjustment also
> but I omitted in order to keep the example short.

Combining this with the parskip problem, the following seems to work by
setting \topsep to -\parskip. Still a weird idea for a layout, but
that's what is specified...

///Peter

> \documentclass{article}
> \usepackage{lipsum,parskip}
> \makeatletter
> \AtBeginDocument{%
> \renewcommand\@listi{%
> \leftmargin \leftmargini
> \topsep -\parskip
> \partopsep 0pt
> \parsep 0pt
> \itemsep 0pt
> }%
> }%
> \makeatother
> \begin{document}
> \lipsum[1]
>
> \lipsum[6]

Guenter Milde

unread,
Mar 21, 2013, 4:45:54 PM3/21/13
to
On 2013-03-21, Peter Flynn wrote:
> On 03/21/2013 12:25 PM, Ulrich D i e z wrote:

> Combining this with the parskip problem, the following seems to work by
> setting \topsep to -\parskip. Still a weird idea for a layout, but
> that's what is specified...

This might also solve the parskip + enumitem problem.

Günter

Peter Flynn

unread,
Mar 30, 2013, 8:53:28 PM3/30/13
to
I fixed that, but some discussion revealed the real reasoning behind the
request. They want the list-spacing to depend on the existence (or not)
of a blank line between list and preceding or following text. There are
therefore four case:

A. no blank line means no vertical white-space:
end of preceding paragraph.
1. first item
2. second item
Next paragraph

B. blank line before list means white-space before list:
end of preceding paragraph.

1. first item
2. second item
Next paragraph

C. blank line after list means white-space after list:
end of preceding paragraph.
1. first item
2. second item

Next paragraph

D. blank line before and after means white-space before and after list:
end of preceding paragraph.

1. first item
2. second item

Next paragraph

Plus, if the object before or after the list is something else, like a
[sub]section heading, block quotation, etc, the same rules would apply.

Perhaps this can be done by detecting and measuring \lastskip at the
start of a list and the beginning of a paragraph?

///Peter

Axel Berger

unread,
Mar 30, 2013, 10:05:28 PM3/30/13
to
Peter Flynn wrote:
> They want the list-spacing to depend on the existence (or not)
> of a blank line between list and preceding or following text.

Ulrike Fischer gave me the solution for that one. The parskip above is
already there depending on whether there is a blank line or other
paragraph end or not. The parskip below is normally the same as above.
If you define:

\newcommand\parafterlist{\@noparlisttrue}

somewhere \makeatletter is set, then you can add \parafterlist before
the \end{environment}

It was meant to have a paragraph skip after but not before the list, as
I like to have an introductory sentence bound to it. Try experimenting
with \@noparlistfalse, I haven't done that so far.

Axel

Peter Flynn

unread,
Apr 3, 2013, 5:31:43 PM4/3/13
to
Thanks very much. I have managed to solve the problems, with the
exception of detecting whether or not a list is followed by a blank line.

Anyone ever done that? I know that it makes a difference when
indentation is in use (no blank line means no indentation on the
following paragraph), but I'm unclear where or if that happens when
using the enumitem and parskip packages, as I am.

///Peter

Ulrich D i e z

unread,
Apr 4, 2013, 6:48:19 AM4/4/13
to
Peter Flynn wrote:

> Thanks very much. I have managed to solve the problems, with the
> exception of detecting whether or not a list is followed by a blank line.
>
> Anyone ever done that? I know that it makes a difference when
> indentation is in use (no blank line means no indentation on the
> following paragraph)

Blank lines usually are tokenized as \par-tokens.

The \end-macro in the LaTeX2e-kernel is defined as follows:

| \end=macro:
| #1->\csname end#1\endcsname \@checkend {#1}\expandafter
| \endgroup \if@endpe \@doendpe \fi \if@ignore \@ignorefalse
| \ignorespaces \fi

So instead of checking for a blank line after
\end{<environment>}, you probably can detect a \par-token
behind an argument that is delimited by the token-sequence
"\if@ignore\@ignorefalse\ignorespaces\fi" .

In case a \par-token is present, you can have repeated/performed
the assignment-sequence
\@topsepadd\topsep
\advance\@topsepadd\partopsep
which is carried out in case the list started a new paragraph (\ifvmode...)
by the \@trivlist-macro which is called at the beginning of the
trivlist-environment and at the beginning of all list-like environments...

In case no \par-token is present, you can set the \@noparlist-switch
to "true" in order to prevent starting a new paragraph at the end
of the list even in case the list is placed at the beginning of a
paragraph...
If you wish to avoid horizontal indentation in case no blank line/no
\par-token does trail the list-like-environment, you can apply \noindent.

The \endtrivlist-macro executed at the end of all list-like
environments can probably be patched to perform the test.

In the example below I have redefined only the \@listi-macro
in order to keep that example short. You also need to redefine
\@listii ... \@listvi accordingly.

Sincerely

Ulrich


\documentclass{article}
\usepackage{hyperref}
\makeatletter
\AtBeginDocument{%
\renewcommand\@listi{%
\leftmargin \leftmargini
\topsep 0pt
\partopsep\baselineskip
\parsep 0pt
\itemsep 0pt
}%
}%
\long\def\checkpar#1\if@ignore\@ignorefalse\ignorespaces\fi{%
\@ifnextchar\par%
{%
\@topsepadd\topsep
\advance\@topsepadd\partopsep
#1\if@ignore\@ignorefalse\ignorespaces\fi
}%
{%
\@noparlisttrue
#1\if@ignore\@ignorefalse\ignorespaces\fi
%\noindent
}%
}%
\let\savedendtrivlist\endtrivlist
\renewcommand\endtrivlist{\checkpar\savedendtrivlist}
\makeatother

\begin{document}
\vspace*{-1in}%
\parindent=1.5cm
No blank line before environment and no blank line after environment:

Text Text
\begin{itemize}
\item itemize 1
\item itemize 2
\end{itemize}
Text Text

Text Text
\begin{enumerate}
\item enumerate 1
\item enumerate 2
\end{enumerate}
Text Text

\hrulefill

A blank line before environment but no blank line after environment:

Text Text

\begin{itemize}
\item itemize 1
\item itemize 2
\end{itemize}
Text Text

Text Text

\begin{enumerate}
\item enumerate 1
\item enumerate 2
\end{enumerate}
Text Text

\hrulefill

No blank line before environment but a blank line after environment:

Text Text
\begin{itemize}
\item itemize 1
\item itemize 2
\end{itemize}

Text Text

Text Text
\begin{enumerate}
\item enumerate 1
\item enumerate 2
\end{enumerate}

Text Text

\hrulefill

A blank line before environment and a blank line after environment:

Text Text

\begin{itemize}
\item itemize 1
\item itemize 2
\end{itemize}

Text Text

Text Text

\begin{enumerate}
\item enumerate 1
\item enumerate 2
\end{enumerate}

Text Text

\end{document}

Ulrich D i e z

unread,
Apr 4, 2013, 1:36:19 PM4/4/13
to
Peter Flynn wrote:

> Thanks very much. I have managed to solve the problems, with the
> exception of detecting whether or not a list is followed by a blank line.
>
> Anyone ever done that? I know that it makes a difference when
> indentation is in use (no blank line means no indentation on the
> following paragraph)


The following approach seems to work without the need of
detecting a trailing \par-token.

No warranties.

Sincerely

Ulrich



\documentclass{article}
%\usepackage{hyperref}
\makeatletter
\newskip\mysavedpartopsep
\AtBeginDocument{%
\renewcommand\@listi{%
\leftmargin \leftmargini
\topsep 0pt
\partopsep\baselineskip
\parsep 0pt
\itemsep 0pt
}%
}%
\long\def\replace@doendpe#1#2\@doendpe{%
\@topsepadd=\topsep
#2\@mydoendpe{#1}%
}%
\newcommand\@mydoendpe[1]{%
\@endpetrue
\def\par{%
\@restorepar
\everypar{}%
\par
% I hope this is the correct way of inserting the
% vertical skip (\partopsep) at the end of the environment.
% But I did not test if this delivers the desired result,
% e.g., with nested list-like-environments:
\if@endpe\vskip#1\relax\fi
\@endpefalse
}%
\everypar{%
% In case you want indentation also at the line following
% the environment when no blank line is present, disable/
% comment out the "{\setbox\z@\lastbox}"-line.
{\setbox\z@\lastbox}%
\everypar{}%
\@endpefalse
}%
}%
%
\let\savedendtrivlist\endtrivlist
\renewcommand\endtrivlist{%
\expandafter\replace@doendpe\expandafter{\the\partopsep}\savedendtrivlist
}%
0 new messages