add README file to explain how to use the git repo
[mit-stationery-latex] / envlab.dtx
1 % \iffalse
2 %<*driver>
3 \ProvidesFile{envlab.drv}
4 %</driver>
5 %<*driver|package|cfg>
6 %<+package>\ProvidesPackage{envlab}
7 %<+cfg>\ProvidesFile{envlab.cfg}
8 [1997/07/16 v1.2 Envelopes and Labels] 
9 %</driver|package|cfg>
10 %<*driver|package>
11 %%
12 %% Copyright Boris Veytsman 1996, 1997
13 %%
14 %</driver|package>
15 %<*driver|package|cfg>
16 % \fi 
17 %%
18 % \CheckSum{1378}
19 %% \CharacterTable
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         \~} 
34 % \iffalse
35 %</driver|package|cfg>
36 %
37 % \section{Documentation driver}
38 %<*driver>
39 % Nothing interesting here\dots
40 %    \begin{macrocode}
41 \documentclass{ltxdoc}
42 \DoNotIndex{\@Alph,\@alph,\@arabic,\@badmath}
43 \DoNotIndex{\@centercr}
44 \DoNotIndex{\@empty,\@ignoretrue}
45 \DoNotIndex{\@ixpt}
46 \DoNotIndex{\@M,\@minus,\@ne,\@plus}
47 \DoNotIndex{\\,\addtolength}
48 \DoNotIndex{\advance}
49 \DoNotIndex{\ast,\begin,\begingroup,\bfseries,\bgroup,\box}
50 \DoNotIndex{\bullet}
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}
65 \DoNotIndex{\p@}
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@}
75 %
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}
94 \CodelineIndex
95 \RecordChanges
96 \EnableCrossrefs
97 \begin{document}
98   \DocInput{envlab.dtx}
99 \end{document}
100 %    \end{macrocode}
101 %</driver>
102 % \fi
103 %
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}
111 %
112 % \newcommand{\EL}{\textsl{EnvLab}}
113 %
114 %
115 % \GetFileInfo{envlab.drv}
116 %
117 % \title{Printing Envelopes and Labels in \LaTeXe: \EL\ Package
118 %  \thanks{This file
119 %        has version number \fileversion, last
120 %        revised \filedate.}
121 %  \thanks{\copyright Boris Veytsman, 1996, 1997}
122 %  }
123 % \author{Boris Veytsman}
124 % \date{\filedate}
125 % \maketitle
126
127 % \tableofcontents
128 %
129 %
130 % \section{Introduction}
131 % \MakeShortVerb{\"}
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
136 %
137 % The detailed usage of the package is described in the file
138 % "elguide.tex". Here we just comment the macros.
139 %
140 % \StopEventually
141 %
142 % \section{Identification}
143 %
144 % First, we must say ``Hello world.'' 
145 %    \begin{macrocode}
146 %<*package>
147 \NeedsTeXFormat{LaTeX2e}
148 %    \end{macrocode}
149 %
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
155 % classes, etc.)
156 %    \begin{macrocode}
157 \def\envlab@oops{%
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}}
165 \def\envlab@ok{%
166   \PackageInfo{envlab}%
167   {Envelopes & Labels package: found makelabels...\MessageBreak%
168   Seems everything is OK. Good luck.}}
169 \@ifundefined{makelabels}{\envlab@oops}{\envlab@ok}
170 %    \end{macrocode}
171 % \end{macro}
172 % \end{macro}
173 % \section{Preliminary code}
174 %
175 % \subsection{Switches, etc.} 
176
177 %
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}.
185 % \begin{table}
186 %   \begin{center}
187 %     \begin{tabular}{cccc}
188 %       \hline
189 %       Media & Number per page & Rotation & Return address \\
190 %       \hline
191 %       Envelopes & One & Settable & Yes\\
192 %       Labels & Several & Not rotated & No\\
193 %       Big Labels & Several & Not rotated & Yes\\
194 %       \hline
195 %     \end{tabular}
196 %   \end{center}
197 %   \caption{Differences between envelopes, labels and big labels}
198 %   \label{tab:diffs}
199 % \end{table}
200 %
201 %    \begin{macrocode}
202 \newif\if@envelope 
203 \@envelopetrue 
204 \newif\if@biglabel 
205 \@biglabelfalse
206 %    \end{macrocode}
207 %
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).
212 %    \begin{macrocode}
213 \newif\if@rotateenvelopes
214 \@rotateenvelopestrue
215 \newif\if@printreturnaddress
216 \@printreturnaddresstrue
217 %    \end{macrocode}
218 %
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
222 % tray.  The
223 % counter "\@envelopeposition" can be, correspondingly, either 0 or 1
224 % or 2. The value of
225 % 3 corresponds to the ``custom placing'', when the user sets
226 % "\EnvelopeLeftMargin" manually.
227 %
228 %    \begin{macrocode}
229 \newcount\@envelopeposition 
230 \@envelopeposition=0\relax
231 %    \end{macrocode}
232 %
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.
243 %    \begin{macrocode}
244 \newif\if@pswait
245 \@pswaitfalse
246 \newif\if@psautotray
247 \@psautotrayfalse
248 \newtoks\PSEnvelopeTray
249 \PSEnvelopeTray={/otherenvelopetray }
250 %    \end{macrocode}
251 %
252 % \end{macro}
253 % \end{macro}
254 % \end{macro}
255 %
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") 
261 %    \begin{macrocode}
262 \newif\if@barcodes
263 \newif\if@alwaysbarcodes
264 \@barcodestrue
265 \@alwaysbarcodesfalse
266 %    \end{macrocode}
267 % \end{macro}
268 % \end{macro}
269 %
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.
273 %    \begin{macrocode}
274 \newif\if@EL@redefine@opening
275 \@EL@redefine@openingfalse
276 %    \end{macrocode}
277 % \end{macro} 
278 %
279 %
280 % \begin{macro}{\if@capitalizeaddress}
281 % Also, we can either capitalize the address (default) or not.
282 %    \begin{macrocode}
283 \newif\if@capitalizeaddress
284 \@capitalizeaddresstrue
285 %    \end{macrocode}
286 % \end{macro}
287 %
288 % \subsection{Lengths and numbers}
289 %
290 % We want all lengths to be user settable, so no "@" in the names.
291 %
292
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
303 % zero
304 %    \begin{macrocode}
305 \newlength{\EnvelopeWidth}
306 \newlength{\EnvelopeHeight}
307 \newlength{\EnvelopeTopMargin}
308 \newlength{\EnvelopeLeftMargin}
309 \setlength{\EnvelopeLeftMargin}{0pt}
310 %    \end{macrocode}
311 %
312
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.
322 %    \begin{macrocode}
323 \newlength{\LabelWidth}
324 \newlength{\LabelHeight}
325 \newlength{\LabelTopMargin}
326 \newlength{\LabelLeftMargin}
327 \newlength{\LabelRightMargin}
328 %    \end{macrocode}
329 %
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
334 %    \begin{macrocode}
335 \newcounter{LabelMaxCol}
336 \newcounter{LabelMaxRow}
337 %    \end{macrocode}
338 %
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.
343 %
344
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.
353 %    \begin{macrocode}
354 \newlength{\FromAddressTopMargin}
355 \newlength{\FromAddressLeftMargin}
356 \newlength{\FromAddressHeight}
357 \newlength{\FromAddressWidth}
358 \newlength{\ToAddressTopMargin}
359 \newlength{\ToAddressLeftMargin}
360 \newlength{\ToAddressWidth}
361 %    \end{macrocode}
362 %
363 % \subsection{Main setting commands}
364 %
365 % OK, we are ready to set up envelopes and labels.
366 %
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.
371 %    \begin{macrocode}
372 \DeclareRobustCommand{\SetEnvelope}[3][0pt]{%
373   \@envelopetrue%
374   \@biglabelfalse%
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}}
385 %    \end{macrocode}
386 % \end{macro}
387 %
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:
392 %    \begin{macrocode}
393 \DeclareRobustCommand{\SetLabel}[7]{%
394   \@envelopefalse%
395   \@biglabelfalse%
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}}
408 %    \end{macrocode}
409 % \end{macro}
410 %
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:
415 %    \begin{macrocode}
416 \DeclareRobustCommand{\SetBigLabel}[7]{%
417   \@envelopefalse%
418   \@biglabeltrue%
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}}
435 %    \end{macrocode}
436 % \end{macro}
437 %
438 % \section{Defining options}
439 %
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
444 % options} 
445 %    \begin{macrocode}
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 }}
458 %    \end{macrocode}
459 %
460 % \subsection{Labels sizes}
461 %
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}  
468 %
469 %    \begin{macrocode}
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}}%
489 %    \end{macrocode}
490 %
491 % \subsection{Optional switches}
492 %
493 % \changes{v1.1}{1996/07/08}{Added new options: "printreturnaddress", 
494 % "noprintreturnaddress"}
495 % \changes{v1.1}{1996/07/08}{Added new options: "pswait", 
496 % "nopswait"}
497 % \changes{v1.2}{1997/07/13}{Added new options: "psautotray", 
498 % "nopsautotray"}
499 % \changes{v1.2}{1997/07/14}{Added new options: "re", "nore"}
500 % All this should be evident\dots
501 %
502 %    \begin{macrocode}
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}
523 %    \end{macrocode}
524 %
525 % \subsection{Unknown options}
526 %
527 % All options we did not declare above are probably the options for the
528 % "graphics" package; let us send them there.
529 %    \begin{macrocode}
530 \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{graphics}}
531 %    \end{macrocode}
532 %
533 % \subsection{Default options}\label{sec:DefOpt}
534 %
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"}
538 %
539 %    \begin{macrocode}
540 \ExecuteOptions{businessenvelope,rotateenvelopes,centerenvelopes}
541 \ExecuteOptions{printbarcodes,capaddress}
542 \ExecuteOptions{nopswait,printreturnaddress,nopsautotray,nore}
543 %    \end{macrocode}
544 %
545 % \section{Configuration file}
546 %
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
551 % is loaded.
552 %    \begin{macrocode}
553 \InputIfFileExists{envlab.cfg}{%
554   \typeout{Loading configuration file envlab.cfg}}{%
555   \typeout{Configuration file envlab.cfg is not found}}
556 %    \end{macrocode}
557 %
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.
564 %
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
567 % foolproof\dots
568 %    \begin{macrocode}
569 %</package>
570 %<*cfg>
571 %%
572 %% The default options go here
573 %%
574 \ExecuteOptions{businessenvelope,rotateenvelopes,centerenvelopes}
575 \ExecuteOptions{printbarcodes,capaddress}
576 \ExecuteOptions{nopswait,printreturnaddress,nopsautotray,nore}
577 %%
578 \AtEndOfPackage{\relax % Customization goes here
579 }
580 %</cfg>
581 %<*package>
582 %    \end{macrocode}
583 %
584 % \section{Processing options and loading packages}
585 % \changes{v0.92}{1996/06/06}{Added \cs{IfFileExists} when loading packages}
586 %    \begin{macrocode}
587 \ProcessOptions
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}}
594 %    \end{macrocode}
595 %
596 % \section{Document layout}
597 %
598 % \subsection{Printer specific commands}
599 % \label{sec:Print}
600 %
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
607 % change). 
608 %    \begin{macrocode}
609 \def\@beginlabelshook{\relax}
610 %    \end{macrocode}
611 %
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.
618 %    \begin{macrocode}
619 \def\@beginlabelpagehook{\relax}
620 %    \end{macrocode}
621 %
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}
633 % \begin{verbatim}
634 % \long\def\g@addto@macro#1#2{{%
635 %   \toks@\expandafter{#1#2}%
636 %   \xdef#1{\the\toks@}}}
637 % \end{verbatim}
638 % We quote this definition in case \emph{They} change Their minds\dots\ 
639 %    \begin{macrocode}
640 \def\AtBeginLabels{\g@addto@macro\@beginlabelshook}
641 \def\AtBeginLabelPage{\g@addto@macro\@beginlabelpagehook}
642 %    \end{macrocode}
643 %   \end{macro}
644 % \end{macro}
645 %
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>".
650 %    \begin{macrocode}
651 \def\PSwait{\special{ps: clear grestore @manualfeed 0 0 bop}}
652 %    \end{macrocode} 
653 % The author explains his code in the following way:
654 % \begin{quotation}
655 %       Here is a possible explanation:
656 %       
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.
665 %       
666 %       I make no guarantee about the reliability of this solution, but initial
667 %       tests indicate it will work for my environment.
668 % \end{quotation}
669 % \end{macro}
670 %
671 % \begin{macro}{\PSautotray}
672 % \changes{v1.2}{1997/07/13}{Wrote new command}
673 % This implements the code by \emph{Uri Blumenthal}
674 % "<uri@.ibm.net>". 
675 %    \begin{macrocode}
676 \edef\PSautotray{%
677   \special{ps:clear grestore 
678     statusdict begin false setduplexmode
679     /manualfeed true def
680     \the\PSEnvelopeTray end 0 0 bop }}
681 %    \end{macrocode}
682 % \end{macro}
683 %
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.
691 %    \begin{macrocode}
692 \if@pswait 
693   \AtBeginLabels{\PSwait}%
694 \else
695   \if@psautotray
696     \AtBeginLabels{\PSautotray}%
697   \fi
698 \fi
699 %    \end{macrocode}
700
701 %
702 % \subsection{Some useful counters for labels}
703 %
704
705
706 % \DescribeMacro{\c@LabelCountCol}
707 % \DescribeMacro{\c@LabelCountRow}
708 % These counters store the position of the currently printed label:
709 %    \begin{macrocode}
710 \newcounter{LabelCountCol}
711 \newcounter{LabelCountRow}
712 %    \end{macrocode}
713 %
714
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:
719 %    \begin{macrocode}
720 \newcounter{LabelOffsetCol}
721 \newcounter{LabelOffsetRow}
722 \setcounter{LabelOffsetCol}{1}
723 \setcounter{LabelOffsetRow}{1}
724 %    \end{macrocode}
725 %
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".
730 %    \begin{macrocode}
731 \DeclareRobustCommand{\FirstLabel}[2]{%
732   \setcounter{LabelOffsetRow}{#1}%
733   \setcounter{LabelOffsetCol}{#2}}
734 %    \end{macrocode}
735 % \end{macro}
736 %
737 %
738 % \subsection{Fonts}
739 %
740 %
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.
746 %    \begin{macrocode}
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%
752   \normalfont}
753 %    \end{macrocode}
754 %   \end{macro}
755 % \end{macro}
756 %
757 % \subsection{Return address}
758 %
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:
764 %    \begin{macrocode}
765 \def\returnaddress{\fromaddress}
766 %    \end{macrocode}
767 % \end{macro}
768
769 % \subsection{Margins, page styles, etc.}
770 %
771
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". 
781 %    \begin{macrocode}
782 \def\startlabels{%
783   \clearpage%
784   \pagestyle{empty}%
785   \setlength{\topmargin}{-1.0in}%
786   \if@envelope%
787     \addtolength{\topmargin}{\EnvelopeTopMargin}%
788     \else \addtolength{\topmargin}{\LabelTopMargin}%
789   \fi%
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}%
799   \if@envelope\relax%
800   \else%
801      \addtolength{\oddsidemargin}{\LabelLeftMargin}%
802   \fi%
803   \setlength{\evensidemargin}{\oddsidemargin}%
804   \setlength{\textwidth}{20in}%
805   \hsize=20in%
806   \baselineskip=0pt%
807   \lineskip=0pt%
808   \parindent=0pt%
809   \if@envelope
810 %    \end{macrocode}
811 %
812 % Now we can calculate "\EnvelopeLeftMargin"
813 %
814 %    \begin{macrocode}
815     \ifcase\the\@envelopeposition%
816       \setlength{\EnvelopeLeftMargin}{\paperwidth}%
817       \if@rotateenvelopes%
818         \addtolength{\EnvelopeLeftMargin}{-\EnvelopeHeight}%
819       \else%
820         \addtolength{\EnvelopeLeftMargin}{-\EnvelopeWidth}%
821       \fi%
822       \setlength{\EnvelopeLeftMargin}{0.5\EnvelopeLeftMargin}%
823     \or%
824       \setlength{\EnvelopeLeftMargin}{0pt}%
825     \or%
826       \setlength{\EnvelopeLeftMargin}{\paperwidth}%
827       \if@rotateenvelopes%
828         \addtolength{\EnvelopeLeftMargin}{-\EnvelopeHeight}%
829       \else%
830         \addtolength{\EnvelopeLeftMargin}{-\EnvelopeWidth}%
831       \fi%
832     \else%
833       \relax%
834     \fi%
835   \else%
836 %    \end{macrocode}
837 %
838 % Initializing labels counters\ldots
839 %
840 %    \begin{macrocode}
841     \setcounter{LabelCountCol}{\theLabelOffsetCol}%
842     \setcounter{LabelCountRow}{\theLabelOffsetRow}%
843     \ifnum\theLabelOffsetRow>1%
844       \null%
845       \loop \vspace*{\LabelHeight}%
846         \addtocounter{LabelOffsetRow}{-1} \ifnum\theLabelOffsetRow>1%
847       \repeat%
848     \fi%
849     \ifnum\theLabelOffsetCol>1%
850       \loop \hspace*{\LabelWidth}\nolinebreak%
851         \addtocounter{LabelOffsetCol}{-1} \ifnum\theLabelOffsetCol>1%
852       \repeat%
853     \fi%
854     \nopagebreak%
855   \fi%
856   \spaceskip0pt\relax%
857   \xspaceskip 0pt\relax%
858   \clubpenalty=0%
859   \widowpenalty=0%
860   \raggedbottom%
861   \sloppy%
862   \setlength\hfuzz{5in}%
863   \setlength\vfuzz{5in}%
864   \ignorespaces%
865   \@beginlabelshook%
866   \@beginlabelpagehook%
867   \nopagebreak}%
868 %    \end{macrocode}
869 % \end{macro}
870 %
871 % \subsection{Printing of the addresses}
872 %
873 % \DescribeMacro{\PrintReturnAddress}
874 % This macro uses the text as an argument and prints it according to
875 %  the conventions.
876 %    \begin{macrocode}
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}}
883 %    \end{macrocode}
884 %
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.
889 %    \begin{macrocode}
890 \newcommand{\PrintAddress}[1]{%
891   \vspace*{\ToAddressTopMargin}
892   \leavevmode
893   \null\hspace*{\ToAddressLeftMargin}
894   \parbox[t]{\ToAddressWidth}{%
895     \lineskip=1pt
896     \if@barcodes \PrintBarCode{#1} \fi 
897     \@toaddressfont
898     \if@capitalizeaddress \@make@capitalize{#1} \else #1 \fi}}
899 %    \end{macrocode}
900 %
901 % \subsection{Label setup}
902 %
903 % \begin{macro}{\PrintLabel}
904 % \changes{v1.2}{1996/09/20}{Added percent signs}
905 % This macro prints a label in a parbox
906 %    \begin{macrocode}
907 \newcommand{\PrintLabel}[1]{%
908   \parbox[t][\LabelHeight]{\LabelWidth}{%
909     \PrintAddress{#1}}}
910 %    \end{macrocode}
911 % \end{macro}
912 %
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.
917 %    \begin{macrocode}
918 \newcommand{\PrintBigLabel}[2]{%
919   \begin{minipage}[t][\LabelHeight]{\LabelWidth}%
920     \baselineskip=0pt%
921     \lineskip=0pt%
922     \parindent=0pt%
923     \begin{center}%
924       \PrintReturnAddress{#1}\\%
925       \rule{\ToAddressWidth}{0.1pt}%
926       \PrintAddress{#2}%
927     \end{center}%
928   \end{minipage}}
929 %    \end{macrocode}
930 %
931 %
932 % \subsection{Envelope setup} 
933
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. 
937 %
938 % \begin{macro}{\PrintEnvelope}
939 % \changes{v1.2}{1996/09/20}{Added percent signs}
940 % This macro makes a minipage with addresses on it.
941 %    \begin{macrocode}
942 \newcommand{\PrintEnvelope}[2]{%
943   \begin{minipage}[t][\EnvelopeHeight]{\EnvelopeWidth}%
944     \baselineskip=0pt%
945     \lineskip=0pt%
946     \parindent=0pt%
947     \PrintReturnAddress{#1}\\%
948     \begin{center}%
949       \PrintAddress{#2}%
950     \end{center}%
951   \end{minipage}}
952 %    \end{macrocode}
953 % \end{macro}
954 %
955 % \begin{macro}{\@PrintEnvelope}
956 % The following macro checks for rotation:
957 %    \begin{macrocode}
958 \newcommand{\@PrintEnvelope}[2]{%
959   \if@rotateenvelopes\rotatebox{90}{\PrintEnvelope{#1}{#2}}%
960   \else\PrintEnvelope{#1}{#2}%
961   \fi}
962 %    \end{macrocode}
963 % \end{macro}
964 % \end{macro}
965 %
966 % \section{Printing of envelopes and labels}
967 %
968 % \subsection{Main Command}
969 %
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.
973 %    \begin{macrocode}
974 \renewcommand{\mlabel}[2]{\ignorespaces%
975   \spaceskip 0pt\relax%
976   \xspaceskip 0pt\relax%
977 %    \end{macrocode}
978 %
979 % \subsection{Printing of one envelope}
980 % \changes{v1.1}{1996/07/09}{Put \cs{@beginlabelpagehook} in the envelope
981 % printing}
982 %    \begin{macrocode}
983   \if@envelope%
984     \leavevmode%
985     \hspace*{\EnvelopeLeftMargin}%
986     \@PrintEnvelope{#1}{#2}%
987     \clearpage%
988     \@beginlabelpagehook%
989 %    \end{macrocode}
990 % \subsection{Printing of one label}
991 % \changes{v1.1}{1996/07/09}{Put \cs{@beginlabelpagehook} in the label 
992 % printing}
993 % \changes{v1.2}{1997/07/14}{Added printing of big labels}
994 %    \begin{macrocode}
995   \else%
996     \ignorespaces%
997     \ifnum\theLabelCountCol>\theLabelMaxCol%
998       \\\nopagebreak%
999       \stepcounter{LabelCountRow}%
1000       \setcounter{LabelCountCol}{1}%
1001     \fi%
1002     \ifnum\theLabelCountRow>\theLabelMaxRow%
1003       \vfill\eject\@beginlabelpagehook%
1004       \setcounter{LabelCountRow}{1}%
1005       \setcounter{LabelCountCol}{1}%
1006     \fi%
1007     \if@biglabel%
1008         \PrintBigLabel{#1}{#2}%
1009     \else%
1010         \PrintLabel{#2}%
1011     \fi%
1012     \ignorespaces\nolinebreak%
1013     \stepcounter{LabelCountCol}%
1014   \fi}%
1015 %    \end{macrocode}
1016 % \end{macro} 
1017 %
1018 % \subsection{Printing of return labels}
1019 %
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.
1023 %
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.
1027 %    \begin{macrocode}
1028 \newcount\@numreturnlabels
1029 %    \end{macrocode}
1030 %
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.
1034 %    \begin{macrocode}
1035 \newcommand{\printreturnlabels}[2]{%
1036   \@numreturnlabels=#1
1037   \def\@toaddressfont{\@fromaddressfont}
1038   \@capitalizeaddressfalse
1039   \@barcodesfalse
1040   \startlabels
1041   \loop \mlabel{\relax}{#2} \advance\@numreturnlabels by -1 
1042     \ifnum\@numreturnlabels>0\repeat}
1043 %    \end{macrocode}
1044 %
1045 % \section{Barcodes}
1046 %
1047 % \subsection{Main command}
1048 %
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}. 
1052 %
1053 % \DescribeMacro{\PrintBarCode}
1054 % First, we extract barcodes by the command "\@extractbarcode". Then
1055 % we print them by "\@printbarcode".
1056 %    \begin{macrocode}
1057 \newcommand{\PrintBarCode}[1]{%
1058   \@extractbarcode{#1}
1059   \@printbarcode}
1060 %    \end{macrocode} 
1061 %
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:
1066 % \begin{itemize}
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"
1070 % \end{itemize}
1071 %
1072 % We print this sequence plus the \emph{control character}. 
1073 % The latter is defined as minus sum of digits of the 
1074 % zip code
1075 % modulo 10 (that is, the complement of the sum of digits to a 
1076 % multiple of 10).
1077 %
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.
1086 %    \begin{macrocode}
1087 \newtoks\@zipcode
1088 \newcount\@zipcodesum
1089 \newif\if@zipcodefound
1090 %    \end{macrocode}
1091 %
1092 %
1093
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}
1100 % \end{enumerate}
1101 %
1102 % \begin{itemize}
1103 %
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.
1107 %    \begin{macrocode}
1108 \long\def\@finishzipcode#1{}
1109 %    \end{macrocode}
1110 %
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} 
1114 %    \begin{macrocode}
1115 \long\def\@firstzipcode#1{%
1116   \@zipcode{#1}
1117   \@zipcodesum=#1\relax
1118   \@zipcodefoundtrue
1119   \@zipcodeloop}
1120 %    \end{macrocode}
1121 %
1122 % \item \DescribeMacro{\@continuezipcode} If we meet a number (0--9)
1123 % in state~\ref{state:found}, we just process it.
1124 %    \begin{macrocode}
1125 \long\def\@continuezipcode#1{%
1126   \@zipcode=\expandafter{\the\@zipcode#1}
1127   \advance\@zipcodesum by #1
1128   \@zipcodeloop}
1129 %    \end{macrocode}
1130 %    
1131 % \item  \DescribeMacro{\@dashzipcode} If we meet a dash in
1132 % state~\ref{state:found}, we gobble it.
1133 %    \begin{macrocode} 
1134 \long\def\@dashzipcode#1{\@zipcodeloop}
1135 %    \end{macrocode}
1136
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.
1140 %    \begin{macrocode} 
1141 \def\@spacezipcode{%
1142   \@zipcodefoundfalse
1143   \afterassignment\@zipcodeloop\let\EL@temp= }
1144 %    \end{macrocode}
1145 %
1146 % \item \DescribeMacro{\@abortzipcode} If we meet anything else in any
1147 % mode, we gobble it and go to state~\ref{state:notfound} 
1148 %    \begin{macrocode}
1149 \long\def\@abortzipcode#1{%
1150   \@zipcodefoundfalse
1151   \@zipcodeloop}
1152 %    \end{macrocode}
1153 %
1154 % \end{itemize}
1155 %
1156 %
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@".
1163 %    \begin{macrocode}
1164 \def\@zipcodeloop{\futurelet\EL@temp\@zipcodeloop@}
1165 %    \end{macrocode}
1166 %
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"
1173 %    \begin{macrocode}
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
1201   \EL@tempa}
1202 %    \end{macrocode}
1203 %
1204 %
1205 % \DescribeMacro{\@extractbarcode}
1206 % The command "\@extractbarcode" puts barcode into the "\@zipcode", 
1207 % and calculates the control character (10 minus sum of the digits
1208 % of the barcode).
1209 %    \begin{macrocode}
1210 \long\def\@extractbarcode#1{%
1211   \@zipcodefoundfalse
1212   \@zipcodeloop#1\@endaddress
1213   \if@alwaysbarcodes \@zipcodefoundtrue \fi
1214   \if@zipcodefound
1215     \ifnum\the\@zipcodesum>0
1216       \loop \advance \@zipcodesum by -10 \ifnum\the\@zipcodesum>0
1217       \repeat
1218     \fi
1219     \multiply\@zipcodesum by -1
1220   \fi}
1221 %    \end{macrocode}
1222 %
1223 % \subsection{Printing barcodes}
1224 %
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.
1231 %    \begin{macrocode}
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}
1240 %    \end{macrocode}
1241 %
1242 % \DescribeMacro{\@barL}
1243 % \DescribeMacro{\@barS}
1244 % The following macros print long and short bars.
1245 %    \begin{macrocode}
1246 \DeclareRobustCommand{\@barL}{%
1247   \rule{\@barcodewidth}{\@barcodeLheight}\hspace{\@barcodeskip}}
1248 \DeclareRobustCommand{\@barS}{%
1249   \rule{\@barcodewidth}{\@barcodeSheight}\hspace{\@barcodeskip}}
1250 %    \end{macrocode}
1251 %
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'').
1257 %    \begin{macrocode}
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%
1271   \EL@tempa}
1272 \def\@printbarcode{%
1273   \if@zipcodefound
1274    \mbox{%
1275     \@barL%
1276     \def\EL@tempa{\@printonezip}%
1277     \expandafter\EL@tempa\the\@zipcode S%
1278     \def\EL@tempa{\@printonezip}%
1279     \expandafter\EL@tempa\the\@zipcodesum S%
1280     \@barL}
1281     \\[1ex]
1282   \fi}
1283 %    \end{macrocode}
1284 %
1285 %
1286 %
1287 % \section{Capitalization}
1288 %
1289 %
1290 % \changes{v1.2}{1996/07/10}{Deleted \cs{global} from capitalization commands}
1291 %
1292 %
1293 %
1294 % These macros process the address (actually, any string) according to the
1295 % USPS recommendations. Specifically, they:
1296 % \begin{itemize}
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
1302 % \end{itemize}
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". 
1308 %
1309 %
1310 %
1311 % \DescribeMacro{\@addr@cap}
1312 % We store the capitalized address in the token list "\@addr@cap".
1313 %    \begin{macrocode}
1314 \newtoks\@addr@cap
1315 %    \end{macrocode}
1316 %
1317 % The following macros process the tokens one by one.
1318 %
1319 % \DescribeMacro{\@finishaddrcap}
1320 % If we meet the special token "\@endaddress", we gobble it and stop.
1321 %    \begin{macrocode}
1322 \long\def\@finishaddrcap#1{}
1323 %    \end{macrocode}
1324 %
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".
1329 %    \begin{macrocode}
1330 \long\def\@dotcommaaddrcap#1{%
1331   \@addrcaploop}
1332 %    \end{macrocode}
1333 %
1334 % \DescribeMacro{\@newlineaddrcap}
1335 % If we meet "\\", we add it to the list
1336 %    \begin{macrocode}
1337 \long\def\@newlineaddrcap#1{%
1338   \@addr@cap=\expandafter{\the\@addr@cap #1}
1339   \@addrcaploop}
1340 %    \end{macrocode}
1341 %
1342 % \DescribeMacro{\@bgroupaddrcap}
1343 % If we meet "\bgroup", we add it to the list the complete group (uppercase)
1344 %    \begin{macrocode}
1345 \long\def\@bgroupaddrcap#1{%
1346   \@addr@cap=\expandafter{\the\@addr@cap {\MakeUppercase{#1}}}
1347   \@addrcaploop}
1348 %    \end{macrocode}
1349 %
1350 % \DescribeMacro{\@spaceaddrcap} 
1351 % If we meet a space we gobble it (oh-oh) and add it to the list. 
1352 %    \begin{macrocode} 
1353 \def\@spaceaddrcap{%
1354   \@addr@cap=\expandafter{\the\@addr@cap\hspace{0.6em}}
1355   \afterassignment\@addrcaploop\let\EL@temp= }
1356 %    \end{macrocode}
1357 %
1358 % \DescribeMacro{\@otheraddrcap}
1359 % And if we meet anything else, we make it uppercase and add to the
1360 % list
1361 %    \begin{macrocode} 
1362 \def\@otheraddrcap#1{%
1363   \@addr@cap=\expandafter{\the\@addr@cap%
1364      \MakeUppercase{#1}\kern1pt\relax}
1365   \@addrcaploop}
1366 %    \end{macrocode}
1367 %
1368 %
1369 % \DescribeMacro{\@addrcaploop}
1370 % This macro is simple. We just put the next token into "\EL@temp" and
1371 % process it through "\@addrcaploop@".
1372 %    \begin{macrocode}
1373 \def\@addrcaploop{\futurelet\EL@temp\@addrcaploop@}
1374 %    \end{macrocode}
1375 %
1376 % \DescribeMacro{\@addrcaploop@}
1377 % This macro performs actual processing\dots
1378 %    \begin{macrocode}
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
1390   \EL@tempa}
1391 %    \end{macrocode}
1392 %
1393 % \DescribeMacro{\@make@capitalize}
1394 %    \begin{macrocode}
1395 \long\def\@make@capitalize#1{%
1396   \@addr@cap={\relax}
1397   \@addrcaploop#1\@endaddress
1398   \the\@addr@cap}
1399 %    \end{macrocode}
1400 %
1401
1402 % \section{Games with \texttt{.aux} file}
1403 %
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 
1410 % file.
1411 %
1412 %
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
1420 % early.
1421 %    \begin{macrocode}
1422 \let\@@mlabel=\@gobbletwo
1423 \AtEndDocument{\let\@@mlabel=\@mlabel}
1424 %    \end{macrocode}
1425 %
1426 %
1427 % The next four commands redefine |\@mlabel| to suppress or resume
1428 %  printing  mailing labels.
1429 %
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.
1434 %    \begin{macrocode}
1435 \def\suppresslabels{\if@filesw\immediate\write\@auxout{%
1436   \string\@suppresslabels}\fi}
1437 %    \end{macrocode}
1438 %
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
1442 % processing. 
1443 %    \begin{macrocode}
1444 \def\@suppresslabels{\let\@mlabel=\@gobbletwo}
1445 %    \end{macrocode}
1446 % \end{macro}
1447 % \end{macro}
1448 %
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.
1456 %    \begin{macrocode}
1457 \def\resumelabels{\if@filesw\immediate\write\@auxout{%
1458   \string\@resumelabels}\fi}
1459 \def\@resumelabels{\let\@mlabel=\@@mlabel}
1460 %    \end{macrocode}
1461 % \end{macro}
1462 % \end{macro}
1463 %
1464 %
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
1472 % system state.
1473 %    \begin{macrocode}
1474 \def\suppressonelabel{\if@filesw\immediate\write\@auxout{%
1475   \string\@suppressonelabel}\fi}
1476 \def\@suppressonelabel{\let\@old@mlabel=\@mlabel%
1477   \def\@mlabel{%
1478     \let\@mlabel=\@old@mlabel%
1479     \@gobbletwo}}
1480 %    \end{macrocode}
1481 % \end{macro}
1482 % \end{macro}
1483 % \end{macro}
1484 %
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
1492 % system state.
1493 %    \begin{macrocode}
1494 \def\printonelabel{\if@filesw\immediate\write\@auxout{%
1495   \string\@printonelabel}\fi}
1496 \def\@printonelabel{\let\@old@mlabel=\@mlabel%
1497   \def\@mlabel{%
1498     \let\@mlabel=\@old@mlabel%
1499     \@@mlabel}}
1500 %    \end{macrocode}
1501 % \end{macro}
1502 % \end{macro}
1503 %
1504 %
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
1512 % does not.
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
1515 % macro. 
1516 %    \begin{macrocode}
1517 \def\ChangeEnvelope{\@ifstar{\@ChangeEnvelopeStar}{\@ChangeEnvelope}}
1518 \newcommand\@ChangeEnvelopeStar[3][0pt]{%
1519   \if@filesw\immediate\write\@auxout{%
1520        \string\@SetEnvelope[#1]{#2}{#3}}%
1521    \fi}
1522 \newcommand\@ChangeEnvelope[3][0pt]{%
1523   \if@filesw\immediate\write\@auxout{%
1524        \string\@SetEnvelope[#1]{#2}{#3}}
1525      \immediate\write\@auxout{\string\@startlabels}
1526   \fi}
1527 %    \end{macrocode}
1528 % \end{macro}
1529 % \end{macro}
1530 %
1531 % \begin{macro}{\@SetEnvelope}
1532 % We define this command as no-op at beginning, and then redefine it 
1533 % before reading |.aux| file.
1534 %    \begin{macrocode}
1535 \def\@SetEnvelope[#1]#2#3{}
1536 \AtEndDocument{\let\@SetEnvelope=\SetEnvelope}
1537 %    \end{macrocode}
1538 % \end{macro}
1539 % \end{macro}
1540 %
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
1548 % does not.
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
1551 % macro. 
1552 %    \begin{macrocode}
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}}%
1557    \fi}
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}
1562   \fi}
1563 %    \end{macrocode}
1564 % \end{macro}
1565 % \end{macro}
1566 %
1567 % \begin{macro}{\@SetLabel}
1568 % We define this command as no-op at beginning, and then redefine it 
1569 % before reading |.aux| file.
1570 %    \begin{macrocode}
1571 \def\@SetLabel#1#2#3#4#5#6#7{}
1572 \AtEndDocument{\let\@SetLabel=\SetLabel}
1573 %    \end{macrocode}
1574 % \end{macro}
1575 % \end{macro}
1576 %
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
1584 % does not.
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
1587 % macro. 
1588 %    \begin{macrocode}
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}}%
1593    \fi}
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}
1598   \fi}
1599 %    \end{macrocode}
1600 % \end{macro}
1601 % \end{macro}
1602 %
1603 % \begin{macro}{\@SetLabel}
1604 % We define this command as no-op at beginning, and then redefine it 
1605 % before reading |.aux| file.
1606 %    \begin{macrocode}
1607 \def\@SetBigLabel#1#2#3#4#5#6#7{}
1608 \AtEndDocument{\let\@SetBigLabel=\SetBigLabel}
1609 %    \end{macrocode}
1610 % \end{macro}
1611 % \end{macro}
1612 %
1613 % \section{Reimplementation of the \cs{opening} command}
1614 % \DescribeMacro{\re}
1615 % Some people like to put below the address information like 
1616 % \begin{quote}
1617 % Re: our recent talk
1618 % \end{quote}
1619 % A way to do this is to include it in the address like this:
1620 % \begin{verbatim}
1621 % \begin{letter}{%
1622 %   Dr.~Austin Tankel\\
1623 %   Some University\\
1624 %   Anytown, Pa 12345\\[1ex]
1625 %   Re: Our recent talk}
1626 % \opening{Dear Austin:}
1627 % \end{verbatim}
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:
1630 % \begin{verbatim}
1631 % \begin{letter}{%
1632 %   Dr.~Austin Tankel\\
1633 %   Some University\\
1634 %   Anytown, Pa 12345}
1635 % \re{Our recent talk}
1636 % \opening{Dear Austin:}
1637 % \end{verbatim}
1638 %
1639
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):
1643 %    \begin{macrocode}
1644 \if@EL@redefine@opening
1645 %    \end{macrocode}
1646 %
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 
1653 %    \begin{macrocode}
1654   \newcommand*{\re}[1]{\def\recontents{#1}}%
1655 %    \end{macrocode}
1656 % \end{macro}
1657 % \end{macro}
1658 %
1659 %
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!)
1663 %    \begin{macrocode}
1664   \def\ReName{Re: }%
1665 %    \end{macrocode}
1666 % \end{macro}
1667 %
1668 % \begin{macro}{\opening}
1669 % \changes{v1.2}{1997/07/14}{Reimplemented standard command
1670 %    \cs{opening}}
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}: 
1674 % \begin{quotation}
1675 %     Text is begun with the |\opening| command, whose argument
1676 %     generates the salutation, as in
1677 %\begin{verbatim}
1678 %      \opening{Dear Henry,}
1679 %\end{verbatim}
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:
1685 %   \begin{itemize}
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
1693 %     address if null.
1694 %   \item |\fromlocation| : argument of current |\location|
1695 %     declaration--null if none.
1696 %   \item |\telephonenum| : argument of current |\telephone|
1697 %     declaration--null if none.
1698 %    \end{itemize}
1699 % \end{quotation}
1700 % We just "\ReName" and "\recontents" here\ldots
1701 %    \begin{macrocode}
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}%
1710     \fi
1711     \vspace{2\parskip}%
1712     {\raggedright \toname \\ \toaddress \par}%
1713     \ifx\@empty\recontents\relax
1714     \else
1715        {\raggedright \ReName \recontents \par}%
1716     \fi
1717     \vspace{2\parskip}%
1718     #1\par\nobreak}%
1719 %    \end{macrocode}
1720 % \end{macro}
1721 %
1722 % Now we close \cs{if@EL@redefine@opening}:
1723 %    \begin{macrocode}
1724 \fi
1725 %    \end{macrocode}
1726 %
1727 % And the last line:
1728 %    \begin{macrocode}
1729 %</package>
1730 %    \end{macrocode}
1731 %
1732 % \Finale
1733 %
1734 % \clearpage
1735 % \addcontentsline{toc}{section}{\protect\refname}
1736 % \begin{thebibliography}{1}
1737 % \bibitem{Enum}
1738 % David Carlisle.
1739 % \newblock {\em The \textsf{enumerate} package}.
1740 % \newblock {CTAN}, v2.02 edition, January 1994.
1741 % \bibitem{letter}
1742 % Leslie Lamport, Frank Mittelbach, and Rainer Sch{\"o}pf.
1743 % \newblock Standard letter document class for {\LaTeX} version 2e.
1744 % \newblock CTAN, 199c.
1745 % \bibitem{Pub25}
1746 % USPS.
1747 % \newblock {\em Designing Business Letter Mail (Pub 25)}, August 1995.
1748 % \end{thebibliography}
1749 %
1750 % \clearpage
1751 % \addcontentsline{toc}{section}{Change History}
1752 % \PrintChanges
1753 %
1754 % \clearpage
1755 %  \addcontentsline{toc}{section}{Index}
1756 %  \PrintIndex
1757 %
1758 \endinput
1759  

Benjamin Mako Hill || Want to submit a patch?