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
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 byadjustwidth
).
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
note that the list is indented, and the separation between Problem and the next
item
is not idealwe 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
item
s, so I pull them together using-\parsep
, and this gives the desired result
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}