% \iffalse %<*driver> \ProvidesFile{envlab.drv} % %<*driver|package|cfg> %<+package>\ProvidesPackage{envlab} %<+cfg>\ProvidesFile{envlab.cfg} [1997/07/16 v1.2 Envelopes and Labels] % %<*driver|package> %% %% Copyright Boris Veytsman 1996, 1997 %% % %<*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 % % % \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} % % \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} % %<*cfg> %% %% The default options go here %% \ExecuteOptions{businessenvelope,rotateenvelopes,centerenvelopes} \ExecuteOptions{printbarcodes,capaddress} \ExecuteOptions{nopswait,printreturnaddress,nopsautotray,nore} %% \AtEndOfPackage{\relax % Customization goes here } % %<*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} "". % \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} % "". % \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} % % \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