7

I want to have a list in my saved box. Why doesn't the following work?

\documentclass{article}
\usepackage{setspace}

\newsavebox{\mybox}

\newenvironment{myenv}{%
  \begin{lrbox}{\mybox}%
  \begin{list}{}{}%
}{%
  \end{list}%
  \end{lrbox}%
  \usebox{\mybox}%
}%

\begin{document}
\begin{myenv}
\item First item.
\item Second item.
\end{myenv}
\end{document} 

Must I use a \minipage?

einpoklum
  • 12,311

3 Answers3

9

Yes, you do have to use a minipage. Indeed lrbox is just the environment form of \sbox that is a companion to \mbox which wouldn't accept a list either: you can't directly typeset a paragraph in a \mbox. But

\begin{lrbox}{\mybox}
\begin{minipage}{5cm}
\begin{enumerate}
\item a
\item b
\end{enumerate}
\end{minipage}
\end{lrbox}

is correct code. In a \mbox or \sbox or lrbox TeX doesn't split lines.

egreg
  • 1,121,712
  • Everything is fine except that I would like to have a minipage with variable width inside lrbox. Is it possible to do it, even if it's not the best? Thank you! – manooooh Mar 08 '20 at 21:07
  • @manooooh What do you mean by “minipage with variable width"? – egreg Mar 08 '20 at 22:10
  • I mean the {5cm} of your code. The 5cm has to be, let's say, \mywidth, where \mywidth changes. – manooooh Mar 08 '20 at 22:15
  • @manooooh Use \mywidth: where's the problem? – egreg Mar 08 '20 at 22:18
  • The problem is that \mywidth is calculated when the minipage is drawn. For example, if we have \begin{enumerate}\item Lonnnng\item Long then \mywidth must be the width of the longest \item (Lonnnng). – manooooh Mar 08 '20 at 22:23
  • 1
    @manooooh Oh! I think you want varwidth, then. Look for it in the site. – egreg Mar 08 '20 at 22:29
8

The evironment lrbox uses the a simple hbox to save the contents. So you have no line breaks. Instead of using lrbox (internal it is a savebox) you can also use the command \setbox in combination with vbox to allow line breaks.

\newenvironment{myenv}{%
 \setbox\mybox=\vbox\bgroup%
  \begin{list}{}{}%
}{%
  \end{list}%
  \egroup
  \usebox{\mybox}%
}%

Here an complete example:

\documentclass{article}
\usepackage{setspace}

\newsavebox{\mybox}

\newenvironment{myenv}{%
 \setbox\mybox=\vbox\bgroup%
  \begin{list}{}{}%
}{%
  \end{list}%
  \egroup
  \usebox{\mybox}%
}%

\begin{document}
\begin{myenv}
\item First item.
\item Second item.
\end{myenv}
\end{document}
Marco Daniel
  • 95,681
2

The environ package allows for "storing" of content in a macro \BODY. Perhaps you might be interested in this implementation:

enter image description here

\documentclass{article}
\usepackage{environ}% http://ctan.org/pkg/environ
\newsavebox{\mybox}
\NewEnviron{myenv}{%
  \let\olditem\item%
  \renewcommand{\item}[1][]{\olditem[##1]\strut}%
  \begin{lrbox}{\mybox}%
  \noindent\begin{minipage}{\linewidth}
  \begin{list}{}{}%
    \BODY%
  \end{list}%
  \end{minipage}
  \end{lrbox}%
  \usebox{\mybox}%
}

\begin{document}
Some text.\strut

\begin{myenv}
\item First item.
\item Second item.
\end{myenv}

Some text.
\end{document}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

Like with most box-implementations of minipage, you may have to play around with the baselineskip measures of \prevdepth. The above redefinition of \item (adding \strut) is a quick-fix. For more on this, see How to keep a constant baselineskip when using minipages (or \parboxes)?

Werner
  • 603,163