% changepage.sty
%
% Provides commands to change the page layout in the middle of a document,
% and to robustly check for typesetting on odd or even pages.
% Instructions for use are at the end of this file.
%
% This package is an extraction of code from the memoir class. It is
% intended to eventually replace the chngpage package.
%
% Author: Peter Wilson (Herries Press) 
%         (occasionaly at herries dot press (at) earthlink dot net)
% Copyright 2008 Peter R. Wilson
%
% If you have any questions you will probably get better and faster 
% answers if you ask them on the comp.text.tex newsgroup as I am away
% more often than I am here.
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3 of this license or (at your option) any 
% later version.
% The latest version of the license is in
%    http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of
% LaTeX version 2003/06/01 or later.
%
% This work has the LPPL maintenance status "author-maintained".
%
% This work consists of this file.
%
%
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{changepage}[2008/08/15 v1.0a check page and change page layout]

%%% Don't use this with memoir
\newcommand*{\cp@whoopsusingmemoir}{}
\@ifclassloaded{memoir}{\def\cp@whoopsusingmemoir{\endinput}}
\cp@whoopsusingmemoir

%% new \if for the strict option
\newif\ifstrictpagecheck
  \strictpagecheckfalse
%% user commands for switching strict page checking on/off
\newcommand*{\strictpagecheck}{\strictpagechecktrue}
\newcommand*{\easypagecheck}{\strictpagecheckfalse}

%% Declare and process options
\DeclareOption{strict}{\strictpagechecktrue}
\ProcessOptions\relax

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% new commands for strict checking of odd/even page
%% Works by writing a label and then checking its pageref
%%

\newif\ifoddpage
\newcounter{cp@cntr}
\newcount\cp@tempcnt % instead of \@memcnta
\newcommand{\cplabel}{^_}

%%%\gdef\thememc@@page{\the\c@page}
\gdef\thepmemc@@page{\the\c@page}

\long\def\pmemprotected@write#1#2#3{% modified \protected@write
  \begingroup
  \let\thepmemc@@page\relax
  #2%
  \let\protect\@unexpandable@protect
  \edef\reserved@a{\write#1{#3}}%
  \reserved@a
  \endgroup
  \if@nobreak\ifvmode\nobreak\fi\fi}

\newcommand*{\pmemlabel}[1]{\@bsphack
  \pmemprotected@write\@auxout{}%
    {\string\newpmemlabel{#1}{\thepmemc@@page}}%
  \@esphack}

\newcommand*{\newpmemlabel}[2]{{\global\@namedef{m@#1}{#2}}}
\newcommand*{\pmemlabelref}[1]{%
  \expandafter\ifx\csname m@#1\endcsname\relax
    0%   % 0 if there is no label yet in the aux file
  \else
    \csname m@#1\endcsname
  \fi}

\DeclareRobustCommand{\checkoddpage}{%
  \oddpagefalse%
  \ifstrictpagecheck%
    \stepcounter{cp@cntr}\pmemlabel{\cplabel\thecp@cntr}%
    \cp@tempcnt=\pmemlabelref{\cplabel\thecp@cntr}\relax
    \ifodd\cp@tempcnt\oddpagetrue\fi
  \else
    \ifodd\c@page\oddpagetrue\fi
  \fi}

%% end newcommands for strict checking of odd/even page
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% copy of some of the code from the ifmtarg package to save requiring ifmtarg
\begingroup
\catcode`\Q=3
\long\gdef\@ifmtarg#1{\@xifmtarg#1QQ\@secondoftwo\@firstoftwo\@nil}
\long\gdef\@xifmtarg#1#2Q#3#4#5\@nil{#4}
\endgroup

%% set the page output parameters
\DeclareRobustCommand{\ch@ngetext}{%
  \setlength{\@colht}{\textheight}\setlength{\@colroom}{\textheight}%
  \setlength{\vsize}{\textheight}\setlength{\columnwidth}{\textwidth}%
  \if@twocolumn%
    \advance\columnwidth-\columnsep \divide\columnwidth\tw@%
    \@firstcolumntrue%
  \fi%
  \setlength{\hsize}{\columnwidth}%
  \setlength{\linewidth}{\hsize}}

\DeclareRobustCommand{\changetext}[5]{%
  \@ifmtarg{#1}{}{\addtolength{\textheight}{#1}}%
  \@ifmtarg{#2}{}{\addtolength{\textwidth}{#2}}%
  \@ifmtarg{#3}{}{\addtolength{\evensidemargin}{#3}}%
  \@ifmtarg{#4}{}{\addtolength{\oddsidemargin}{#4}}%
  \@ifmtarg{#5}{}{\addtolength{\columnsep}{#5}}%
  \ch@ngetext}

\DeclareRobustCommand{\changepage}[9]{%
  \@ifmtarg{#1}{}{\addtolength{\textheight}{#1}}%
  \@ifmtarg{#2}{}{\addtolength{\textwidth}{#2}}%
  \@ifmtarg{#3}{}{\addtolength{\evensidemargin}{#3}}%
  \@ifmtarg{#4}{}{\addtolength{\oddsidemargin}{#4}}%
  \@ifmtarg{#5}{}{\addtolength{\columnsep}{#5}}%
  \ch@ngetext%
  \@ifmtarg{#6}{}{\addtolength{\topmargin}{#6}}%
  \@ifmtarg{#7}{}{\addtolength{\headheight}{#7}}%
  \@ifmtarg{#8}{}{\addtolength{\headsep}{#8}}%
  \@ifmtarg{#9}{}{\addtolength{\footskip}{#9}}}

\newenvironment{adjustwidth}[2]{%
  \begin{list}{}{%
    \topsep\z@%
    \listparindent\parindent%
    \parsep\parskip%
    \@ifmtarg{#1}{\setlength{\leftmargin}{\z@}}%
                 {\setlength{\leftmargin}{#1}}%
    \@ifmtarg{#2}{\setlength{\rightmargin}{\z@}}%
                 {\setlength{\rightmargin}{#2}}%
    }
    \item[]}{\end{list}}

\newenvironment{adjustwidth*}[2]{%
  \begin{list}{}{%
    \topsep\z@%
    \listparindent\parindent%
    \parsep\parskip%
    \checkoddpage
    \ifoddpage%     odd numbered page
      \@ifmtarg{#1}{\setlength{\leftmargin}{\z@}}%
                   {\setlength{\leftmargin}{#1}}%
      \@ifmtarg{#2}{\setlength{\rightmargin}{\z@}}%
                   {\setlength{\rightmargin}{#2}}%
    \else%          even numbered page
      \@ifmtarg{#2}{\setlength{\leftmargin}{\z@}}%
                   {\setlength{\leftmargin}{#2}}%
      \@ifmtarg{#1}{\setlength{\rightmargin}{\z@}}%
                   {\setlength{\rightmargin}{#1}}%
    \fi}
    \item[]}{\end{list}}

\endinput

% Usage:
% ------
%
% \usepackage[strict]{changepage}
%
%%%%%%%%%%%%%%%
% \checkoddpage
%%%%%%%%%%%%%%%
%
%    The \checkoddpage command can be used anywhere in the body of
% a document to determine if TeX is typesetting on an odd or
% even numbered page. If on an odd page then \ifoddpage is
% set TRUE, otherwise (on an even page) \ifoddpage is set
% FALSE.
%
%    Strict page checking works by the \checkoddpage command generating 
% a label and then checking the \pageref for the label (actually, a special 
% version of \pageref is required and is used internally by \checkoddpage). 
% This mechanism requires at least two LaTeX passes to ensure that 
% the labels have settled (on the initial pass there will be no labels
% in the *.aux file to be checked).
%
%   The label identifier is composed of the command \cplabel
% and an automatically generated number. \cplabel, initially
% defined as `^_', can be changed in the preamble if it will cause
% a clash with any author-defined labels. The default labels will
% be of the form `^_N' where N is a positive integer.
%
%     The package option `strict' turns on strict page checking --- the default
% is not to use strict checking. Strict page checking can be turned on or 
% off at any time by the commands \strictpagecheck or \easypagecheck.
% The easy page check just tests the page number to see if it is odd or even, 
% which does not always give the correct result because of TeX's asynchronous
% output mechanism.
% 
%%%%%%%%%%%%%
% adjustwidth
%%%%%%%%%%%%%
%    Within an adjustwidth environment the left and right margins can be
% adjusted. The environment takes two required length arguments: 
%
% \begin{adjustwidth}{leftmargin}{rightmargin}
%
%     A positive length value will increase the relevant margin (shortening
% the text lines) while a negative length value will decrease the margin
% (lengthening text lines). An empty length argument means no change
% to the margin. At the end of the environment the margins revert to
% their original values.
%
%    For example, to extend the text into the right margin:
% \begin{adjustwidth}{}{-8em}
%
%   The starred version, adjustwidth*, causes the values of the
% margins to switch between odd and even pages.
%
%    If the document is being set twosided it might be advantageous
% to have any wider text extending into the outside margin. This
% could be done via the optional argument, as:
% \begin{adjustwidth*}{}{-8em}
%
%    To have the adjusted text horizontally centered with respect to
% any surrounding text, the margins should be adjusted equally:
% \begin{adjustwidth}{-4em}{-4em}
%
%    For interest, \begin{quotation} is pretty much equivalent
% to \begin{adjustwidth}{2.5em}{2.5em}
%
%    The environment may also be used inside a float if the contents are
% a bit too wide for the text block, but can still fit within the physical
% page:
% \begin{figure}
%   \begin{adjustwidth}{-2em}{-2em}
%      \includegraphics{wide}
%      \caption{Wide figure}
%   \end{adjustwidth}
% \end{figure}
%
%   Sometimes, because of the asynchronous nature of the TeX output
% routine, the margin switching may be incorrect (like \marginpar sometimes)
% near the top of a page. This can be corrected by using the package
% option `strict' (i.e., \usepackage[strict]{chngpage}), which causes
% adjustwidth to use the \checkoddpage command (see below).
%
%   A disadvantage of the strict option is that the package generates
% a new label for each adjustwidth environment, and TeX may run out
% of space if there are an excessive number of labels in the document.
%
%   Whether or not the strict option is used, `strict adjustwidths'
% can be turned on by putting the command \strictpagecheck before
% the environment, and turned off by using \easypagecheck.
%
%     NOTE: In a twocolumn document, the adjustwidth environment 
% treats both columns equally. For example, if the width is meant
% to be wider at the outer margin, then on odd pages the extra width
% will be at the right of any column, and on even pages the extra
% will be at the left of any column. You can get interesting effects
% by careful hand tuning on two column pages.
%
%%%%%%%%%%%%%
% \changetext
%%%%%%%%%%%%%
%     The \changetext command is for changing the size and horizontal position
% of the text block on a page. The command takes 5 arguments, each of which 
% is a length or is empty. i.e.,
%
% \changetext{textheight}{textwidth}{evensidemargin}{oddsidemargin}{columnsep}
%
% The given lengths are added to the corresponding current lengths and
% the remainder of the current page is typeset using the changed text block 
% layout. The new layout remains in effect until another \change... command 
% is issued.
%
%%%%%%%%%%%%%
% \changepage
%%%%%%%%%%%%%
%     The \changepage command is for changing the general layout of
% a page. The command takes 9 arguments, each of which is a length or is empty. 
% The first 5 arguments are the same as for \changetext and have the same effect.
% The last four arguments are:
%
% \changepage{5 args}{topmargin}{headheight}{headsep}{footskip}
%
% These lengths are added to the corresponding current lengths and
% thus modify the vertical positions of the elements of the page. The
% remainder of the current page is typeset using the changed text block 
% and page layout. The new layout remains in effect until another 
% \change... command is issued.
%
% NOTE 1: Not supplying a value for a length argument is equivalent
%         to giving it a zero length value.
%
% NOTE 2: For any given page, everything is constant except for the textwidth
%         and columnsep (for example, what is the meaning of two
%         topmargins on a single column page?).
%         It is therefore best to change anything else at the
%         start of a new page. Further, any changes only apply to whole
%         paragraphs. If you want an odd shaped paragraph use either
%         the hanging package or the TeX \parshape command.
%
%     For example, to change from single column pages to double column
% pages where the text block is both shorter and wider, then to revert
% back to the initial layout:
% ... single column normal page
% \newpage % or \clearpage
% \changetext{-5\baselineskip}{10em}{-5em}{-5em}{}
% \twocolumn
% ... two column pages
% \clearpage 
% \changetext{5\baselineskip}{-10em}{5em}{5em}{}
% \onecolumn
% ... normal pages
%
% Note the adjustments to the margins which will keep the vertical centerline
% of the textblock at the same position on the page.
%
%    As another example, to increase the width of a single paragraph:
%
% \changetext{0pt}{5em}{}{}{}%
% Start of wider paragraph text ...
% ... end of paragraph.
%
% \changetext{0pt}{-5em}{}{}{}
% Start of a normal paragraph ...
%
%     Under some circumstances you can include a \change... command as part of
% the argument to \afterpage (from the afterpage package) and it may work.
% Similarly it may work in a heading style used for \thispagestyle to change
% a single page.
%
%
% Changes in version 1.0a (2008/08/15)
% ----------------------
% o Fixed typo (a missing `p', courtesy Will Robertson)
% 
% Changes in version 1.0 (2008/03/22)
% ----------------------
% o First public release
% 
% Peter W.
%

