15

I cannot make lrbox work if put within a \newenvironment. I'll explain with an example. If I write:

\documentclass{article}

\newsavebox{\mybox}

\begin{lrbox}{\mybox}
    \begin{minipage}[t]{\textwidth}
     \hfill
      \begin{minipage}[t]{0.7\textwidth}
         \noindent
         \textbf{ABSTRACT} \\
         Test Test Test Test Test Test Test Test Test Test Test Test Test 
         \\
         \\
       \end{minipage}
    \end{minipage}
\end{lrbox}

\begin{document}

\usebox{\mybox}

\end{document}

Then I obtain the result I want. But if I try to create a new environment that has to behave like the code above, I obtain a blank page. Specifically, if I write:

\documentclass{article}

\newsavebox{\mybox}

\newenvironment{myenv}
{
   \begin{lrbox}{\mybox}
     \begin{minipage}[t]{\textwidth}
     \hfill
     \begin{minipage}[t]{0.7\textwidth}
        \noindent
        \textbf{ABSTRACT} \\
}{
        \\
        \\
     \end{minipage}
    \end{minipage}
   \end{lrbox}
}

\begin{myenv}
Test Test Test Test Test Test Test Test Test Test Test Test Test Test 
\end{myenv}

\begin{document}

\usebox{\mybox}

\end{document}

I obtain a blank page. Is anyone able to explain me why, please?

0
14

The environment makes a group and so the local setting of \mybox is discarded. the lrbox command has some code to "unwind" one level of grouping from a latex environment so that its normal use leaves the box defined after \end{lrbox} but this only undoes one level. I think @tohez answer is safe here, or an alternative, which similarly abuses LaTeX syntax a bit is to trick lrbox into making a global assignment

Changing your call to

 \begin{lrbox}{0\null\global\setbox\mybox}

will work (it makes a local assignment to box 0 then globally assigns the body of the environment to your box)

2
  • Would you consider this a good way to store an environment's body in a box for further processing? Is there a better way?
    – Bananguin
    Jul 13 '15 at 21:42
  • 1
    @user1129682 not really. I'd use tohez (user now called yo') answer or simply use \begin{lrbox}{0}....\end{lrbox}\global\setbox\mybox\box0 so lrbox locally saves the box then you globally copy it to \mybox. Jul 13 '15 at 21:51
8

If you substitute \begin{lrbox}->\lrbox and \end{lrbox}->\endlrbox, it works perfectly.

There seem to be some problem with calling \begin{mybox}...\end{mybox}, because every \begin{ENV}...\end{ENV} pair encloses the contents into an extra pair of \begingroup...\endgroup, which are TeX primitives that makes box assignments local.

In the solution, the \begingroup from \begin{mybox} is undone by \lrbox, but would not be undone by \begin{lrbox} since in that case only \begingroup from \begin{lrbox} is undone. (And the same applies for \end{lrbox} and \endgroup.)

Remark: You can write \ENV...\endENV for any environment, but it changes their behaviour and the result can be unpredictable.

(Thanks @Stephan and @Martin for comments.)

\documentclass{article}

\newsavebox{\mybox}

\newenvironment{myenv}
{
   \lrbox\mybox
     \begin{minipage}[t]{\textwidth}
     \hfill
     \begin{minipage}[t]{0.7\textwidth}
        \noindent
        \textbf{ABSTRACT}
}{
     \end{minipage}
    \end{minipage}
   \endlrbox
}

\begin{myenv}
Test Test Test Test Test Test Test Test Test Test Test Test Test Test 
\end{myenv}

\begin{document}

\usebox{\mybox}

\end{document}
8
  • 2
    Uh, the other way round... \lrbox explicitly starts with \endgroup to undo the \begingroup from \begin{lrbox}. The way you use it here, the \endgroup can undo the \begingroup from \begin{myenv}. Mar 23 '12 at 15:21
  • 1
    This solution is correct, but some extra explanation would be good. It doesn't "changes the behaviour of boxes", it simply places them into a group, which makes the box assignment local. I assume you meant that. lrbox is quite special because it needs to cancel the usual environment group out. It works well inside another environment as long you are using the box register only within it. Your solution makes the lrbox code cancels out the group added by the myenv environment and makes the box assignment accessible by the outside scope (like @StephanLehmke already mentioned).
    – Martin Scharrer
    Mar 23 '12 at 15:26
  • A curiosity. Is the problem that the article.cls redefines the normal behavior of the lrbox environment, or is this behavior the standard \begin{lrbox}\end{lrbox} behavior?
    – Michele
    Mar 23 '12 at 15:30
  • @MartinScharrer Thanks for the comments, updated.
    – yo'
    Mar 23 '12 at 15:37
  • @Michele I believe that lrbox is defined this way in all standard classes. It is simply that some commands cause trouble inside environments.
    – yo'
    Mar 23 '12 at 15:40
5

The box is assigned locally by lrbox. Hence, the end of your environment undoes the assignment.

Try the lrbox* construct from this posting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.