Definitive guide to trivlists

I cannot say this answer is a definitive guide, but the definitive statement one can make about trivlists are that they are plain vanilla  lists.

\begin{trivlist}
  \item $\varepsilon$-\TeX
  \item[test] a line to test
  \item Ghostscript, version $\ge8.31$
  \item dvipdfmx, version $\ge20080607$ for DVI to PDF conversion
  \item Adobe Reader or another viewer
\end{trivlist}

In simple terms the trivlist environment turns each item into a paragraph and thus it is easier to apply formatting information to a list of paragraphs or items if you want to think of them this way. As it carries common information to all lists, it is used to build up more complicated structures. All LaTeX's lists use parshape to shape the paragraph and the source is not easy to follow.

The definite guide of course is File A: ltlists.dtx in source2e.

A good use of trivlists is to simplify the writing of table heads and produce semantic table environments:

\documentclass{article}
\begin{document}
\newenvironment{name}
  {\trivlist\item
   \tabular{@{}ll@{}}}
  {\endtabular\endtrivlist}
\begin{name}
   First    & Mary  \\
   Second   & Jones \\
   Nickname & --- \\
\end{name}
\end{document}

Yiannis provided the details of where to find the definitive guide:

texdoc source2e

Section 56 is very detailed, and provides all of the parameters that can be tweaked. I thought I'd provide a small example for future reference- perhaps it will help others creating environments. (I don't claim this answer is the definitive guide, but merely an introductory experiment that may help others.)

Motivation

Firstly though, the reason I am interested in lists and trivlists is to create theorem-like environments. In particular, I wanted to emulate the break style from the ntheorem package, which produces something like

enter image description here

Initially I thought that a trivlist would be appropriate, but referencing @egreg's comment to this answer

This works provided that no list based environment appears within this trivlist. \begin{list}{}{\leftmargin=2cm}...\end{list} wouldn't have this problem (and is the approach taken by adjustwidth).

So, I then decided to use the list environment instead of the trivlist, and studied the changepage documentation too.

The list environment

The list environment has the form

\begin{list}{<label>}{options}
\item ...
\end{list}

A complete set of options is detailed in source2e, but I'll only go into a few of them here. For my particular application, I don't need a <label>, so this argument will always be empty.

  • the default settings of the list environment (without any options)

        \begin{list}{}{}
          \item {\bfseries Problem}
          \item \lipsum[1]
        \end{list}
    

    give the following output

enter image description here

  • note that the list is indented, and the separation between Problem and the next item is not ideal

  • we can tweak a few options

      \begin{list}{}{% options
            \setlength{\leftmargin}{0mm}%     leftmargin
            \parsep\parskip%                  space between paragraphs within an item
            \setlength{\itemsep}{-\parsep}%   space between items
       }
       \item {\bfseries Problem}
       \item \lipsum[1]
       \end{list}
    
  • I don't want any space between my items, so I pull them together using -\parsep, and this gives the desired result

enter image description here

Of course, this can be all be done in the pre-amble to make a \newenvironment

\newenvironment{problem}{\begin{list}{}{%
              \setlength{\leftmargin}{0mm}%
              \setlength{\rightmargin}{0mm}%
              \setlength{\topsep}{0mm}%
              \setlength{\partopsep}{0mm}%
              \parsep\parskip%
              \setlength{\itemsep}{-\parsep}%
              }\needspace{\baselineskip}\item {\bfseries Problem}
              \item}{\end{list}}

I've used the needspace package which provides the command \needspace{<space>} to stop page breaks happening between Problem and the body of the environment.


EDIT

Thanks to Philippe Goutet for pointing out that the needspace approach is actually quite flawed; in particular, if the problem environment immediately follows an occurrence of \section{} then it could potentially widow the section heading, and start a new page- very bad! So, he proposed that I copy the definitions of \item and \@item (from ltlists.dtx) into some new commands called \nobreakitem and \@nobreakitem and change the \addpenalty\@itempenalty to \addpenalty\@M.

A complete MWE follows that demonstrates this in action, and in particular, demonstrates that we don't get any lonely orphaned section headings- hoorah!

\documentclass{article}
\usepackage[showframe=true]{geometry}
\usepackage{lipsum}

\makeatletter
% copied from ltlists.dtx
\def\nobreakitem{%
  \@inmatherr\nobreakitem
  \@ifnextchar [\@nobreakitem{\@noitemargtrue \@nobreakitem[\@itemlabel]}}
\def\@nobreakitem[#1]{%
  \if@noparitem
    \@donoparitem
  \else
    \if@inlabel
      \indent \par
    \fi
    \ifhmode
      \unskip\unskip \par
    \fi
    \if@newlist
      \if@nobreak
        \@nbitem
      \else
        \addpenalty\@beginparpenalty
        \addvspace\@topsep
        \addvspace{-\parskip}%
      \fi
    \else
      \addpenalty\@M%only new bit!
      \addvspace\itemsep
    \fi
    \global\@inlabeltrue
  \fi
  \everypar{%
    \@minipagefalse
    \global\@newlistfalse
    \if@inlabel
      \global\@inlabelfalse
      {\setbox\z@\lastbox
       \ifvoid\z@
         \kern-\itemindent
       \fi}%
      \box\@labels
      \penalty\z@
    \fi
    \if@nobreak
      \@nobreakfalse
      \clubpenalty \@M
    \else
      \clubpenalty \@clubpenalty
      \everypar{}%
    \fi}%
  \if@noitemarg
    \@noitemargfalse
    \if@nmbrlist
      \refstepcounter\@listctr
    \fi
  \fi
  \sbox\@tempboxa{\makelabel{#1}}%
  \global\setbox\@labels\hbox{%
    \unhbox\@labels
    \hskip \itemindent
    \hskip -\labelwidth 
    \hskip -\labelsep
    \ifdim \wd\@tempboxa >\labelwidth
      \box\@tempboxa
    \else
      \hbox to\labelwidth {\unhbox\@tempboxa}%
    \fi
    \hskip \labelsep}%
  \ignorespaces}
\makeatother

\newenvironment{problem}{\begin{list}{}{%
            \parsep\parskip%
            \setlength{\itemsep}{-\parsep}%
            }\item {\bfseries Problem}
            \nobreakitem}{\end{list}}

\begin{document}

\lipsum[1]
\vspace{13.55cm} % just to simulate potential page breaks
\section{no page breaks here!}
\begin{problem}
\lipsum[1]

\lipsum[1]
\end{problem}
\end{document}