% \iffalse
%<*driver>
\ProvidesFile{envlab.drv}
%</driver>
%<*driver|package|cfg>
%<+package>\ProvidesPackage{envlab}
%<+cfg>\ProvidesFile{envlab.cfg}
[1997/07/16 v1.2 Envelopes and Labels] 
%</driver|package|cfg>
%<*driver|package>
%%
%% Copyright Boris Veytsman 1996, 1997
%%
%</driver|package>
%<*driver|package|cfg>
% \fi 
%%
% \CheckSum{1378}
%% \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         \~} 
% \iffalse
%</driver|package|cfg>
%
% \section{Documentation driver}
%<*driver>
% Nothing interesting here\dots
%    \begin{macrocode}
\documentclass{ltxdoc}
\DoNotIndex{\@Alph,\@alph,\@arabic,\@badmath}
\DoNotIndex{\@centercr}
\DoNotIndex{\@empty,\@ignoretrue}
\DoNotIndex{\@ixpt}
\DoNotIndex{\@M,\@minus,\@ne,\@plus}
\DoNotIndex{\\,\addtolength}
\DoNotIndex{\advance}
\DoNotIndex{\ast,\begin,\begingroup,\bfseries,\bgroup,\box}
\DoNotIndex{\bullet}
\DoNotIndex{\cdot,\cr,\day,\DeclareOption}
\DoNotIndex{\def,\DocInput,\documentclass}
\DoNotIndex{\DoNotIndex,\egroup,\ifx,\else,\fi,\endtrivlist}
\DoNotIndex{\EnableCrossrefs,\end,\end@dblfloat,\end@float,\endgroup}
\DoNotIndex{\endlist,\everycr,\ExecuteOptions}
\DoNotIndex{\filedate,\filename,\fileversion}
\DoNotIndex{\global,\halign,\hangindent,\hbox,\hfil,\hfill,\hrule}
\DoNotIndex{\hsize,\hskip,\hspace,\hss,\ifcase,\or,\fi}
\DoNotIndex{\ifvmode,\fi,\ifnum,\fi,\input}
\DoNotIndex{\kern,\leavevmode,\let,\leftmark}
\DoNotIndex{\list,\llap,\long,\m@ne,\m@th,\mark}
\DoNotIndex{\month,\newcommand,\newcounter,\newenvironment}
\DoNotIndex{\NeedsTeXFormat,\newdimen}
\DoNotIndex{\newpage,\nobreak,\noindent,\number}
\DoNotIndex{\p@}
\DoNotIndex{\pagestyle,\par}
\DoNotIndex{\penalty,\PrintChanges,\PrintIndex,\ProcessOptions}
\DoNotIndex{\protect,\ProvidesClass,\raggedbottom,\raggedright}
\DoNotIndex{\refstepcounter,\relax,\renewcommand,\reset@font}
\DoNotIndex{\rightmargin,\rlap,\rmfamily}
\DoNotIndex{\setbox,\setcounter,\setlength}
\DoNotIndex{\skip,\slshape,\space}
\DoNotIndex{\trivlist,\typeout,\tw@}
\DoNotIndex{\vskip,\vspace,\year,\z@}
%
\DoNotIndex{\@ptsize,\@sptoken,\addtocounter,\afterassignment}
\DoNotIndex{\AtEndOfPackage,\baselineskip,\boxmaxdepth,\clearpage}
\DoNotIndex{\clubpenalty,\csname,\CurrentOption,\DeclareRobustCommand}
\DoNotIndex{\eject,\endcsname,\evensidemargin,\expandafter}
\DoNotIndex{\footnotesize,\footskip,\fromaddress,\futurelet}
\DoNotIndex{\headheight,\headsep,\hfuzz,\ignorespaces}
\DoNotIndex{\InputIfFileExists,\large,\lineskip,\loop}
\DoNotIndex{\MakeUppercase,\MessageBreak,\mbox,\multiply}
\DoNotIndex{\newcount,\newif,\newlength,\newtoks,\nolinebreak}
\DoNotIndex{\nopagebreak,\normalfont,\normalsize,\null,\newline}
\DoNotIndex{\oddsidemargin,\PackageError,\PackageInfo}
\DoNotIndex{\paperheight,\paperwidth,\parbox,\parindent}
\DoNotIndex{\PassOptionsToPackage,\ProvidesPackage,\RequirePackage}
\DoNotIndex{\rule,\selectfont,\sffamily,\sloppy,\small,\spaceskip}
\DoNotIndex{\stepcounter,\textheight,\textwidth,\the,\topmargin}
\DoNotIndex{\unhbox,\voidb@x,\vsize,\vfuzz,\widowpenalty,\xspaceskip}
\DoNotIndex{\AtBeginDocument,\AtEndDocument}
\usepackage{enumerate}
\CodelineIndex
\RecordChanges
\EnableCrossrefs
\begin{document}
  \DocInput{envlab.dtx}
\end{document}
%    \end{macrocode}
%</driver>
% \fi
%
% \changes{v0.9}{1996/05/31}{Beta version}
% \changes{v0.91}{1996/05/31}{Added new option---"alwaysbarcodes"}
% \changes{v1.0}{1996/06/09}{First released version}
% \changes{v1.1}{1996/07/08}{Fixed typos in "elold.ins"}
% \changes{v1.1}{1996/07/08}{Updated User Guide}
% \changes{v1.2}{1996/07/10}{Changed envlab.ins: made it parallel.}
%% \changes{v1.2}{1996/07/16}{Updated User Guide}
%
% \newcommand{\EL}{\textsl{EnvLab}}
%
%
% \GetFileInfo{envlab.drv}
%
% \title{Printing Envelopes and Labels in \LaTeXe: \EL\ Package
%  \thanks{This file
%        has version number \fileversion, last
%        revised \filedate.}
%  \thanks{\copyright Boris Veytsman, 1996, 1997}
%  }
% \author{Boris Veytsman}
% \date{\filedate}
% \maketitle
% 
% \tableofcontents
%
%
% \section{Introduction}
% \MakeShortVerb{\"}
% The standard "\makelabels" command in the \LaTeXe\ "letter.cls"
% documentclass typesets labels on Avery 5352 sheets. A typical user
% may want more. \EL\ redefines "\makelabels" in\footnote{hopefully}
% a more useful and customizable way
%
% The detailed usage of the package is described in the file
% "elguide.tex". Here we just comment the macros.
%
% \StopEventually
%
% \section{Identification}
%
% First, we must say ``Hello world.'' 
%    \begin{macrocode}
%<*package>
\NeedsTeXFormat{LaTeX2e}
%    \end{macrocode}
%
% \begin{macro}{\envlab@ok}
% \begin{macro}{\envlab@oops}
% \changes{v1.2}{1997/07/10}{Used \cs{@ifundefined} instead of direct check}
% Now let us check whether we in the letter documentclass. Actually we
% will accept any class that has "\makelabels" defined (custom letter
% classes, etc.)
%    \begin{macrocode}
\def\envlab@oops{%
  \PackageError{envlab}%
  {Envlab is used outside of \MessageBreak%
   a letter-compatible documentclass}%
  {You are trying to use Envelopes & Labels\MessageBreak%
   package, but your documentclass does not\MessageBreak%
   understand address formatting commands.\MessageBreak%
   Try standard document class letter\MessageBreak}}
\def\envlab@ok{%
  \PackageInfo{envlab}%
  {Envelopes & Labels package: found makelabels...\MessageBreak%
  Seems everything is OK. Good luck.}}
\@ifundefined{makelabels}{\envlab@oops}{\envlab@ok}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \section{Preliminary code}
%
% \subsection{Switches, etc.} 
% 
%
% \DescribeMacro{\if@envelope}
% \DescribeMacro{\if@biglabel}
% \changes{v1.2}{1997/07/13}{Added Big Labels---thanks to Genick
% Bar-Meir, "meyerson@msi.umn.edu"}
% There are three kinds of things we can print: envelopes (default)
% labels and big labels The differences are summarized in
% Table~\ref{tab:diffs}.
% \begin{table}
%   \begin{center}
%     \begin{tabular}{cccc}
%       \hline
%       Media & Number per page & Rotation & Return address \\
%       \hline
%       Envelopes & One & Settable & Yes\\
%       Labels & Several & Not rotated & No\\
%       Big Labels & Several & Not rotated & Yes\\
%       \hline
%     \end{tabular}
%   \end{center}
%   \caption{Differences between envelopes, labels and big labels}
%   \label{tab:diffs}
% \end{table}
%
%    \begin{macrocode}
\newif\if@envelope 
\@envelopetrue 
\newif\if@biglabel 
\@biglabelfalse
%    \end{macrocode}
%
% \DescribeMacro{\if@rotateenvelopes}
% \DescribeMacro{\if@printreturnaddress}
% Now we must determine whether we want to rotate envelopes and
% whether to include return address (both yes by default).
%    \begin{macrocode}
\newif\if@rotateenvelopes
\@rotateenvelopestrue
\newif\if@printreturnaddress
\@printreturnaddresstrue
%    \end{macrocode}
%
% \DescribeMacro{\@envelopeposition}
% Now let us decide how to print envelopes. They can be either centered
% (default) \emph{or} shifted to the left or to the right of the paper
% tray.  The
% counter "\@envelopeposition" can be, correspondingly, either 0 or 1
% or 2. The value of
% 3 corresponds to the ``custom placing'', when the user sets
% "\EnvelopeLeftMargin" manually.
%
%    \begin{macrocode}
\newcount\@envelopeposition 
\@envelopeposition=0\relax
%    \end{macrocode}
%
% \begin{macro}{\if@pswait}
% \changes{v1.1}{1996/07/08}{Added \cs{if@pswait}}
% \begin{macro}{\if@psautotray}
% \changes{v1.1}{1997/07/13}{Added \cs{if@psautotray}}
% \begin{macro}{\PSEnvelopeTray}
% \changes{v1.1}{1997/07/13}{Added \cs{PSEnvelopeTray}}
% The switches "\if@pswait" and "\if@psautotray" control optional manual 
% feeding of envelopes and labels in \textsl{Postscript} printers 
% (see Section~\ref{sec:Print} for details). The register
% "\PSEnvelopeTray" contains the  name of the required tray.
%    \begin{macrocode}
\newif\if@pswait
\@pswaitfalse
\newif\if@psautotray
\@psautotrayfalse
\newtoks\PSEnvelopeTray
\PSEnvelopeTray={/otherenvelopetray }
%    \end{macrocode}
%
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\if@barcodes}
% \begin{macro}{\if@alwaysbarcodes}
% We can either print bar codes (default) or not. The second switch
% forces to print barcodes even if they are not last in the address
% (like "Pa 16801\\USA") 
%    \begin{macrocode}
\newif\if@barcodes
\newif\if@alwaysbarcodes
\@barcodestrue
\@alwaysbarcodesfalse
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\if@EL@redefine@opening}
% \changes{v1.2}{1997/07/14}{Wrote new command}
% Now let us decide whether to mess with the "\opening" command.
%    \begin{macrocode}
\newif\if@EL@redefine@opening
\@EL@redefine@openingfalse
%    \end{macrocode}
% \end{macro} 
%
%
% \begin{macro}{\if@capitalizeaddress}
% Also, we can either capitalize the address (default) or not.
%    \begin{macrocode}
\newif\if@capitalizeaddress
\@capitalizeaddresstrue
%    \end{macrocode}
% \end{macro}
%
% \subsection{Lengths and numbers}
%
% We want all lengths to be user settable, so no "@" in the names.
%
% 
% \DescribeMacro{\EnvelopeWidth}
% \DescribeMacro{\EnvelopeHeight}
% \DescribeMacro{\EnvelopeTopMargin}
% \DescribeMacro{\EnvelopeLeftMargin}
% An envelope has four basic lengths.
% The first two are self-evident. The third is the distance between the
% edge of the paper and the leading edge of the envelope. All
% pre-defined envelope sizes set this to zero. The fourth is the distance
% between the left edge of the paper and the envelope. Its value depends
% on the value of the "\@envelopeposition" variable. We will preset it to
% zero
%    \begin{macrocode}
\newlength{\EnvelopeWidth}
\newlength{\EnvelopeHeight}
\newlength{\EnvelopeTopMargin}
\newlength{\EnvelopeLeftMargin}
\setlength{\EnvelopeLeftMargin}{0pt}
%    \end{macrocode}
%
% 
% \DescribeMacro{\LabelWidth}
% \DescribeMacro{\LabelHeight}
% \DescribeMacro{\LabelTopMargin}
% \DescribeMacro{\LabelLeftMargin}
% \DescribeMacro{\LabelRightMargin}
% A label has more parameters.
% The first two are the same as for the envelopes. The next two define the
% distances from the paper edges to the beginning of the labels. The
% last one describes the distance between the labels.
%    \begin{macrocode}
\newlength{\LabelWidth}
\newlength{\LabelHeight}
\newlength{\LabelTopMargin}
\newlength{\LabelLeftMargin}
\newlength{\LabelRightMargin}
%    \end{macrocode}
%
% \DescribeMacro{\c@LabelMaxCol}
% \DescribeMacro{\c@LabelMaxRow}
% The following numbers define, how many labels are in each row and how
% many rows are on each page
%    \begin{macrocode}
\newcounter{LabelMaxCol}
\newcounter{LabelMaxRow}
%    \end{macrocode}
%
% The lengths above are \emph{external} parameters that determine an
% envelope or a label. Now we will describe \emph{internal} lengths. We
% define them here because the commands "\SetEnvelope" and "\SetLabel"
% determine them basing on the given envelope or label type.
%
% 
% \DescribeMacro{\FromAddressTopMargin}
% \DescribeMacro{\FromAddressLeftMargin}
% \DescribeMacro{\FromAddressHeight}
% \DescribeMacro{\FromAddressWidth}
% \DescribeMacro{\ToAddressTopMargin}
% \DescribeMacro{\ToAddressLeftMargin}
% \DescribeMacro{\ToAddressWidth}
% The following lengths are self-evident.
%    \begin{macrocode}
\newlength{\FromAddressTopMargin}
\newlength{\FromAddressLeftMargin}
\newlength{\FromAddressHeight}
\newlength{\FromAddressWidth}
\newlength{\ToAddressTopMargin}
\newlength{\ToAddressLeftMargin}
\newlength{\ToAddressWidth}
%    \end{macrocode}
%
% \subsection{Main setting commands}
%
% OK, we are ready to set up envelopes and labels.
%
% \begin{macro}{\SetEnvelope}
% \changes{v1.2}{1997/07/14}{Added \cs{@biglabelfalse}}
% The command "\SetEnvelope" has three parameters: optional top Margin,
% width and height of the envelope.
%    \begin{macrocode}
\DeclareRobustCommand{\SetEnvelope}[3][0pt]{%
  \@envelopetrue%
  \@biglabelfalse%
  \setlength{\EnvelopeTopMargin}{#1}%
  \setlength{\EnvelopeWidth}{#2}%
  \setlength{\EnvelopeHeight}{#3}%
  \setlength{\FromAddressTopMargin}{0.5in}%
  \setlength{\FromAddressLeftMargin}{0.5in}%
  \setlength{\FromAddressHeight}{0.33\EnvelopeHeight}%
  \setlength{\FromAddressWidth}{0.5\EnvelopeWidth}%
  \setlength{\ToAddressTopMargin}{0.5in}%
  \setlength{\ToAddressLeftMargin}{0.5in}%
  \setlength{\ToAddressWidth}{3in}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SetLabel}
% \changes{v1.2}{1997/07/14}{Added \cs{@biglabelfalse}}
% The command "\SetLabel" has seven parameters: five lengths and two
% numbers. All are mandatory:
%    \begin{macrocode}
\DeclareRobustCommand{\SetLabel}[7]{%
  \@envelopefalse%
  \@biglabelfalse%
  \setlength{\LabelWidth}{#1}%
  \setlength{\LabelHeight}{#2}%
  \setlength{\LabelTopMargin}{#3}%
  \setlength{\LabelLeftMargin}{#4}%
  \setlength{\LabelRightMargin}{#5}%
  \setcounter{LabelMaxCol}{#6}%
  \setcounter{LabelMaxRow}{#7}%
  \setlength{\ToAddressTopMargin}{0.1in}%
  \setlength{\ToAddressLeftMargin}{0.2in}%
  \setlength{\ToAddressWidth}{\LabelWidth}%
  \addtolength{\ToAddressWidth}{-\ToAddressLeftMargin}%
  \addtolength{\ToAddressWidth}{-\LabelRightMargin}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SetBigLabel}
% \changes{v1.2}{1997/07/14}{Wrote new command}
% The command "\SetBigLabel" has seven parameters: five lengths and two
% numbers. All are mandatory:
%    \begin{macrocode}
\DeclareRobustCommand{\SetBigLabel}[7]{%
  \@envelopefalse%
  \@biglabeltrue%
  \setlength{\LabelWidth}{#1}%
  \setlength{\LabelHeight}{#2}%
  \setlength{\LabelTopMargin}{#3}%
  \setlength{\LabelLeftMargin}{#4}%
  \setlength{\LabelRightMargin}{#5}%
  \setcounter{LabelMaxCol}{#6}%
  \setcounter{LabelMaxRow}{#7}%
  \setlength{\FromAddressTopMargin}{0.0in}%
  \setlength{\FromAddressLeftMargin}{0.5in}%
  \setlength{\FromAddressHeight}{0.33\LabelHeight}%
  \setlength{\ToAddressTopMargin}{0.1in}%
  \setlength{\ToAddressLeftMargin}{0.5in}%
  \setlength{\ToAddressWidth}{\LabelWidth}%
  \addtolength{\ToAddressWidth}{-\ToAddressLeftMargin}%
  \addtolength{\ToAddressWidth}{-\LabelRightMargin}%
  \setlength{\FromAddressWidth}{\ToAddressWidth}}
%    \end{macrocode}
% \end{macro}
%
% \section{Defining options}
%
% \subsection{Envelope Sizes}
% \changes{v1.2}{1996/07/22}{Added new option: dlenvelope (thanks to
% "J.P.Jansen@net.HCC.nl")} 
% \changes{v1.2}{1997/07/13}{Added \cs{PSEnvelopeTray} to envelope
% options} 
%    \begin{macrocode}
\DeclareOption{businessenvelope}{\SetEnvelope{9.5in}{4.125in}%
  \PSEnvelopeTray={/com10envelopetray }}
\DeclareOption{executiveenvelope}{\SetEnvelope{7.5in}{3.875in}%
  \PSEnvelopeTray={/monarcenvelopetray }}
\DeclareOption{bookletenvelope}{\SetEnvelope{10.5in}{7.5in}}
\DeclareOption{personalenvelope}{\SetEnvelope{6.5in}{3.625in}}
\DeclareOption{c6envelope}{\SetEnvelope{162mm}{114mm}}
\DeclareOption{c65envelope}{\SetEnvelope{224mm}{114mm}}
\DeclareOption{c5envelope}{\SetEnvelope{229mm}{162mm}%
  \PSEnvelopeTray={/162x229cenvelopetray }}
\DeclareOption{dlenvelope}{\SetEnvelope{220mm}{110mm}%
  \PSEnvelopeTray={/dlenvelopetray }}
%    \end{macrocode}
%
% \subsection{Labels sizes}
%
% \changes{v1.2}{1996/07/22}{Added new option: herma4625label (thanks to
% "J.P.Jansen@net.HCC.nl")} 
% \changes{v1.2}{1996/09/06}{Added new option: avery5262label (thanks to
% Uri Blumenthal "uri@ibm.net")}
% \changes{v1.2}{1997/07/13}{Added new option: avery5164biglabel}  
% \changes{v1.2}{1997/07/13}{Added new option: avery5163biglabel}  
%
%    \begin{macrocode}
\DeclareOption{avery5160label}{%
  \SetLabel{2.75in}{1in}{0.5in}{0.19in}{0.12in}{3}{10}}
\DeclareOption{avery5161label}{%
  \SetLabel{4.19in}{1in}{0.5in}{0.16in}{0.19in}{2}{10}}
\DeclareOption{avery5162label}{%
  \SetLabel{4.19in}{1.33in}{0.83in}{0.16in}{0.19in}{2}{7}}
\DeclareOption{avery5163label}{%
  \SetLabel{4.19in}{2in}{0.5in}{0.16in}{0.19in}{2}{5}}
\DeclareOption{avery5164label}{%
  \SetLabel{4.19in}{3.33in}{0.5in}{0.16in}{0.19in}{2}{3}}
\DeclareOption{herma4625label}{%
  \SetLabel{105mm}{42.3mm}{0mm}{5mm}{5mm}{2}{7}}
\DeclareOption{avery5262label}{%
  \SetLabel{110mm}{34mm}{21mm}{4mm}{5mm}{2}{7}}
\DeclareOption{avery5163biglabel}{%
  \SetBigLabel{4.19in}{2in}{0.5in}{0.16in}{0.19in}{2}{5}%
  \setlength{\ToAddressTopMargin}{0.1in}}%
\DeclareOption{avery5164biglabel}{%
  \SetBigLabel{4.19in}{3.33in}{0.5in}{0.16in}{0.19in}{2}{3}}%
%    \end{macrocode}
%
% \subsection{Optional switches}
%
% \changes{v1.1}{1996/07/08}{Added new options: "printreturnaddress", 
% "noprintreturnaddress"}
% \changes{v1.1}{1996/07/08}{Added new options: "pswait", 
% "nopswait"}
% \changes{v1.2}{1997/07/13}{Added new options: "psautotray", 
% "nopsautotray"}
% \changes{v1.2}{1997/07/14}{Added new options: "re", "nore"}
% All this should be evident\dots
%
%    \begin{macrocode}
\DeclareOption{rotateenvelopes}{\@rotateenvelopestrue}
\DeclareOption{norotateenvelopes}{\@rotateenvelopesfalse}
\DeclareOption{centerenvelopes}{\@envelopeposition=0\relax}
\DeclareOption{leftenvelopes}{\@envelopeposition=1\relax}
\DeclareOption{rightenvelopes}{\@envelopeposition=2\relax}
\DeclareOption{customenvelopes}{\@envelopeposition=3\relax}
\DeclareOption{printbarcodes}{\@barcodestrue}
\DeclareOption{noprintbarcodes}{\@barcodesfalse\@alwaysbarcodesfalse}
\DeclareOption{alwaysbarcodes}{\@alwaysbarcodestrue\@barcodestrue}
\DeclareOption{noalwaysbarcodes}{\@alwaysbarcodesfalse}
\DeclareOption{capaddress}{\@capitalizeaddresstrue}
\DeclareOption{nocapaddress}{\@capitalizeaddressfalse}
\DeclareOption{printreturnaddress}{\@printreturnaddresstrue}
\DeclareOption{noprintreturnaddress}{\@printreturnaddressfalse}
\DeclareOption{pswait}{\@pswaittrue\@psautotrayfalse}
\DeclareOption{nopswait}{\@pswaitfalse}
\DeclareOption{psautotray}{\@psautotraytrue\@pswaitfalse}
\DeclareOption{nopsautotray}{\@psautotrayfalse}
\DeclareOption{re}{\@EL@redefine@openingtrue}
\DeclareOption{nore}{\@EL@redefine@openingfalse}
%    \end{macrocode}
%
% \subsection{Unknown options}
%
% All options we did not declare above are probably the options for the
% "graphics" package; let us send them there.
%    \begin{macrocode}
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{graphics}}
%    \end{macrocode}
%
% \subsection{Default options}\label{sec:DefOpt}
%
% \changes{v1.1}{1996/07/08}{Fixed typo in "businessenvelope" option}
% \changes{v1.1}{1996/07/09}{Added default options: "nopswait", 
% "printreturnaddress"}
%
%    \begin{macrocode}
\ExecuteOptions{businessenvelope,rotateenvelopes,centerenvelopes}
\ExecuteOptions{printbarcodes,capaddress}
\ExecuteOptions{nopswait,printreturnaddress,nopsautotray,nore}
%    \end{macrocode}
%
% \section{Configuration file}
%
% At this point we will look for the configuration file. This file is
% named "envlab.cfg". The options declared in this file will supersede
% the ones declared in Section~\ref{sec:DefOpt}, but will be in their
% turn be superseded by the options explicitly defined when the package
% is loaded.
%    \begin{macrocode}
\InputIfFileExists{envlab.cfg}{%
  \typeout{Loading configuration file envlab.cfg}}{%
  \typeout{Configuration file envlab.cfg is not found}}
%    \end{macrocode}
%
% Now let us discuss the structure of the configuration file. We want it
% to contain default options, and therefore to be loaded before the
% "\ProcessOptions" command. On the other hand we want it to contain
% some definitions that \emph{supersede} the ones in this package. The
% hook "\AtEndOfPackage" helps to do this: we will just delay all
% definitions until later.
%
% OK, let's construct an example of "envlab.cfg" file. The commands here
% essentially repeat Section~\ref{sec:DefOpt}, but we want to be
% foolproof\dots
%    \begin{macrocode}
%</package>
%<*cfg>
%%
%% The default options go here
%%
\ExecuteOptions{businessenvelope,rotateenvelopes,centerenvelopes}
\ExecuteOptions{printbarcodes,capaddress}
\ExecuteOptions{nopswait,printreturnaddress,nopsautotray,nore}
%%
\AtEndOfPackage{\relax % Customization goes here
}
%</cfg>
%<*package>
%    \end{macrocode}
%
% \section{Processing options and loading packages}
% \changes{v0.92}{1996/06/06}{Added \cs{IfFileExists} when loading packages}
%    \begin{macrocode}
\ProcessOptions
\IfFileExists{graphics.sty}{%
  \RequirePackage{graphics}}{%
  \PackageWarning{envlab}{%
    You don't have the graphics package!\MessageBreak
    Probably you will not be able to print\MessageBreak
    envelopes sidewise. \MessageBreak}}
%    \end{macrocode}
%
% \section{Document layout}
%
% \subsection{Printer specific commands}
% \label{sec:Print}
%
% \DescribeMacro{\@beginlabelshook}
% \changes{v1.1}{1996/07/09}{Replaced \cs{@printpreamble} with 
% \cs{@beginlabelshook}}
% The command "\@beginlabelshook" is called at the beginning of the
% printing of envelopes and labels. We define it to be a no-op, but it
% is possible to introduce some printer-specific commands (like paper
% change). 
%    \begin{macrocode}
\def\@beginlabelshook{\relax}
%    \end{macrocode}
%
% \DescribeMacro{\@beginlabelpagehook}
% \changes{v1.1}{1996/07/09}{Introduced new command 
% \cs{@beginlabelpagehook}}
% The command "\@beginlabelpagehook" is like "\@beginlabelshook", but is 
% called at the beginning of each \emph{page}
%  of envelopes and labels.
%    \begin{macrocode}
\def\@beginlabelpagehook{\relax}
%    \end{macrocode}
%
% \begin{macro}{\AtBeginLabels}
% \changes{v1.1}{1996/07/08}{Made \cs{AtBeginLabels} cumulative}
%   \begin{macro}{\AtBeginLabelPage}
% \changes{v1.1}{1996/07/09}{Introduced \cs{AtBeginLabelPage}}
% The hooks "\AtBeginLabels" and "\AtBeginLabelPage" redefine 
% "\@beginlabelshook" and  "\@beginlabelpagehook". They are built like 
% the standard \LaTeXe\ hooks
% "\AtBeginDocument", "\AtBeginDvi", etc. In the implementation we use the 
% \emph{internal} \LaTeXe\ command "\g@addto@macro". In the current 
% (June~1996) \LaTeXe\ release it is defined as:
% \DescribeMacro{\g@addto@macro}
% \begin{verbatim}
% \long\def\g@addto@macro#1#2{{%
%   \toks@\expandafter{#1#2}%
%   \xdef#1{\the\toks@}}}
% \end{verbatim}
% We quote this definition in case \emph{They} change Their minds\dots\ 
%    \begin{macrocode}
\def\AtBeginLabels{\g@addto@macro\@beginlabelshook}
\def\AtBeginLabelPage{\g@addto@macro\@beginlabelpagehook}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\PSwait}
% \changes{v1.1}{1996/07/09}{Put William Slough's code in a separate macro}
% \textsl{PostScript} printers can be switched to the manual feeding mode 
% with the following code by \emph{William Slough} "<cfwas@eiu.edu>".
%    \begin{macrocode}
\def\PSwait{\special{ps: clear grestore @manualfeed 0 0 bop}}
%    \end{macrocode} 
% The author explains his code in the following way:
% \begin{quotation}
%       Here is a possible explanation:
%       
%       The clear removes operands from the PostScript stack, which has the
%       effect of reversing some actions from the *previous* bop.  Unfortunately,
%       it reverses other important actions too (such as font size), but the
%       grestore seems to get these back.  Then the desired @manualfeed, followed
%       by the ``bop'' for the beginning of page.  The pair of 0's are used for
%       bop and are completely bogus.  However, from what I could detect, 0's are
%       as good as anything.  The values that DVIPS provides for bop seem to be
%       related to DVI page numbers.
%       
%       I make no guarantee about the reliability of this solution, but initial
%       tests indicate it will work for my environment.
% \end{quotation}
% \end{macro}
%
% \begin{macro}{\PSautotray}
% \changes{v1.2}{1997/07/13}{Wrote new command}
% This implements the code by \emph{Uri Blumenthal}
% "<uri@.ibm.net>". 
%    \begin{macrocode}
\edef\PSautotray{%
  \special{ps:clear grestore 
    statusdict begin false setduplexmode
    /manualfeed true def
    \the\PSEnvelopeTray end 0 0 bop }}
%    \end{macrocode}
% \end{macro}
%
% \changes{v1.1}{1996/07/08}{Added implementation of the "pswait" option}
% \changes{v1.1}{1996/07/09}{Moved \cs{PSwait} code to \cs{AtBeginLabelPage}}
% \changes{v1.1}{1996/07/15}{Moved \cs{PSwait} code to
%   \cs{AtBeginLabels}}
% \changes{v1.1}{1997/07/13}{Added implementation of the "psautotray" option}
% The option "pswait" puts the "\PSwait" code in the beginning of each
% page. The option "\psautotray" puts there the "\PSautotray" code.
%    \begin{macrocode}
\if@pswait 
  \AtBeginLabels{\PSwait}%
\else
  \if@psautotray
    \AtBeginLabels{\PSautotray}%
  \fi
\fi
%    \end{macrocode}
% 
%
% \subsection{Some useful counters for labels}
%
% 
% 
% \DescribeMacro{\c@LabelCountCol}
% \DescribeMacro{\c@LabelCountRow}
% These counters store the position of the currently printed label:
%    \begin{macrocode}
\newcounter{LabelCountCol}
\newcounter{LabelCountRow}
%    \end{macrocode}
%
% 
% \DescribeMacro{\c@LabelOffsetCol}
% \DescribeMacro{\c@LabelOffsetRow}
% And these counters provide the offset for the label printed on a
% partially used sheet:
%    \begin{macrocode}
\newcounter{LabelOffsetCol}
\newcounter{LabelOffsetRow}
\setcounter{LabelOffsetCol}{1}
\setcounter{LabelOffsetRow}{1}
%    \end{macrocode}
%
% \begin{macro}{\FirstLabel}
% \changes{v1.1}{1996/07/08}{Introduced new command \cs{FirstLabel}}
% The command "\FirstLabel"\marg{Row}\marg{Col} sets the counters 
% "LabelOffsetRow" and "LabelOffsetCol".
%    \begin{macrocode}
\DeclareRobustCommand{\FirstLabel}[2]{%
  \setcounter{LabelOffsetRow}{#1}%
  \setcounter{LabelOffsetCol}{#2}}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Fonts}
%
%
% \begin{macro}{\@toaddressfont}
%   \begin{macro}{\@fromaddressfont}
% \changes{v1.1}{1996/07/08}{Fixed documentation about \cs{@fromaddressfont}}
% We want the address to be printed in \textsf{\large 12pt sans serif}
% font. The return address will be printed in 10pt normal font.
%    \begin{macrocode}
\def\@toaddressfont{%
  \ifcase\@ptsize \large\or\normalsize\or\small\fi%
  \sffamily\selectfont}
\def\@fromaddressfont{%
  \ifcase\@ptsize \normalsize\or\small\or\footnotesize\fi%
  \normalfont}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \subsection{Return address}
%
% \begin{macro}{\returnaddress}
% \changes{v1.2}{1997/07/13}{Deleted check for \cs{if@envelope}}
% The standard letter class defines "\returnaddress" to be null. This
% is sensible if we are printing labels, but not so good if we are
% printing \emph{envelopes}. Therefore let us redefine it:
%    \begin{macrocode}
\def\returnaddress{\fromaddress}
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Margins, page styles, etc.}
%
% 
% \begin{macro}{\startlabels}
% \changes{v1.2}{1996/09/07}{Added \cs{clearpage}}
% \changes{v1.2}{1996/09/20}{Added percent signs}
% \changes{v1.2}{1997/07/10}{Moved here calculations for 
%   \cs{EnvelopeLeftMargin}} 
% \changes{v1.2}{1997/07/10}{Added \cs{LabelLeftMargin}} 
% The command "\startlabels" is the internal command that prepares
% the paper for labels or envelopes, resets the internal counters and
% calls "\@beginlabelshook". 
%    \begin{macrocode}
\def\startlabels{%
  \clearpage%
  \pagestyle{empty}%
  \setlength{\topmargin}{-1.0in}%
  \if@envelope%
    \addtolength{\topmargin}{\EnvelopeTopMargin}%
    \else \addtolength{\topmargin}{\LabelTopMargin}%
  \fi%
  \setlength{\headheight}{0pt}%
  \setlength{\headsep}{0pt}%
  \setlength{\footskip}{0pt}% 
  \setlength{\textheight}{200in}%
  \setlength\paperheight{\textheight}%
  \global\vsize=200in\relax%
  \addtolength{\textheight}{-\topmargin}%
  \addtolength{\textheight}{-1.0in}%
  \setlength{\oddsidemargin}{-1.0in}%
  \if@envelope\relax%
  \else%
     \addtolength{\oddsidemargin}{\LabelLeftMargin}%
  \fi%
  \setlength{\evensidemargin}{\oddsidemargin}%
  \setlength{\textwidth}{20in}%
  \hsize=20in%
  \baselineskip=0pt%
  \lineskip=0pt%
  \parindent=0pt%
  \if@envelope
%    \end{macrocode}
%
% Now we can calculate "\EnvelopeLeftMargin"
%
%    \begin{macrocode}
    \ifcase\the\@envelopeposition%
      \setlength{\EnvelopeLeftMargin}{\paperwidth}%
      \if@rotateenvelopes%
        \addtolength{\EnvelopeLeftMargin}{-\EnvelopeHeight}%
      \else%
        \addtolength{\EnvelopeLeftMargin}{-\EnvelopeWidth}%
      \fi%
      \setlength{\EnvelopeLeftMargin}{0.5\EnvelopeLeftMargin}%
    \or%
      \setlength{\EnvelopeLeftMargin}{0pt}%
    \or%
      \setlength{\EnvelopeLeftMargin}{\paperwidth}%
      \if@rotateenvelopes%
        \addtolength{\EnvelopeLeftMargin}{-\EnvelopeHeight}%
      \else%
        \addtolength{\EnvelopeLeftMargin}{-\EnvelopeWidth}%
      \fi%
    \else%
      \relax%
    \fi%
  \else%
%    \end{macrocode}
%
% Initializing labels counters\ldots
%
%    \begin{macrocode}
    \setcounter{LabelCountCol}{\theLabelOffsetCol}%
    \setcounter{LabelCountRow}{\theLabelOffsetRow}%
    \ifnum\theLabelOffsetRow>1%
      \null%
      \loop \vspace*{\LabelHeight}%
        \addtocounter{LabelOffsetRow}{-1} \ifnum\theLabelOffsetRow>1%
      \repeat%
    \fi%
    \ifnum\theLabelOffsetCol>1%
      \loop \hspace*{\LabelWidth}\nolinebreak%
        \addtocounter{LabelOffsetCol}{-1} \ifnum\theLabelOffsetCol>1%
      \repeat%
    \fi%
    \nopagebreak%
  \fi%
  \spaceskip0pt\relax%
  \xspaceskip 0pt\relax%
  \clubpenalty=0%
  \widowpenalty=0%
  \raggedbottom%
  \sloppy%
  \setlength\hfuzz{5in}%
  \setlength\vfuzz{5in}%
  \ignorespaces%
  \@beginlabelshook%
  \@beginlabelpagehook%
  \nopagebreak}%
%    \end{macrocode}
% \end{macro}
%
% \subsection{Printing of the addresses}
%
% \DescribeMacro{\PrintReturnAddress}
% This macro uses the text as an argument and prints it according to
%  the conventions.
%    \begin{macrocode}
\newcommand{\PrintReturnAddress}[1]{%
  \vspace*{\FromAddressTopMargin}
  \null\hspace{\FromAddressLeftMargin}
  \parbox[t][\FromAddressHeight]{\FromAddressWidth}%
    {\@fromaddressfont \lineskip=1pt 
      \if@printreturnaddress #1\else\relax\fi}}
%    \end{macrocode}
%
% \DescribeMacro{\PrintAddress}
% This macro works like "\PrintReturnAddress", with several important
% differences: it prints barcodes if necessary \emph{and}
% capitalizes the address.
%    \begin{macrocode}
\newcommand{\PrintAddress}[1]{%
  \vspace*{\ToAddressTopMargin}
  \leavevmode
  \null\hspace*{\ToAddressLeftMargin}
  \parbox[t]{\ToAddressWidth}{%
    \lineskip=1pt
    \if@barcodes \PrintBarCode{#1} \fi 
    \@toaddressfont
    \if@capitalizeaddress \@make@capitalize{#1} \else #1 \fi}}
%    \end{macrocode}
%
% \subsection{Label setup}
%
% \begin{macro}{\PrintLabel}
% \changes{v1.2}{1996/09/20}{Added percent signs}
% This macro prints a label in a parbox
%    \begin{macrocode}
\newcommand{\PrintLabel}[1]{%
  \parbox[t][\LabelHeight]{\LabelWidth}{%
    \PrintAddress{#1}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\PrintBigLabel}
% \changes{v1.2}{1997/07/13}{Wrote new command}
% This macro makes a minipage with addresses on it, similarly to
% "\PrintEnvelope" below.
%    \begin{macrocode}
\newcommand{\PrintBigLabel}[2]{%
  \begin{minipage}[t][\LabelHeight]{\LabelWidth}%
    \baselineskip=0pt%
    \lineskip=0pt%
    \parindent=0pt%
    \begin{center}%
      \PrintReturnAddress{#1}\\%
      \rule{\ToAddressWidth}{0.1pt}%
      \PrintAddress{#2}%
    \end{center}%
  \end{minipage}}
%    \end{macrocode}
%
%
% \subsection{Envelope setup} 
% 
% Labels include one box per label, so their setup is simple. The 
% situation with envelopes is different: they contain several boxes, and
% could be rotated, centered, etc. 
%
% \begin{macro}{\PrintEnvelope}
% \changes{v1.2}{1996/09/20}{Added percent signs}
% This macro makes a minipage with addresses on it.
%    \begin{macrocode}
\newcommand{\PrintEnvelope}[2]{%
  \begin{minipage}[t][\EnvelopeHeight]{\EnvelopeWidth}%
    \baselineskip=0pt%
    \lineskip=0pt%
    \parindent=0pt%
    \PrintReturnAddress{#1}\\%
    \begin{center}%
      \PrintAddress{#2}%
    \end{center}%
  \end{minipage}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@PrintEnvelope}
% The following macro checks for rotation:
%    \begin{macrocode}
\newcommand{\@PrintEnvelope}[2]{%
  \if@rotateenvelopes\rotatebox{90}{\PrintEnvelope{#1}{#2}}%
  \else\PrintEnvelope{#1}{#2}%
  \fi}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \section{Printing of envelopes and labels}
%
% \subsection{Main Command}
%
% \begin{macro}{\mlabel}
% Now we are prepared to print actual envelopes and labels. It is done by 
% the "\mlabel" command. It has two forms: for labels and envelopes.
%    \begin{macrocode}
\renewcommand{\mlabel}[2]{\ignorespaces%
  \spaceskip 0pt\relax%
  \xspaceskip 0pt\relax%
%    \end{macrocode}
%
% \subsection{Printing of one envelope}
% \changes{v1.1}{1996/07/09}{Put \cs{@beginlabelpagehook} in the envelope
% printing}
%    \begin{macrocode}
  \if@envelope%
    \leavevmode%
    \hspace*{\EnvelopeLeftMargin}%
    \@PrintEnvelope{#1}{#2}%
    \clearpage%
    \@beginlabelpagehook%
%    \end{macrocode}
% \subsection{Printing of one label}
% \changes{v1.1}{1996/07/09}{Put \cs{@beginlabelpagehook} in the label 
% printing}
% \changes{v1.2}{1997/07/14}{Added printing of big labels}
%    \begin{macrocode}
  \else%
    \ignorespaces%
    \ifnum\theLabelCountCol>\theLabelMaxCol%
      \\\nopagebreak%
      \stepcounter{LabelCountRow}%
      \setcounter{LabelCountCol}{1}%
    \fi%
    \ifnum\theLabelCountRow>\theLabelMaxRow%
      \vfill\eject\@beginlabelpagehook%
      \setcounter{LabelCountRow}{1}%
      \setcounter{LabelCountCol}{1}%
    \fi%
    \if@biglabel%
        \PrintBigLabel{#1}{#2}%
    \else%
        \PrintLabel{#2}%
    \fi%
    \ignorespaces\nolinebreak%
    \stepcounter{LabelCountCol}%
  \fi}%
%    \end{macrocode}
% \end{macro} 
%
% \subsection{Printing of return labels}
%
% We print only mailing addresses on labels. The user is supposed to have
% preprinted return labels. Here we describe a utility for printing them.
% This utility should be used in a separate document.
%
% \DescribeMacro{\@numreturnlabels}
% The counter "\@numreturnlabels" stores the number of return labels to
% be printed. Note that it is a \TeX\ counter, not a \LaTeX\ one.
%    \begin{macrocode}
\newcount\@numreturnlabels
%    \end{macrocode}
%
% \DescribeMacro{\printreturnlabels}
% This macro has two parameters: the number of labels to be printed and 
% the text that is printed. It is the same on all labels.
%    \begin{macrocode}
\newcommand{\printreturnlabels}[2]{%
  \@numreturnlabels=#1
  \def\@toaddressfont{\@fromaddressfont}
  \@capitalizeaddressfalse
  \@barcodesfalse
  \startlabels
  \loop \mlabel{\relax}{#2} \advance\@numreturnlabels by -1 
    \ifnum\@numreturnlabels>0\repeat}
%    \end{macrocode}
%
% \section{Barcodes}
%
% \subsection{Main command}
%
% The USPS Postnet codes are printed accordingly to the specifications
% Ref.~\cite{Pub25}. The scanning algorithm
% is stolen from David Carlisle's \textsf{enumerate} package~\cite{Enum}. 
%
% \DescribeMacro{\PrintBarCode}
% First, we extract barcodes by the command "\@extractbarcode". Then
% we print them by "\@printbarcode".
%    \begin{macrocode}
\newcommand{\PrintBarCode}[1]{%
  \@extractbarcode{#1}
  \@printbarcode}
%    \end{macrocode} 
%
% \subsection{Extraction of barcodes}\label{sec:Extract}
% \changes{v1.2}{1996/07/10}{Deleted \cs{global} from zipcode 
%   extracting commands}
% We define zipcode as a sequence of digits (0--9) that:
% \begin{itemize}
% \item Has no characters other than digits and dashes (-) inside it
% \item Has no bracketed groups inside it and is not bracketed itself
% \item Is the last in the address field unless "\if@alwaysbarcodes=true"
% \end{itemize}
%
% We print this sequence plus the \emph{control character}. 
% The latter is defined as minus sum of digits of the 
% zip code
% modulo 10 (that is, the complement of the sum of digits to a 
% multiple of 10).
%
% First, some internal registers.
% \DescribeMacro{\@zipcode}
% \DescribeMacro{\@zipcodesum}
% \DescribeMacro{\@zipcodefound}
% The token list "\@zipcode" contains barcode found so far. The register 
% "\@zipcodesum" first contains the sum of digits of the barcode, and
% then the control character. The
% switch "\@zipcodefound" shows whether we found zip code so far.
%    \begin{macrocode}
\newtoks\@zipcode
\newcount\@zipcodesum
\newif\if@zipcodefound
%    \end{macrocode}
%
%
% 
% There are two modes for gobbling tokens:
% \begin{enumerate}[{State} A:]
% \item We are outside a potential zipcode sequence
% ("\if@zipcodefound=false")\label{state:notfound}
% \item We are inside a potential zipcode sequence
% ("\if@zipcodefound=true")\label{state:found}
% \end{enumerate}
%
% \begin{itemize}
%
% \item \DescribeMacro{\@endaddress} \DescribeMacro{\@finishzipcode}
% If we meet in any state the special token "\@endaddress", we 
% gobble it and finish the loop.
%    \begin{macrocode}
\long\def\@finishzipcode#1{}
%    \end{macrocode}
%
% \item  \DescribeMacro{\@firstzipcode} If we meet a number (0--9) in
% state~\ref{state:notfound}, we initialize registers, process the
% token and go to state~\ref{state:found} 
%    \begin{macrocode}
\long\def\@firstzipcode#1{%
  \@zipcode{#1}
  \@zipcodesum=#1\relax
  \@zipcodefoundtrue
  \@zipcodeloop}
%    \end{macrocode}
%
% \item \DescribeMacro{\@continuezipcode} If we meet a number (0--9)
% in state~\ref{state:found}, we just process it.
%    \begin{macrocode}
\long\def\@continuezipcode#1{%
  \@zipcode=\expandafter{\the\@zipcode#1}
  \advance\@zipcodesum by #1
  \@zipcodeloop}
%    \end{macrocode}
%    
% \item  \DescribeMacro{\@dashzipcode} If we meet a dash in
% state~\ref{state:found}, we gobble it.
%    \begin{macrocode} 
\long\def\@dashzipcode#1{\@zipcodeloop}
%    \end{macrocode}
% 
% \item \DescribeMacro{\@spacezipcode} If we meet a space in any
% state, we gobble it and go to the state~\ref{state:notfound}. The
% trick is from Carlisle's \textsf{enumerate} package.
%    \begin{macrocode} 
\def\@spacezipcode{%
  \@zipcodefoundfalse
  \afterassignment\@zipcodeloop\let\EL@temp= }
%    \end{macrocode}
%
% \item \DescribeMacro{\@abortzipcode} If we meet anything else in any
% mode, we gobble it and go to state~\ref{state:notfound} 
%    \begin{macrocode}
\long\def\@abortzipcode#1{%
  \@zipcodefoundfalse
  \@zipcodeloop}
%    \end{macrocode}
%
% \end{itemize}
%
%
% \DescribeMacro{\@zipcodeloop}
% \DescribeMacro{\EL@temp}
% \changes{v1.2}{1997/07/14}{Changed \cs{@temp} to \cs{EL@temp} to
% avoid clashes with amsmath}
% This macro is simple. We just put the next token into "\EL@temp" and
% process it through "\@zipcodeloop@".
%    \begin{macrocode}
\def\@zipcodeloop{\futurelet\EL@temp\@zipcodeloop@}
%    \end{macrocode}
%
% \DescribeMacro{\@zipcodeloop@}
% \DescribeMacro{\EL@tempa}
% \changes{v1.2}{1997/07/14}{Changed \cs{@tempa} to \cs{EL@tempa} to
% avoid clashes with amsmath}
% This macro performs actual processing\dots We put the command
% that gobbles the next token into "\EL@tempa"
%    \begin{macrocode}
\def\@zipcodeloop@{%
  \ifx \@endaddress\EL@temp      \def\EL@tempa{\@finishzipcode}    \else
  \ifx 0\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 1\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 2\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 3\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 4\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 5\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 6\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 7\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 8\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx 9\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
               \else           \def\EL@tempa{\@firstzipcode} \fi \else
  \ifx -\EL@temp \if@zipcodefound \def\EL@tempa{\@dashzipcode}
               \else           \def\EL@tempa{\@abortzipcode} \fi \else
  \ifx \@sptoken\EL@temp         \def\EL@tempa{\@spacezipcode}     \else
                               \def\EL@tempa{\@abortzipcode}
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
  \EL@tempa}
%    \end{macrocode}
%
%
% \DescribeMacro{\@extractbarcode}
% The command "\@extractbarcode" puts barcode into the "\@zipcode", 
% and calculates the control character (10 minus sum of the digits
% of the barcode).
%    \begin{macrocode}
\long\def\@extractbarcode#1{%
  \@zipcodefoundfalse
  \@zipcodeloop#1\@endaddress
  \if@alwaysbarcodes \@zipcodefoundtrue \fi
  \if@zipcodefound
    \ifnum\the\@zipcodesum>0
      \loop \advance \@zipcodesum by -10 \ifnum\the\@zipcodesum>0
      \repeat
    \fi
    \multiply\@zipcodesum by -1
  \fi}
%    \end{macrocode}
%
% \subsection{Printing barcodes}
%
% \DescribeMacro{\@barcodewidth}
% \DescribeMacro{\@barcodeLheight}
% \DescribeMacro{\@barcodeSheight}
% \DescribeMacro{\@barcodeskip}
% First, some lengths. ``L'' and ``S'' below refer to ``long'' and
% ``short'' bars correspondingly.
%    \begin{macrocode}
\newlength{\@barcodewidth}
\newlength{\@barcodeLheight}
\newlength{\@barcodeSheight}
\newlength{\@barcodeskip}
\setlength{\@barcodewidth}{0.020in}
\setlength{\@barcodeLheight}{0.125in}
\setlength{\@barcodeSheight}{0.050in}
\setlength{\@barcodeskip}{0.026in}
%    \end{macrocode}
%
% \DescribeMacro{\@barL}
% \DescribeMacro{\@barS}
% The following macros print long and short bars.
%    \begin{macrocode}
\DeclareRobustCommand{\@barL}{%
  \rule{\@barcodewidth}{\@barcodeLheight}\hspace{\@barcodeskip}}
\DeclareRobustCommand{\@barS}{%
  \rule{\@barcodewidth}{\@barcodeSheight}\hspace{\@barcodeskip}}
%    \end{macrocode}
%
% \DescribeMacro{\@printonezip}
% \DescribeMacro{\@printbarcode}
% The scanning of "\@zipcode" is simpler than the scanning of the address:
% the only tokens we can meet are digits. Well, we will add an end marking
% token to the list. Let it be the letter ``S'' (from ``Stop'').
%    \begin{macrocode}
\def\@printonezip#1{%
  \ifx1#1\@barS\@barS\@barS\@barL\@barL\else
  \ifx2#1\@barS\@barS\@barL\@barS\@barL\else
  \ifx3#1\@barS\@barS\@barL\@barL\@barS\else
  \ifx4#1\@barS\@barL\@barS\@barS\@barL\else
  \ifx5#1\@barS\@barL\@barS\@barL\@barS\else
  \ifx6#1\@barS\@barL\@barL\@barS\@barS\else
  \ifx7#1\@barL\@barS\@barS\@barS\@barL\else
  \ifx8#1\@barL\@barS\@barS\@barL\@barS\else
  \ifx9#1\@barL\@barS\@barL\@barS\@barS\else
  \ifx0#1\@barL\@barL\@barS\@barS\@barS\else
  \ifx S#1\def\EL@tempa{\relax}%
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
  \EL@tempa}
\def\@printbarcode{%
  \if@zipcodefound
   \mbox{%
    \@barL%
    \def\EL@tempa{\@printonezip}%
    \expandafter\EL@tempa\the\@zipcode S%
    \def\EL@tempa{\@printonezip}%
    \expandafter\EL@tempa\the\@zipcodesum S%
    \@barL}
    \\[1ex]
  \fi}
%    \end{macrocode}
%
%
%
% \section{Capitalization}
%
%
% \changes{v1.2}{1996/07/10}{Deleted \cs{global} from capitalization commands}
%
%
%
% These macros process the address (actually, any string) according to the
% USPS recommendations. Specifically, they:
% \begin{itemize}
% \item Strip dots (.) and commas (,) from the address unless they are 
% enclosed in brackets
% \item Make all letters uppercase
% \item Add 1pt space between letters
% \item Add 1em space between words
% \end{itemize}
% An interesting question is whether we should de-accent accented
% letters. USPS says nothing about it. In the present version accents
% are \emph{not} stripped. However due to the scanning algorithm they
% should be enclosed by brackets, like this:  
% "{\u S}andor {\c C}edi". 
%
%
%
% \DescribeMacro{\@addr@cap}
% We store the capitalized address in the token list "\@addr@cap".
%    \begin{macrocode}
\newtoks\@addr@cap
%    \end{macrocode}
%
% The following macros process the tokens one by one.
%
% \DescribeMacro{\@finishaddrcap}
% If we meet the special token "\@endaddress", we gobble it and stop.
%    \begin{macrocode}
\long\def\@finishaddrcap#1{}
%    \end{macrocode}
%
% \DescribeMacro{\@dotcommaaddrcap}
% If we meet comma or dot, we gobble it and do \emph{not} stop. This macro 
% is also useful for gobbling \LaTeXe\ \textsf{letter} commands like
% "\voidb@x" and "\unhbox".
%    \begin{macrocode}
\long\def\@dotcommaaddrcap#1{%
  \@addrcaploop}
%    \end{macrocode}
%
% \DescribeMacro{\@newlineaddrcap}
% If we meet "\\", we add it to the list
%    \begin{macrocode}
\long\def\@newlineaddrcap#1{%
  \@addr@cap=\expandafter{\the\@addr@cap #1}
  \@addrcaploop}
%    \end{macrocode}
%
% \DescribeMacro{\@bgroupaddrcap}
% If we meet "\bgroup", we add it to the list the complete group (uppercase)
%    \begin{macrocode}
\long\def\@bgroupaddrcap#1{%
  \@addr@cap=\expandafter{\the\@addr@cap {\MakeUppercase{#1}}}
  \@addrcaploop}
%    \end{macrocode}
%
% \DescribeMacro{\@spaceaddrcap} 
% If we meet a space we gobble it (oh-oh) and add it to the list. 
%    \begin{macrocode} 
\def\@spaceaddrcap{%
  \@addr@cap=\expandafter{\the\@addr@cap\hspace{0.6em}}
  \afterassignment\@addrcaploop\let\EL@temp= }
%    \end{macrocode}
%
% \DescribeMacro{\@otheraddrcap}
% And if we meet anything else, we make it uppercase and add to the
% list
%    \begin{macrocode} 
\def\@otheraddrcap#1{%
  \@addr@cap=\expandafter{\the\@addr@cap%
     \MakeUppercase{#1}\kern1pt\relax}
  \@addrcaploop}
%    \end{macrocode}
%
%
% \DescribeMacro{\@addrcaploop}
% This macro is simple. We just put the next token into "\EL@temp" and
% process it through "\@addrcaploop@".
%    \begin{macrocode}
\def\@addrcaploop{\futurelet\EL@temp\@addrcaploop@}
%    \end{macrocode}
%
% \DescribeMacro{\@addrcaploop@}
% This macro performs actual processing\dots
%    \begin{macrocode}
\def\@addrcaploop@{%
  \ifx \@endaddress\EL@temp      \def\EL@tempa{\@finishaddrcap}    \else
  \ifx .\EL@temp                 \def\EL@tempa{\@dotcommaaddrcap}  \else
  \ifx ,\EL@temp                 \def\EL@tempa{\@dotcommaaddrcap}  \else
  \ifx \voidb@x\EL@temp          \def\EL@tempa{\@dotcommaaddrcap}  \else
  \ifx \unhbox\EL@temp            \def\EL@tempa{\@dotcommaaddrcap} \else
  \ifx \\\EL@temp                \def\EL@tempa{\@newlineaddrcap}   \else
  \ifx \bgroup\EL@temp           \def\EL@tempa{\@bgroupaddrcap}    \else
  \ifx \@sptoken\EL@temp         \def\EL@tempa{\@spaceaddrcap}     \else
                               \def\EL@tempa{\@otheraddrcap}
  \fi\fi\fi\fi\fi\fi\fi\fi
  \EL@tempa}
%    \end{macrocode}
%
% \DescribeMacro{\@make@capitalize}
%    \begin{macrocode}
\long\def\@make@capitalize#1{%
  \@addr@cap={\relax}
  \@addrcaploop#1\@endaddress
  \the\@addr@cap}
%    \end{macrocode}
%
% 
% \section{Games with \texttt{.aux} file}
%
% The commands described in this section write something to the
% |.aux| file, and thus change the way \EL\ treats the labels and
% envelopes. Since the action is delayed till the |.aux| file is
% processed, these commands affect only the labels automatically 
% extracted from the |letter| environment, and do not affect the 
% labels explicitly defined by the |\mlabel| commands in the main 
% file.
%
%
% \changes{v1.2}{1996/09/07}{Added \cs{@@mlabel}}
% \DescribeMacro{\@@mlabel}
% The macro |\@@mlabel| stores the status of the |\@mlabel| as 
% determined by |\makelabels|. It is a no-op at the start. 
% If |\makelabels| redefines |\@mlabel|, we catch it through the 
% |\AtEndDocument| hook. Note that since |\makelabel| is allowed 
% only in the preamble, we are not in danger of redefining commands too
% early.
%    \begin{macrocode}
\let\@@mlabel=\@gobbletwo
\AtEndDocument{\let\@@mlabel=\@mlabel}
%    \end{macrocode}
%
%
% The next four commands redefine |\@mlabel| to suppress or resume
%  printing  mailing labels.
%
% \begin{macro}{\suppresslabels}
% \changes{v1.2}{1996/09/06}{Wrote new command}
%  This command suppress printing labels and envelopes until it is
%  resumed by |\resumelabels| or similar commands.
%    \begin{macrocode}
\def\suppresslabels{\if@filesw\immediate\write\@auxout{%
  \string\@suppresslabels}\fi}
%    \end{macrocode}
%
% \begin{macro}{\@suppresslabels}
% \changes{v1.2}{1996/09/07}{Deleted the \cs{AtBeginDocument} hook}
% This is the internal command that performs the actual
% processing. 
%    \begin{macrocode}
\def\@suppresslabels{\let\@mlabel=\@gobbletwo}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\resumelabels}
% \changes{v1.2}{1996/09/06}{Wrote new command}
% \begin{macro}{\@resumelabels}
% \changes{v1.2}{1996/09/07}{Changed \cs{mlabel} to \cs{@@mlabel} and 
%   deleted the \cs{AtBeginDocument} hook}
%  These commands resume printing labels and envelopes if it was
%  suppressed by |\suppresslabels| or similar commands.
%    \begin{macrocode}
\def\resumelabels{\if@filesw\immediate\write\@auxout{%
  \string\@resumelabels}\fi}
\def\@resumelabels{\let\@mlabel=\@@mlabel}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\suppressonelabel}
% \changes{v1.2}{1996/06/09}{Wrote new command}
% \begin{macro}{\@suppressonelabel}
% \changes{v1.2}{1996/09/07}{Deleted the \cs{AtBeginDocument} hook}
% \begin{macro}{\@old@mlabel}
%  These commands suppress printing of one label or envelope.
%  The macro |\@old@mlabel| is used to store the
% system state.
%    \begin{macrocode}
\def\suppressonelabel{\if@filesw\immediate\write\@auxout{%
  \string\@suppressonelabel}\fi}
\def\@suppressonelabel{\let\@old@mlabel=\@mlabel%
  \def\@mlabel{%
    \let\@mlabel=\@old@mlabel%
    \@gobbletwo}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\printonelabel}
% \changes{v1.2}{1996/06/09}{Wrote new command}
% \begin{macro}{\@printonelabel}
% \changes{v1.2}{1996/09/07}{Changed \cs{mlabel} to \cs{@@mlabel} and 
%   deleted the \cs{AtBeginDocument} hook}
%  These commands resume printing for one label or envelope 
% The macro |\@old@mlabel| is used to store the
% system state.
%    \begin{macrocode}
\def\printonelabel{\if@filesw\immediate\write\@auxout{%
  \string\@printonelabel}\fi}
\def\@printonelabel{\let\@old@mlabel=\@mlabel%
  \def\@mlabel{%
    \let\@mlabel=\@old@mlabel%
    \@@mlabel}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\ChangeEnvelope}
% \changes{v1.2}{1996/09/07}{Wrote new command}
% \begin{macro}{\@ChangeEnvelope}
% \begin{macro}{\@ChangeEnvelopeStar}
% This macro writes |\@SetEnvelope| to the |.aux| file. It has 
% two forms: starred and and unstarred. In the unstarred mode it also
% writes |\@startlabels| to the |.aux| file. In the unstarred form it
% does not.
% Since we want to treat \emph{both} stars and optional arguments, we
% introduce two internal commands that can be invoked by the main
% macro. 
%    \begin{macrocode}
\def\ChangeEnvelope{\@ifstar{\@ChangeEnvelopeStar}{\@ChangeEnvelope}}
\newcommand\@ChangeEnvelopeStar[3][0pt]{%
  \if@filesw\immediate\write\@auxout{%
       \string\@SetEnvelope[#1]{#2}{#3}}%
   \fi}
\newcommand\@ChangeEnvelope[3][0pt]{%
  \if@filesw\immediate\write\@auxout{%
       \string\@SetEnvelope[#1]{#2}{#3}}
     \immediate\write\@auxout{\string\@startlabels}
  \fi}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@SetEnvelope}
% We define this command as no-op at beginning, and then redefine it 
% before reading |.aux| file.
%    \begin{macrocode}
\def\@SetEnvelope[#1]#2#3{}
\AtEndDocument{\let\@SetEnvelope=\SetEnvelope}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\ChangeLabel}
% \changes{v1.2}{1997/07/11}{Wrote new command}
% \begin{macro}{\@ChangeLabel}
% \begin{macro}{\@ChangeLabelStar}
% This macro writes |\@SetLabel| to the |.aux| file. It has 
% two forms: starred and and unstarred. In the unstarred mode it also
% writes |\@startlabels| to the |.aux| file. In the unstarred form it
% does not.
% Since we want to treat \emph{both} stars and optional arguments, we
% introduce two internal commands that can be invoked by the main
% macro. 
%    \begin{macrocode}
\def\ChangeLabel{\@ifstar{\@ChangeLabelStar}{\@ChangeLabel}}
\newcommand\@ChangeLabelStar[7]{%
  \if@filesw\immediate\write\@auxout{%
       \string\@SetLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
   \fi}
\newcommand\@ChangeLabel[7]{%
  \if@filesw\immediate\write\@auxout{%
       \string\@SetLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}
     \immediate\write\@auxout{\string\@startlabels}
  \fi}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@SetLabel}
% We define this command as no-op at beginning, and then redefine it 
% before reading |.aux| file.
%    \begin{macrocode}
\def\@SetLabel#1#2#3#4#5#6#7{}
\AtEndDocument{\let\@SetLabel=\SetLabel}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\ChangeBigLabel}
% \changes{v1.2}{1997/07/13}{Wrote new command}
% \begin{macro}{\@ChangeBigLabel}
% \begin{macro}{\@ChangeBigLabelStar}
% This macro writes |\@SetBigLabel| to the |.aux| file. It has 
% two forms: starred and and unstarred. In the unstarred mode it also
% writes |\@startlabels| to the |.aux| file. In the unstarred form it
% does not.
% Since we want to treat \emph{both} stars and optional arguments, we
% introduce two internal commands that can be invoked by the main
% macro. 
%    \begin{macrocode}
\def\ChangeBigLabel{\@ifstar{\@ChangeBigLabelStar}{\@ChangeBigLabel}}
\newcommand\@ChangeBigLabelStar[7]{%
  \if@filesw\immediate\write\@auxout{%
       \string\@SetBigLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
   \fi}
\newcommand\@ChangeBigLabel[7]{%
  \if@filesw\immediate\write\@auxout{%
       \string\@SetBigLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}
     \immediate\write\@auxout{\string\@startlabels}
  \fi}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@SetLabel}
% We define this command as no-op at beginning, and then redefine it 
% before reading |.aux| file.
%    \begin{macrocode}
\def\@SetBigLabel#1#2#3#4#5#6#7{}
\AtEndDocument{\let\@SetBigLabel=\SetBigLabel}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \section{Reimplementation of the \cs{opening} command}
% \DescribeMacro{\re}
% Some people like to put below the address information like 
% \begin{quote}
% Re: our recent talk
% \end{quote}
% A way to do this is to include it in the address like this:
% \begin{verbatim}
% \begin{letter}{%
%   Dr.~Austin Tankel\\
%   Some University\\
%   Anytown, Pa 12345\\[1ex]
%   Re: Our recent talk}
% \opening{Dear Austin:}
% \end{verbatim}
% However, this additional info will be put in the mailing label,
% which is wrong.  Here we describe a macro that works like this:
% \begin{verbatim}
% \begin{letter}{%
%   Dr.~Austin Tankel\\
%   Some University\\
%   Anytown, Pa 12345}
% \re{Our recent talk}
% \opening{Dear Austin:}
% \end{verbatim}
%
% 
% Now, the implementation.
% First, lets us check whether the option "re" is chosen (otherwise we
% don't bother to redefine the commands):
%    \begin{macrocode}
\if@EL@redefine@opening
%    \end{macrocode}
%
% \begin{macro}{\re}
% \changes{v1.2}{1997/07/14}{Wrote new command}
% \begin{macro}{\recontentents}
% \changes{v1.2}{1997/07/14}{Wrote new command}
% The command "\re" just defines "\recontents". Also, we initialize
% "\recontents" to be initially empty 
%    \begin{macrocode}
  \newcommand*{\re}[1]{\def\recontents{#1}}%
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\ReName}
% \changes{v1.2}{1997/07/14}{Wrote new command}
% By default it is just plain style ``Re: '' (note the space!)
%    \begin{macrocode}
  \def\ReName{Re: }%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\opening}
% \changes{v1.2}{1997/07/14}{Reimplemented standard command
%    \cs{opening}}
% Now we redefine the standard "\opening" command to include the "\re"
% info. Here is the quote from the standard "letter"
% class~\cite{letter}: 
% \begin{quotation}
%     Text is begun with the |\opening| command, whose argument
%     generates the salutation, as in
%\begin{verbatim}
%      \opening{Dear Henry,}
%\end{verbatim}
%    This should produce everything up to and including the
%    `Dear Henry,' and a |\par| command that follows.
%    Since there's a |\vfil| at the bottom of every page,
%    it can add vertical fill to position a short letter.
%    It should use the following commands:
%   \begin{itemize}
%   \item |\toname| : name part of `to' address.
%                     Will be one line long.
%   \item |\toaddress| : address part of `to' address.
%                        The lines separated by |\\|.
%   \item |\fromname| : name of sender.
%   \item |\fromaddress| : argument of current |\address|
%     declaration-- null if none.  Should use standard institutional
%     address if null.
%   \item |\fromlocation| : argument of current |\location|
%     declaration--null if none.
%   \item |\telephonenum| : argument of current |\telephone|
%     declaration--null if none.
%    \end{itemize}
% \end{quotation}
% We just "\ReName" and "\recontents" here\ldots
%    \begin{macrocode}
  \renewcommand*{\opening}[1]{\ifx\@empty\fromaddress
    \thispagestyle{firstpage}%
      {\raggedleft\@date\par}%
    \else  % home address
      \thispagestyle{empty}%
      {\raggedleft\begin{tabular}{l}\ignorespaces
          \fromaddress \\*[2\parskip]%
          \@date \end{tabular}\par}%
    \fi
    \vspace{2\parskip}%
    {\raggedright \toname \\ \toaddress \par}%
    \ifx\@empty\recontents\relax
    \else
       {\raggedright \ReName \recontents \par}%
    \fi
    \vspace{2\parskip}%
    #1\par\nobreak}%
%    \end{macrocode}
% \end{macro}
%
% Now we close \cs{if@EL@redefine@opening}:
%    \begin{macrocode}
\fi
%    \end{macrocode}
%
% And the last line:
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale
%
% \clearpage
% \addcontentsline{toc}{section}{\protect\refname}
% \begin{thebibliography}{1}
% \bibitem{Enum}
% David Carlisle.
% \newblock {\em The \textsf{enumerate} package}.
% \newblock {CTAN}, v2.02 edition, January 1994.
% \bibitem{letter}
% Leslie Lamport, Frank Mittelbach, and Rainer Sch{\"o}pf.
% \newblock Standard letter document class for {\LaTeX} version 2e.
% \newblock CTAN, 199c.
% \bibitem{Pub25}
% USPS.
% \newblock {\em Designing Business Letter Mail (Pub 25)}, August 1995.
% \end{thebibliography}
%
% \clearpage
% \addcontentsline{toc}{section}{Change History}
% \PrintChanges
%
% \clearpage
%  \addcontentsline{toc}{section}{Index}
%  \PrintIndex
%
\endinput