5

I want create an environment with newenvironment that does the following: it evaluates the height of the environment and then prints it as many times (textheight/height) as will fit upon one page.

Here is an attempt to print the environment twice:

\documentclass{article}
\newenvironment{double}{\newcommand{\todouble}\bgroup}{\egroup\todouble\todouble}
\begin{document}
\begin{double}
    Hello, World!
\end{double}
\end{document}

My first idea is to use \newenvironment to define an environment that uses \newcommand to define a command \todouble that contains the contents of the environment. At the end of the environment \todouble is called twice.

But this fails with the error:

! Extra }, or forgotten \endgroup.
\enddouble ->\egroup 
                 \todouble \todouble 
l.6 \end{double}

How can I fix it?

  • 4
    What exactly are you trying to do? If you just want to save the contents of an env in a macro, see the environ package. – daleif Feb 18 '15 at 10:30
  • Oh, environ seems very good - I'll use it for another task :) Thanks for information! – uzsolt Feb 18 '15 at 12:32
7

You can't use \bgroup for delimiting a mandatory argument. And you want leaders to fill up the page with copies of what you absorbed.

\documentclass{article}

\newenvironment{double}
 {%
  \par % be in vertical mode
  \setbox0=\vbox\bgroup % start a box
  \strut % ensure good height for the first line
  \ignorespaces % ignore the end of line
 }
 {%
  \egroup % end the box
  \hrule height0pt % vertical analog of \leavevmode
  \cleaders\copy0\vfill % repeat as much as necessary
 }
\begin{document}
\begin{double}
    Hello, World!
\end{double}
\end{document}

enter image description here

An extended version that checks whether at least two copies of the box fit in the page and just prints the box if not.

\documentclass{article}

\usepackage{lipsum}

\newenvironment{double}
 {%
  \par % be in vertical mode
  \setbox0=\vbox\bgroup % start a box
  \strut % ensure good height for the first line
  \ignorespaces % ignore the end of line
 }
 {%
  \ifhmode\strut\fi\egroup % end the box
  % see if at least two copies of the box fit in the page
  \ifdim\ht0 < \dimexpr .5\textwidth-4ex\relax
    \hrule height0pt % vertical analog of \leavevmode
    \cleaders\copy0\vfill % repeat as much as necessary
    \clearpage
  \else
    \unvbox0
    \clearpage
  \fi
 }
\begin{document}
\begin{double}
    Hello, World!
\end{double}

\begin{double}
\lipsum*[2]
\end{double}

\begin{double}
\lipsum
\end{double}
\end{document}
  • 1
    Thank you! I think I should learn a bit more about LaTeX... – uzsolt Feb 18 '15 at 12:33
  • @uzsolt \leaders are not in the LaTeX manual. Consult TeX by Topic (or the TeXbook) for them. – egreg Feb 18 '15 at 12:43
  • your solution doesn't work when the text's height is more than a page height. How can I fix it? – uzsolt Feb 22 '15 at 16:46
  • @uzsolt How can you fill a page with something that's bigger than the page? Do you want to truncate it? – egreg Feb 22 '15 at 16:46
  • Good question :) Is it possible to modify your solution to handle this situation? If the body is bigger than a page should be two (or more) page. – uzsolt Feb 22 '15 at 16:48

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.