9

The problem is as follows.

In a memoir document, I defined the page geometry:

\usepackage{geometry}
\geometry{
paperwidth=5.25in,
paperheight=8in,
textwidth=95mm,
textheight=150mm,
outer=17mm
}
\setlength{\stockwidth}{5.25in}
\setlength{\stockheight}{8in}
\addtolength{\headheight}{5pt}

Then I defined an environment to put a piece of text dead centre on a page:

\newenvironment{quotepage}[1]%
{\newpage\newgeometry{margin=0pt}%
\thispagestyle{empty}%
\bgroup\centering%
\noindent\par\mbox{}\vspace*{-\baselineskip}\vfill%
\begin{minipage}{#1}%
\setlength{\parskip}{0.6\baselineskip}%
\setlength{\parindent}{0pt}%
}{\end{minipage}%
\vfill\egroup%
\restoregeometry}

When using this environment,

\begin{quotepage}{0.7\linewidth}
\itshape
What is the Noble Truth of Suffering? ...

Saṃyutta Nikāya 56.11, Dhammacakkappavattana Sutta
\end{quotepage}

The next page (the one after \restoregeometry was called) will begin with good header and textwidth, but the page content runs way off the page at the bottom. The page after that has good header, footer, text width, height and all.

text runs off the page

However, this doesn't happen if I don't use an environment. If I just copy-paste the code which the environment should insert, the page after \restoregeometry is good, and so are the rest.

Very puzzling. Something is going wrong with how I defined the environment, but I can't figure it out. Can someone see the problem?

lockstep
  • 250,273
Gambhiro
  • 3,384

2 Answers2

9

You're using a group too many and don't restore properly the geometry, as the \restoregeometry command is issued when LaTeX is still processing the environment, which forms a group:

\newenvironment{quotepage}[1]
  {\newpage
   \newgeometry{margin=0pt}
   \thispagestyle{empty}
   \centering
   \vspace*{\fill}\vspace{-\baselineskip}
   \begin{minipage}{#1}
   \setlength{\parskip}{0.6\baselineskip}
   \setlength{\parindent}{0pt}
  }
  {\end{minipage}
   \vfill
   \clearpage
   \aftergroup\restoregeometry
  }

You may want to look at other solutions, for example TikZ provides the ability to put nodes at the physical page center.

\usepackage{tikz}
\newsavebox{\quotepagebox}
\newenvironment{quotepage}[1]
  {\begin{lrbox}{\quotepagebox}\begin{minipage}{#1}
   \setlength{\parskip}{0.6\baselineskip}
   \setlength{\parindent}{0pt}}
  {\end{minipage}\end{lrbox}%
   \clearpage\thispagestyle{empty}
   \begin{tikzpicture}[remember picture,overlay]  
   \node at (current page.center) {\usebox{\quotepagebox}};
   \end{tikzpicture}
   \clearpage}
egreg
  • 1,121,712
  • Thanks for the neat codeblock! I'll look into the tikz node business too, sounds much simpler. – Gambhiro Jan 09 '12 at 10:35
  • @Nyiti You may want to look at the code provided in my last edit. – egreg Jan 09 '12 at 10:48
  • @egreg that works, but it removes \doublespacing in my case. Is that intentional? – ghx Jul 08 '20 at 01:32
  • @ghx That might depend on many factors; please, ask a new question with all the needed details. – egreg Jul 08 '20 at 07:28
  • @egreg ok please see: https://tex.stackexchange.com/questions/552734/afterpage-and-newgeometry-spacing-issue – ghx Jul 08 '20 at 12:50
2

As egreg said, \restoregeometry must be executed outside the environment.

You can use the \AfterEndEnvironment-hook from the etoolbox package for that.

From the etoolbox documentation:

\AfterEndEnvironment{environment}{code}

Appends arbitrary code to a hook executed at a very late point by the \end command, after the group holding the environment has been closed.

MWE:

\documentclass[a6paper,landscape]{article}
\usepackage{etoolbox}
\usepackage[showframe]{geometry}
\usepackage{lipsum}

\newenvironment{myenv}{Hello!}{Bye!}
\BeforeBeginEnvironment{myenv}{\newgeometry{left=5mm,right=5mm,top=5mm,bottom=5mm}}
\AfterEndEnvironment{myenv}{\restoregeometry}

\begin{document}
\lipsum[1]
\begin{myenv}
Test
\end{myenv}
\lipsum[2-3]
\end{document}

Output:

Output of the MWE in dual view. Despite page 2 having newgeometry, text on page 3 does not run off the page bottom.

user72575
  • 143