[Tex/LaTex] How to make a list of unbreakable items

listspage-breaking

In continuation of this question, I tried to make a list of items each consisting of unbreakable text. This can be done manually using minipage:

\documentclass[10pt,a4paper]{article}
\usepackage{lipsum} %for example
\setlength{\textheight}{7cm} %about one item fits per page
\begin{document}
\begin{itemize}
\item\begin{minipage}[t]{\linewidth}
\lipsum[1]
\end{minipage}
\item\begin{minipage}[t]{\linewidth}
\lipsum[2]
\end{minipage}
\end{itemize}
\end{document}

What I would like it to to define a list environment that is just like itemize (or whatever) only that the items are automatically inserted into a minipage as in my manual example. The solution should be robust for nested list environments, so if \item is to be redifined, it has to be done so in a very gentle way…not sure how. After redefining the environment itemize-block (for example) the following code should compile and not break the text in each item across pages:

\begin{itemize-block}
\item
\lipsum[1]
\item \begin{itemize}
\item let us make sure it compiles even with 
\item a nested list...
\end{itemize}
\item
\lipsum[2]
\end{itemize-block}

This can surely be done…only I have no idea how.

Best Answer

This is how I would do it:

\newenvironment{block-itemize}{%
  \itemize
  \let\olditem\item
  \let\closepage\relax  
  \renewcommand\item[1][]{%
    \closepage\olditem[#1]\minipage[t]{\linewidth}%
    \let\closepage\endminipage
  }%
}{%
  \closepage
  \enditemize
}

Then you write

\begin{block-itemize}
\item \lipsum[1]
\item \lipsum[2]
\end{block-itemize}

And a short explanation: When it starts, the environment begins a regular \itemize and then saves the usual definition of \item into \olditem. Then \item is redefined so that: (1) it closes the “previous” minipage (2) it starts a regular item (using \olditem) and (3) it opens a new minipage. Of course, for the very first item there is no minipage to close, that's why \closepage is first defined as \relax (do nothing) but it is then redefined to \endminipage right after the first use of \item. The end of the environment simply closes both the last minipage and the itemize environment.

Note: Actually, I would use something like \my@olditem and \my@closepage and throw the whole definition into a style file so that I don't accidentally redefine commands from another package. But I wanted to keep the code above somewhat clean without all those @'s lying around.

Related Question