% \iffalse meta-comment
%
% Copyright (C) 2007
% Rolf Niepraschk, Rolf.Niepraschk@gmx.de
% 
% 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 this 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/12/01 or later.
% 
% This work has the LPPL maintenance status "author-maintained".
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{blowup.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{blowup}
%<*package>
    [2008/11/14 0.1j Document Scaling (RN)]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{array,longtable}
\IfFileExists{ragged2e.sty}{%
  \usepackage{ragged2e}}{\let\RaggedRight=\raggedright}
\newcommand{\m}[1]{\mbox{$\langle$\it #1\/$\rangle$}}
\renewcommand{\arg}[1]{{\ttfamily\string{}\m{#1}{\ttfamily\string}}}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{blowup.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{499}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v0.1a}{2007/08/14}{Initial version. (RN)}
%
% \GetFileInfo{blowup.dtx}
%
% \DoNotIndex{\newcommand,\newenvironment}
% 
% \newcommand\afterheading{\par\nobreak\@afterheading}
% \newcolumntype{P}[1]{>{\RaggedRight\hspace{0pt}}p{#1}}
% 
%
% \title{The \textsf{blowup} package\thanks{This document
%   corresponds to \textsf{blowup}~\fileversion, dated \filedate.}}
% \author{Rolf Niepraschk \\ \texttt{Rolf.Niepraschk@gmx.de}}
%
% \maketitle
% 
%    \begin{abstract}
%       \noindent
%       This package only defines the user-level macro \cmd{\blowUp}, 
%       which can be used to upscale or downscale all pages 
%       of a document. It is 
%       similar to the \TeX\ primitive \cmd{\magnification} but more 
%       accurate and user-friendly. \cmd{\blowUp} 
%       may be useful for the creation of posters from a normal-sized 
%       document and for many kinds of fine adjustments of a ready 
%       typesetted document (e.\,g., minor changes of scaling and 
%       position of the pages). 
%    \end{abstract}
%
%    \tableofcontents
%
% \section{Usage}
% Load the package after other packages that affect the paper size 
% (e.\,g., \textsf{geometry} and \textsf{hyperref}). 
% Then call the macro \cmd{\blowUp} before |\begin{document}| to scale 
% the document. \par \medskip \noindent
%  |\usepackage{blowup}| \par \noindent
%  \cmd{\blowUp}\arg{key=value} \par \noindent
%  \vspace{-\baselineskip}
%  \setlength\extrarowheight{.2ex}
%  \begin{longtable}{@{}lP{.75\linewidth}@{}}
%    \multicolumn{1}{@{}l}{\textbf{key}} & 
%    \multicolumn{1}{l@{}}{\textbf{value}} \tabularnewline \hline 
%    paper     & The final paper size: \tabularnewline
%              & |letter|, |legal|, |executive| or a paper size from the 
%              ISO/DIN paper series A, B, C, D 
%              (e.\,g., |a8|, |c7|,..., |b1|, |a0|) or a pair of dimensions
%              in curly brackets (e.\,g., |paper={925mm,1225mm}|) or the 
%              letter `x' followed by a scaling factor 
%              (e.\,g., |paper=x1.414213|). \tabularnewline[.4\baselineskip]
%    landscape & Exchanges paperwidth and paperheight: \tabularnewline
%              & |true| (the same as no value) or |false|. \tabularnewline[.4\baselineskip]
%    noscale   & No scaling of the original paper size: \tabularnewline
%              & |true| (the same as no value) or |false|. \tabularnewline[.4\baselineskip]
%    pos       & Position of the page on the paper: \tabularnewline
%              & |left| or |right|, |inside| or |outside|, |top| or |bottom| 
%              (only the first letter is significant; default is 
%              centering), or
%              a pair of dimensions in curly brackets which means the offset  
%              from the lower left or lower outside corner of the final paper. 
%              Only meaningful for |noscale=true| and up-scaled paper 
%              size. \tabularnewline[.4\baselineskip]
%    onepage   & Suppresses the second page and all following pages: \tabularnewline 
%              & |true| (the same as no value) or |false|. \tabularnewline
%              & Useful for creating a one-side paper like a poster.
%  \end{longtable}
%  \vspace{0\baselineskip}
%  See also the example documents |blowup-test?.tex|.
%
%    \section{Required Packages}
%
%    The \textsf{blowup} package requires the following packages: 
%    \textsf{everyshi}, \textsf{graphics}, \textsf{keyval}, and 
%    \textsf{typearea}.
%
% \StopEventually{\PrintChanges\PrintIndex}
%
% \section{Implementation}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%  Load some packages for utility macros. 
%    \begin{macrocode}
\RequirePackage{everyshi,graphics,keyval}
\@ifpackageloaded{typearea}{}{%
  \newcommand*\BL@save@dimen[1]{%
    \@ifundefined{BL@#1}{%
      \expandafter\newlength\csname BL@#1\endcsname}{}%
    \csname BL@#1\endcsname\csname #1\endcsname
    \g@addto@macro\BL@restore@dimens{%
      \csname #1\endcsname\csname BL@#1\endcsname}%
  }%
  \newcommand*\BL@restore@dimens{}%
%    \end{macrocode}
% Some dimensions changed by \textsf{typearea} must be saved and restored.
%    \begin{macrocode}
    \BL@save@dimen{textwidth}%
    \BL@save@dimen{textheight}%
    \BL@save@dimen{evensidemargin}%
    \BL@save@dimen{oddsidemargin}%
    \BL@save@dimen{topmargin}%
    \BL@save@dimen{headheight}%
    \BL@save@dimen{headsep}%
    \BL@save@dimen{topskip}%
    \BL@save@dimen{footskip}%
    \BL@save@dimen{baselineskip}%
%    \end{macrocode}
% \changes{v0.1j}{2008/11/14}{Undefine \cmd{\l@addto@macro}. (RN)}
% Prevent an error if \cmd{\l@addto@macro} is already defined.
%    \begin{macrocode}
    \let\l@addto@macro=\relax
    \RequirePackage{typearea}%
    \BL@restore@dimens
    \let\BL@save@dimen=\relax
    \let\BL@restore@dimens=\relax
}
\providecommand*\vb@xt@{\vbox to}
%    \end{macrocode}
% \begin{macro}{\sPaperWidth}
% \begin{macro}{\sPaperHeight}
% The size of the scaled pages.
%    \begin{macrocode}
\newlength\sPaperWidth  \sPaperWidth=\paperwidth
\newlength\sPaperHeight \sPaperHeight=\paperheight
%    \end{macrocode}
% \end{macro}
% \end{macro}
%    \begin{macrocode}
\newcommand*\BL@@resize{}
%    \end{macrocode}
% \begin{macro}{\BL@scalePage}
% Scales the output box to the dimension of the new paper size.
%    \begin{macrocode}
\newcommand*\BL@scalePage{%
  \setbox\@cclv=\vbox{\vskip1in\unvbox\@cclv}%
  \setbox\@cclv=\vbox{\moveright1in\box\@cclv}%
  \setbox\@cclv=\hb@xt@\paperwidth{\box\@cclv\hss}%
  \setbox\@cclv=\vb@xt@\paperheight{\box\@cclv\vss}%
  \let\BL@@resize=\@firstofone
  \ifBL@noscale\else
    \def\BL@@resize##1{\resizebox{\sPaperWidth}{!}{##1}}%
    \setbox\@tempboxa=\hbox{\set@typeset@protect
      \BL@@resize{\copy\@cclv}}%
    \ifdim\ht\@tempboxa>\sPaperHeight
      \def\BL@@resize##1{\resizebox{!}{\sPaperHeight}{##1}}%
    \fi
  \fi
  \setbox\@tempboxa=\vb@xt@\sPaperHeight{\set@typeset@protect
    \kern\z@\BL@t
    \hb@xt@\sPaperWidth{\BL@l\BL@@resize{\box\@cclv}\BL@r}%
    \BL@b\kern\z@
  }%
  \setbox\@cclv=\vbox{\box\@tempboxa}%
  \setbox\@cclv=\vbox{\vskip-1in\unvbox\@cclv}%
  \setbox\@cclv=\vbox{\moveright-1in\box\@cclv}%
}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\newcommand\BL@tempa{}
\newcommand\BL@tempb{}
\newcommand*\BL@strip@comma{}
\def\BL@strip@comma#1,{#1}
%    \end{macrocode}
% \begin{macro}{\BL@if@dimen@pair}
% The parameter two will be executed if the first parameter is 
% a comma-separated pair of two dimensions. If not the parameter three 
% will be executed.
%    \begin{macrocode}
\newcommand*\BL@if@dimen@pair[1]{%
  \expandafter\BL@@if@dimen@pair#1,\@nil
}
\newcommand*\BL@@if@dimen@pair{}
\def\BL@@if@dimen@pair#1,#2\@nil{%
  \edef\BL@tempa{#1}\edef\BL@tempb{#2}%
  \@tempswafalse
  \ifx\BL@tempb\@empty\else
    \edef\BL@tempb{\expandafter\BL@strip@comma\BL@tempb}%
    \ifdimen{\BL@tempa}{\@tempswatrue}{}%
    \if@tempswa
      \ifdimen{\BL@tempb}{}{\@tempswafalse}%
    \fi
  \fi
  \if@tempswa
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\newcommand*\BL@strip@x{}
\def\BL@strip@x#1x{#1}
%    \end{macrocode}
% \begin{macro}{\BL@if@factor}
% The parameter two will be executed if the first parameter is the 
% small letter x (`times') immediately followed by a number. If not 
% the parameter three will be executed.
%    \begin{macrocode}
\newcommand*\BL@if@factor[1]{%
  \expandafter\BL@@if@factor#1x\@nil
}
\newcommand*\BL@@if@factor{}
\def\BL@@if@factor#1x#2\@nil{%
  \edef\BL@tempa{#2}%
  \ifx\BL@tempa\@empty
    \expandafter\@secondoftwo
  \else
    \edef\BL@tempa{\expandafter\BL@strip@x\BL@tempa}%
    \expandafter\@firstoftwo
  \fi
}
%    \end{macrocode}
% \end{macro}
% The key-value definitions for \cmd{\blowUp}
%    \begin{macrocode}
\define@key{BL@}{paper}{%
  \BL@if@dimen@pair{#1}{%
    \global\sPaperWidth=\BL@tempa\relax
    \global\sPaperHeight=\BL@tempb\relax
  }{%
    \BL@if@factor{#1}{%
      \global\sPaperWidth=\BL@tempa\paperwidth
      \global\sPaperHeight=\BL@tempa\paperheight
    }{%
      \begingroup
%    \end{macrocode}
%  Get the paper size. Reset the landscape mode because one of the 
%  \textsf{KOMA-SCRIPT} classes may be loaded in landscape mode too.
%    \begin{macrocode}
        \KOMAoptions{paper=portrait,paper=#1}%
        \global\sPaperWidth=\paperwidth
        \global\sPaperHeight=\paperheight
      \endgroup
    }%
  }%
}%
\newif\ifBL@noscale \BL@noscalefalse
\define@key{BL@}{noscale}[true]{%
  \csname BL@noscale#1\endcsname
}
\newcommand*\BL@l{\hss}
\newcommand*\BL@r{\hss}
\newcommand*\BL@i{}
\newcommand*\BL@o{}
\newcommand*\BL@t{\vss}
\newcommand*\BL@b{\vss}
%    \end{macrocode}
% \begin{macro}{\BL@setPos}
% Modify the macros \cmd{\BL@l}, \cmd{\BL@r} (\cmd{\BL@i}, \cmd{\BL@o}), 
% \cmd{\BL@t}, and \cmd{\BL@b} for positioning the page on the paper.
%    \begin{macrocode}
\newcommand\BL@setPos[1]{%
  \def\BL@l{\hss}\def\BL@r{\hss}%
  \def\BL@t{\vss}\def\BL@b{\vss}%
  \def\BL@i{}\def\BL@o{}%
  \BL@if@dimen@pair{#1}{%
    \edef\BL@b{\vskip\BL@tempb}%
    \if@twoside
      \edef\BL@l{\noexpand\ifodd\value{page}%
        \hskip\BL@tempa\noexpand\else\hss\noexpand\fi}%
      \edef\BL@r{\noexpand\ifodd\value{page}%
        \hss\noexpand\else\hskip\BL@tempa\noexpand\fi}%
    \else
      \edef\BL@l{\hskip\BL@tempa}%
    \if
  }{%
    \@for\BL@tempa:=#1\do{%
%    \end{macrocode}
%  Extract the first letter.
%    \begin{macrocode}
      \edef\BL@tempb{\expandafter\@car\BL@tempa\@nil}%
      \expandafter\let\csname BL@\BL@tempb \endcsname\relax
      \if@twoside
        \ifx\BL@i\relax
          \def\BL@r{\ifodd\value{page}\hss\else\relax\fi}%
          \def\BL@l{\ifodd\value{page}\relax\else\hss\fi}%
        \fi
        \ifx\BL@o\relax
          \def\BL@l{\ifodd\value{page}\hss\else\relax\fi}%
          \def\BL@r{\ifodd\value{page}\relax\else\hss\fi}%
        \fi
      \fi
    }%
  }%
}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\define@key{BL@}{pos}{%
  \BL@setPos{#1}%
}
\newif\ifBL@landscape \BL@landscapefalse
\define@key{BL@}{landscape}[true]{%
  \csname BL@landscape#1\endcsname
}
\newcommand*\BL@pageInit{}
\define@key{BL@}{onepage}[true]{%
  \csname if#1\endcsname
    \def\BL@pageInit{\gdef\shipout{\setbox\@tempboxa=}}%
  \fi
}
%    \end{macrocode}
% \begin{macro}{\blowUp}
% The only user-level macro.
%    \begin{macrocode}
\newcommand*\blowUp[1]{%
  \setkeys{BL@}{#1}%
  \ifBL@landscape
    \@tempdima=\sPaperWidth
    \global\sPaperWidth=\sPaperHeight
    \global\sPaperHeight=\@tempdima
  \fi
  \EveryShipout{\BL@scalePage}%
  \gdef\blowUp##1{%
    \PackageWarning{blowup}{%
      Only the first call of `\string\blowUp' \MessageBreak is effective}}%
}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\EveryShipout{\BL@pageInit}
\@onlypreamble\blowUp
\AtBeginDocument{%
%    \end{macrocode}
% The package \textsf{geometry} must not 
% write (wrong) pagesize informations to the output file. 
%    \begin{macrocode}
  \let\Gm@checkdrivers=\relax
  \BL@pagesize@specials{\sPaperWidth}{\sPaperHeight}%
}
%    \end{macrocode}
% \begin{macro}{\BL@pagesize@specials}
% Write pagesize informations to the output file. Depends on \TeX\ 
% compiler or driver.
%    \begin{macrocode}
\newcommand*\BL@pagesize@specials[2]{}
\@ifundefined{Gin@driver}{}{%
  \ifx\Gin@driver\@empty\else
    \filename@parse{\Gin@driver}\@tempswafalse
    \def\reserved@a{dvips}%
    \ifx\filename@base\reserved@a\@tempswatrue\fi
    \def\reserved@a{dvipdfm}%
    \ifx\filename@base\reserved@a\@tempswatrue\fi
    \if@tempswa
      \PackageInfo{blowup}{Generating code for dvips}%
      \def\BL@pagesize@specials#1#2{%
        \@tempdima=#1\@tempdimb=#2%
        \AtBeginDvi{\special{papersize=\the\@tempdima,\the\@tempdimb}}}%
    \fi
    \def\reserved@a{pdftex}%
    \ifx\filename@base\reserved@a
      \PackageInfo{blowup}{Generating code for pdfTeX}%
      \def\BL@pagesize@specials#1#2{%
        \pdfpagewidth=#1\relax\pdfpageheight=#2\relax}%
    \fi
    \def\reserved@a{vtex}%
    \ifx\filename@base\reserved@a
      \PackageInfo{blowup}{Generating code for VTeX}%
      \def\BL@pagesize@specials#1#2{%
        \mediawidth=#1\relax\mediaheight=#2\relax}%
    \fi
  \fi
}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale
%\endinput
