12.07.2015 Views

Printing Envelopes and Labels in LATEX2ε: EnvLab Package - Mirror

Printing Envelopes and Labels in LATEX2ε: EnvLab Package - Mirror

Printing Envelopes and Labels in LATEX2ε: EnvLab Package - Mirror

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> <strong>Envelopes</strong> <strong>and</strong> <strong>Labels</strong> <strong>in</strong> L A TEX2ε:<strong>EnvLab</strong> <strong>Package</strong> ∗†Boris Veytsman1997/07/16Contents1 Introduction 22 Identification 23 Prelim<strong>in</strong>ary code 33.1 Switches, etc. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33.2 Lengths <strong>and</strong> numbers . . . . . . . . . . . . . . . . . . . . . . . . . 43.3 Ma<strong>in</strong> sett<strong>in</strong>g comm<strong>and</strong>s . . . . . . . . . . . . . . . . . . . . . . . . 54 Def<strong>in</strong><strong>in</strong>g options 64.1 Envelope Sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64.2 <strong>Labels</strong> sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64.3 Optional switches . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74.4 Unknown options . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74.5 Default options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Configuration file 76 Process<strong>in</strong>g options <strong>and</strong> load<strong>in</strong>g packages 87 Document layout 87.1 Pr<strong>in</strong>ter specific comm<strong>and</strong>s . . . . . . . . . . . . . . . . . . . . . . . 87.2 Some useful counters for labels . . . . . . . . . . . . . . . . . . . . 107.3 Fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107.4 Return address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107.5 Marg<strong>in</strong>s, page styles, etc. . . . . . . . . . . . . . . . . . . . . . . . 107.6 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of the addresses . . . . . . . . . . . . . . . . . . . . . . . . 127.7 Label setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12∗ This file has version number v1.2, last revised 1997/07/16.† c○Boris Veytsman, 1996, 19971


7.8 Envelope setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of envelopes <strong>and</strong> labels 138.1 Ma<strong>in</strong> Comm<strong>and</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138.2 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of one envelope . . . . . . . . . . . . . . . . . . . . . . . . 148.3 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of one label . . . . . . . . . . . . . . . . . . . . . . . . . . 148.4 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of return labels . . . . . . . . . . . . . . . . . . . . . . . . 149 Barcodes 159.1 Ma<strong>in</strong> comm<strong>and</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159.2 Extraction of barcodes . . . . . . . . . . . . . . . . . . . . . . . . . 159.3 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> barcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1710 Capitalization 1811 Games with .aux file 2012 Reimplementation of the \open<strong>in</strong>g comm<strong>and</strong> 22References 241 IntroductionThe st<strong>and</strong>ard \makelabels comm<strong>and</strong> <strong>in</strong> the L A TEX2ε letter.cls documentclasstypesets labels on Avery 5352 sheets. A typical user may want more. <strong>EnvLab</strong>redef<strong>in</strong>es \makelabels <strong>in</strong> 1 a more useful <strong>and</strong> customizable wayThe detailed usage of the package is described <strong>in</strong> the file elguide.tex. Herewe just comment the macros.2 IdentificationFirst, we must say “Hello world.”1 〈∗package〉2 \NeedsTeXFormat{LaTeX2e}\envlab@ok\envlab@oopsNow let us check whether we <strong>in</strong> the letter documentclass. Actually we will acceptany class that has \makelabels def<strong>in</strong>ed (custom letter classes, etc.)3 \def\envlab@oops{%4 \<strong>Package</strong>Error{envlab}%5 {Envlab is used outside of \MessageBreak%6 a letter-compatible documentclass}%7 {You are try<strong>in</strong>g to use <strong>Envelopes</strong> & <strong>Labels</strong>\MessageBreak%8 package, but your documentclass does not\MessageBreak%9 underst<strong>and</strong> address formatt<strong>in</strong>g comm<strong>and</strong>s.\MessageBreak%10 Try st<strong>and</strong>ard document class letter\MessageBreak}}1 hopefully2


Media Number per page Rotation Return address<strong>Envelopes</strong> One Settable Yes<strong>Labels</strong> Several Not rotated NoBig <strong>Labels</strong> Several Not rotated YesTable 1: Differences between envelopes, labels <strong>and</strong> big labels11 \def\envlab@ok{%12 \<strong>Package</strong>Info{envlab}%13 {<strong>Envelopes</strong> & <strong>Labels</strong> package: found makelabels...\MessageBreak%14 Seems everyth<strong>in</strong>g is OK. Good luck.}}15 \@ifundef<strong>in</strong>ed{makelabels}{\envlab@oops}{\envlab@ok}3 Prelim<strong>in</strong>ary code3.1 Switches, etc.\if@envelope There are three k<strong>in</strong>ds of th<strong>in</strong>gs we can pr<strong>in</strong>t: envelopes (default) labels <strong>and</strong> big\if@biglabel labels The differences are summarized <strong>in</strong> Table 1.16 \newif\if@envelope17 \@envelopetrue18 \newif\if@biglabel19 \@biglabelfalse\if@rotateenvelopes Now we must determ<strong>in</strong>e whether we want to rotate envelopes <strong>and</strong> whether to\if@pr<strong>in</strong>treturnaddress <strong>in</strong>clude return address (both yes by default).\@envelopeposition20 \newif\if@rotateenvelopes21 \@rotateenvelopestrue22 \newif\if@pr<strong>in</strong>treturnaddress23 \@pr<strong>in</strong>treturnaddresstrueNow let us decide how to pr<strong>in</strong>t envelopes. They can be either centered (default)or shifted to the left or to the right of the paper tray. The counter\@envelopeposition can be, correspond<strong>in</strong>gly, either 0 or 1 or 2. The value of 3corresponds to the “custom plac<strong>in</strong>g”, when the user sets \EnvelopeLeftMarg<strong>in</strong>manually.24 \newcount\@envelopeposition25 \@envelopeposition=0\relax\if@pswait\if@psautotray\PSEnvelopeTrayThe switches \if@pswait <strong>and</strong> \if@psautotray control optional manual feed<strong>in</strong>gof envelopes <strong>and</strong> labels <strong>in</strong> Postscript pr<strong>in</strong>ters (see Section 7.1 for details). Theregister \PSEnvelopeTray conta<strong>in</strong>s the name of the required tray.26 \newif\if@pswait27 \@pswaitfalse28 \newif\if@psautotray29 \@psautotrayfalse3


30 \newtoks\PSEnvelopeTray31 \PSEnvelopeTray={/otherenvelopetray }\if@barcodes\if@alwaysbarcodesWe can either pr<strong>in</strong>t bar codes (default) or not. The second switch forces to pr<strong>in</strong>tbarcodes even if they are not last <strong>in</strong> the address (like Pa 16801\\USA)32 \newif\if@barcodes33 \newif\if@alwaysbarcodes34 \@barcodestrue35 \@alwaysbarcodesfalse\if@EL@redef<strong>in</strong>e@open<strong>in</strong>g Now let us decide whether to mess with the \open<strong>in</strong>g comm<strong>and</strong>.36 \newif\if@EL@redef<strong>in</strong>e@open<strong>in</strong>g37 \@EL@redef<strong>in</strong>e@open<strong>in</strong>gfalse\if@capitalizeaddress Also, we can either capitalize the address (default) or not.\EnvelopeWidth\EnvelopeHeight\EnvelopeTopMarg<strong>in</strong>\EnvelopeLeftMarg<strong>in</strong>\LabelWidth\LabelHeight\LabelTopMarg<strong>in</strong>\LabelLeftMarg<strong>in</strong>\LabelRightMarg<strong>in</strong>38 \newif\if@capitalizeaddress39 \@capitalizeaddresstrue3.2 Lengths <strong>and</strong> numbersWe want all lengths to be user settable, so no @ <strong>in</strong> the names.An envelope has four basic lengths. The first two are self-evident. The third isthe distance between the edge of the paper <strong>and</strong> the lead<strong>in</strong>g edge of the envelope.All pre-def<strong>in</strong>ed envelope sizes set this to zero. The fourth is the distance betweenthe left edge of the paper <strong>and</strong> the envelope. Its value depends on the value of the\@envelopeposition variable. We will preset it to zero40 \newlength{\EnvelopeWidth}41 \newlength{\EnvelopeHeight}42 \newlength{\EnvelopeTopMarg<strong>in</strong>}43 \newlength{\EnvelopeLeftMarg<strong>in</strong>}44 \setlength{\EnvelopeLeftMarg<strong>in</strong>}{0pt}A label has more parameters. The first two are the same as for the envelopes.The next two def<strong>in</strong>e the distances from the paper edges to the beg<strong>in</strong>n<strong>in</strong>g of thelabels. The last one describes the distance between the labels.45 \newlength{\LabelWidth}46 \newlength{\LabelHeight}47 \newlength{\LabelTopMarg<strong>in</strong>}48 \newlength{\LabelLeftMarg<strong>in</strong>}49 \newlength{\LabelRightMarg<strong>in</strong>}\c@LabelMaxCol The follow<strong>in</strong>g numbers def<strong>in</strong>e, how many labels are <strong>in</strong> each row <strong>and</strong> how many\c@LabelMaxRow rows are on each page50 \newcounter{LabelMaxCol}51 \newcounter{LabelMaxRow}The lengths above are external parameters that determ<strong>in</strong>e an envelope or alabel. Now we will describe <strong>in</strong>ternal lengths. We def<strong>in</strong>e them here because thecomm<strong>and</strong>s \SetEnvelope <strong>and</strong> \SetLabel determ<strong>in</strong>e them bas<strong>in</strong>g on the givenenvelope or label type.4


\FromAddressTopMarg<strong>in</strong>\FromAddressLeftMarg<strong>in</strong>\FromAddressHeight\FromAddressWidth\ToAddressTopMarg<strong>in</strong>\ToAddressLeftMarg<strong>in</strong>\ToAddressWidthThe follow<strong>in</strong>g lengths are self-evident.52 \newlength{\FromAddressTopMarg<strong>in</strong>}53 \newlength{\FromAddressLeftMarg<strong>in</strong>}54 \newlength{\FromAddressHeight}55 \newlength{\FromAddressWidth}56 \newlength{\ToAddressTopMarg<strong>in</strong>}57 \newlength{\ToAddressLeftMarg<strong>in</strong>}58 \newlength{\ToAddressWidth}3.3 Ma<strong>in</strong> sett<strong>in</strong>g comm<strong>and</strong>sOK, we are ready to set up envelopes <strong>and</strong> labels.\SetEnvelope The comm<strong>and</strong> \SetEnvelope has three parameters: optional top Marg<strong>in</strong>, width<strong>and</strong> height of the envelope.59 \DeclareRobustComm<strong>and</strong>{\SetEnvelope}[3][0pt]{%60 \@envelopetrue%61 \@biglabelfalse%62 \setlength{\EnvelopeTopMarg<strong>in</strong>}{#1}%63 \setlength{\EnvelopeWidth}{#2}%64 \setlength{\EnvelopeHeight}{#3}%65 \setlength{\FromAddressTopMarg<strong>in</strong>}{0.5<strong>in</strong>}%66 \setlength{\FromAddressLeftMarg<strong>in</strong>}{0.5<strong>in</strong>}%67 \setlength{\FromAddressHeight}{0.33\EnvelopeHeight}%68 \setlength{\FromAddressWidth}{0.5\EnvelopeWidth}%69 \setlength{\ToAddressTopMarg<strong>in</strong>}{0.5<strong>in</strong>}%70 \setlength{\ToAddressLeftMarg<strong>in</strong>}{0.5<strong>in</strong>}%71 \setlength{\ToAddressWidth}{3<strong>in</strong>}}\SetLabel The comm<strong>and</strong> \SetLabel has seven parameters: five lengths <strong>and</strong> two numbers.All are m<strong>and</strong>atory:72 \DeclareRobustComm<strong>and</strong>{\SetLabel}[7]{%73 \@envelopefalse%74 \@biglabelfalse%75 \setlength{\LabelWidth}{#1}%76 \setlength{\LabelHeight}{#2}%77 \setlength{\LabelTopMarg<strong>in</strong>}{#3}%78 \setlength{\LabelLeftMarg<strong>in</strong>}{#4}%79 \setlength{\LabelRightMarg<strong>in</strong>}{#5}%80 \setcounter{LabelMaxCol}{#6}%81 \setcounter{LabelMaxRow}{#7}%82 \setlength{\ToAddressTopMarg<strong>in</strong>}{0.1<strong>in</strong>}%83 \setlength{\ToAddressLeftMarg<strong>in</strong>}{0.2<strong>in</strong>}%84 \setlength{\ToAddressWidth}{\LabelWidth}%85 \addtolength{\ToAddressWidth}{-\ToAddressLeftMarg<strong>in</strong>}%86 \addtolength{\ToAddressWidth}{-\LabelRightMarg<strong>in</strong>}}\SetBigLabel The comm<strong>and</strong>\SetBigLabel has seven parameters: five lengths <strong>and</strong> two numbers.All are m<strong>and</strong>atory:5


87 \DeclareRobustComm<strong>and</strong>{\SetBigLabel}[7]{%88 \@envelopefalse%89 \@biglabeltrue%90 \setlength{\LabelWidth}{#1}%91 \setlength{\LabelHeight}{#2}%92 \setlength{\LabelTopMarg<strong>in</strong>}{#3}%93 \setlength{\LabelLeftMarg<strong>in</strong>}{#4}%94 \setlength{\LabelRightMarg<strong>in</strong>}{#5}%95 \setcounter{LabelMaxCol}{#6}%96 \setcounter{LabelMaxRow}{#7}%97 \setlength{\FromAddressTopMarg<strong>in</strong>}{0.0<strong>in</strong>}%98 \setlength{\FromAddressLeftMarg<strong>in</strong>}{0.5<strong>in</strong>}%99 \setlength{\FromAddressHeight}{0.33\LabelHeight}%100 \setlength{\ToAddressTopMarg<strong>in</strong>}{0.1<strong>in</strong>}%101 \setlength{\ToAddressLeftMarg<strong>in</strong>}{0.5<strong>in</strong>}%102 \setlength{\ToAddressWidth}{\LabelWidth}%103 \addtolength{\ToAddressWidth}{-\ToAddressLeftMarg<strong>in</strong>}%104 \addtolength{\ToAddressWidth}{-\LabelRightMarg<strong>in</strong>}%105 \setlength{\FromAddressWidth}{\ToAddressWidth}}4 Def<strong>in</strong><strong>in</strong>g options4.1 Envelope Sizes106 \DeclareOption{bus<strong>in</strong>essenvelope}{\SetEnvelope{9.5<strong>in</strong>}{4.125<strong>in</strong>}%107 \PSEnvelopeTray={/com10envelopetray }}108 \DeclareOption{executiveenvelope}{\SetEnvelope{7.5<strong>in</strong>}{3.875<strong>in</strong>}%109 \PSEnvelopeTray={/monarcenvelopetray }}110 \DeclareOption{bookletenvelope}{\SetEnvelope{10.5<strong>in</strong>}{7.5<strong>in</strong>}}111 \DeclareOption{personalenvelope}{\SetEnvelope{6.5<strong>in</strong>}{3.625<strong>in</strong>}}112 \DeclareOption{c6envelope}{\SetEnvelope{162mm}{114mm}}113 \DeclareOption{c65envelope}{\SetEnvelope{224mm}{114mm}}114 \DeclareOption{c5envelope}{\SetEnvelope{229mm}{162mm}%115 \PSEnvelopeTray={/162x229cenvelopetray }}116 \DeclareOption{dlenvelope}{\SetEnvelope{220mm}{110mm}%117 \PSEnvelopeTray={/dlenvelopetray }}4.2 <strong>Labels</strong> sizes118 \DeclareOption{avery5160label}{%119 \SetLabel{2.75<strong>in</strong>}{1<strong>in</strong>}{0.5<strong>in</strong>}{0.19<strong>in</strong>}{0.12<strong>in</strong>}{3}{10}}120 \DeclareOption{avery5161label}{%121 \SetLabel{4.19<strong>in</strong>}{1<strong>in</strong>}{0.5<strong>in</strong>}{0.16<strong>in</strong>}{0.19<strong>in</strong>}{2}{10}}122 \DeclareOption{avery5162label}{%123 \SetLabel{4.19<strong>in</strong>}{1.33<strong>in</strong>}{0.83<strong>in</strong>}{0.16<strong>in</strong>}{0.19<strong>in</strong>}{2}{7}}124 \DeclareOption{avery5163label}{%125 \SetLabel{4.19<strong>in</strong>}{2<strong>in</strong>}{0.5<strong>in</strong>}{0.16<strong>in</strong>}{0.19<strong>in</strong>}{2}{5}}126 \DeclareOption{avery5164label}{%127 \SetLabel{4.19<strong>in</strong>}{3.33<strong>in</strong>}{0.5<strong>in</strong>}{0.16<strong>in</strong>}{0.19<strong>in</strong>}{2}{3}}128 \DeclareOption{herma4625label}{%6


129 \SetLabel{105mm}{42.3mm}{0mm}{5mm}{5mm}{2}{7}}130 \DeclareOption{avery5262label}{%131 \SetLabel{110mm}{34mm}{21mm}{4mm}{5mm}{2}{7}}132 \DeclareOption{avery5163biglabel}{%133 \SetBigLabel{4.19<strong>in</strong>}{2<strong>in</strong>}{0.5<strong>in</strong>}{0.16<strong>in</strong>}{0.19<strong>in</strong>}{2}{5}%134 \setlength{\ToAddressTopMarg<strong>in</strong>}{0.1<strong>in</strong>}}%135 \DeclareOption{avery5164biglabel}{%136 \SetBigLabel{4.19<strong>in</strong>}{3.33<strong>in</strong>}{0.5<strong>in</strong>}{0.16<strong>in</strong>}{0.19<strong>in</strong>}{2}{3}}%4.3 Optional switchesAll this should be evident. . .137 \DeclareOption{rotateenvelopes}{\@rotateenvelopestrue}138 \DeclareOption{norotateenvelopes}{\@rotateenvelopesfalse}139 \DeclareOption{centerenvelopes}{\@envelopeposition=0\relax}140 \DeclareOption{leftenvelopes}{\@envelopeposition=1\relax}141 \DeclareOption{rightenvelopes}{\@envelopeposition=2\relax}142 \DeclareOption{customenvelopes}{\@envelopeposition=3\relax}143 \DeclareOption{pr<strong>in</strong>tbarcodes}{\@barcodestrue}144 \DeclareOption{nopr<strong>in</strong>tbarcodes}{\@barcodesfalse\@alwaysbarcodesfalse}145 \DeclareOption{alwaysbarcodes}{\@alwaysbarcodestrue\@barcodestrue}146 \DeclareOption{noalwaysbarcodes}{\@alwaysbarcodesfalse}147 \DeclareOption{capaddress}{\@capitalizeaddresstrue}148 \DeclareOption{nocapaddress}{\@capitalizeaddressfalse}149 \DeclareOption{pr<strong>in</strong>treturnaddress}{\@pr<strong>in</strong>treturnaddresstrue}150 \DeclareOption{nopr<strong>in</strong>treturnaddress}{\@pr<strong>in</strong>treturnaddressfalse}151 \DeclareOption{pswait}{\@pswaittrue\@psautotrayfalse}152 \DeclareOption{nopswait}{\@pswaitfalse}153 \DeclareOption{psautotray}{\@psautotraytrue\@pswaitfalse}154 \DeclareOption{nopsautotray}{\@psautotrayfalse}155 \DeclareOption{re}{\@EL@redef<strong>in</strong>e@open<strong>in</strong>gtrue}156 \DeclareOption{nore}{\@EL@redef<strong>in</strong>e@open<strong>in</strong>gfalse}4.4 Unknown optionsAll options we did not declare above are probably the options for the graphicspackage; let us send them there.157 \DeclareOption*{\PassOptionsTo<strong>Package</strong>{\CurrentOption}{graphics}}4.5 Default options158 \ExecuteOptions{bus<strong>in</strong>essenvelope,rotateenvelopes,centerenvelopes}159 \ExecuteOptions{pr<strong>in</strong>tbarcodes,capaddress}160 \ExecuteOptions{nopswait,pr<strong>in</strong>treturnaddress,nopsautotray,nore}5 Configuration fileAt this po<strong>in</strong>t we will look for the configuration file. This file is namedenvlab.cfg.The options declared <strong>in</strong> this file will supersede the ones declared <strong>in</strong> Section 4.5,7


ut will be <strong>in</strong> their turn be superseded by the options explicitly def<strong>in</strong>ed when thepackage is loaded.161 \InputIfFileExists{envlab.cfg}{%162 \typeout{Load<strong>in</strong>g configuration file envlab.cfg}}{%163 \typeout{Configuration file envlab.cfg is not found}}Now let us discuss the structure of the configuration file. We want it to conta<strong>in</strong>default options, <strong>and</strong> therefore to be loaded before the\ProcessOptionscomm<strong>and</strong>.On the other h<strong>and</strong> we want it to conta<strong>in</strong> some def<strong>in</strong>itions that supersede the ones<strong>in</strong> this package. The hook \AtEndOf<strong>Package</strong> helps to do this: we will just delayall def<strong>in</strong>itions until later.OK, let’s construct an example of envlab.cfg file. The comm<strong>and</strong>s here essentiallyrepeat Section 4.5, but we want to be foolproof...164 〈/package〉165 〈∗cfg〉166 %%167 %% The default options go here168 %%169 \ExecuteOptions{bus<strong>in</strong>essenvelope,rotateenvelopes,centerenvelopes}170 \ExecuteOptions{pr<strong>in</strong>tbarcodes,capaddress}171 \ExecuteOptions{nopswait,pr<strong>in</strong>treturnaddress,nopsautotray,nore}172 %%173 \AtEndOf<strong>Package</strong>{\relax % Customization goes here174 }175 〈/cfg〉176 〈∗package〉6 Process<strong>in</strong>g options <strong>and</strong> load<strong>in</strong>g packages177 \ProcessOptions178 \IfFileExists{graphics.sty}{%179 \Require<strong>Package</strong>{graphics}}{%180 \<strong>Package</strong>Warn<strong>in</strong>g{envlab}{%181 You don’t have the graphics package!\MessageBreak182 Probably you will not be able to pr<strong>in</strong>t\MessageBreak183 envelopes sidewise. \MessageBreak}}7 Document layout\@beg<strong>in</strong>labelshook\@beg<strong>in</strong>labelpagehook7.1 Pr<strong>in</strong>ter specific comm<strong>and</strong>sThe comm<strong>and</strong> \@beg<strong>in</strong>labelshook is called at the beg<strong>in</strong>n<strong>in</strong>g of the pr<strong>in</strong>t<strong>in</strong>g ofenvelopes <strong>and</strong> labels. We def<strong>in</strong>e it to be a no-op, but it is possible to <strong>in</strong>troducesome pr<strong>in</strong>ter-specific comm<strong>and</strong>s (like paper change).184 \def\@beg<strong>in</strong>labelshook{\relax}The comm<strong>and</strong> \@beg<strong>in</strong>labelpagehook is like \@beg<strong>in</strong>labelshook, but iscalled at the beg<strong>in</strong>n<strong>in</strong>g of each page of envelopes <strong>and</strong> labels.185 \def\@beg<strong>in</strong>labelpagehook{\relax}8


\AtBeg<strong>in</strong><strong>Labels</strong>\AtBeg<strong>in</strong>LabelPage\g@addto@macroThe hooks\AtBeg<strong>in</strong><strong>Labels</strong><strong>and</strong>\AtBeg<strong>in</strong>LabelPageredef<strong>in</strong>e\@beg<strong>in</strong>labelshook<strong>and</strong> \@beg<strong>in</strong>labelpagehook. They are built like the st<strong>and</strong>ard L A TEX2ε hooks\AtBeg<strong>in</strong>Document,\AtBeg<strong>in</strong>Dvi, etc. In the implementation we use the <strong>in</strong>ternalL A TEX2ε comm<strong>and</strong> \g@addto@macro. In the current (June 1996) L A TEX2ε releaseit is def<strong>in</strong>ed as:\long\def\g@addto@macro#1#2{{%\toks@\exp<strong>and</strong>after{#1#2}%\xdef#1{\the\toks@}}}We quote this def<strong>in</strong>ition <strong>in</strong> case They change Their m<strong>in</strong>ds. . .186 \def\AtBeg<strong>in</strong><strong>Labels</strong>{\g@addto@macro\@beg<strong>in</strong>labelshook}187 \def\AtBeg<strong>in</strong>LabelPage{\g@addto@macro\@beg<strong>in</strong>labelpagehook}\PSwait PostScript pr<strong>in</strong>ters can be switched to the manual feed<strong>in</strong>g mode with the follow<strong>in</strong>gcode by William Slough .188 \def\PSwait{\special{ps: clear grestore @manualfeed 0 0 bop}}The author expla<strong>in</strong>s his code <strong>in</strong> the follow<strong>in</strong>g way:Here is a possible explanation:The clear removes oper<strong>and</strong>s from the PostScript stack, which hasthe effect of revers<strong>in</strong>g some actions from the *previous* bop. Unfortunately,it reverses other important actions too (such as font size), butthe grestore seems to get these back. Then the desired @manualfeed,followed by the “bop” for the beg<strong>in</strong>n<strong>in</strong>g of page. The pair of 0’s areused for bop <strong>and</strong> are completely bogus. However, from what I coulddetect, 0’s are as good as anyth<strong>in</strong>g. The values that DVIPS providesfor bop seem to be related to DVI page numbers.I make no guarantee about the reliability of this solution, but <strong>in</strong>itialtests <strong>in</strong>dicate it will work for my environment.\PSautotray This implements the code by Uri Blumenthal .189 \edef\PSautotray{%190 \special{ps:clear grestore191 statusdict beg<strong>in</strong> false setduplexmode192 /manualfeed true def193 \the\PSEnvelopeTray end 0 0 bop }}The option pswait puts the \PSwait code <strong>in</strong> the beg<strong>in</strong>n<strong>in</strong>g of each page. Theoption \psautotray puts there the \PSautotray code.194 \if@pswait195 \AtBeg<strong>in</strong><strong>Labels</strong>{\PSwait}%196 \else197 \if@psautotray198 \AtBeg<strong>in</strong><strong>Labels</strong>{\PSautotray}%199 \fi200 \fi9


7.2 Some useful counters for labels\c@LabelCountCol These counters store the position of the currently pr<strong>in</strong>ted label:\c@LabelCountRow 201 \newcounter{LabelCountCol}202 \newcounter{LabelCountRow}\c@LabelOffsetCol And these counters provide the offset for the label pr<strong>in</strong>ted on a partially used\c@LabelOffsetRow sheet:203 \newcounter{LabelOffsetCol}204 \newcounter{LabelOffsetRow}205 \setcounter{LabelOffsetCol}{1}206 \setcounter{LabelOffsetRow}{1}\FirstLabel The comm<strong>and</strong> \FirstLabel{〈Row〉}{〈Col〉} sets the counters LabelOffsetRow<strong>and</strong> LabelOffsetCol.\@toaddressfont\@fromaddressfont207 \DeclareRobustComm<strong>and</strong>{\FirstLabel}[2]{%208 \setcounter{LabelOffsetRow}{#1}%209 \setcounter{LabelOffsetCol}{#2}}7.3 FontsWe want the address to be pr<strong>in</strong>ted <strong>in</strong> 12pt sans serif font. The return addresswill be pr<strong>in</strong>ted <strong>in</strong> 10pt normal font.210 \def\@toaddressfont{%211 \ifcase\@ptsize \large\or\normalsize\or\small\fi%212 \sffamily\selectfont}213 \def\@fromaddressfont{%214 \ifcase\@ptsize \normalsize\or\small\or\footnotesize\fi%215 \normalfont}7.4 Return address\returnaddress The st<strong>and</strong>ard letter class def<strong>in</strong>es \returnaddress to be null. This is sensible ifwe are pr<strong>in</strong>t<strong>in</strong>g labels, but not so good if we are pr<strong>in</strong>t<strong>in</strong>g envelopes. Therefore letus redef<strong>in</strong>e it:216 \def\returnaddress{\fromaddress}7.5 Marg<strong>in</strong>s, page styles, etc.\startlabels The comm<strong>and</strong> \startlabels is the <strong>in</strong>ternal comm<strong>and</strong> that prepares the paper forlabels or envelopes, resets the <strong>in</strong>ternal counters <strong>and</strong> calls \@beg<strong>in</strong>labelshook.217 \def\startlabels{%218 \clearpage%219 \pagestyle{empty}%220 \setlength{\topmarg<strong>in</strong>}{-1.0<strong>in</strong>}%221 \if@envelope%222 \addtolength{\topmarg<strong>in</strong>}{\EnvelopeTopMarg<strong>in</strong>}%223 \else \addtolength{\topmarg<strong>in</strong>}{\LabelTopMarg<strong>in</strong>}%10


224 \fi%225 \setlength{\headheight}{0pt}%226 \setlength{\headsep}{0pt}%227 \setlength{\footskip}{0pt}%228 \setlength{\textheight}{200<strong>in</strong>}%229 \setlength\paperheight{\textheight}%230 \global\vsize=200<strong>in</strong>\relax%231 \addtolength{\textheight}{-\topmarg<strong>in</strong>}%232 \addtolength{\textheight}{-1.0<strong>in</strong>}%233 \setlength{\oddsidemarg<strong>in</strong>}{-1.0<strong>in</strong>}%234 \if@envelope\relax%235 \else%236 \addtolength{\oddsidemarg<strong>in</strong>}{\LabelLeftMarg<strong>in</strong>}%237 \fi%238 \setlength{\evensidemarg<strong>in</strong>}{\oddsidemarg<strong>in</strong>}%239 \setlength{\textwidth}{20<strong>in</strong>}%240 \hsize=20<strong>in</strong>%241 \basel<strong>in</strong>eskip=0pt%242 \l<strong>in</strong>eskip=0pt%243 \par<strong>in</strong>dent=0pt%244 \if@envelopeNow we can calculate \EnvelopeLeftMarg<strong>in</strong>245 \ifcase\the\@envelopeposition%246 \setlength{\EnvelopeLeftMarg<strong>in</strong>}{\paperwidth}%247 \if@rotateenvelopes%248 \addtolength{\EnvelopeLeftMarg<strong>in</strong>}{-\EnvelopeHeight}%249 \else%250 \addtolength{\EnvelopeLeftMarg<strong>in</strong>}{-\EnvelopeWidth}%251 \fi%252 \setlength{\EnvelopeLeftMarg<strong>in</strong>}{0.5\EnvelopeLeftMarg<strong>in</strong>}%253 \or%254 \setlength{\EnvelopeLeftMarg<strong>in</strong>}{0pt}%255 \or%256 \setlength{\EnvelopeLeftMarg<strong>in</strong>}{\paperwidth}%257 \if@rotateenvelopes%258 \addtolength{\EnvelopeLeftMarg<strong>in</strong>}{-\EnvelopeHeight}%259 \else%260 \addtolength{\EnvelopeLeftMarg<strong>in</strong>}{-\EnvelopeWidth}%261 \fi%262 \else%263 \relax%264 \fi%265 \else%Initializ<strong>in</strong>g labels counters...266 \setcounter{LabelCountCol}{\theLabelOffsetCol}%267 \setcounter{LabelCountRow}{\theLabelOffsetRow}%268 \ifnum\theLabelOffsetRow>1%269 \null%11


270 \loop \vspace*{\LabelHeight}%271 \addtocounter{LabelOffsetRow}{-1} \ifnum\theLabelOffsetRow>1%272 \repeat%273 \fi%274 \ifnum\theLabelOffsetCol>1%275 \loop \hspace*{\LabelWidth}\nol<strong>in</strong>ebreak%276 \addtocounter{LabelOffsetCol}{-1} \ifnum\theLabelOffsetCol>1%277 \repeat%278 \fi%279 \nopagebreak%280 \fi%281 \spaceskip0pt\relax%282 \xspaceskip 0pt\relax%283 \clubpenalty=0%284 \widowpenalty=0%285 \raggedbottom%286 \sloppy%287 \setlength\hfuzz{5<strong>in</strong>}%288 \setlength\vfuzz{5<strong>in</strong>}%289 \ignorespaces%290 \@beg<strong>in</strong>labelshook%291 \@beg<strong>in</strong>labelpagehook%292 \nopagebreak}%\Pr<strong>in</strong>tReturnAddress\Pr<strong>in</strong>tAddress7.6 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of the addressesThis macro uses the text as an argument <strong>and</strong> pr<strong>in</strong>ts it accord<strong>in</strong>g to the conventions.293 \newcomm<strong>and</strong>{\Pr<strong>in</strong>tReturnAddress}[1]{%294 \vspace*{\FromAddressTopMarg<strong>in</strong>}295 \null\hspace{\FromAddressLeftMarg<strong>in</strong>}296 \parbox[t][\FromAddressHeight]{\FromAddressWidth}%297 {\@fromaddressfont \l<strong>in</strong>eskip=1pt298 \if@pr<strong>in</strong>treturnaddress #1\else\relax\fi}}This macro works like \Pr<strong>in</strong>tReturnAddress, with several important differences:it pr<strong>in</strong>ts barcodes if necessary <strong>and</strong> capitalizes the address.299 \newcomm<strong>and</strong>{\Pr<strong>in</strong>tAddress}[1]{%300 \vspace*{\ToAddressTopMarg<strong>in</strong>}301 \leavevmode302 \null\hspace*{\ToAddressLeftMarg<strong>in</strong>}303 \parbox[t]{\ToAddressWidth}{%304 \l<strong>in</strong>eskip=1pt305 \if@barcodes \Pr<strong>in</strong>tBarCode{#1} \fi306 \@toaddressfont307 \if@capitalizeaddress \@make@capitalize{#1} \else #1 \fi}}7.7 Label setup\Pr<strong>in</strong>tLabel This macro pr<strong>in</strong>ts a label <strong>in</strong> a parbox12


308 \newcomm<strong>and</strong>{\Pr<strong>in</strong>tLabel}[1]{%309 \parbox[t][\LabelHeight]{\LabelWidth}{%310 \Pr<strong>in</strong>tAddress{#1}}}\Pr<strong>in</strong>tBigLabel This macro makes a m<strong>in</strong>ipage with addresses on it, similarly to \Pr<strong>in</strong>tEnvelopebelow.311 \newcomm<strong>and</strong>{\Pr<strong>in</strong>tBigLabel}[2]{%312 \beg<strong>in</strong>{m<strong>in</strong>ipage}[t][\LabelHeight]{\LabelWidth}%313 \basel<strong>in</strong>eskip=0pt%314 \l<strong>in</strong>eskip=0pt%315 \par<strong>in</strong>dent=0pt%316 \beg<strong>in</strong>{center}%317 \Pr<strong>in</strong>tReturnAddress{#1}\\%318 \rule{\ToAddressWidth}{0.1pt}%319 \Pr<strong>in</strong>tAddress{#2}%320 \end{center}%321 \end{m<strong>in</strong>ipage}}7.8 Envelope setup<strong>Labels</strong> <strong>in</strong>clude one box per label, so their setup is simple. The situation withenvelopes is different: they conta<strong>in</strong> several boxes, <strong>and</strong> could be rotated, centered,etc.\Pr<strong>in</strong>tEnvelope This macro makes a m<strong>in</strong>ipage with addresses on it.322 \newcomm<strong>and</strong>{\Pr<strong>in</strong>tEnvelope}[2]{%323 \beg<strong>in</strong>{m<strong>in</strong>ipage}[t][\EnvelopeHeight]{\EnvelopeWidth}%324 \basel<strong>in</strong>eskip=0pt%325 \l<strong>in</strong>eskip=0pt%326 \par<strong>in</strong>dent=0pt%327 \Pr<strong>in</strong>tReturnAddress{#1}\\%328 \beg<strong>in</strong>{center}%329 \Pr<strong>in</strong>tAddress{#2}%330 \end{center}%331 \end{m<strong>in</strong>ipage}}\@Pr<strong>in</strong>tEnvelope The follow<strong>in</strong>g macro checks for rotation:332 \newcomm<strong>and</strong>{\@Pr<strong>in</strong>tEnvelope}[2]{%333 \if@rotateenvelopes\rotatebox{90}{\Pr<strong>in</strong>tEnvelope{#1}{#2}}%334 \else\Pr<strong>in</strong>tEnvelope{#1}{#2}%335 \fi}8 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of envelopes <strong>and</strong> labels8.1 Ma<strong>in</strong> Comm<strong>and</strong>\mlabel Now we are prepared to pr<strong>in</strong>t actual envelopes <strong>and</strong> labels. It is done by the\mlabel comm<strong>and</strong>. It has two forms: for labels <strong>and</strong> envelopes.13


336 \renewcomm<strong>and</strong>{\mlabel}[2]{\ignorespaces%337 \spaceskip 0pt\relax%338 \xspaceskip 0pt\relax%8.2 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of one envelope339 \if@envelope%340 \leavevmode%341 \hspace*{\EnvelopeLeftMarg<strong>in</strong>}%342 \@Pr<strong>in</strong>tEnvelope{#1}{#2}%343 \clearpage%344 \@beg<strong>in</strong>labelpagehook%8.3 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of one label345 \else%346 \ignorespaces%347 \ifnum\theLabelCountCol>\theLabelMaxCol%348 \\\nopagebreak%349 \stepcounter{LabelCountRow}%350 \setcounter{LabelCountCol}{1}%351 \fi%352 \ifnum\theLabelCountRow>\theLabelMaxRow%353 \vfill\eject\@beg<strong>in</strong>labelpagehook%354 \setcounter{LabelCountRow}{1}%355 \setcounter{LabelCountCol}{1}%356 \fi%357 \if@biglabel%358 \Pr<strong>in</strong>tBigLabel{#1}{#2}%359 \else%360 \Pr<strong>in</strong>tLabel{#2}%361 \fi%362 \ignorespaces\nol<strong>in</strong>ebreak%363 \stepcounter{LabelCountCol}%364 \fi}%\@numreturnlabels\pr<strong>in</strong>treturnlabels8.4 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> of return labelsWe pr<strong>in</strong>t only mail<strong>in</strong>g addresses on labels. The user is supposed to have prepr<strong>in</strong>tedreturn labels. Here we describe a utility for pr<strong>in</strong>t<strong>in</strong>g them. This utility should beused <strong>in</strong> a separate document.The counter \@numreturnlabels stores the number of return labels to bepr<strong>in</strong>ted. Note that it is a TEX counter, not a L A TEX one.365 \newcount\@numreturnlabelsThis macro has two parameters: the number of labels to be pr<strong>in</strong>ted <strong>and</strong> thetext that is pr<strong>in</strong>ted. It is the same on all labels.366 \newcomm<strong>and</strong>{\pr<strong>in</strong>treturnlabels}[2]{%367 \@numreturnlabels=#1368 \def\@toaddressfont{\@fromaddressfont}14


369 \@capitalizeaddressfalse370 \@barcodesfalse371 \startlabels372 \loop \mlabel{\relax}{#2} \advance\@numreturnlabels by -1373 \ifnum\@numreturnlabels>0\repeat}9 Barcodes\Pr<strong>in</strong>tBarCode9.1 Ma<strong>in</strong> comm<strong>and</strong>The USPS Postnet codes are pr<strong>in</strong>ted accord<strong>in</strong>gly to the specifications Ref. [3]. Thescann<strong>in</strong>g algorithm is stolen from David Carlisle’s enumerate package [1].First, we extract barcodes by the comm<strong>and</strong>\@extractbarcode. Then we pr<strong>in</strong>tthem by \@pr<strong>in</strong>tbarcode.374 \newcomm<strong>and</strong>{\Pr<strong>in</strong>tBarCode}[1]{%375 \@extractbarcode{#1}376 \@pr<strong>in</strong>tbarcode}\@zipcode\@zipcodesum\@zipcodefound9.2 Extraction of barcodesWe def<strong>in</strong>e zipcode as a sequence of digits (0–9) that:• Has no characters other than digits <strong>and</strong> dashes (-) <strong>in</strong>side it• Has no bracketed groups <strong>in</strong>side it <strong>and</strong> is not bracketed itself• Is the last <strong>in</strong> the address field unless \if@alwaysbarcodes=trueWe pr<strong>in</strong>t this sequence plus the control character. The latter is def<strong>in</strong>ed asm<strong>in</strong>us sum of digits of the zip code modulo 10 (that is, the complement of thesum of digits to a multiple of 10).First, some <strong>in</strong>ternal registers. The token list\@zipcode conta<strong>in</strong>s barcode foundso far. The register \@zipcodesum first conta<strong>in</strong>s the sum of digits of the barcode,<strong>and</strong> then the control character. The switch \@zipcodefound shows whether wefound zip code so far.377 \newtoks\@zipcode378 \newcount\@zipcodesum379 \newif\if@zipcodefoundThere are two modes for gobbl<strong>in</strong>g tokens:State A: We are outside a potential zipcode sequence (\if@zipcodefound=false)State B: We are <strong>in</strong>side a potential zipcode sequence (\if@zipcodefound=true)\@endaddress\@f<strong>in</strong>ishzipcode• If we meet <strong>in</strong> any state the special token \@endaddress, we gobble it <strong>and</strong>f<strong>in</strong>ish the loop.380 \long\def\@f<strong>in</strong>ishzipcode#1{}15


\@firstzipcode\@cont<strong>in</strong>uezipcode• If we meet a number (0–9) <strong>in</strong> state A, we <strong>in</strong>itialize registers, process thetoken <strong>and</strong> go to state B381 \long\def\@firstzipcode#1{%382 \@zipcode{#1}383 \@zipcodesum=#1\relax384 \@zipcodefoundtrue385 \@zipcodeloop}• If we meet a number (0–9) <strong>in</strong> state B, we just process it.386 \long\def\@cont<strong>in</strong>uezipcode#1{%387 \@zipcode=\exp<strong>and</strong>after{\the\@zipcode#1}388 \advance\@zipcodesum by #1389 \@zipcodeloop}\@dashzipcode\@spacezipcode\@abortzipcode• If we meet a dash <strong>in</strong> state B, we gobble it.390 \long\def\@dashzipcode#1{\@zipcodeloop}• If we meet a space <strong>in</strong> any state, we gobble it <strong>and</strong> go to the state A. Thetrick is from Carlisle’s enumerate package.391 \def\@spacezipcode{%392 \@zipcodefoundfalse393 \afterassignment\@zipcodeloop\let\EL@temp= }• If we meet anyth<strong>in</strong>g else <strong>in</strong> any mode, we gobble it <strong>and</strong> go to state A394 \long\def\@abortzipcode#1{%395 \@zipcodefoundfalse396 \@zipcodeloop}\@zipcodeloop This macro is simple. We just put the next token <strong>in</strong>to \EL@temp <strong>and</strong> process\EL@temp it through \@zipcodeloop@.397 \def\@zipcodeloop{\futurelet\EL@temp\@zipcodeloop@}\@zipcodeloop@ This macro performs actual process<strong>in</strong>g...We put the comm<strong>and</strong> that gobbles\EL@tempa the next token <strong>in</strong>to \EL@tempa398 \def\@zipcodeloop@{%399 \ifx \@endaddress\EL@temp \def\EL@tempa{\@f<strong>in</strong>ishzipcode} \else400 \ifx 0\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}401 \else \def\EL@tempa{\@firstzipcode} \fi \else402 \ifx 1\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}403 \else \def\EL@tempa{\@firstzipcode} \fi \else404 \ifx 2\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}405 \else \def\EL@tempa{\@firstzipcode} \fi \else406 \ifx 3\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}407 \else \def\EL@tempa{\@firstzipcode} \fi \else408 \ifx 4\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}409 \else \def\EL@tempa{\@firstzipcode} \fi \else410 \ifx 5\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}16


\@extractbarcode411 \else \def\EL@tempa{\@firstzipcode} \fi \else412 \ifx 6\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}413 \else \def\EL@tempa{\@firstzipcode} \fi \else414 \ifx 7\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}415 \else \def\EL@tempa{\@firstzipcode} \fi \else416 \ifx 8\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}417 \else \def\EL@tempa{\@firstzipcode} \fi \else418 \ifx 9\EL@temp \if@zipcodefound \def\EL@tempa{\@cont<strong>in</strong>uezipcode}419 \else \def\EL@tempa{\@firstzipcode} \fi \else420 \ifx -\EL@temp \if@zipcodefound \def\EL@tempa{\@dashzipcode}421 \else \def\EL@tempa{\@abortzipcode} \fi \else422 \ifx \@sptoken\EL@temp \def\EL@tempa{\@spacezipcode} \else423 \def\EL@tempa{\@abortzipcode}424 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi425 \EL@tempa}The comm<strong>and</strong> \@extractbarcode puts barcode <strong>in</strong>to the \@zipcode, <strong>and</strong> calculatesthe control character (10 m<strong>in</strong>us sum of the digits of the barcode).426 \long\def\@extractbarcode#1{%427 \@zipcodefoundfalse428 \@zipcodeloop#1\@endaddress429 \if@alwaysbarcodes \@zipcodefoundtrue \fi430 \if@zipcodefound431 \ifnum\the\@zipcodesum>0432 \loop \advance \@zipcodesum by -10 \ifnum\the\@zipcodesum>0433 \repeat434 \fi435 \multiply\@zipcodesum by -1436 \fi}\@barcodewidth\@barcodeLheight\@barcodeSheight\@barcodeskip\@pr<strong>in</strong>tonezip\@pr<strong>in</strong>tbarcode9.3 <strong>Pr<strong>in</strong>t<strong>in</strong>g</strong> barcodesFirst, some lengths. “L” <strong>and</strong> “S” below refer to “long” <strong>and</strong> “short” bars correspond<strong>in</strong>gly.437 \newlength{\@barcodewidth}438 \newlength{\@barcodeLheight}439 \newlength{\@barcodeSheight}440 \newlength{\@barcodeskip}441 \setlength{\@barcodewidth}{0.020<strong>in</strong>}442 \setlength{\@barcodeLheight}{0.125<strong>in</strong>}443 \setlength{\@barcodeSheight}{0.050<strong>in</strong>}444 \setlength{\@barcodeskip}{0.026<strong>in</strong>}\@barL The follow<strong>in</strong>g macros pr<strong>in</strong>t long <strong>and</strong> short bars.\@barS 445 \DeclareRobustComm<strong>and</strong>{\@barL}{%446 \rule{\@barcodewidth}{\@barcodeLheight}\hspace{\@barcodeskip}}447 \DeclareRobustComm<strong>and</strong>{\@barS}{%448 \rule{\@barcodewidth}{\@barcodeSheight}\hspace{\@barcodeskip}}The scann<strong>in</strong>g of \@zipcode is simpler than the scann<strong>in</strong>g of the address: the17


only tokens we can meet are digits. Well, we will add an end mark<strong>in</strong>g token tothe list. Let it be the letter “S” (from “Stop”).449 \def\@pr<strong>in</strong>tonezip#1{%450 \ifx1#1\@barS\@barS\@barS\@barL\@barL\else451 \ifx2#1\@barS\@barS\@barL\@barS\@barL\else452 \ifx3#1\@barS\@barS\@barL\@barL\@barS\else453 \ifx4#1\@barS\@barL\@barS\@barS\@barL\else454 \ifx5#1\@barS\@barL\@barS\@barL\@barS\else455 \ifx6#1\@barS\@barL\@barL\@barS\@barS\else456 \ifx7#1\@barL\@barS\@barS\@barS\@barL\else457 \ifx8#1\@barL\@barS\@barS\@barL\@barS\else458 \ifx9#1\@barL\@barS\@barL\@barS\@barS\else459 \ifx0#1\@barL\@barL\@barS\@barS\@barS\else460 \ifx S#1\def\EL@tempa{\relax}%461 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%462 \EL@tempa}463 \def\@pr<strong>in</strong>tbarcode{%464 \if@zipcodefound465 \mbox{%466 \@barL%467 \def\EL@tempa{\@pr<strong>in</strong>tonezip}%468 \exp<strong>and</strong>after\EL@tempa\the\@zipcode S%469 \def\EL@tempa{\@pr<strong>in</strong>tonezip}%470 \exp<strong>and</strong>after\EL@tempa\the\@zipcodesum S%471 \@barL}472 \\[1ex]473 \fi}10 CapitalizationThese macros process the address (actually, any str<strong>in</strong>g) accord<strong>in</strong>g to the USPSrecommendations. Specifically, they:• Strip dots (.) <strong>and</strong> commas (,) from the address unless they are enclosed <strong>in</strong>brackets• Make all letters uppercase• Add 1pt space between letters• Add 1em space between words\@addr@capAn <strong>in</strong>terest<strong>in</strong>g question is whether we should de-accent accented letters. USPSsays noth<strong>in</strong>g about it. In the present version accents are not stripped. Howeverdue to the scann<strong>in</strong>g algorithm they should be enclosed by brackets, like this:{\u S}<strong>and</strong>or {\c C}edi.We store the capitalized address <strong>in</strong> the token list \@addr@cap.474 \newtoks\@addr@cap18


\@f<strong>in</strong>ishaddrcap\@dotcommaaddrcap\@newl<strong>in</strong>eaddrcap\@bgroupaddrcap\@spaceaddrcap\@otheraddrcap\@addrcaploop\@addrcaploop@\@make@capitalizeThe follow<strong>in</strong>g macros process the tokens one by one.If we meet the special token \@endaddress, we gobble it <strong>and</strong> stop.475 \long\def\@f<strong>in</strong>ishaddrcap#1{}If we meet comma or dot, we gobble it <strong>and</strong> do not stop. This macro is alsouseful for gobbl<strong>in</strong>g L A TEX2ε letter comm<strong>and</strong>s like \voidb@x <strong>and</strong> \unhbox.476 \long\def\@dotcommaaddrcap#1{%477 \@addrcaploop}If we meet \\, we add it to the list478 \long\def\@newl<strong>in</strong>eaddrcap#1{%479 \@addr@cap=\exp<strong>and</strong>after{\the\@addr@cap #1}480 \@addrcaploop}If we meet \bgroup, we add it to the list the complete group (uppercase)481 \long\def\@bgroupaddrcap#1{%482 \@addr@cap=\exp<strong>and</strong>after{\the\@addr@cap {\MakeUppercase{#1}}}483 \@addrcaploop}If we meet a space we gobble it (oh-oh) <strong>and</strong> add it to the list.484 \def\@spaceaddrcap{%485 \@addr@cap=\exp<strong>and</strong>after{\the\@addr@cap\hspace{0.6em}}486 \afterassignment\@addrcaploop\let\EL@temp= }And if we meet anyth<strong>in</strong>g else, we make it uppercase <strong>and</strong> add to the list487 \def\@otheraddrcap#1{%488 \@addr@cap=\exp<strong>and</strong>after{\the\@addr@cap%489 \MakeUppercase{#1}\kern1pt\relax}490 \@addrcaploop}This macro is simple. We just put the next token <strong>in</strong>to \EL@temp <strong>and</strong> processit through \@addrcaploop@.491 \def\@addrcaploop{\futurelet\EL@temp\@addrcaploop@}This macro performs actual process<strong>in</strong>g.. .492 \def\@addrcaploop@{%493 \ifx \@endaddress\EL@temp \def\EL@tempa{\@f<strong>in</strong>ishaddrcap} \else494 \ifx .\EL@temp \def\EL@tempa{\@dotcommaaddrcap} \else495 \ifx ,\EL@temp \def\EL@tempa{\@dotcommaaddrcap} \else496 \ifx \voidb@x\EL@temp \def\EL@tempa{\@dotcommaaddrcap} \else497 \ifx \unhbox\EL@temp \def\EL@tempa{\@dotcommaaddrcap} \else498 \ifx \\\EL@temp \def\EL@tempa{\@newl<strong>in</strong>eaddrcap} \else499 \ifx \bgroup\EL@temp \def\EL@tempa{\@bgroupaddrcap} \else500 \ifx \@sptoken\EL@temp \def\EL@tempa{\@spaceaddrcap} \else501 \def\EL@tempa{\@otheraddrcap}502 \fi\fi\fi\fi\fi\fi\fi\fi503 \EL@tempa}504 \long\def\@make@capitalize#1{%505 \@addr@cap={\relax}506 \@addrcaploop#1\@endaddress507 \the\@addr@cap}19


11 Games with .aux file\@@mlabelThe comm<strong>and</strong>s described <strong>in</strong> this section write someth<strong>in</strong>g to the .aux file, <strong>and</strong> thuschange the way <strong>EnvLab</strong> treats the labels <strong>and</strong> envelopes. S<strong>in</strong>ce the action is delayedtill the .aux file is processed, these comm<strong>and</strong>s affect only the labels automaticallyextracted from the letter environment, <strong>and</strong> do not affect the labels explicitlydef<strong>in</strong>ed by the \mlabel comm<strong>and</strong>s <strong>in</strong> the ma<strong>in</strong> file.The macro \@@mlabel stores the status of the \@mlabel as determ<strong>in</strong>ed by\makelabels. It is a no-op at the start. If \makelabels redef<strong>in</strong>es \@mlabel,we catch it through the \AtEndDocument hook. Note that s<strong>in</strong>ce \makelabel isallowed only <strong>in</strong> the preamble, we are not <strong>in</strong> danger of redef<strong>in</strong><strong>in</strong>g comm<strong>and</strong>s tooearly.508 \let\@@mlabel=\@gobbletwo509 \AtEndDocument{\let\@@mlabel=\@mlabel}The next four comm<strong>and</strong>s redef<strong>in</strong>e \@mlabel to suppress or resume pr<strong>in</strong>t<strong>in</strong>gmail<strong>in</strong>g labels.\suppresslabels This comm<strong>and</strong> suppress pr<strong>in</strong>t<strong>in</strong>g labels <strong>and</strong> envelopes until it is resumed by\resumelabels or similar comm<strong>and</strong>s.510 \def\suppresslabels{\if@filesw\immediate\write\@auxout{%511 \str<strong>in</strong>g\@suppresslabels}\fi}\@suppresslabels This is the <strong>in</strong>ternal comm<strong>and</strong> that performs the actual process<strong>in</strong>g.\resumelabels\@resumelabels512 \def\@suppresslabels{\let\@mlabel=\@gobbletwo}These comm<strong>and</strong>s resume pr<strong>in</strong>t<strong>in</strong>g labels <strong>and</strong> envelopes if it was suppressed by\suppresslabels or similar comm<strong>and</strong>s.513 \def\resumelabels{\if@filesw\immediate\write\@auxout{%514 \str<strong>in</strong>g\@resumelabels}\fi}515 \def\@resumelabels{\let\@mlabel=\@@mlabel}\suppressonelabel\@suppressonelabel\@old@mlabelThese comm<strong>and</strong>s suppress pr<strong>in</strong>t<strong>in</strong>g of one label or envelope.\@old@mlabel is used to store the system state.516 \def\suppressonelabel{\if@filesw\immediate\write\@auxout{%517 \str<strong>in</strong>g\@suppressonelabel}\fi}518 \def\@suppressonelabel{\let\@old@mlabel=\@mlabel%519 \def\@mlabel{%520 \let\@mlabel=\@old@mlabel%521 \@gobbletwo}}The macro\pr<strong>in</strong>tonelabel\@pr<strong>in</strong>tonelabelThese comm<strong>and</strong>s resume pr<strong>in</strong>t<strong>in</strong>g for one label or envelope The macro\@old@mlabelis used to store the system state.522 \def\pr<strong>in</strong>tonelabel{\if@filesw\immediate\write\@auxout{%523 \str<strong>in</strong>g\@pr<strong>in</strong>tonelabel}\fi}524 \def\@pr<strong>in</strong>tonelabel{\let\@old@mlabel=\@mlabel%525 \def\@mlabel{%526 \let\@mlabel=\@old@mlabel%527 \@@mlabel}}20


\ChangeEnvelope\@ChangeEnvelope\@ChangeEnvelopeStarThis macro writes \@SetEnvelope to the .aux file. It has two forms: starred <strong>and</strong><strong>and</strong> unstarred. In the unstarred mode it also writes \@startlabels to the .auxfile. In the unstarred form it does not. S<strong>in</strong>ce we want to treat both stars <strong>and</strong>optional arguments, we <strong>in</strong>troduce two <strong>in</strong>ternal comm<strong>and</strong>s that can be <strong>in</strong>voked bythe ma<strong>in</strong> macro.528 \def\ChangeEnvelope{\@ifstar{\@ChangeEnvelopeStar}{\@ChangeEnvelope}}529 \newcomm<strong>and</strong>\@ChangeEnvelopeStar[3][0pt]{%530 \if@filesw\immediate\write\@auxout{%531 \str<strong>in</strong>g\@SetEnvelope[#1]{#2}{#3}}%532 \fi}533 \newcomm<strong>and</strong>\@ChangeEnvelope[3][0pt]{%534 \if@filesw\immediate\write\@auxout{%535 \str<strong>in</strong>g\@SetEnvelope[#1]{#2}{#3}}536 \immediate\write\@auxout{\str<strong>in</strong>g\@startlabels}537 \fi}\@SetEnvelope We def<strong>in</strong>e this comm<strong>and</strong> as no-op at beg<strong>in</strong>n<strong>in</strong>g, <strong>and</strong> then redef<strong>in</strong>e it before read<strong>in</strong>g.aux file.\ChangeLabel\@ChangeLabel\@ChangeLabelStar538 \def\@SetEnvelope[#1]#2#3{}539 \AtEndDocument{\let\@SetEnvelope=\SetEnvelope}This macro writes \@SetLabel to the .aux file. It has two forms: starred <strong>and</strong> <strong>and</strong>unstarred. In the unstarred mode it also writes \@startlabels to the .aux file.In the unstarred form it does not. S<strong>in</strong>ce we want to treat both stars <strong>and</strong> optionalarguments, we <strong>in</strong>troduce two <strong>in</strong>ternal comm<strong>and</strong>s that can be <strong>in</strong>voked by the ma<strong>in</strong>macro.540 \def\ChangeLabel{\@ifstar{\@ChangeLabelStar}{\@ChangeLabel}}541 \newcomm<strong>and</strong>\@ChangeLabelStar[7]{%542 \if@filesw\immediate\write\@auxout{%543 \str<strong>in</strong>g\@SetLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%544 \fi}545 \newcomm<strong>and</strong>\@ChangeLabel[7]{%546 \if@filesw\immediate\write\@auxout{%547 \str<strong>in</strong>g\@SetLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}548 \immediate\write\@auxout{\str<strong>in</strong>g\@startlabels}549 \fi}\@SetLabel We def<strong>in</strong>e this comm<strong>and</strong> as no-op at beg<strong>in</strong>n<strong>in</strong>g, <strong>and</strong> then redef<strong>in</strong>e it before read<strong>in</strong>g.aux file.550 \def\@SetLabel#1#2#3#4#5#6#7{}551 \AtEndDocument{\let\@SetLabel=\SetLabel}\ChangeBigLabel\@ChangeBigLabel\@ChangeBigLabelStarThis macro writes \@SetBigLabel to the .aux file. It has two forms: starred <strong>and</strong><strong>and</strong> unstarred. In the unstarred mode it also writes \@startlabels to the .auxfile. In the unstarred form it does not. S<strong>in</strong>ce we want to treat both stars <strong>and</strong>optional arguments, we <strong>in</strong>troduce two <strong>in</strong>ternal comm<strong>and</strong>s that can be <strong>in</strong>voked bythe ma<strong>in</strong> macro.552 \def\ChangeBigLabel{\@ifstar{\@ChangeBigLabelStar}{\@ChangeBigLabel}}21


553 \newcomm<strong>and</strong>\@ChangeBigLabelStar[7]{%554 \if@filesw\immediate\write\@auxout{%555 \str<strong>in</strong>g\@SetBigLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%556 \fi}557 \newcomm<strong>and</strong>\@ChangeBigLabel[7]{%558 \if@filesw\immediate\write\@auxout{%559 \str<strong>in</strong>g\@SetBigLabel{#1}{#2}{#3}{#4}{#5}{#6}{#7}}560 \immediate\write\@auxout{\str<strong>in</strong>g\@startlabels}561 \fi}\@SetLabel We def<strong>in</strong>e this comm<strong>and</strong> as no-op at beg<strong>in</strong>n<strong>in</strong>g, <strong>and</strong> then redef<strong>in</strong>e it before read<strong>in</strong>g.aux file.562 \def\@SetBigLabel#1#2#3#4#5#6#7{}563 \AtEndDocument{\let\@SetBigLabel=\SetBigLabel}12 Reimplementation of the \open<strong>in</strong>g comm<strong>and</strong>\reSome people like to put below the address <strong>in</strong>formation likeRe: our recent talkA way to do this is to <strong>in</strong>clude it <strong>in</strong> the address like this:\beg<strong>in</strong>{letter}{%Dr.~Aust<strong>in</strong> Tankel\\Some University\\Anytown, Pa 12345\\[1ex]Re: Our recent talk}\open<strong>in</strong>g{Dear Aust<strong>in</strong>:}However, this additional <strong>in</strong>fo will be put <strong>in</strong> the mail<strong>in</strong>g label, which is wrong. Herewe describe a macro that works like this:\beg<strong>in</strong>{letter}{%Dr.~Aust<strong>in</strong> Tankel\\Some University\\Anytown, Pa 12345}\re{Our recent talk}\open<strong>in</strong>g{Dear Aust<strong>in</strong>:}Now, the implementation. First, lets us check whether the option re is chosen(otherwise we don’t bother to redef<strong>in</strong>e the comm<strong>and</strong>s):564 \if@EL@redef<strong>in</strong>e@open<strong>in</strong>g\re\recontententsThe comm<strong>and</strong> \re just def<strong>in</strong>es \recontents. Also, we <strong>in</strong>itialize \recontents tobe <strong>in</strong>itially empty565 \newcomm<strong>and</strong>*{\re}[1]{\def\recontents{#1}}%22


\ReName By default it is just pla<strong>in</strong> style “Re: ” (note the space!)566 \def\ReName{Re: }%\open<strong>in</strong>g Now we redef<strong>in</strong>e the st<strong>and</strong>ard \open<strong>in</strong>g comm<strong>and</strong> to <strong>in</strong>clude the \re <strong>in</strong>fo. Hereis the quote from the st<strong>and</strong>ard letter class [2]:Text is begun with the \open<strong>in</strong>g comm<strong>and</strong>, whose argument generatesthe salutation, as <strong>in</strong>\open<strong>in</strong>g{Dear Henry,}This should produce everyth<strong>in</strong>g up to <strong>and</strong> <strong>in</strong>clud<strong>in</strong>g the ‘Dear Henry,’<strong>and</strong> a\par comm<strong>and</strong> that follows. S<strong>in</strong>ce there’s a\vfil at the bottomof every page, it can add vertical fill to position a short letter. It shoulduse the follow<strong>in</strong>g comm<strong>and</strong>s:• \toname : name part of ‘to’ address. Will be one l<strong>in</strong>e long.• \toaddress : address part of ‘to’ address. The l<strong>in</strong>es separatedby \\.• \fromname : name of sender.• \fromaddress : argument of current \address declaration– nullif none. Should use st<strong>and</strong>ard <strong>in</strong>stitutional address if null.• \fromlocation : argument of current \location declaration–null if none.• \telephonenum : argument of current \telephone declaration–null if none.We just \ReName <strong>and</strong> \recontents here. . .567 \renewcomm<strong>and</strong>*{\open<strong>in</strong>g}[1]{\ifx\@empty\fromaddress568 \thispagestyle{firstpage}%569 {\raggedleft\@date\par}%570 \else % home address571 \thispagestyle{empty}%572 {\raggedleft\beg<strong>in</strong>{tabular}{l}\ignorespaces573 \fromaddress \\*[2\parskip]%574 \@date \end{tabular}\par}%575 \fi576 \vspace{2\parskip}%577 {\raggedright \toname \\ \toaddress \par}%578 \ifx\@empty\recontents\relax579 \else580 {\raggedright \ReName \recontents \par}%581 \fi582 \vspace{2\parskip}%583 #1\par\nobreak}%Now we close \if@EL@redef<strong>in</strong>e@open<strong>in</strong>g:584 \fiAnd the last l<strong>in</strong>e:585 〈/package〉23


References[1] David Carlisle. The enumerate package. CTAN, v2.02 edition, January 1994.[2] Leslie Lamport, Frank Mittelbach, <strong>and</strong> Ra<strong>in</strong>er Schöpf. St<strong>and</strong>ard letter documentclass for L A TEX version 2e. CTAN, 199c.[3] USPS. Design<strong>in</strong>g Bus<strong>in</strong>ess Letter Mail (Pub 25), August 1995.24


Change Historyv0.9General: Beta version . . . . . . . . . 1v0.91General: Added new option—alwaysbarcodes . . . . . . . . . . . 1v0.92General: Added \IfFileExistswhen load<strong>in</strong>g packages . . . . . . 8v1.0General: First released version . . . 1v1.1\@fromaddressfont: Fixeddocumentation about\@fromaddressfont . . . . . . . 10General: Added default options:nopswait, pr<strong>in</strong>treturnaddress. . . . . . . . . . . . . . . . . . . . . . . . 7Added implementation of thepsautotray option . . . . . . . . . 9Added implementation of thepswait option . . . . . . . . . . . . . 9Added new options: pr<strong>in</strong>treturnaddress,nopr<strong>in</strong>treturnaddress . . . . . . 7Added new options: pswait,nopswait . . . . . . . . . . . . . . . . 7Fixed typo <strong>in</strong> bus<strong>in</strong>essenvelopeoption . . . . . . . . . . . . . . . . . . 7Fixed typos <strong>in</strong> elold.<strong>in</strong>s . . . . . 1Introduced new comm<strong>and</strong>\@beg<strong>in</strong>labelpagehook . . . . . . 8Moved \PSwait code to\AtBeg<strong>in</strong>LabelPage . . . . . . . . 9Moved \PSwait code to\AtBeg<strong>in</strong><strong>Labels</strong> . . . . . . . . . . . 9Replaced \@pr<strong>in</strong>tpreamble with\@beg<strong>in</strong>labelshook . . . . . . . . 8Updated User Guide . . . . . . . . 1\AtBeg<strong>in</strong>LabelPage: Introduced\AtBeg<strong>in</strong>LabelPage . . . . . . . . 9\AtBeg<strong>in</strong><strong>Labels</strong>: Made\AtBeg<strong>in</strong><strong>Labels</strong>cumulative . . . . . . . . . . . . . . . 9\FirstLabel: Introduced new comm<strong>and</strong>\FirstLabel . . . . . . . . 10\if@psautotray: Added\if@psautotray. . . . . . . . . . . . . . . . . . . . . . . . 3\if@pswait: Added \if@pswait . . 3\mlabel: Put\@beg<strong>in</strong>labelpagehook<strong>in</strong> the envelope pr<strong>in</strong>t<strong>in</strong>g . . . . . 14Put \@beg<strong>in</strong>labelpagehook <strong>in</strong>the label pr<strong>in</strong>t<strong>in</strong>g . . . . . . . . . 14\PSEnvelopeTray: Added\PSEnvelopeTray . . . . . . . . . . 3\PSwait: Put William Slough’scode <strong>in</strong> a separate macro . . . . . 9v1.2\@pr<strong>in</strong>tonelabel: Changed\mlabel to \@@mlabel <strong>and</strong>deleted the \AtBeg<strong>in</strong>Documenthook . . . . . . . . . . . . . . . . . . 20\@resumelabels: Changed \mlabelto \@@mlabel <strong>and</strong> deleted the\AtBeg<strong>in</strong>Document hook . . . . 20\@suppresslabels: Deleted the\AtBeg<strong>in</strong>Document hook . . . . 20\@suppressonelabel: Deleted the\AtBeg<strong>in</strong>Document hook . . . . 20General: Added \@@mlabel . . . . . 20Added \PSEnvelopeTray to envelopeoptions . . . . . . . . . . . . . 6Added Big <strong>Labels</strong>—thanksto Genick Bar-Meir,meyerson@msi.umn.edu . . . . . . 3Added new option: avery5163biglabel. . . . . . . . . . . . 6Added new option: avery5164biglabel. . . . . . . . . . . . 6Added new option: avery5262label(thanks to UriBlumenthal uri@ibm.net) . . . . 6Added new option: dlenvelope(thanks toJ.P.Jansen@net.HCC.nl). . . . . . . . . . . . . . . . . . . . . . . . 6Added new option: herma4625label(thanks toJ.P.Jansen@net.HCC.nl). . . . . . . . . . . . . . . . . . . . . . . . 6Added new options: psautotray,nopsautotray . . . . . . . . . . . . . 7Added new options: re, nore . . 7Changed \@tempa to \EL@tempato avoid clashes with amsmath 16Changed \@temp to \EL@temp toavoid clashes with amsmath . 1625


Changed envlab.<strong>in</strong>s: made it parallel.. . . . . . . . . . . . . . . . . . . . 1Deleted \global from capitalizationcomm<strong>and</strong>s . . . . . . . . . . . 18Deleted \global from zipcodeextract<strong>in</strong>g comm<strong>and</strong>s . . . . . . 15Updated User Guide . . . . . . . . 1\ChangeBigLabel: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . 21\ChangeEnvelope: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . 21\ChangeLabel: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . 21\envlab@oops: Used\@ifundef<strong>in</strong>ed<strong>in</strong>stead of direct check . . . . . . . 2\if@EL@redef<strong>in</strong>e@open<strong>in</strong>g: Wrotenew comm<strong>and</strong> . . . . . . . . . . . . 4\mlabel: Added pr<strong>in</strong>t<strong>in</strong>g of big labels. . . . . . . . . . . . . . . . . . . 14\open<strong>in</strong>g: Reimplemented st<strong>and</strong>ardcomm<strong>and</strong> \open<strong>in</strong>g . . . . 23\Pr<strong>in</strong>tBigLabel: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . 13\Pr<strong>in</strong>tEnvelope: Added percentsigns . . . . . . . . . . . . . . . . . . 13\Pr<strong>in</strong>tLabel: Added percent signs 12\pr<strong>in</strong>tonelabel: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . 20\PSautotray: Wrote new comm<strong>and</strong> 9\re: Wrote new comm<strong>and</strong> . . . . . 22\recontentents: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . 22\ReName: Wrote new comm<strong>and</strong> . . 23\resumelabels: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . 20\returnaddress: Deleted check for\if@envelope . . . . . . . . . . . . 10\SetBigLabel: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . . 5\SetEnvelope: Added\@biglabelfalse. . . . . . . . . . . . . . . . . . . . . . . . 5\SetLabel: Added\@biglabelfalse. . . . . . . . . . . . . . . . . . . . . . . . 5\startlabels: Added \clearpage 10Added \LabelLeftMarg<strong>in</strong> . . . 10Added percent signs . . . . . . . . 10Moved here calculations for\EnvelopeLeftMarg<strong>in</strong> . . . . . . 10\suppresslabels: Wrote new comm<strong>and</strong>. . . . . . . . . . . . . . . . . . 20\suppressonelabel: Wrote newcomm<strong>and</strong> . . . . . . . . . . . . . . . 2026


IndexNumbers written <strong>in</strong> italic refer to the page where the correspond<strong>in</strong>g entry is described;numbers underl<strong>in</strong>ed refer to the code l<strong>in</strong>e of the def<strong>in</strong>ition; numbers <strong>in</strong>roman refer to the code l<strong>in</strong>es where the entry is used.Symbols\@@mlabel . . . . . 20,508, 509, 515, 527\@ChangeBigLabel . . 552\@ChangeBigLabelStar. . . . . . . . . . . 552\@ChangeEnvelope . . 528\@ChangeEnvelopeStar. . . . . . . . . . . 528\@ChangeLabel . . . . . 540\@ChangeLabelStar . 540\@EL@redef<strong>in</strong>e@open<strong>in</strong>gfalse. . . . . . . . 37, 156\@EL@redef<strong>in</strong>e@open<strong>in</strong>gtrue. . . . . . . . . . . 155\@Pr<strong>in</strong>tEnvelope 332, 342\@SetBigLabel . . . . .. 555, 559, 562, 563\@SetEnvelope . . . . .. . . . 531, 535, 538\@SetLabel . . . . . . .. 543, 547, 550, 562\@abortzipcode . . . .. 16, 394, 421, 423\@addr@cap . . . . 18,474, 479, 482,485, 488, 505, 507\@addrcaploop . . 19,477, 480, 483,486, 490, 491, 506\@addrcaploop@ . . . .. . . . . 19, 491, 492\@alwaysbarcodesfalse. . . . . 35, 144, 146\@alwaysbarcodestrue. . . . . . . . . . . 145\@auxout 510, 513, 516,522, 530, 534,536, 542, 546,548, 554, 558, 560\@barL . . . . . 17, 445,450–459, 466, 471\@barS . 17, 447, 450–459\@barcodeLheight . .. 17, 438, 442, 446\@barcodeSheight . .. 17, 439, 443, 448\@barcodesfalse 144, 370\@barcodeskip . . 17,440, 444, 446, 448\@barcodestrue . . . .. . . . . 34, 143, 145\@barcodewidth . 17,437, 441, 446, 448\@beg<strong>in</strong>labelpagehook. . . . . . 8, 185,187, 291, 344, 353\@beg<strong>in</strong>labelshook .. . 8, 184, 186, 290\@bgroupaddrcap . . .. . . . . 19, 481, 499\@biglabelfalse . . .. . . . . . . 19, 61, 74\@biglabeltrue . . . . 89\@capitalizeaddressfalse. . . . . . . . 148, 369\@capitalizeaddresstrue. . . . . . . . 39, 147\@cont<strong>in</strong>uezipcode .. . . . . 16, 386,400, 402, 404,406, 408, 410,412, 414, 416, 418\@dashzipcode . . . . .. . . . . 16, 390, 420\@date . . . . . . . 569, 574\@dotcommaaddrcap .. . 19, 476, 494–497\@endaddress . . . 15,399, 428, 493, 506\@envelopefalse . 73, 88\@envelopeposition 3,24, 25, 139–142, 245\@envelopetrue . . 17, 60\@extractbarcode . .. . . . . 17, 375, 426\@f<strong>in</strong>ishaddrcap . . .. . . . . 19, 475, 493\@f<strong>in</strong>ishzipcode . . .. . . . . 15, 380, 399\@firstzipcode . . . .. . . . . 16, 381,401, 403, 405,407, 409, 411,413, 415, 417, 419\@fromaddressfont .. . . . 210, 297, 368\@gobbletwo 508, 512, 521\@ifstar . . 528, 540, 552\@ifundef<strong>in</strong>ed . . . . . 15\@make@capitalize .. . . . . 19, 307, 504\@mlabel 509, 512, 515,518–520, 524–526\@newl<strong>in</strong>eaddrcap . .. . . . . 19, 478, 498\@numreturnlabels 14,365, 367, 372, 373\@old@mlabel . . . . . .. . . . 516, 524, 526\@otheraddrcap . . . .. . . . . 19, 487, 501\@pr<strong>in</strong>tbarcode . . . .. . . . . 17, 376, 463\@pr<strong>in</strong>tonelabel . . . 522\@pr<strong>in</strong>tonezip . . . . .. 17, 449, 467, 469\@pr<strong>in</strong>treturnaddressfalse. . . . . . . . . . . 150\@pr<strong>in</strong>treturnaddresstrue. . . . . . . . 23, 149\@psautotrayfalse .. . . . . 29, 151, 154\@psautotraytrue . . 153\@pswaitfalse . . . . .. . . . . 27, 152, 153\@pswaittrue . . . . . . 151\@resumelabels . . . . 51327


\@rotateenvelopesfalse. . . . . . . . . . . 138\@rotateenvelopestrue. . . . . . . . 21, 137\@spaceaddrcap . . . .. . . . . 19, 484, 500\@spacezipcode . . . .. . . . . 16, 391, 422\@startlabels . . . . .. . . . 536, 548, 560\@suppresslabels . .. . . . . . . . 511, 512\@suppressonelabel . 516\@toaddressfont . . .. . . . 210, 306, 368\@zipcode . . . . . 15,377, 382, 387, 468\@zipcodefound . . . . 15\@zipcodefoundfalse. . . . 392, 395, 427\@zipcodefoundtrue .. . . . . . . . 384, 429\@zipcodeloop . . 16,385, 389, 390,393, 396, 397, 428\@zipcodeloop@ . . . .. . . . . 16, 397, 398\@zipcodesum . . . 15,378, 383, 388,431, 432, 435, 470A\AtBeg<strong>in</strong>LabelPage . 186\AtBeg<strong>in</strong><strong>Labels</strong> . . . .. . . . 186, 195, 198C\c@LabelCountCol . . 10\c@LabelCountRow . . 10\c@LabelMaxCol . . . . . 4\c@LabelMaxRow . . . . . 4\c@LabelOffsetCol . 10\c@LabelOffsetRow . 10\ChangeBigLabel . . . 552\ChangeEnvelope . . . 528\ChangeLabel . . . . . . 540E\edef . . . . . . . . . . . . 189\EL@temp . . . . . . 16,393, 397, 399,400, 402, 404,406, 408, 410,412, 414, 416,418, 420, 422,486, 491, 493–500\EL@tempa . . . . . 16,399–423, 425,460, 462, 467–470, 493–501, 503\EnvelopeHeight 4, 41,64, 67, 248, 258, 323\EnvelopeLeftMarg<strong>in</strong>. . . . . . . . . . 4,43, 44, 246, 248,250, 252, 254,256, 258, 260, 341\EnvelopeTopMarg<strong>in</strong> .. . . . 4, 42, 62, 222\EnvelopeWidth 4, 40,63, 68, 250, 260, 323\envlab@ok . . . . . . . . 3\envlab@oops . . . . . . . 3F\FirstLabel . . . . . . . 207\FromAddressHeight .. 5, 54, 67, 99, 296\FromAddressLeftMarg<strong>in</strong>. 5, 53, 66, 98, 295\FromAddressTopMarg<strong>in</strong>. 5, 52, 65, 97, 294\FromAddressWidth .5, 55, 68, 105, 296G\g@addto@macro . . . .. . . . . . 9, 186, 187I\if@alwaysbarcodes .. . . . . . . . 32, 429\if@barcodes . . . 32, 305\if@biglabel . 3, 18, 357\if@capitalizeaddress. . . . . . . . 38, 307\if@EL@redef<strong>in</strong>e@open<strong>in</strong>g. . . . . . . . 36, 564\if@envelope . 3, 16,221, 234, 244, 339\if@filesw . . . . . . .. 510, 513, 516,522, 530, 534,542, 546, 554, 558\if@pr<strong>in</strong>treturnaddress. . . . . . . 3, 22, 298\if@psautotray . 26, 197\if@pswait . . . . 26, 194\if@rotateenvelopes3, 20, 247, 257, 333\if@zipcodefound 379,400, 402, 404,406, 408, 410,412, 414, 416,418, 420, 430, 464\IfFileExists . . . . . 178\immediate . . . . . . .. 510, 513, 516,522, 530, 534,536, 542, 546,548, 554, 558, 560L\LabelHeight 4, 46, 76,91, 99, 270, 309, 312\LabelLeftMarg<strong>in</strong> . .. 4, 48, 78, 93, 236\LabelRightMarg<strong>in</strong> 4,49, 79, 86, 94, 104\LabelTopMarg<strong>in</strong> . . .. 4, 47, 77, 92, 223\LabelWidth . . . . . . .4, 45, 75, 84, 90,102, 275, 309, 312M\mlabel . . . . . . 336, 372O\open<strong>in</strong>g . . . . . . . . . 567P\<strong>Package</strong>Warn<strong>in</strong>g . . . 180\parskip . . 573, 576, 582\Pr<strong>in</strong>tAddress . . 12,299, 310, 319, 329\Pr<strong>in</strong>tBarCode . . . . .. . . . . 15, 305, 37428


\Pr<strong>in</strong>tBigLabel 311, 358\Pr<strong>in</strong>tEnvelope . . . .. . . . 322, 333, 334\Pr<strong>in</strong>tLabel . . . 308, 360\pr<strong>in</strong>tonelabel . . . . 522\Pr<strong>in</strong>tReturnAddress. 12, 293, 317, 327\pr<strong>in</strong>treturnlabels .. . . . . . . . 14, 366\PSautotray . . . 189, 198\PSEnvelopeTray . . .. . . . . 26, 107,109, 115, 117, 193\PSwait . . . . . . 188, 195R\raggedleft . . . 569, 572\re . . . . . . . . . . 22, 565\recontentents . . . . 565\recontents 565, 578, 580\ReName . . . . . . 566, 580\repeat 272, 277, 373, 433\resumelabels . . . . . 513\returnaddress . . . . 216\rotatebox . . . . . . . 333S\SetBigLabel . . . . . .. 87, 133, 136, 563\SetEnvelope . . . . . .. . 59, 106, 108,110–114, 116, 539\SetLabel . . 72, 119,121, 123, 125,127, 129, 131, 551\special . . . . . 188, 190\startlabels . . 217, 371\str<strong>in</strong>g 511, 514, 517,523, 531, 535,536, 543, 547,548, 555, 559, 560\suppresslabels . . . 510\suppressonelabel . 516T\theLabelCountCol . 347\theLabelCountRow . 352\theLabelMaxCol . . . 347\theLabelMaxRow . . . 352\theLabelOffsetCol .. . . . 266, 274, 276\theLabelOffsetRow .. . . . 267, 268, 271\thispagestyle 568, 571\toaddress . . . . . . . 577\ToAddressLeftMarg<strong>in</strong>. . . . 5, 57, 70,83, 85, 101, 103, 302\ToAddressTopMarg<strong>in</strong>. . . . . . . 5, 56,69, 82, 100, 134, 300\ToAddressWidth . . .5, 58, 71, 84–86,102–105, 303, 318\toname . . . . . . . . . . 577V\vfill . . . . . . . . . . . 353W\write 510, 513, 516,522, 530, 534,536, 542, 546,548, 554, 558, 56029

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!