3 \ProvidesFile{envlab.drv}
6 %<+package>\ProvidesPackage{envlab}
7 %<+cfg>\ProvidesFile{envlab.cfg}
8 [1997/07/16 v1.2 Envelopes and Labels]
12 %% Copyright Boris Veytsman 1996, 1997
15 %<*driver|package|cfg>
20 %% {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
21 %% 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
22 %% Digits \0\1\2\3\4\5\6\7\8\9
23 %% Exclamation \! Double quote \" Hash (number) \#
24 %% Dollar \$ Percent \% Ampersand \&
25 %% Acute accent \' Left paren \( Right paren \)
26 %% Asterisk \* Plus \+ Comma \,
27 %% Minus \- Point \. Solidus \/
28 %% Colon \: Semicolon \; Less than \<
29 %% Equals \= Greater than \> Question mark \?
30 %% Commercial at \@ Left bracket \[ Backslash \\
31 %% Right bracket \] Circumflex \^ Underscore \_
32 %% Grave accent \` Left brace \{ Vertical bar \|
33 %% Right brace \} Tilde \~}
35 %</driver|package|cfg>
37 % \section{Documentation driver}
39 % Nothing interesting here\dots
41 \documentclass{ltxdoc}
42 \DoNotIndex{\@Alph,\@alph,\@arabic,\@badmath}
43 \DoNotIndex{\@centercr}
44 \DoNotIndex{\@empty,\@ignoretrue}
46 \DoNotIndex{\@M,\@minus,\@ne,\@plus}
47 \DoNotIndex{\\,\addtolength}
49 \DoNotIndex{\ast,\begin,\begingroup,\bfseries,\bgroup,\box}
51 \DoNotIndex{\cdot,\cr,\day,\DeclareOption}
52 \DoNotIndex{\def,\DocInput,\documentclass}
53 \DoNotIndex{\DoNotIndex,\egroup,\ifx,\else,\fi,\endtrivlist}
54 \DoNotIndex{\EnableCrossrefs,\end,\end@dblfloat,\end@float,\endgroup}
55 \DoNotIndex{\endlist,\everycr,\ExecuteOptions}
56 \DoNotIndex{\filedate,\filename,\fileversion}
57 \DoNotIndex{\global,\halign,\hangindent,\hbox,\hfil,\hfill,\hrule}
58 \DoNotIndex{\hsize,\hskip,\hspace,\hss,\ifcase,\or,\fi}
59 \DoNotIndex{\ifvmode,\fi,\ifnum,\fi,\input}
60 \DoNotIndex{\kern,\leavevmode,\let,\leftmark}
61 \DoNotIndex{\list,\llap,\long,\m@ne,\m@th,\mark}
62 \DoNotIndex{\month,\newcommand,\newcounter,\newenvironment}
63 \DoNotIndex{\NeedsTeXFormat,\newdimen}
64 \DoNotIndex{\newpage,\nobreak,\noindent,\number}
66 \DoNotIndex{\pagestyle,\par}
67 \DoNotIndex{\penalty,\PrintChanges,\PrintIndex,\ProcessOptions}
68 \DoNotIndex{\protect,\ProvidesClass,\raggedbottom,\raggedright}
69 \DoNotIndex{\refstepcounter,\relax,\renewcommand,\reset@font}
70 \DoNotIndex{\rightmargin,\rlap,\rmfamily}
71 \DoNotIndex{\setbox,\setcounter,\setlength}
72 \DoNotIndex{\skip,\slshape,\space}
73 \DoNotIndex{\trivlist,\typeout,\tw@}
74 \DoNotIndex{\vskip,\vspace,\year,\z@}
76 \DoNotIndex{\@ptsize,\@sptoken,\addtocounter,\afterassignment}
77 \DoNotIndex{\AtEndOfPackage,\baselineskip,\boxmaxdepth,\clearpage}
78 \DoNotIndex{\clubpenalty,\csname,\CurrentOption,\DeclareRobustCommand}
79 \DoNotIndex{\eject,\endcsname,\evensidemargin,\expandafter}
80 \DoNotIndex{\footnotesize,\footskip,\fromaddress,\futurelet}
81 \DoNotIndex{\headheight,\headsep,\hfuzz,\ignorespaces}
82 \DoNotIndex{\InputIfFileExists,\large,\lineskip,\loop}
83 \DoNotIndex{\MakeUppercase,\MessageBreak,\mbox,\multiply}
84 \DoNotIndex{\newcount,\newif,\newlength,\newtoks,\nolinebreak}
85 \DoNotIndex{\nopagebreak,\normalfont,\normalsize,\null,\newline}
86 \DoNotIndex{\oddsidemargin,\PackageError,\PackageInfo}
87 \DoNotIndex{\paperheight,\paperwidth,\parbox,\parindent}
88 \DoNotIndex{\PassOptionsToPackage,\ProvidesPackage,\RequirePackage}
89 \DoNotIndex{\rule,\selectfont,\sffamily,\sloppy,\small,\spaceskip}
90 \DoNotIndex{\stepcounter,\textheight,\textwidth,\the,\topmargin}
91 \DoNotIndex{\unhbox,\voidb@x,\vsize,\vfuzz,\widowpenalty,\xspaceskip}
92 \DoNotIndex{\AtBeginDocument,\AtEndDocument}
93 \usepackage{enumerate}
104 % \changes{v0.9}{1996/05/31}{Beta version}
105 % \changes{v0.91}{1996/05/31}{Added new option---"alwaysbarcodes"}
106 % \changes{v1.0}{1996/06/09}{First released version}
107 % \changes{v1.1}{1996/07/08}{Fixed typos in "elold.ins"}
108 % \changes{v1.1}{1996/07/08}{Updated User Guide}
109 % \changes{v1.2}{1996/07/10}{Changed envlab.ins: made it parallel.}
110 %% \changes{v1.2}{1996/07/16}{Updated User Guide}
112 % \newcommand{\EL}{\textsl{EnvLab}}
115 % \GetFileInfo{envlab.drv}
117 % \title{Printing Envelopes and Labels in \LaTeXe: \EL\ Package
119 % has version number \fileversion, last
120 % revised \filedate.}
121 % \thanks{\copyright Boris Veytsman, 1996, 1997}
123 % \author{Boris Veytsman}
130 % \section{Introduction}
132 % The standard "\makelabels" command in the \LaTeXe\ "letter.cls"
133 % documentclass typesets labels on Avery 5352 sheets. A typical user
134 % may want more. \EL\ redefines "\makelabels" in\footnote{hopefully}
135 % a more useful and customizable way
137 % The detailed usage of the package is described in the file
138 % "elguide.tex". Here we just comment the macros.
142 % \section{Identification}
144 % First, we must say ``Hello world.''
147 \NeedsTeXFormat{LaTeX2e}
150 % \begin{macro}{\envlab@ok}
151 % \begin{macro}{\envlab@oops}
152 % \changes{v1.2}{1997/07/10}{Used \cs{@ifundefined} instead of direct check}
153 % Now let us check whether we in the letter documentclass. Actually we
154 % will accept any class that has "\makelabels" defined (custom letter
158 \PackageError{envlab}%
159 {Envlab is used outside of \MessageBreak%
160 a letter-compatible documentclass}%
161 {You are trying to use Envelopes & Labels\MessageBreak%
162 package, but your documentclass does not\MessageBreak%
163 understand address formatting commands.\MessageBreak%
164 Try standard document class letter\MessageBreak}}
166 \PackageInfo{envlab}%
167 {Envelopes & Labels package: found makelabels...\MessageBreak%
168 Seems everything is OK. Good luck.}}
169 \@ifundefined{makelabels}{\envlab@oops}{\envlab@ok}
173 % \section{Preliminary code}
175 % \subsection{Switches, etc.}
178 % \DescribeMacro{\if@envelope}
179 % \DescribeMacro{\if@biglabel}
180 % \changes{v1.2}{1997/07/13}{Added Big Labels---thanks to Genick
181 % Bar-Meir, "meyerson@msi.umn.edu"}
182 % There are three kinds of things we can print: envelopes (default)
183 % labels and big labels The differences are summarized in
184 % Table~\ref{tab:diffs}.
187 % \begin{tabular}{cccc}
189 % Media & Number per page & Rotation & Return address \\
191 % Envelopes & One & Settable & Yes\\
192 % Labels & Several & Not rotated & No\\
193 % Big Labels & Several & Not rotated & Yes\\
197 % \caption{Differences between envelopes, labels and big labels}
208 % \DescribeMacro{\if@rotateenvelopes}
209 % \DescribeMacro{\if@printreturnaddress}
210 % Now we must determine whether we want to rotate envelopes and
211 % whether to include return address (both yes by default).
213 \newif\if@rotateenvelopes
214 \@rotateenvelopestrue
215 \newif\if@printreturnaddress
216 \@printreturnaddresstrue
219 % \DescribeMacro{\@envelopeposition}
220 % Now let us decide how to print envelopes. They can be either centered
221 % (default) \emph{or} shifted to the left or to the right of the paper
223 % counter "\@envelopeposition" can be, correspondingly, either 0 or 1
225 % 3 corresponds to the ``custom placing'', when the user sets
226 % "\EnvelopeLeftMargin" manually.
229 \newcount\@envelopeposition
230 \@envelopeposition=0\relax
233 % \begin{macro}{\if@pswait}
234 % \changes{v1.1}{1996/07/08}{Added \cs{if@pswait}}
235 % \begin{macro}{\if@psautotray}
236 % \changes{v1.1}{1997/07/13}{Added \cs{if@psautotray}}
237 % \begin{macro}{\PSEnvelopeTray}
238 % \changes{v1.1}{1997/07/13}{Added \cs{PSEnvelopeTray}}
239 % The switches "\if@pswait" and "\if@psautotray" control optional manual
240 % feeding of envelopes and labels in \textsl{Postscript} printers
241 % (see Section~\ref{sec:Print} for details). The register
242 % "\PSEnvelopeTray" contains the name of the required tray.
248 \newtoks\PSEnvelopeTray
249 \PSEnvelopeTray={/otherenvelopetray }
256 % \begin{macro}{\if@barcodes}
257 % \begin{macro}{\if@alwaysbarcodes}
258 % We can either print bar codes (default) or not. The second switch
259 % forces to print barcodes even if they are not last in the address
260 % (like "Pa 16801\\USA")
263 \newif\if@alwaysbarcodes
265 \@alwaysbarcodesfalse
270 % \begin{macro}{\if@EL@redefine@opening}
271 % \changes{v1.2}{1997/07/14}{Wrote new command}
272 % Now let us decide whether to mess with the "\opening" command.
274 \newif\if@EL@redefine@opening
275 \@EL@redefine@openingfalse
280 % \begin{macro}{\if@capitalizeaddress}
281 % Also, we can either capitalize the address (default) or not.
283 \newif\if@capitalizeaddress
284 \@capitalizeaddresstrue
288 % \subsection{Lengths and numbers}
290 % We want all lengths to be user settable, so no "@" in the names.
293 % \DescribeMacro{\EnvelopeWidth}
294 % \DescribeMacro{\EnvelopeHeight}
295 % \DescribeMacro{\EnvelopeTopMargin}
296 % \DescribeMacro{\EnvelopeLeftMargin}
297 % An envelope has four basic lengths.
298 % The first two are self-evident. The third is the distance between the
299 % edge of the paper and the leading edge of the envelope. All
300 % pre-defined envelope sizes set this to zero. The fourth is the distance
301 % between the left edge of the paper and the envelope. Its value depends
302 % on the value of the "\@envelopeposition" variable. We will preset it to
305 \newlength{\EnvelopeWidth}
306 \newlength{\EnvelopeHeight}
307 \newlength{\EnvelopeTopMargin}
308 \newlength{\EnvelopeLeftMargin}
309 \setlength{\EnvelopeLeftMargin}{0pt}
313 % \DescribeMacro{\LabelWidth}
314 % \DescribeMacro{\LabelHeight}
315 % \DescribeMacro{\LabelTopMargin}
316 % \DescribeMacro{\LabelLeftMargin}
317 % \DescribeMacro{\LabelRightMargin}
318 % A label has more parameters.
319 % The first two are the same as for the envelopes. The next two define the
320 % distances from the paper edges to the beginning of the labels. The
321 % last one describes the distance between the labels.
323 \newlength{\LabelWidth}
324 \newlength{\LabelHeight}
325 \newlength{\LabelTopMargin}
326 \newlength{\LabelLeftMargin}
327 \newlength{\LabelRightMargin}
330 % \DescribeMacro{\c@LabelMaxCol}
331 % \DescribeMacro{\c@LabelMaxRow}
332 % The following numbers define, how many labels are in each row and how
333 % many rows are on each page
335 \newcounter{LabelMaxCol}
336 \newcounter{LabelMaxRow}
339 % The lengths above are \emph{external} parameters that determine an
340 % envelope or a label. Now we will describe \emph{internal} lengths. We
341 % define them here because the commands "\SetEnvelope" and "\SetLabel"
342 % determine them basing on the given envelope or label type.
345 % \DescribeMacro{\FromAddressTopMargin}
346 % \DescribeMacro{\FromAddressLeftMargin}
347 % \DescribeMacro{\FromAddressHeight}
348 % \DescribeMacro{\FromAddressWidth}
349 % \DescribeMacro{\ToAddressTopMargin}
350 % \DescribeMacro{\ToAddressLeftMargin}
351 % \DescribeMacro{\ToAddressWidth}
352 % The following lengths are self-evident.
354 \newlength{\FromAddressTopMargin}
355 \newlength{\FromAddressLeftMargin}
356 \newlength{\FromAddressHeight}
357 \newlength{\FromAddressWidth}
358 \newlength{\ToAddressTopMargin}
359 \newlength{\ToAddressLeftMargin}
360 \newlength{\ToAddressWidth}
363 % \subsection{Main setting commands}
365 % OK, we are ready to set up envelopes and labels.
367 % \begin{macro}{\SetEnvelope}
368 % \changes{v1.2}{1997/07/14}{Added \cs{@biglabelfalse}}
369 % The command "\SetEnvelope" has three parameters: optional top Margin,
370 % width and height of the envelope.
372 \DeclareRobustCommand{\SetEnvelope}[3][0pt]{%
375 \setlength{\EnvelopeTopMargin}{#1}%
376 \setlength{\EnvelopeWidth}{#2}%
377 \setlength{\EnvelopeHeight}{#3}%
378 \setlength{\FromAddressTopMargin}{0.5in}%
379 \setlength{\FromAddressLeftMargin}{0.5in}%
380 \setlength{\FromAddressHeight}{0.33\EnvelopeHeight}%
381 \setlength{\FromAddressWidth}{0.5\EnvelopeWidth}%
382 \setlength{\ToAddressTopMargin}{0.5in}%
383 \setlength{\ToAddressLeftMargin}{0.5in}%
384 \setlength{\ToAddressWidth}{3in}}
388 % \begin{macro}{\SetLabel}
389 % \changes{v1.2}{1997/07/14}{Added \cs{@biglabelfalse}}
390 % The command "\SetLabel" has seven parameters: five lengths and two
391 % numbers. All are mandatory:
393 \DeclareRobustCommand{\SetLabel}[7]{%
396 \setlength{\LabelWidth}{#1}%
397 \setlength{\LabelHeight}{#2}%
398 \setlength{\LabelTopMargin}{#3}%
399 \setlength{\LabelLeftMargin}{#4}%
400 \setlength{\LabelRightMargin}{#5}%
401 \setcounter{LabelMaxCol}{#6}%
402 \setcounter{LabelMaxRow}{#7}%
403 \setlength{\ToAddressTopMargin}{0.1in}%
404 \setlength{\ToAddressLeftMargin}{0.2in}%
405 \setlength{\ToAddressWidth}{\LabelWidth}%
406 \addtolength{\ToAddressWidth}{-\ToAddressLeftMargin}%
407 \addtolength{\ToAddressWidth}{-\LabelRightMargin}}
411 % \begin{macro}{\SetBigLabel}
412 % \changes{v1.2}{1997/07/14}{Wrote new command}
413 % The command "\SetBigLabel" has seven parameters: five lengths and two
414 % numbers. All are mandatory:
416 \DeclareRobustCommand{\SetBigLabel}[7]{%
419 \setlength{\LabelWidth}{#1}%
420 \setlength{\LabelHeight}{#2}%
421 \setlength{\LabelTopMargin}{#3}%
422 \setlength{\LabelLeftMargin}{#4}%
423 \setlength{\LabelRightMargin}{#5}%
424 \setcounter{LabelMaxCol}{#6}%
425 \setcounter{LabelMaxRow}{#7}%
426 \setlength{\FromAddressTopMargin}{0.0in}%
427 \setlength{\FromAddressLeftMargin}{0.5in}%
428 \setlength{\FromAddressHeight}{0.33\LabelHeight}%
429 \setlength{\ToAddressTopMargin}{0.1in}%
430 \setlength{\ToAddressLeftMargin}{0.5in}%
431 \setlength{\ToAddressWidth}{\LabelWidth}%
432 \addtolength{\ToAddressWidth}{-\ToAddressLeftMargin}%
433 \addtolength{\ToAddressWidth}{-\LabelRightMargin}%
434 \setlength{\FromAddressWidth}{\ToAddressWidth}}
438 % \section{Defining options}
440 % \subsection{Envelope Sizes}
441 % \changes{v1.2}{1996/07/22}{Added new option: dlenvelope (thanks to
442 % "J.P.Jansen@net.HCC.nl")}
443 % \changes{v1.2}{1997/07/13}{Added \cs{PSEnvelopeTray} to envelope
446 \DeclareOption{businessenvelope}{\SetEnvelope{9.5in}{4.125in}%
447 \PSEnvelopeTray={/com10envelopetray }}
448 \DeclareOption{executiveenvelope}{\SetEnvelope{7.5in}{3.875in}%
449 \PSEnvelopeTray={/monarcenvelopetray }}
450 \DeclareOption{bookletenvelope}{\SetEnvelope{10.5in}{7.5in}}
451 \DeclareOption{personalenvelope}{\SetEnvelope{6.5in}{3.625in}}
452 \DeclareOption{c6envelope}{\SetEnvelope{162mm}{114mm}}
453 \DeclareOption{c65envelope}{\SetEnvelope{224mm}{114mm}}
454 \DeclareOption{c5envelope}{\SetEnvelope{229mm}{162mm}%
455 \PSEnvelopeTray={/162x229cenvelopetray }}
456 \DeclareOption{dlenvelope}{\SetEnvelope{220mm}{110mm}%
457 \PSEnvelopeTray={/dlenvelopetray }}
460 % \subsection{Labels sizes}
462 % \changes{v1.2}{1996/07/22}{Added new option: herma4625label (thanks to
463 % "J.P.Jansen@net.HCC.nl")}
464 % \changes{v1.2}{1996/09/06}{Added new option: avery5262label (thanks to
465 % Uri Blumenthal "uri@ibm.net")}
466 % \changes{v1.2}{1997/07/13}{Added new option: avery5164biglabel}
467 % \changes{v1.2}{1997/07/13}{Added new option: avery5163biglabel}
470 \DeclareOption{avery5160label}{%
471 \SetLabel{2.75in}{1in}{0.5in}{0.19in}{0.12in}{3}{10}}
472 \DeclareOption{avery5161label}{%
473 \SetLabel{4.19in}{1in}{0.5in}{0.16in}{0.19in}{2}{10}}
474 \DeclareOption{avery5162label}{%
475 \SetLabel{4.19in}{1.33in}{0.83in}{0.16in}{0.19in}{2}{7}}
476 \DeclareOption{avery5163label}{%
477 \SetLabel{4.19in}{2in}{0.5in}{0.16in}{0.19in}{2}{5}}
478 \DeclareOption{avery5164label}{%
479 \SetLabel{4.19in}{3.33in}{0.5in}{0.16in}{0.19in}{2}{3}}
480 \DeclareOption{herma4625label}{%
481 \SetLabel{105mm}{42.3mm}{0mm}{5mm}{5mm}{2}{7}}
482 \DeclareOption{avery5262label}{%
483 \SetLabel{110mm}{34mm}{21mm}{4mm}{5mm}{2}{7}}
484 \DeclareOption{avery5163biglabel}{%
485 \SetBigLabel{4.19in}{2in}{0.5in}{0.16in}{0.19in}{2}{5}%
486 \setlength{\ToAddressTopMargin}{0.1in}}%
487 \DeclareOption{avery5164biglabel}{%
488 \SetBigLabel{4.19in}{3.33in}{0.5in}{0.16in}{0.19in}{2}{3}}%
491 % \subsection{Optional switches}
493 % \changes{v1.1}{1996/07/08}{Added new options: "printreturnaddress",
494 % "noprintreturnaddress"}
495 % \changes{v1.1}{1996/07/08}{Added new options: "pswait",
497 % \changes{v1.2}{1997/07/13}{Added new options: "psautotray",
499 % \changes{v1.2}{1997/07/14}{Added new options: "re", "nore"}
500 % All this should be evident\dots
503 \DeclareOption{rotateenvelopes}{\@rotateenvelopestrue}
504 \DeclareOption{norotateenvelopes}{\@rotateenvelopesfalse}
505 \DeclareOption{centerenvelopes}{\@envelopeposition=0\relax}
506 \DeclareOption{leftenvelopes}{\@envelopeposition=1\relax}
507 \DeclareOption{rightenvelopes}{\@envelopeposition=2\relax}
508 \DeclareOption{customenvelopes}{\@envelopeposition=3\relax}
509 \DeclareOption{printbarcodes}{\@barcodestrue}
510 \DeclareOption{noprintbarcodes}{\@barcodesfalse\@alwaysbarcodesfalse}
511 \DeclareOption{alwaysbarcodes}{\@alwaysbarcodestrue\@barcodestrue}
512 \DeclareOption{noalwaysbarcodes}{\@alwaysbarcodesfalse}
513 \DeclareOption{capaddress}{\@capitalizeaddresstrue}
514 \DeclareOption{nocapaddress}{\@capitalizeaddressfalse}
515 \DeclareOption{printreturnaddress}{\@printreturnaddresstrue}
516 \DeclareOption{noprintreturnaddress}{\@printreturnaddressfalse}
517 \DeclareOption{pswait}{\@pswaittrue\@psautotrayfalse}
518 \DeclareOption{nopswait}{\@pswaitfalse}
519 \DeclareOption{psautotray}{\@psautotraytrue\@pswaitfalse}
520 \DeclareOption{nopsautotray}{\@psautotrayfalse}
521 \DeclareOption{re}{\@EL@redefine@openingtrue}
522 \DeclareOption{nore}{\@EL@redefine@openingfalse}
525 % \subsection{Unknown options}
527 % All options we did not declare above are probably the options for the
528 % "graphics" package; let us send them there.
530 \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{graphics}}
533 % \subsection{Default options}\label{sec:DefOpt}
535 % \changes{v1.1}{1996/07/08}{Fixed typo in "businessenvelope" option}
536 % \changes{v1.1}{1996/07/09}{Added default options: "nopswait",
537 % "printreturnaddress"}
540 \ExecuteOptions{businessenvelope,rotateenvelopes,centerenvelopes}
541 \ExecuteOptions{printbarcodes,capaddress}
542 \ExecuteOptions{nopswait,printreturnaddress,nopsautotray,nore}
545 % \section{Configuration file}
547 % At this point we will look for the configuration file. This file is
548 % named "envlab.cfg". The options declared in this file will supersede
549 % the ones declared in Section~\ref{sec:DefOpt}, but will be in their
550 % turn be superseded by the options explicitly defined when the package
553 \InputIfFileExists{envlab.cfg}{%
554 \typeout{Loading configuration file envlab.cfg}}{%
555 \typeout{Configuration file envlab.cfg is not found}}
558 % Now let us discuss the structure of the configuration file. We want it
559 % to contain default options, and therefore to be loaded before the
560 % "\ProcessOptions" command. On the other hand we want it to contain
561 % some definitions that \emph{supersede} the ones in this package. The
562 % hook "\AtEndOfPackage" helps to do this: we will just delay all
563 % definitions until later.
565 % OK, let's construct an example of "envlab.cfg" file. The commands here
566 % essentially repeat Section~\ref{sec:DefOpt}, but we want to be
572 %% The default options go here
574 \ExecuteOptions{businessenvelope,rotateenvelopes,centerenvelopes}
575 \ExecuteOptions{printbarcodes,capaddress}
576 \ExecuteOptions{nopswait,printreturnaddress,nopsautotray,nore}
578 \AtEndOfPackage{\relax % Customization goes here
584 % \section{Processing options and loading packages}
585 % \changes{v0.92}{1996/06/06}{Added \cs{IfFileExists} when loading packages}
588 \IfFileExists{graphics.sty}{%
589 \RequirePackage{graphics}}{%
590 \PackageWarning{envlab}{%
591 You don't have the graphics package!\MessageBreak
592 Probably you will not be able to print\MessageBreak
593 envelopes sidewise. \MessageBreak}}
596 % \section{Document layout}
598 % \subsection{Printer specific commands}
601 % \DescribeMacro{\@beginlabelshook}
602 % \changes{v1.1}{1996/07/09}{Replaced \cs{@printpreamble} with
603 % \cs{@beginlabelshook}}
604 % The command "\@beginlabelshook" is called at the beginning of the
605 % printing of envelopes and labels. We define it to be a no-op, but it
606 % is possible to introduce some printer-specific commands (like paper
609 \def\@beginlabelshook{\relax}
612 % \DescribeMacro{\@beginlabelpagehook}
613 % \changes{v1.1}{1996/07/09}{Introduced new command
614 % \cs{@beginlabelpagehook}}
615 % The command "\@beginlabelpagehook" is like "\@beginlabelshook", but is
616 % called at the beginning of each \emph{page}
617 % of envelopes and labels.
619 \def\@beginlabelpagehook{\relax}
622 % \begin{macro}{\AtBeginLabels}
623 % \changes{v1.1}{1996/07/08}{Made \cs{AtBeginLabels} cumulative}
624 % \begin{macro}{\AtBeginLabelPage}
625 % \changes{v1.1}{1996/07/09}{Introduced \cs{AtBeginLabelPage}}
626 % The hooks "\AtBeginLabels" and "\AtBeginLabelPage" redefine
627 % "\@beginlabelshook" and "\@beginlabelpagehook". They are built like
628 % the standard \LaTeXe\ hooks
629 % "\AtBeginDocument", "\AtBeginDvi", etc. In the implementation we use the
630 % \emph{internal} \LaTeXe\ command "\g@addto@macro". In the current
631 % (June~1996) \LaTeXe\ release it is defined as:
632 % \DescribeMacro{\g@addto@macro}
634 % \long\def\g@addto@macro#1#2{{%
635 % \toks@\expandafter{#1#2}%
636 % \xdef#1{\the\toks@}}}
638 % We quote this definition in case \emph{They} change Their minds\dots\
640 \def\AtBeginLabels{\g@addto@macro\@beginlabelshook}
641 \def\AtBeginLabelPage{\g@addto@macro\@beginlabelpagehook}
646 % \begin{macro}{\PSwait}
647 % \changes{v1.1}{1996/07/09}{Put William Slough's code in a separate macro}
648 % \textsl{PostScript} printers can be switched to the manual feeding mode
649 % with the following code by \emph{William Slough} "<cfwas@eiu.edu>".
651 \def\PSwait{\special{ps: clear grestore @manualfeed 0 0 bop}}
653 % The author explains his code in the following way:
655 % Here is a possible explanation:
657 % The clear removes operands from the PostScript stack, which has the
658 % effect of reversing some actions from the *previous* bop. Unfortunately,
659 % it reverses other important actions too (such as font size), but the
660 % grestore seems to get these back. Then the desired @manualfeed, followed
661 % by the ``bop'' for the beginning of page. The pair of 0's are used for
662 % bop and are completely bogus. However, from what I could detect, 0's are
663 % as good as anything. The values that DVIPS provides for bop seem to be
664 % related to DVI page numbers.
666 % I make no guarantee about the reliability of this solution, but initial
667 % tests indicate it will work for my environment.
671 % \begin{macro}{\PSautotray}
672 % \changes{v1.2}{1997/07/13}{Wrote new command}
673 % This implements the code by \emph{Uri Blumenthal}
677 \special{ps:clear grestore
678 statusdict begin false setduplexmode
680 \the\PSEnvelopeTray end 0 0 bop }}
684 % \changes{v1.1}{1996/07/08}{Added implementation of the "pswait" option}
685 % \changes{v1.1}{1996/07/09}{Moved \cs{PSwait} code to \cs{AtBeginLabelPage}}
686 % \changes{v1.1}{1996/07/15}{Moved \cs{PSwait} code to
687 % \cs{AtBeginLabels}}
688 % \changes{v1.1}{1997/07/13}{Added implementation of the "psautotray" option}
689 % The option "pswait" puts the "\PSwait" code in the beginning of each
690 % page. The option "\psautotray" puts there the "\PSautotray" code.
693 \AtBeginLabels{\PSwait}%
696 \AtBeginLabels{\PSautotray}%
702 % \subsection{Some useful counters for labels}
706 % \DescribeMacro{\c@LabelCountCol}
707 % \DescribeMacro{\c@LabelCountRow}
708 % These counters store the position of the currently printed label:
710 \newcounter{LabelCountCol}
711 \newcounter{LabelCountRow}
715 % \DescribeMacro{\c@LabelOffsetCol}
716 % \DescribeMacro{\c@LabelOffsetRow}
717 % And these counters provide the offset for the label printed on a
718 % partially used sheet:
720 \newcounter{LabelOffsetCol}
721 \newcounter{LabelOffsetRow}
722 \setcounter{LabelOffsetCol}{1}
723 \setcounter{LabelOffsetRow}{1}
726 % \begin{macro}{\FirstLabel}
727 % \changes{v1.1}{1996/07/08}{Introduced new command \cs{FirstLabel}}
728 % The command "\FirstLabel"\marg{Row}\marg{Col} sets the counters
729 % "LabelOffsetRow" and "LabelOffsetCol".
731 \DeclareRobustCommand{\FirstLabel}[2]{%
732 \setcounter{LabelOffsetRow}{#1}%
733 \setcounter{LabelOffsetCol}{#2}}
741 % \begin{macro}{\@toaddressfont}
742 % \begin{macro}{\@fromaddressfont}
743 % \changes{v1.1}{1996/07/08}{Fixed documentation about \cs{@fromaddressfont}}
744 % We want the address to be printed in \textsf{\large 12pt sans serif}
745 % font. The return address will be printed in 10pt normal font.
747 \def\@toaddressfont{%
748 \ifcase\@ptsize \large\or\normalsize\or\small\fi%
749 \sffamily\selectfont}
750 \def\@fromaddressfont{%
751 \ifcase\@ptsize \normalsize\or\small\or\footnotesize\fi%
757 % \subsection{Return address}
759 % \begin{macro}{\returnaddress}
760 % \changes{v1.2}{1997/07/13}{Deleted check for \cs{if@envelope}}
761 % The standard letter class defines "\returnaddress" to be null. This
762 % is sensible if we are printing labels, but not so good if we are
763 % printing \emph{envelopes}. Therefore let us redefine it:
765 \def\returnaddress{\fromaddress}
769 % \subsection{Margins, page styles, etc.}
772 % \begin{macro}{\startlabels}
773 % \changes{v1.2}{1996/09/07}{Added \cs{clearpage}}
774 % \changes{v1.2}{1996/09/20}{Added percent signs}
775 % \changes{v1.2}{1997/07/10}{Moved here calculations for
776 % \cs{EnvelopeLeftMargin}}
777 % \changes{v1.2}{1997/07/10}{Added \cs{LabelLeftMargin}}
778 % The command "\startlabels" is the internal command that prepares
779 % the paper for labels or envelopes, resets the internal counters and
780 % calls "\@beginlabelshook".
785 \setlength{\topmargin}{-1.0in}%
787 \addtolength{\topmargin}{\EnvelopeTopMargin}%
788 \else \addtolength{\topmargin}{\LabelTopMargin}%
790 \setlength{\headheight}{0pt}%
791 \setlength{\headsep}{0pt}%
792 \setlength{\footskip}{0pt}%
793 \setlength{\textheight}{200in}%
794 \setlength\paperheight{\textheight}%
795 \global\vsize=200in\relax%
796 \addtolength{\textheight}{-\topmargin}%
797 \addtolength{\textheight}{-1.0in}%
798 \setlength{\oddsidemargin}{-1.0in}%
801 \addtolength{\oddsidemargin}{\LabelLeftMargin}%
803 \setlength{\evensidemargin}{\oddsidemargin}%
804 \setlength{\textwidth}{20in}%
812 % Now we can calculate "\EnvelopeLeftMargin"
815 \ifcase\the\@envelopeposition%
816 \setlength{\EnvelopeLeftMargin}{\paperwidth}%
818 \addtolength{\EnvelopeLeftMargin}{-\EnvelopeHeight}%
820 \addtolength{\EnvelopeLeftMargin}{-\EnvelopeWidth}%
822 \setlength{\EnvelopeLeftMargin}{0.5\EnvelopeLeftMargin}%
824 \setlength{\EnvelopeLeftMargin}{0pt}%
826 \setlength{\EnvelopeLeftMargin}{\paperwidth}%
828 \addtolength{\EnvelopeLeftMargin}{-\EnvelopeHeight}%
830 \addtolength{\EnvelopeLeftMargin}{-\EnvelopeWidth}%
838 % Initializing labels counters\ldots
841 \setcounter{LabelCountCol}{\theLabelOffsetCol}%
842 \setcounter{LabelCountRow}{\theLabelOffsetRow}%
843 \ifnum\theLabelOffsetRow>1%
845 \loop \vspace*{\LabelHeight}%
846 \addtocounter{LabelOffsetRow}{-1} \ifnum\theLabelOffsetRow>1%
849 \ifnum\theLabelOffsetCol>1%
850 \loop \hspace*{\LabelWidth}\nolinebreak%
851 \addtocounter{LabelOffsetCol}{-1} \ifnum\theLabelOffsetCol>1%
857 \xspaceskip 0pt\relax%
862 \setlength\hfuzz{5in}%
863 \setlength\vfuzz{5in}%
866 \@beginlabelpagehook%
871 % \subsection{Printing of the addresses}
873 % \DescribeMacro{\PrintReturnAddress}
874 % This macro uses the text as an argument and prints it according to
877 \newcommand{\PrintReturnAddress}[1]{%
878 \vspace*{\FromAddressTopMargin}
879 \null\hspace{\FromAddressLeftMargin}
880 \parbox[t][\FromAddressHeight]{\FromAddressWidth}%
881 {\@fromaddressfont \lineskip=1pt
882 \if@printreturnaddress #1\else\relax\fi}}
885 % \DescribeMacro{\PrintAddress}
886 % This macro works like "\PrintReturnAddress", with several important
887 % differences: it prints barcodes if necessary \emph{and}
888 % capitalizes the address.
890 \newcommand{\PrintAddress}[1]{%
891 \vspace*{\ToAddressTopMargin}
893 \null\hspace*{\ToAddressLeftMargin}
894 \parbox[t]{\ToAddressWidth}{%
896 \if@barcodes \PrintBarCode{#1} \fi
898 \if@capitalizeaddress \@make@capitalize{#1} \else #1 \fi}}
901 % \subsection{Label setup}
903 % \begin{macro}{\PrintLabel}
904 % \changes{v1.2}{1996/09/20}{Added percent signs}
905 % This macro prints a label in a parbox
907 \newcommand{\PrintLabel}[1]{%
908 \parbox[t][\LabelHeight]{\LabelWidth}{%
913 % \begin{macro}{\PrintBigLabel}
914 % \changes{v1.2}{1997/07/13}{Wrote new command}
915 % This macro makes a minipage with addresses on it, similarly to
916 % "\PrintEnvelope" below.
918 \newcommand{\PrintBigLabel}[2]{%
919 \begin{minipage}[t][\LabelHeight]{\LabelWidth}%
924 \PrintReturnAddress{#1}\\%
925 \rule{\ToAddressWidth}{0.1pt}%
932 % \subsection{Envelope setup}
934 % Labels include one box per label, so their setup is simple. The
935 % situation with envelopes is different: they contain several boxes, and
936 % could be rotated, centered, etc.
938 % \begin{macro}{\PrintEnvelope}
939 % \changes{v1.2}{1996/09/20}{Added percent signs}
940 % This macro makes a minipage with addresses on it.
942 \newcommand{\PrintEnvelope}[2]{%
943 \begin{minipage}[t][\EnvelopeHeight]{\EnvelopeWidth}%
947 \PrintReturnAddress{#1}\\%
955 % \begin{macro}{\@PrintEnvelope}
956 % The following macro checks for rotation:
958 \newcommand{\@PrintEnvelope}[2]{%
959 \if@rotateenvelopes\rotatebox{90}{\PrintEnvelope{#1}{#2}}%
960 \else\PrintEnvelope{#1}{#2}%
966 % \section{Printing of envelopes and labels}
968 % \subsection{Main Command}
970 % \begin{macro}{\mlabel}
971 % Now we are prepared to print actual envelopes and labels. It is done by
972 % the "\mlabel" command. It has two forms: for labels and envelopes.
974 \renewcommand{\mlabel}[2]{\ignorespaces%
975 \spaceskip 0pt\relax%
976 \xspaceskip 0pt\relax%
979 % \subsection{Printing of one envelope}
980 % \changes{v1.1}{1996/07/09}{Put \cs{@beginlabelpagehook} in the envelope
985 \hspace*{\EnvelopeLeftMargin}%
986 \@PrintEnvelope{#1}{#2}%
988 \@beginlabelpagehook%
990 % \subsection{Printing of one label}
991 % \changes{v1.1}{1996/07/09}{Put \cs{@beginlabelpagehook} in the label
993 % \changes{v1.2}{1997/07/14}{Added printing of big labels}
997 \ifnum\theLabelCountCol>\theLabelMaxCol%
999 \stepcounter{LabelCountRow}%
1000 \setcounter{LabelCountCol}{1}%
1002 \ifnum\theLabelCountRow>\theLabelMaxRow%
1003 \vfill\eject\@beginlabelpagehook%
1004 \setcounter{LabelCountRow}{1}%
1005 \setcounter{LabelCountCol}{1}%
1008 \PrintBigLabel{#1}{#2}%
1012 \ignorespaces\nolinebreak%
1013 \stepcounter{LabelCountCol}%
1018 % \subsection{Printing of return labels}
1020 % We print only mailing addresses on labels. The user is supposed to have
1021 % preprinted return labels. Here we describe a utility for printing them.
1022 % This utility should be used in a separate document.
1024 % \DescribeMacro{\@numreturnlabels}
1025 % The counter "\@numreturnlabels" stores the number of return labels to
1026 % be printed. Note that it is a \TeX\ counter, not a \LaTeX\ one.
1028 \newcount\@numreturnlabels
1031 % \DescribeMacro{\printreturnlabels}
1032 % This macro has two parameters: the number of labels to be printed and
1033 % the text that is printed. It is the same on all labels.
1035 \newcommand{\printreturnlabels}[2]{%
1036 \@numreturnlabels=#1
1037 \def\@toaddressfont{\@fromaddressfont}
1038 \@capitalizeaddressfalse
1041 \loop \mlabel{\relax}{#2} \advance\@numreturnlabels by -1
1042 \ifnum\@numreturnlabels>0\repeat}
1045 % \section{Barcodes}
1047 % \subsection{Main command}
1049 % The USPS Postnet codes are printed accordingly to the specifications
1050 % Ref.~\cite{Pub25}. The scanning algorithm
1051 % is stolen from David Carlisle's \textsf{enumerate} package~\cite{Enum}.
1053 % \DescribeMacro{\PrintBarCode}
1054 % First, we extract barcodes by the command "\@extractbarcode". Then
1055 % we print them by "\@printbarcode".
1057 \newcommand{\PrintBarCode}[1]{%
1058 \@extractbarcode{#1}
1062 % \subsection{Extraction of barcodes}\label{sec:Extract}
1063 % \changes{v1.2}{1996/07/10}{Deleted \cs{global} from zipcode
1064 % extracting commands}
1065 % We define zipcode as a sequence of digits (0--9) that:
1067 % \item Has no characters other than digits and dashes (-) inside it
1068 % \item Has no bracketed groups inside it and is not bracketed itself
1069 % \item Is the last in the address field unless "\if@alwaysbarcodes=true"
1072 % We print this sequence plus the \emph{control character}.
1073 % The latter is defined as minus sum of digits of the
1075 % modulo 10 (that is, the complement of the sum of digits to a
1078 % First, some internal registers.
1079 % \DescribeMacro{\@zipcode}
1080 % \DescribeMacro{\@zipcodesum}
1081 % \DescribeMacro{\@zipcodefound}
1082 % The token list "\@zipcode" contains barcode found so far. The register
1083 % "\@zipcodesum" first contains the sum of digits of the barcode, and
1084 % then the control character. The
1085 % switch "\@zipcodefound" shows whether we found zip code so far.
1088 \newcount\@zipcodesum
1089 \newif\if@zipcodefound
1094 % There are two modes for gobbling tokens:
1095 % \begin{enumerate}[{State} A:]
1096 % \item We are outside a potential zipcode sequence
1097 % ("\if@zipcodefound=false")\label{state:notfound}
1098 % \item We are inside a potential zipcode sequence
1099 % ("\if@zipcodefound=true")\label{state:found}
1104 % \item \DescribeMacro{\@endaddress} \DescribeMacro{\@finishzipcode}
1105 % If we meet in any state the special token "\@endaddress", we
1106 % gobble it and finish the loop.
1108 \long\def\@finishzipcode#1{}
1111 % \item \DescribeMacro{\@firstzipcode} If we meet a number (0--9) in
1112 % state~\ref{state:notfound}, we initialize registers, process the
1113 % token and go to state~\ref{state:found}
1115 \long\def\@firstzipcode#1{%
1117 \@zipcodesum=#1\relax
1122 % \item \DescribeMacro{\@continuezipcode} If we meet a number (0--9)
1123 % in state~\ref{state:found}, we just process it.
1125 \long\def\@continuezipcode#1{%
1126 \@zipcode=\expandafter{\the\@zipcode#1}
1127 \advance\@zipcodesum by #1
1131 % \item \DescribeMacro{\@dashzipcode} If we meet a dash in
1132 % state~\ref{state:found}, we gobble it.
1134 \long\def\@dashzipcode#1{\@zipcodeloop}
1137 % \item \DescribeMacro{\@spacezipcode} If we meet a space in any
1138 % state, we gobble it and go to the state~\ref{state:notfound}. The
1139 % trick is from Carlisle's \textsf{enumerate} package.
1141 \def\@spacezipcode{%
1143 \afterassignment\@zipcodeloop\let\EL@temp= }
1146 % \item \DescribeMacro{\@abortzipcode} If we meet anything else in any
1147 % mode, we gobble it and go to state~\ref{state:notfound}
1149 \long\def\@abortzipcode#1{%
1157 % \DescribeMacro{\@zipcodeloop}
1158 % \DescribeMacro{\EL@temp}
1159 % \changes{v1.2}{1997/07/14}{Changed \cs{@temp} to \cs{EL@temp} to
1160 % avoid clashes with amsmath}
1161 % This macro is simple. We just put the next token into "\EL@temp" and
1162 % process it through "\@zipcodeloop@".
1164 \def\@zipcodeloop{\futurelet\EL@temp\@zipcodeloop@}
1167 % \DescribeMacro{\@zipcodeloop@}
1168 % \DescribeMacro{\EL@tempa}
1169 % \changes{v1.2}{1997/07/14}{Changed \cs{@tempa} to \cs{EL@tempa} to
1170 % avoid clashes with amsmath}
1171 % This macro performs actual processing\dots We put the command
1172 % that gobbles the next token into "\EL@tempa"
1174 \def\@zipcodeloop@{%
1175 \ifx \@endaddress\EL@temp \def\EL@tempa{\@finishzipcode} \else
1176 \ifx 0\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1177 \else \def\EL@tempa{\@firstzipcode} \fi \else
1178 \ifx 1\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1179 \else \def\EL@tempa{\@firstzipcode} \fi \else
1180 \ifx 2\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1181 \else \def\EL@tempa{\@firstzipcode} \fi \else
1182 \ifx 3\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1183 \else \def\EL@tempa{\@firstzipcode} \fi \else
1184 \ifx 4\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1185 \else \def\EL@tempa{\@firstzipcode} \fi \else
1186 \ifx 5\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1187 \else \def\EL@tempa{\@firstzipcode} \fi \else
1188 \ifx 6\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1189 \else \def\EL@tempa{\@firstzipcode} \fi \else
1190 \ifx 7\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1191 \else \def\EL@tempa{\@firstzipcode} \fi \else
1192 \ifx 8\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1193 \else \def\EL@tempa{\@firstzipcode} \fi \else
1194 \ifx 9\EL@temp \if@zipcodefound \def\EL@tempa{\@continuezipcode}
1195 \else \def\EL@tempa{\@firstzipcode} \fi \else
1196 \ifx -\EL@temp \if@zipcodefound \def\EL@tempa{\@dashzipcode}
1197 \else \def\EL@tempa{\@abortzipcode} \fi \else
1198 \ifx \@sptoken\EL@temp \def\EL@tempa{\@spacezipcode} \else
1199 \def\EL@tempa{\@abortzipcode}
1200 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
1205 % \DescribeMacro{\@extractbarcode}
1206 % The command "\@extractbarcode" puts barcode into the "\@zipcode",
1207 % and calculates the control character (10 minus sum of the digits
1210 \long\def\@extractbarcode#1{%
1212 \@zipcodeloop#1\@endaddress
1213 \if@alwaysbarcodes \@zipcodefoundtrue \fi
1215 \ifnum\the\@zipcodesum>0
1216 \loop \advance \@zipcodesum by -10 \ifnum\the\@zipcodesum>0
1219 \multiply\@zipcodesum by -1
1223 % \subsection{Printing barcodes}
1225 % \DescribeMacro{\@barcodewidth}
1226 % \DescribeMacro{\@barcodeLheight}
1227 % \DescribeMacro{\@barcodeSheight}
1228 % \DescribeMacro{\@barcodeskip}
1229 % First, some lengths. ``L'' and ``S'' below refer to ``long'' and
1230 % ``short'' bars correspondingly.
1232 \newlength{\@barcodewidth}
1233 \newlength{\@barcodeLheight}
1234 \newlength{\@barcodeSheight}
1235 \newlength{\@barcodeskip}
1236 \setlength{\@barcodewidth}{0.020in}
1237 \setlength{\@barcodeLheight}{0.125in}
1238 \setlength{\@barcodeSheight}{0.050in}
1239 \setlength{\@barcodeskip}{0.026in}
1242 % \DescribeMacro{\@barL}
1243 % \DescribeMacro{\@barS}
1244 % The following macros print long and short bars.
1246 \DeclareRobustCommand{\@barL}{%
1247 \rule{\@barcodewidth}{\@barcodeLheight}\hspace{\@barcodeskip}}
1248 \DeclareRobustCommand{\@barS}{%
1249 \rule{\@barcodewidth}{\@barcodeSheight}\hspace{\@barcodeskip}}
1252 % \DescribeMacro{\@printonezip}
1253 % \DescribeMacro{\@printbarcode}
1254 % The scanning of "\@zipcode" is simpler than the scanning of the address:
1255 % the only tokens we can meet are digits. Well, we will add an end marking
1256 % token to the list. Let it be the letter ``S'' (from ``Stop'').
1258 \def\@printonezip#1{%
1259 \ifx1#1\@barS\@barS\@barS\@barL\@barL\else
1260 \ifx2#1\@barS\@barS\@barL\@barS\@barL\else
1261 \ifx3#1\@barS\@barS\@barL\@barL\@barS\else
1262 \ifx4#1\@barS\@barL\@barS\@barS\@barL\else
1263 \ifx5#1\@barS\@barL\@barS\@barL\@barS\else
1264 \ifx6#1\@barS\@barL\@barL\@barS\@barS\else
1265 \ifx7#1\@barL\@barS\@barS\@barS\@barL\else
1266 \ifx8#1\@barL\@barS\@barS\@barL\@barS\else
1267 \ifx9#1\@barL\@barS\@barL\@barS\@barS\else
1268 \ifx0#1\@barL\@barL\@barS\@barS\@barS\else
1269 \ifx S#1\def\EL@tempa{\relax}%
1270 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
1272 \def\@printbarcode{%
1276 \def\EL@tempa{\@printonezip}%
1277 \expandafter\EL@tempa\the\@zipcode S%
1278 \def\EL@tempa{\@printonezip}%
1279 \expandafter\EL@tempa\the\@zipcodesum S%
1287 % \section{Capitalization}
1290 % \changes{v1.2}{1996/07/10}{Deleted \cs{global} from capitalization commands}
1294 % These macros process the address (actually, any string) according to the
1295 % USPS recommendations. Specifically, they:
1297 % \item Strip dots (.) and commas (,) from the address unless they are
1298 % enclosed in brackets
1299 % \item Make all letters uppercase
1300 % \item Add 1pt space between letters
1301 % \item Add 1em space between words
1303 % An interesting question is whether we should de-accent accented
1304 % letters. USPS says nothing about it. In the present version accents
1305 % are \emph{not} stripped. However due to the scanning algorithm they
1306 % should be enclosed by brackets, like this:
1307 % "{\u S}andor {\c C}edi".
1311 % \DescribeMacro{\@addr@cap}
1312 % We store the capitalized address in the token list "\@addr@cap".
1317 % The following macros process the tokens one by one.
1319 % \DescribeMacro{\@finishaddrcap}
1320 % If we meet the special token "\@endaddress", we gobble it and stop.
1322 \long\def\@finishaddrcap#1{}
1325 % \DescribeMacro{\@dotcommaaddrcap}
1326 % If we meet comma or dot, we gobble it and do \emph{not} stop. This macro
1327 % is also useful for gobbling \LaTeXe\ \textsf{letter} commands like
1328 % "\voidb@x" and "\unhbox".
1330 \long\def\@dotcommaaddrcap#1{%
1334 % \DescribeMacro{\@newlineaddrcap}
1335 % If we meet "\\", we add it to the list
1337 \long\def\@newlineaddrcap#1{%
1338 \@addr@cap=\expandafter{\the\@addr@cap #1}
1342 % \DescribeMacro{\@bgroupaddrcap}
1343 % If we meet "\bgroup", we add it to the list the complete group (uppercase)
1345 \long\def\@bgroupaddrcap#1{%
1346 \@addr@cap=\expandafter{\the\@addr@cap {\MakeUppercase{#1}}}
1350 % \DescribeMacro{\@spaceaddrcap}
1351 % If we meet a space we gobble it (oh-oh) and add it to the list.
1353 \def\@spaceaddrcap{%
1354 \@addr@cap=\expandafter{\the\@addr@cap\hspace{0.6em}}
1355 \afterassignment\@addrcaploop\let\EL@temp= }
1358 % \DescribeMacro{\@otheraddrcap}
1359 % And if we meet anything else, we make it uppercase and add to the
1362 \def\@otheraddrcap#1{%
1363 \@addr@cap=\expandafter{\the\@addr@cap%
1364 \MakeUppercase{#1}\kern1pt\relax}
1369 % \DescribeMacro{\@addrcaploop}
1370 % This macro is simple. We just put the next token into "\EL@temp" and
1371 % process it through "\@addrcaploop@".
1373 \def\@addrcaploop{\futurelet\EL@temp\@addrcaploop@}
1376 % \DescribeMacro{\@addrcaploop@}
1377 % This macro performs actual processing\dots
1379 \def\@addrcaploop@{%
1380 \ifx \@endaddress\EL@temp \def\EL@tempa{\@finishaddrcap} \else
1381 \ifx .\EL@temp \def\EL@tempa{\@dotcommaaddrcap} \else
1382 \ifx ,\EL@temp \def\EL@tempa{\@dotcommaaddrcap} \else
1383 \ifx \voidb@x\EL@temp \def\EL@tempa{\@dotcommaaddrcap} \else
1384 \ifx \unhbox\EL@temp \def\EL@tempa{\@dotcommaaddrcap} \else
1385 \ifx \\\EL@temp \def\EL@tempa{\@newlineaddrcap} \else
1386 \ifx \bgroup\EL@temp \def\EL@tempa{\@bgroupaddrcap} \else
1387 \ifx \@sptoken\EL@temp \def\EL@tempa{\@spaceaddrcap} \else
1388 \def\EL@tempa{\@otheraddrcap}
1389 \fi\fi\fi\fi\fi\fi\fi\fi
1393 % \DescribeMacro{\@make@capitalize}
1395 \long\def\@make@capitalize#1{%
1397 \@addrcaploop#1\@endaddress
1402 % \section{Games with \texttt{.aux} file}
1404 % The commands described in this section write something to the
1405 % |.aux| file, and thus change the way \EL\ treats the labels and
1406 % envelopes. Since the action is delayed till the |.aux| file is
1407 % processed, these commands affect only the labels automatically
1408 % extracted from the |letter| environment, and do not affect the
1409 % labels explicitly defined by the |\mlabel| commands in the main
1413 % \changes{v1.2}{1996/09/07}{Added \cs{@@mlabel}}
1414 % \DescribeMacro{\@@mlabel}
1415 % The macro |\@@mlabel| stores the status of the |\@mlabel| as
1416 % determined by |\makelabels|. It is a no-op at the start.
1417 % If |\makelabels| redefines |\@mlabel|, we catch it through the
1418 % |\AtEndDocument| hook. Note that since |\makelabel| is allowed
1419 % only in the preamble, we are not in danger of redefining commands too
1422 \let\@@mlabel=\@gobbletwo
1423 \AtEndDocument{\let\@@mlabel=\@mlabel}
1427 % The next four commands redefine |\@mlabel| to suppress or resume
1428 % printing mailing labels.
1430 % \begin{macro}{\suppresslabels}
1431 % \changes{v1.2}{1996/09/06}{Wrote new command}
1432 % This command suppress printing labels and envelopes until it is
1433 % resumed by |\resumelabels| or similar commands.
1435 \def\suppresslabels{\if@filesw\immediate\write\@auxout{%
1436 \string\@suppresslabels}\fi}
1439 % \begin{macro}{\@suppresslabels}
1440 % \changes{v1.2}{1996/09/07}{Deleted the \cs{AtBeginDocument} hook}
1441 % This is the internal command that performs the actual
1444 \def\@suppresslabels{\let\@mlabel=\@gobbletwo}
1449 % \begin{macro}{\resumelabels}
1450 % \changes{v1.2}{1996/09/06}{Wrote new command}
1451 % \begin{macro}{\@resumelabels}
1452 % \changes{v1.2}{1996/09/07}{Changed \cs{mlabel} to \cs{@@mlabel} and
1453 % deleted the \cs{AtBeginDocument} hook}
1454 % These commands resume printing labels and envelopes if it was
1455 % suppressed by |\suppresslabels| or similar commands.
1457 \def\resumelabels{\if@filesw\immediate\write\@auxout{%
1458 \string\@resumelabels}\fi}
1459 \def\@resumelabels{\let\@mlabel=\@@mlabel}
1465 % \begin{macro}{\suppressonelabel}
1466 % \changes{v1.2}{1996/06/09}{Wrote new command}
1467 % \begin{macro}{\@suppressonelabel}
1468 % \changes{v1.2}{1996/09/07}{Deleted the \cs{AtBeginDocument} hook}
1469 % \begin{macro}{\@old@mlabel}
1470 % These commands suppress printing of one label or envelope.
1471 % The macro |\@old@mlabel| is used to store the
1474 \def\suppressonelabel{\if@filesw\immediate\write\@auxout{%
1475 \string\@suppressonelabel}\fi}
1476 \def\@suppressonelabel{\let\@old@mlabel=\@mlabel%
1478 \let\@mlabel=\@old@mlabel%
1485 % \begin{macro}{\printonelabel}
1486 % \changes{v1.2}{1996/06/09}{Wrote new command}
1487 % \begin{macro}{\@printonelabel}
1488 % \changes{v1.2}{1996/09/07}{Changed \cs{mlabel} to \cs{@@mlabel} and
1489 % deleted the \cs{AtBeginDocument} hook}
1490 % These commands resume printing for one label or envelope
1491 % The macro |\@old@mlabel| is used to store the
1494 \def\printonelabel{\if@filesw\immediate\write\@auxout{%
1495 \string\@printonelabel}\fi}
1496 \def\@printonelabel{\let\@old@mlabel=\@mlabel%
1498 \let\@mlabel=\@old@mlabel%
1505 % \begin{macro}{\ChangeEnvelope}
1506 % \changes{v1.2}{1996/09/07}{Wrote new command}
1507 % \begin{macro}{\@ChangeEnvelope}
1508 % \begin{macro}{\@ChangeEnvelopeStar}
1509 % This macro writes |\@SetEnvelope| to the |.aux| file. It has
1510 % two forms: starred and and unstarred. In the unstarred mode it also
1511 % writes |\@startlabels| to the |.aux| file. In the unstarred form it
1513 % Since we want to treat \emph{both} stars and optional arguments, we
1514 % introduce two internal commands that can be invoked by the main
1517 \def\ChangeEnvelope{\@ifstar{\@ChangeEnvelopeStar}{\@ChangeEnvelope}}
1518 \newcommand\@ChangeEnvelopeStar[3][0pt]{%
1519 \if@filesw\immediate\write\@auxout{%
1520 \string\@SetEnvelope[#1]{#2}{#3}}%
1522 \newcommand\@ChangeEnvelope[3][0pt]{%
1523 \if@filesw\immediate\write\@auxout{%
1524 \string\@SetEnvelope[#1]{#2}{#3}}
1525 \immediate\write\@auxout{\string\@startlabels}
1531 % \begin{macro}{\@SetEnvelope}
1532 % We define this command as no-op at beginning, and then redefine it
1533 % before reading |.aux| file.
1535 \def\@SetEnvelope[#1]#2#3{}
1536 \AtEndDocument{\let\@SetEnvelope=\SetEnvelope}
1541 % \begin{macro}{\ChangeLabel}
1542 % \changes{v1.2}{1997/07/11}{Wrote new command}
1543 % \begin{macro}{\@ChangeLabel}
1544 % \begin{macro}{\@ChangeLabelStar}
1545 % This macro writes |\@SetLabel| to the |.aux| file. It has
1546 % two forms: starred and and unstarred. In the unstarred mode it also
1547 % writes |\@startlabels| to the |.aux| file. In the unstarred form it
1549 % Since we want to treat \emph{both} stars and optional arguments, we
1550 % introduce two internal commands that can be invoked by the main
1553 \def\ChangeLabel{\@ifstar{\@ChangeLabelStar}{\@ChangeLabel}}
1554 \newcommand\@ChangeLabelStar[7]{%
1555 \if@filesw\immediate\write\@auxout{%
1556 \string\@SetLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
1558 \newcommand\@ChangeLabel[7]{%
1559 \if@filesw\immediate\write\@auxout{%
1560 \string\@SetLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}
1561 \immediate\write\@auxout{\string\@startlabels}
1567 % \begin{macro}{\@SetLabel}
1568 % We define this command as no-op at beginning, and then redefine it
1569 % before reading |.aux| file.
1571 \def\@SetLabel#1#2#3#4#5#6#7{}
1572 \AtEndDocument{\let\@SetLabel=\SetLabel}
1577 % \begin{macro}{\ChangeBigLabel}
1578 % \changes{v1.2}{1997/07/13}{Wrote new command}
1579 % \begin{macro}{\@ChangeBigLabel}
1580 % \begin{macro}{\@ChangeBigLabelStar}
1581 % This macro writes |\@SetBigLabel| to the |.aux| file. It has
1582 % two forms: starred and and unstarred. In the unstarred mode it also
1583 % writes |\@startlabels| to the |.aux| file. In the unstarred form it
1585 % Since we want to treat \emph{both} stars and optional arguments, we
1586 % introduce two internal commands that can be invoked by the main
1589 \def\ChangeBigLabel{\@ifstar{\@ChangeBigLabelStar}{\@ChangeBigLabel}}
1590 \newcommand\@ChangeBigLabelStar[7]{%
1591 \if@filesw\immediate\write\@auxout{%
1592 \string\@SetBigLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
1594 \newcommand\@ChangeBigLabel[7]{%
1595 \if@filesw\immediate\write\@auxout{%
1596 \string\@SetBigLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}
1597 \immediate\write\@auxout{\string\@startlabels}
1603 % \begin{macro}{\@SetLabel}
1604 % We define this command as no-op at beginning, and then redefine it
1605 % before reading |.aux| file.
1607 \def\@SetBigLabel#1#2#3#4#5#6#7{}
1608 \AtEndDocument{\let\@SetBigLabel=\SetBigLabel}
1613 % \section{Reimplementation of the \cs{opening} command}
1614 % \DescribeMacro{\re}
1615 % Some people like to put below the address information like
1617 % Re: our recent talk
1619 % A way to do this is to include it in the address like this:
1622 % Dr.~Austin Tankel\\
1624 % Anytown, Pa 12345\\[1ex]
1625 % Re: Our recent talk}
1626 % \opening{Dear Austin:}
1628 % However, this additional info will be put in the mailing label,
1629 % which is wrong. Here we describe a macro that works like this:
1632 % Dr.~Austin Tankel\\
1634 % Anytown, Pa 12345}
1635 % \re{Our recent talk}
1636 % \opening{Dear Austin:}
1640 % Now, the implementation.
1641 % First, lets us check whether the option "re" is chosen (otherwise we
1642 % don't bother to redefine the commands):
1644 \if@EL@redefine@opening
1647 % \begin{macro}{\re}
1648 % \changes{v1.2}{1997/07/14}{Wrote new command}
1649 % \begin{macro}{\recontentents}
1650 % \changes{v1.2}{1997/07/14}{Wrote new command}
1651 % The command "\re" just defines "\recontents". Also, we initialize
1652 % "\recontents" to be initially empty
1654 \newcommand*{\re}[1]{\def\recontents{#1}}%
1660 % \begin{macro}{\ReName}
1661 % \changes{v1.2}{1997/07/14}{Wrote new command}
1662 % By default it is just plain style ``Re: '' (note the space!)
1668 % \begin{macro}{\opening}
1669 % \changes{v1.2}{1997/07/14}{Reimplemented standard command
1671 % Now we redefine the standard "\opening" command to include the "\re"
1672 % info. Here is the quote from the standard "letter"
1673 % class~\cite{letter}:
1675 % Text is begun with the |\opening| command, whose argument
1676 % generates the salutation, as in
1678 % \opening{Dear Henry,}
1680 % This should produce everything up to and including the
1681 % `Dear Henry,' and a |\par| command that follows.
1682 % Since there's a |\vfil| at the bottom of every page,
1683 % it can add vertical fill to position a short letter.
1684 % It should use the following commands:
1686 % \item |\toname| : name part of `to' address.
1687 % Will be one line long.
1688 % \item |\toaddress| : address part of `to' address.
1689 % The lines separated by |\\|.
1690 % \item |\fromname| : name of sender.
1691 % \item |\fromaddress| : argument of current |\address|
1692 % declaration-- null if none. Should use standard institutional
1694 % \item |\fromlocation| : argument of current |\location|
1695 % declaration--null if none.
1696 % \item |\telephonenum| : argument of current |\telephone|
1697 % declaration--null if none.
1700 % We just "\ReName" and "\recontents" here\ldots
1702 \renewcommand*{\opening}[1]{\ifx\@empty\fromaddress
1703 \thispagestyle{firstpage}%
1704 {\raggedleft\@date\par}%
1705 \else % home address
1706 \thispagestyle{empty}%
1707 {\raggedleft\begin{tabular}{l}\ignorespaces
1708 \fromaddress \\*[2\parskip]%
1709 \@date \end{tabular}\par}%
1712 {\raggedright \toname \\ \toaddress \par}%
1713 \ifx\@empty\recontents\relax
1715 {\raggedright \ReName \recontents \par}%
1722 % Now we close \cs{if@EL@redefine@opening}:
1727 % And the last line:
1735 % \addcontentsline{toc}{section}{\protect\refname}
1736 % \begin{thebibliography}{1}
1739 % \newblock {\em The \textsf{enumerate} package}.
1740 % \newblock {CTAN}, v2.02 edition, January 1994.
1742 % Leslie Lamport, Frank Mittelbach, and Rainer Sch{\"o}pf.
1743 % \newblock Standard letter document class for {\LaTeX} version 2e.
1744 % \newblock CTAN, 199c.
1747 % \newblock {\em Designing Business Letter Mail (Pub 25)}, August 1995.
1748 % \end{thebibliography}
1751 % \addcontentsline{toc}{section}{Change History}
1755 % \addcontentsline{toc}{section}{Index}