summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/cjw/cjw-ltr.dtx
blob: 42e80bc36ee004444ff16149127fb7a2a3f4352a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
% \iffalse -*- LaTeX -*-
%
%   This is file `cjw-ltr.dtx'.  You can run this file through LaTeX2e
%   to get a .dvi file of documentation.  The file `cjw-ltr.ins' should
%   have come with this file.  Run it through LaTeX2e to extract the
%   actual class file.
%
% \fi
\def\fileversion{0.9}
\def\filedate{1997/01/01}
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%%
%  \CheckSum{592}
%
% \iffalse
%
%<*driver>

\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{cjw-ltr.dtx}
    [\filedate\space v\fileversion\space
     Modified Letter Class for LaTeX2e---CJW]

\documentclass{ltxdoc}

\GetFileInfo{cjw-ltr.dtx}
\EnableCrossrefs         
% \DisableCrossrefs % Say \DisableCrossrefs if index is ready
% \OnlyDescription  % comment out for implementation details
\RecordChanges

\begin{document}
  \DocInput{cjw-ltr.dtx}
\end{document}
%</driver>
% \fi
%
% \DeclareRobustCommand{\cseq}[1]{\texttt{\bslash#1}}
% \DeclareRobustCommand{\pkg} [1]{\textsf{#1}}
% \DeclareRobustCommand{\env} [1]{\textsf{#1}}
%
% \providecommand{\ie}{\emph{i.e.},\ }
%
% \renewcommand{\thefootnote}{\fnsymbol{footnote}}
%
% \hyphenation{white-space}
%
% \title{The \pkg{cjw-ltr} Class\thanks{%
%   This file has version \fileversion{} as of \filedate.}}
% \author{Colin J.~Wynne\thanks{E-Mail at:
%   \texttt{cwynne@mts.jhu.edu}, \texttt{cwynne@jhu.edu}\,.}}
% \date{\filedate}
%
% \maketitle
%
% \setcounter{StandardModuleDepth}{1}
%
% {\parskip 0pt		^^A % This is the hack used by |doc.dtx|.
%  			^^A % (bug in \LaTeX?)
%  \tableofcontents
% }
%
% \section*{Introduction}
%
% I recently made the change to \LaTeXe{} after some years of
% dedication to \PlainTeX{} and that code which I had already
% written for it.  Among that code were macros for writing letters.
% Since I am studying in Germany this year, I had also written a set
% of macros for writing proper letters according to accepted German
% format.
%
% After switching to \LaTeX, I of course gave the \pkg{letter} class a
% try.  I didn't like some of the default behaviour that the class
% produces.  Furthermore, there was no support for writing German
% letters.  I am aware that a style file \pkg{dinbrief} exists for
% \LaTeX{} 2.09 or \LaTeXe{} in compatibility mode, but I would prefer
% to use something exclusively \LaTeXe.  Since I planned on doing some
% cosmetic alterations to the basic \pkg{letter} class anyway, I
% figured it wouldn't be too much extra to include the capability of
% formatting German letters as well.
%
% So, this is what I have come up with.  Feel free to e-mail me
% comments, suggestions, bugs, etc.
%
%
% \section{Creating Letters}
%
% \DescribeMacro{\letterskip}
% The first problem that I had with the \pkg{letter} class was
% spacing.  I do not like having the paragraphs of my letters
% unindented and separated by white space.  This poses a problem since
% the vertical space between the components of the letter are defined
% (nay, \emph{hard-wired}) as multiples of \cseq{parskip}.  Therefore,
% all vertical space has been defined in terms of \cseq{letterskip}, a
% length which is set initially to 0.7\,em, which happens to be the
% \pkg{letter} class's default value for \cseq{parskip}.
%
% \subsection{Standard Letters}
%
% \DescribeEnv{letter}
% \DescribeMacro{fax}
% American format letters are still delineated by the \env{letter}
% environment.  No changes have been made here; the single mandatory
% argument (which may be left empty) is still the address of the
% recipient.  I have, however, added a macro \cseq{fax}, analagous to
% \cseq{telephone}, for including a fax number in the return address.
% If the recipient's fax is also desired, it should probably just be
% included in the argument to the \env{letter} environment, perhaps
% using the \cseq{faxlabel} macro, as well (see below).
%
% Now, one of the things that I have always been taught about proper
% business letters is that the closing and the sender's address should
% line up, and be as far right as possible.  The standard \pkg{letter}
% class does not do this; instead, the address is set as far right as
% possible and the closing begins \cseq{indentedwidth} from the right
% margin.  By default, this is exactly in the middle of the page.  I
% can not express satisfactorily just how ugly and unbalanced this
% seems to me.
% \DescribeMacro{\addresswidth}
% So, first I have \cseq{let} the length \cseq{indentedwidth} to the slightly
% more intuitive \cseq{addresswidth}.  When the letter's \cseq{opening} is
% declared, \cseq{addresswidth} is fixed at the size of the return
% address.  Both the sending address and the closing will be set
% at in a box of width \cseq{addresswidth}; the box is flush right,
% the material within the box is flush left.
%
% \DescribeMacro{\opening}
% The \cseq{opening} macro still takes the text of the opening as its one
% argument, and still begins the letter by typesetting the addresses
% and date.  There are a few differences in the typesetting, though.
% First, if a \cseq{telephone} command has been entered, the number will
% be set as the last line of the address.  Then comes the skip between
% the address and the date.  This skip is rather smaller that that
% provided by the \pkg{letter} class.  I found this to be 
% preferable. Then come the recipient's address and the greeting.
% After these are typeset, the \cseq{parindent} is set to 20\,pt and the
% \cseq{parskip} to 0\,pt plus 1\,pt.  The values can be reset after the
% \cseq{opening} call and before the text of the body if such is desired.
%
% \DescribeMacro{\closing}
% The only change to the closing macro is the substitution of
% \cseq{letterskip} for the original \cseq{medskipamount}.  This means that
% all vertical space in a letter---between address and date and
% recipient's address, between address and greeting, etc.---are
% proportional.  I considered defining each of those quantities to be
% their own macro, such as \cseq{beforedateskip}, \cseq{beforerecipientskip},
% and so forth, but that seemed a little bit excessive.  If, however,
% such flexibility is desired, feel free to ask for it.
%
% \subsection{German Letters}
%
% \DescribeEnv{brief}
% \llap{\footnotemark}\footnotetext{Dies soll wirklich auf Deutsch
%   sein, oder?  Das hatte ich betrachtet, aber es schien mir ein
%   bi\ss chen durcheinander, die beiden Sprachen in dieser
%   Dokumentation zu mischen.  Wenn jemand die \"Ubersetzung will,
%   k\"onnte er mich fragen.  Anderseits ist jeder frei, die
%   \"Ubersetzung selbst zu erledigen.}^^A%
% The environment for a German letter is, appropriately enough, named
% \env{brief} (the German word for letter).  As for |begin{letter}|,
% the invocation takes the recipient's address as the one mandatory
% argument.  However, in standard format, the address line containing
% the \emph{Postleitzahl} (zip code, postal code---whatever) and the
% city is separated by a bit of whitespace from the rest of the
% address.  Thus, whereas other lines of the address are delineated
% by the |\\| macro, the sequence |!!| indicates the beginning of the
% PLZ.  Thus, my former address would most likely be entered as:
%   \begin{verbatim}
% \begin{brief}{%
%   Herrn                \\
%   Colin J. Wynne       \\
%   Klosterweg 28 / L110 !!
%   76131 Karlsruhe}
% \end{verbatim}
%
% \DescribeMacro{\totitle}
% \DescribeMacro{\toPLZ}
% I have not included any macros for creating mailing labels---other
% than the standard macros from the \pkg{letter} class.  However, if
% someone feels the need to write such, then the following is
% significant.  For a standard letter, the first line is taken as the
% recipient's `title'.  This can be a proper academic or professional
% title, or, more commonly, simply a polite \emph{Herrn}, as in the
% example above.  This is stored in the macro \cseq{totitle}.  The PLZ
% information (everything in the argument after |!!|) is stored in
% \cseq{toPLZ}.  These complement the standard \cseq{toname} and \cseq{toaddress}.
% I would add appropriate macros myself, but I have no facilities for
% printing mailing labels to check the result.  I imagine, though,
% that setting
%   \begin{verbatim}
% \edef\toname{\totitle \\ \toname}
% \edef\toaddress{\toaddress \\ \toPLZ}
%   \end{verbatim}
% would allow existing labelling functions to suffice.  (\cseq{edef} to
% avoid a recursive definition, of course.)
%
% \DescribeMacro{\ort}
% \DescribeMacro{\datum}
% \DescribeMacro{\heute}
% \DescribeMacro{\absender}
% \DescribeMacro{\telefon}
% \DescribeMacro{\unterschrift}
% German equivalents are allowed for the standard information
% providing macros.  \cseq{ort} is equivalent to \cseq{location}, and can be
% used to provide the place name on the dateline.  The date itself can
% be entered with the \cseq{datum} command, and the \cseq{heute} macro
% produces the current date in German format.  Thus, the input
% |\ort{Karlsruhe} \datum{\heute}| could produce the dateline
% `Karlsruhe, den 14. Mai 1995'
% at the top of the letter.  \cseq{absender} is used as \cseq{address} to
% indicate the sender's address, with \cseq{telefon} to provide a
% telephone number, and \cseq{fax} is of course the same as in
% English.  Finally, \cseq{unterschrift} provides the signature after
% the closing.
% \DescribeMacro{\betreff}
% \DescribeMacro{\bezug}
% Commands are also given for entering the optional \emph{Betreff} and
% \emph{Bezug} information.  A note to purists: one should include
% both or neither of these lines.  By default, the labels ``Betreff''
% and ``Bezug'' are printed at the beginning of their respective
% lines.  The actual label (including an empty label) can be entered
% as an optional argument to the \cseq{betreff} or \cseq{bezug} commands.
%
% \DescribeMacro{\anrede}
% \DescribeMacro{\gruss}
% The opening and closing of a letter are called by macros named for
% the German equivalents to \cseq{opening} and \cseq{closing}, namely
% \cseq{anrede} and \cseq{gruss}.
%
% \DescribeMacro{\anlage}
% Enclosures are indicated by the \cseq{anlage} command, which calls the
% standard \cseq{encl} macro.  \cseq{anlage} takes an optional argument,
% namely the \cseq{enclname} macro, which is used to label the enclosures.
% By default, ``Anlage'' is the label.  Since multiple enclosures are
% fairly standard, one can enter simply `n' (that is,
% |\anlage[n]|\meta{enclosures}) and produce the expected label
% ``Anlagen.''
%
%
% \StopEventually{\PrintChanges\PrintIndex}
%
% \iffalse
%<*class>

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{cjw-ltr}
    [\filedate\space v\fileversion\space
	 Modified Letter Class for LaTeX2e---CJW]

% \fi
%
% \section{The Code}
%
% The very first thing to do is to include the file |letter.cls|,
% since most of what's in there is very good, and I don't want to
% have to rewrite it and bloat this file.  We make sure as well that
% it inherits any options.
%    \begin{macrocode}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{letter}}
\ProcessOptions

\LoadClass{letter}
%    \end{macrocode}
% Now we can start to change things.  I think the default \cseq{headsep}
% is too large; so, we will make it a bit smaller.
%    \begin{macrocode}
\setlength\headsep   {25\p@}
%    \end{macrocode}
% Next, we provide the length that will be used for vertical space
% within a letter.  We initialise it to a reasonable value.
%    \begin{macrocode}
\newlength{\letterskip}
  \setlength{\letterskip}{0.7em}
%    \end{macrocode}
%
% \subsection{Standard Letters}
%
% \begin{macro}{\addresswidth}
% We first declare the length \cseq{addresswidth}, which is used to
% determine how far from the right margin the sender's adress and the
% closing should be set.  Since the \pkg{letter} class uses the
% \cseq{indentedwidth} length to help place the sender's address, we
% will simply recycle that length for our own purposes.
%    \begin{macrocode}
\let\addresswidth\indentedwidth
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\faxlabel}
% \begin{macro}{\tellabel}
% If a fax number is included, it should be labeled so as not to be
% confused with a telephone number.  The labels (appropriate to both
% German and English) will simply be `Tel:' and `Fax:'.  But, in the
% interest of \ae{}sthetics, we want the printed versions to have the
% same width, so that the actual numbers line up nicely.  Since `Fax:'
% is clearly the wider label, we use it to determine the width we
% want.
%    \begin{macrocode}
\newlength\lblwd
{\setbox0=\hbox{Fax:\enskip}\global\setlength{\lblwd}{\wd0}}
\newcommand*{\faxlabel}{\hbox to\lblwd{Fax:\enskip\hfil}}
\newcommand*{\tellabel}{\hbox to\lblwd{Tel:\enskip\hfil}}
%    \end{macrocode}
% \end{macro}
% \end{macro}

% \begin{macro}{\fax}
% \begin{macro}{\check@iffax}
% The \cseq{fax} command simply sets a global placeholder.
%    \begin{macrocode}
\newcommand*{\fax}[1]{\def\faxnum{#1}}
  \fax{}
%    \end{macrocode}
% The \cseq{check@iffax} macro inserts the labels if appropriate.
%    \begin{macrocode}
\def\check@iffax{%
  \ifx\@empty\faxnum\else
    \edef\faxnum{\protect\faxlabel\faxnum}
    \ifx\@empty\telephonenum\else
      \edef\telephonenum{\protect\tellabel\telephonenum}
  \fi\fi}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\opening}
% The \cseq{opening} macro will collect all information for the
% \env{letter} environment and begin the typesetting.  First, we
% calculate the actual width of the given address.  
%    \begin{macrocode}
\def\opening#1{%
%    \end{macrocode}
% The first step is to determine what actual address information we
% have.  We will figure this out and put it into a placeholder.  If a
% fax number is included, we will want to use labels for telephone and
% fax.
%    \begin{macrocode}
 \check@iffax
  \def\from@address{%
%    \end{macrocode}
% We see if a return address was supplied.  If not, we simply set
% the date.
%    \begin{macrocode}
    \ifx\@empty\fromaddress%
      \@date%
%    \end{macrocode}
% If so, we typeset the address including a telephone number if one is
% supplied.  Then comes a bit of whitespace and the date.
%    \begin{macrocode}
    \else% home address
      \fromaddress%
      \ifx\@empty\telephonenum\else%
        \\ \telephonenum%
      \fi%
      \ifx\@empty\faxnum\else%
        \\ \faxnum%
      \fi%
      \\*[\letterskip]\@date%
    \fi}
  \setbox0=\hbox{%
    \begin{tabular}{l}\from@address\end{tabular}}
%    \end{macrocode}
% With these values we set out global value for \cseq{addresswidth}.
%    \begin{macrocode}
  \global\setlength{\addresswidth}{\wd0}
%    \end{macrocode}
% With no address, we want the |firstpage| pagestyle.
%    \begin{macrocode}
  \ifx\@empty\fromaddress
    \thispagestyle{firstpage}%
%    \end{macrocode}
% With one, we want the |empty| pagestyle for the first page.
%    \begin{macrocode}
  \else
    \thispagestyle{empty}
  \fi
%    \end{macrocode}
% In either case, we fill horizontally and dump the box with the
% address information.
%    \begin{macrocode}
  \noindent\hfill\box0
  \par
%    \end{macrocode}
% After the date comes some more whitespace and the recipient---
%    \begin{macrocode}
  \vspace{2\letterskip}%
  {\raggedright\toname\\ \toaddress\par}%
%    \end{macrocode}
% ---then more whitespace and the text of the greeting.  Note that all
% of the whitespace is given in terms of \cseq{letterskip}.
%    \begin{macrocode}
  \vspace{2\letterskip}%
  \noindent#1%
%    \end{macrocode}
% Finally, we reset the values of \cseq{parindent} and \cseq{parskip} and
% inhibit a break before the body.  (What set of addresses would make
% \TeX{} \emph{want} to break after the greeting?)
%    \begin{macrocode}
  \setlength{\parindent}{20\p@}
  \setlength{\parskip}{0\p@ \@plus\@ne\p@\relax}
  \par\nobreak}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\closing}
% The \cseq{closing} macro is unchanged from the \pkg{letter} class,
% except for the change from \cseq{parindent} to \cseq{letterskip} and
% the use of \cseq{addresswidth} in determining the box size.
%    \begin{macrocode}
\long\def\closing#1{\par\nobreak\vspace{2\letterskip}%
  \stopbreaks
  \noindent\hfill
  \parbox{\addresswidth}{\raggedright%
       #1\\[6\letterskip]%
       \ifx\@empty\fromsig
           \fromname
       \else
	   \fromsig
       \fi\strut}
   \par}
%    \end{macrocode}
% \end{macro}
%
% \subsection{German Letters}
%
% First, we \cseq{let} several appropriate macros for German usage.
%    \begin{macrocode}
\let\unterschrift \signature
\let\absender     \address
\let\ort          \location
\let\telefon      \telephone
\let\datum        \date
%    \end{macrocode}
% \begin{macro}{\heute}
% Here are some simple definitions which I use in my own macro files.
%    \begin{macrocode}
\newcommand{\theday}{\number\day\relax}
\newcommand{\themonth}{%
  \ifcase\month\or January\or February\or%
  March\or April\or May\or June\or July\or August\or%
  September\or October\or November\or December\fi}
\newcommand{\themonat}{%
  \ifcase\month\or Januar\or Februar\or%
  M\"arz\or April\or Mai\or Juni\or Juli\or August\or%
  September\or Oktober\or November\or Dezember\fi}
\newcommand{\theyear}{\number\year\relax}
%    \end{macrocode}
% From these we can construct a German date macro, \cseq{heute}.
%    \begin{macrocode}
\newcommand{\heute}{den~\theday.\ \themonat\ \theyear}
%    \end{macrocode}
% These are also useful if one prefers a different (\ie date first)
% format for the \cseq{today} macro.
% \end{macro}
%
% \begin{macro}{\betreff}
% \begin{macro}{\bezug}
% Next come the macros for the additional information which may be
% included in the headers of a German letter.
% \changes{v0.5}{1995/06/10}{Fixed a bug (incorrect macro parameter)
%   in \cseq{betreff} and \cseq{bezug}.}
%    \begin{macrocode}
\newcommand{\betreff}[2][Betreff]{%
  \def\betreffname{#1}\long\def\@betreff{#2}}
\newcommand{\bezug}[2][Bezug]{%
  \def\bezugname{#1}\long\def\@bezug{#2}}
%    \end{macrocode}
% These are initialised to be empty.
%    \begin{macrocode}
\betreff[]{}
\bezug[]{}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{environment}{brief}
% Now comes the \env{brief} environment itself.  German letters are
% suppose to use unindented and separated paragraphs, so we will set
% the proper values as soon as the environment is entered.
%    \begin{macrocode}
\long\def\brief#1{%
  \newpage
  \setlength{\parindent}{0pt}
  \setlength{\parskip}{0.7em}
%    \end{macrocode}
% Further initialisations are taken from the \cseq{letter} macro.
%    \begin{macrocode}
    \if@twoside \ifodd\c@page
                \else\thispagestyle{empty} \hbox{}\newpage\fi
    \fi
    \c@page\@ne
    \interlinepenalty=200 % Smaller than the TeXbook value
%    \end{macrocode}
% Since the supplied argument has more information in it than that
% given to a \env{letter} environment, we must have our own equivalent
% to the \pkg{letter} class's |\@processto|.
%    \begin{macrocode}
    \@prozessan{\leavevmode\ignorespaces #1}
%    \end{macrocode}
% Lastly, we make the default date a German one.
%    \begin{macrocode}
    \date{\heute}}
%    \end{macrocode}
% \begin{macro}{\@prozessan}
% \changes{v0.5}{1995/06/10}{The \cseq{@prozessan} macro and its
%   subprocesses completely rewritten, as the previous version (v0.1)
%   was very broken.}
% The address processing is based on the |\@processto| macro from
% \pkg{letter.cls}.  We call the first subprocess, |\@xproz|, to fetch
% the PLZ part of the address.
%    \begin{macrocode}
\long\def\@prozessan#1{%
  \@xproz #1!!@@@%
%    \end{macrocode}
% If there is a PLZ, the first test includes an extra occurrence of
% |!!| in the \cseq{toPLZ} macro.  So, we call |\@xproz| again without the
% extra characters (which were necesary to make sure that we didn't
% get a `usage doesn't match definition' error the first time around).
%    \begin{macrocode}
  \ifx\@empty\toPLZ\else\@xproz #1@@@\fi%
%    \end{macrocode}
% The |\@xproz| macro has now stored all the address parts before the
% PLZ in |\@tempa|.  Now there are up to three different parts that
% may be in |\@tempa| which we will try to separate out.  We use
% \cseq{expandafter} in order that the tokens within |\@tempa| get
% properly considered.
%    \begin{macrocode}
  \expandafter\@yproz \@tempa\\@@@%
%    \end{macrocode}
% The |\@yproz| splits the input into |\@tempb|, the part before the
% first linebreak, and |\@tempc|, the rest.  If the second part, that
% in |\@tempc|, is empty, then we want to set the third part,
% |\@tempd|, to be empty, too.
%    \begin{macrocode}
  \ifx\@empty\@tempc
    \let\@tempd\@empty
%    \end{macrocode}
% Otherwise, we call |\@zproz| to further subdivide the address input.
%    \begin{macrocode}
  \else
    \expandafter\@zproz \@tempa\\@@@%
%    \end{macrocode}
% If there is a third part, |\@tempd|, we have the same problem with
% extra characters as above in \cseq{toPLZ}.  We call |\@zproz| one more
% time in order to read |\@tempd| correctly.
%    \begin{macrocode}
    \ifx\@empty\@tempd
      \else
      \expandafter\@zproz \@tempa{}@@@%
    \fi
  \fi
%    \end{macrocode}
% Now we need to decide what to call whichever address pieces actually
% exist.  Obviously, if everything back to |\@tempb| was empty, all of
% the address parts should be likewise.
%    \begin{macrocode}
  \ifx\@empty\@tempb
    \let\totitle\@empty \let\toname\@empty \let\toaddress\@empty
  \else
%    \end{macrocode}
% Now we have at least one address part.  If that is the only one, it
% is most certainly not a title, so \cseq{totitle} must be set empty.
%    \begin{macrocode}
    \ifx\@empty\@tempc
      \let\totitle\@empty
%    \end{macrocode}
% One line with a PLZ is almost assuredly an address proper.  Without
% a PLZ it is probably a name.
%    \begin{macrocode}
      \ifx\@empty\toPLZ
        \let\toname\@tempb \let\toaddress\@empty
      \else
        \let\toname\@empty \let\toaddress\@tempb
      \fi
%    \end{macrocode}
% If |\@tempb| and |\@tempc| contain something, but |\@tempd| is
% empty, the two lines should be name and address.
%    \begin{macrocode}
    \else
      \ifx\@empty\@tempd
        \let\totitle\@empty \let\toname\@tempb \let\toaddress\@tempc
%    \end{macrocode}
% The last option is that title, name and address are all present.
%    \begin{macrocode}
      \else
        \let\totitle\@tempb \let\toname\@tempc \let\toaddress\@tempd
      \fi
    \fi
    \fi}
%    \end{macrocode}
% This is my second implementation of the |\@prozessan| macro.  The
% first was truly ugly and had the added disadvantage of, well, not
% working.  In fact, it failed miserably for a few relatively simple
% cases.  That the current version (as far I can tell) works does not,
% however, excuse the fact that it is still somewhat ugly and seems to
% me to be very efficient.  I am still open to any suggested
% improvements. 
%
% The subproceses to |\@prozessan| are simply designed to be able to
% make assignments based on the structure of the passed argument.
%    \begin{macrocode}
\long\def\@xproz #1!!#2@@@{\def\@tempa{#1}\def\toPLZ{#2}}
\long\def\@yproz #1\\#2@@@{\def\@tempb{#1}\def\@tempc{#2}\def\@tempd{}}
\long\def\@zproz #1\\#2\\#3@@@{\def\@tempc{#2}\def\@tempd{#3}}
%    \end{macrocode}
% \end{macro}
%
% The end of the \env{brief} environment is identical to that of the
% \env{letter} environment.
%    \begin{macrocode}
\let\endbrief\endletter
%    \end{macrocode}
% \end{environment}
%
% \begin{macro}{\anrede}
% As for the \cseq{opening} macro in the \env{letter} environment, the
% \cseq{anrede} macro signals the beginning of the letter.  We begin by
% setting the dateline.
% \changes{v0.5}{1995/06/10}{Use \cseq{@dateline} instead of
%   \cseq{@tempa}, because \cseq{raggedright}, or \emph{something},
%   seemed to mess with \cseq{@tempa}.  Also move the conditional
%   outside of the definition of \cseq{@dateline}.}
%    \begin{macrocode}
\def\anrede#1{%
  \check@iffax
  \ifx\@empty\fromlocation
    \def\@dateline{\@date}
  \else
    \def\@dateline{\fromlocation,\space\@date}
  \fi
%    \end{macrocode}
% Set with a typewriter, a German letter should leave two blank lines
% before the return address.  Since we are using something a little
% more capable than a typewriter, we will leave a small amount of
% whitespace, in the form of a multiple of \cseq{letterskip}.
%    \begin{macrocode}
  \null\vspace{1.2\letterskip}
  \noindent\ignorespaces
%    \end{macrocode}
% If there is no return address (a situation which I don't actually
% see happening with this format), just set the dateline at the right
% margin.
%    \begin{macrocode}
  \ifx\@empty\fromaddress%
    \pagestyle{firstpage}%
    {\raggedleft \@dateline}%
%    \end{macrocode}
% Otherwise, the address is set at the left margin and the dateline
% right justified at the level of the first line of the sender
% information.  A telephone number and fax, if provided, follow the address.
% \changes{v0.5}{1995/06/10}{Added code to include a telephone number
%   in the return address information.}
%    \begin{macrocode}
  \else % Home address
    \pagestyle{empty}%
    {\raggedright%
       \fromname \hfill \@dateline\\
       \fromaddress}
        \ifx\@empty\telephonenum
        \else
          \\ \telephonenum
        \fi
        \ifx\@empty\faxnum
        \else
          \\ \faxnum
        \fi
  \fi
  \par
%    \end{macrocode}
% Next comes whitespace approximately twice as large as the topskip.
%    \begin{macrocode}
  \vspace{2.2\letterskip}
%    \end{macrocode}
% We then set the recipient's address.  Using the information provided
% from the |\@prozessan| macro above, we include those pieces which
% were supplied.
%    \begin{macrocode}
  {\raggedright
     \ifx\@empty\totitle
     \else
       \totitle \\
     \fi
     \toname
     \ifx\@empty\toaddress
     \else
       \\ \toaddress
     \fi
     \ifx\@empty\toPLZ
     \else
       \\*[0.6\letterskip]\toPLZ
     \fi
   \par}
%    \end{macrocode}
% After the address come, if supplied, the \emph{Betreff} and
% \emph{Bezug} lines.  First, though, we check to see if only one is
% supplied---if so, we issue a warning.
%    \begin{macrocode}
  \@checkbetreffbezug
%    \end{macrocode}
% Now we can typeset those lines.  A small amount of whitespace
% separates them from one another and from the address.
%    \begin{macrocode}
    \ifx\@empty\@betreff
    \else
      \vspace{\letterskip}
      \ifx\@empty\betreffname
      \else
        \betreffname:\quad
      \fi
      \@betreff\par
    \fi
    \ifx\@empty\@bezug
    \else
      \vspace{1\letterskip}
      \ifx\@empty\bezugname
      \else
        \bezugname:\quad
      \fi
      \@bezug\par
    \fi
%    \end{macrocode}
% A slightly larger amount of whitespace precedes the actual
% \emph{Anrede}.
%    \begin{macrocode}
  \vspace{1.4\letterskip}%
  #1\par\nobreak}
%    \end{macrocode}
% \end{macro}
% The |\@checkbetreffbezug| macro emits a warning if only one of those
% two lines is supplied.
%    \begin{macrocode}
\def\@checkbetreffbezug{%
  \ifx\@empty\@betreff
    \ifx\@empty\@bezug
    \else
      \ClassWarningNoLine{cjw-ltr}{%
        Die \protect\betreff und \protect\bezug Befehlen sollen nur
                                                    \MessageBreak 
        zusammen verwendet werden.  Ihnen fehlt die  \MessageBreak
        Betreff-Zeile.}
    \fi
  \else
    \ifx\@empty\@bezug
      \ClassWarningNoLine{cjw-ltr}{%
        Die \protect\betreff und \protect\bezug Befehlen sollen nur
                                                    \MessageBreak 
        zusammen verwendet werden.  Ihnen fehlt die  \MessageBreak
        Bezug-Zeile.}
    \fi
  \fi}
%    \end{macrocode}
%
% \begin{macro}{\gruss}
% The command \cseq{gruss} ends a letter by first adding some whitespace
% and disabling further pagebreaks.
%    \begin{macrocode}
\long\def\gruss#1{\par\nobreak\vspace{2\letterskip}%
  \stopbreaks
  \noindent%
%    \end{macrocode}
% The closing itself is set, leaving enough whitespace for the actual
% signature.
%    \begin{macrocode}
  {\raggedright #1 \\[5\letterskip]
     \ifx\@empty\fromsig
       \fromname
     \else
       \fromsig
     \fi}
  \par
%    \end{macrocode}
% Finally, a bit of white space separates the bottom of the closing
% from any postscripts.
%    \begin{macrocode}
  \vspace{\letterskip}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\anlage}
% Enclosures, \emph{Anlagen}, are specified by the \cseq{anlage} command.
% As with \cseq{betreff} and \cseq{bezug}, the label is given by an optional
% argument.
%    \begin{macrocode}
\newcommand{\anlage}[1][Anlage]{%
%    \end{macrocode}
% If the optional argument is simply `n', we pluralize the label.
%    \begin{macrocode}
  \def\@tempa{n} \def\@tempb{#1}
  \ifx\@tempa\@tempb
    \renewcommand{\enclname}{Anlagen}
%    \end{macrocode}
% Otherwise, the optional argument (or the default, if none is given)
% becomes the label.
%    \begin{macrocode}
  \else
    \renewcommand{\enclname}{\@tempb}
  \fi\encl}
%    \end{macrocode}
% \end{macro}
% And with that, we are done.
%
% \iffalse
%</class>
% \fi
%
% \Finale
%