summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/mdwtools/mdwmath.dtx
blob: 3dc85872f804d2c7f2d040fed2c9c7b5d6a33372 (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
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
% \begin{meta-comment}
%
% $Id: mdwmath.dtx,v 1.1 1996/11/19 20:53:21 mdw Exp $
%
% Various nicer mathematical things
%
% (c) 1996 Mark Wooding
%
%----- Revision history -----------------------------------------------------
%
% $Log: mdwmath.dtx,v $
% Revision 1.1  1996/11/19 20:53:21  mdw
% Initial revision
%
%
% \end{meta-comment}
%
% \begin{meta-comment} <general public licence>
%%
%% mdwmath package -- various nicer mathematical things
%% Copyright (c) 1996 Mark Wooding
%%
%% This program is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by
%% the Free Software Foundation; either version 2 of the License, or
%% (at your option) any later version.
%%
%% This program is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%% GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public License
%% along with this program; if not, write to the Free Software
%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
%%
% \end{meta-comment}
%
% \begin{meta-comment} <Package preamble>
%<+package>\NeedsTeXFormat{LaTeX2e}
%<+package>\ProvidesPackage{mdwmath}
%<+package>                [1996/04/11 1.1 Nice mathematical things]
%<+oldeqnarray>\NeedsTeXFormat{LaTeX2e}
%<+oldeqnarray>\ProvidesPackage{eqnarray}
%<+oldeqnarray>                [1996/04/11 1.1 Old enhanced eqnarray]
% \end{meta-comment}
%
% \CheckSum{259}
% \begin{old-eqnarray}
% \CheckSum{484}
% \end{old-eqnarray}
%% \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         \~}
%%
%
% \begin{meta-comment}
%
%<*driver>
\input{mdwtools}
\describespackage{mdwmath}
% \describespackage{eqnarray}
\ignoreenv{old-eqnarray}
% \unignoreenv{old-eqnarray}
\mdwdoc
%</driver>
%
% \end{meta-comment}
%
% \section{User guide}
%
% \subsection{Square root typesetting}
%
% \DescribeMacro{\sqrt}
% The package supplies a star variant of the |\sqrt| command which omits the
% vinculum over the operand (the line over the top).  While this is most
% useful in simple cases like $\sqrt*{2}$ it works for any size of operand.
% The package also re-implements the standard square root command so that it
% positions the root number rather better.
%
% \begin{figure}
% \begin{demo}[w]{Examples of the new square root command}
%\[ \sqrt*{2} \quad \mbox{rather than} \quad \sqrt{2} \]
%\[ \sqrt*[3]{2} \quad \mbox{ rather than } \quad \sqrt[3]{2} \]
%\[ \sqrt{x^3 + \sqrt*[y]{\alpha}} - \sqrt*[n+1]{a} \]
%\[ x = \sqrt*[3]{\frac{3y}{7}} \]
%\[ q = \frac{2\sqrt*{2}}{5}+\sqrt[\frac{n+1}{2}]{2x^2+3xy-y^2} \]
% \end{demo}
% \end{figure}
%
% [Note that omission of the vinculum was originally a cost-cutting exercise
% because the radical symbol can just fit in next to its operand and
% everything ends up being laid out along a line.  However, I find that the
% square root without vinculum is less cluttered, so I tend to use it when
% it doesn't cause ambiguity.]
%
% \subsection{Some maths symbols you already have}
%
% Having just tried to do some simple things, I've found that there are maths
% symbols missing.  Here they are, in all their glory:
%
% \begin{center} \unverb\| \begin{tabular}{cl|cl|cl}
% $\&$ & "\&"		& $\bitor$ & "\bitor"	& $\dbland$ & "\dbland" \\
% $\bitand$ & "\bitand"	& $\dblor$ & "\dblor"	& 
% \end{tabular} \end{center}
%
% \begin{ignore}
% There used to be an eqnarray here, but that's migrated its way into the
% \package{mdwtab} package.  Maybe the original version, without dependency
% on \package{mdwtab} ought to be releasable separately.  I'll keep it around
% just in case.
%
% The following is the documentation for the original version.  There's an
% updated edition in \package{mdwtab}.
% \end{ignore}
%
% \begin{old-eqnarray}
%
% \subsection{A new \env{eqnarray} environment}
%
% \LaTeX's built-in \env{eqnarray} is horrible -- it puts far too much space
% between the items in the array.  This environment is rather nearer to the
% \env{amsmath} \env{align} environments, although rather less capable.
%
% \bigskip
% \DescribeEnv{eqnarray}
% {\synshorts
% \setbox0\hbox{"\\begin{eqnarray}["<preamble>"]" \dots "\\end{eqnarray}"}
% \leavevmode \hskip-\parindent \fbox{\box0}
% }
% \smallskip
%
% The new version of \env{eqnarray} tries to do everything which you really
% want it to.  The \synt{preamble} string allows you to define the column
% types in a vaguely similar way to the wonderful \env{tabular} environment.
% The types provided (and it's easy-ish to add more) are:
%
% \def\ch{\char`}
% \begin{description} \def\makelabel{\hskip\labelsep\normalfont\ttfamily}
% \item [r] Right aligned equation
% \item [c] Centre-aligned equation
% \item [l] Left aligned equation
% \item [\textrm{\texttt{Tr}, \texttt{Tc} and \texttt{Tl}}] Right, centre and
%       left aligned text (not maths)
% \item [L] Left aligned zero-width equation
% \item [x] Centred entire equation
% \item [:] Big gap separating sets of equations
% \item [q] Quad space
% \item [>\ch\{\synt{text}\ch\}] Insert text before column
% \item [<\ch\{\synt{text}\ch\}] Insert text after column
% \end{description}
%
% Some others are also defined: don't use them because they do complicated
% things which are hard to explain and they aren't much use anyway.
%
% The default preamble, if you don't supply one of your own, is \lit{rcl}.
% Most of the time, \lit{rl} is sufficient, although compatibility is more
% important to me.
%
% By default, there is no space between columns, which makes formul\ae\ in an
% \env{eqnarray} environment look just like formul\ae\ typeset on their own,
% except that things get aligned in columns.  This is where the default
% \env{eqnarray} falls down: it leaves |\arraycolsep| space between each
% column making the thing look horrible.
%
% An example would be good here, I think.  This one's from exercise 22.9 of
% the \textit{\TeX book}.
%
% \begin{demo}[w]{Simultaneous equations}
%\begin{eqnarray}[rcrcrcrl]
%  10w & + &  3x & + & 3y & + & 18z & = 1 \\
%   6w & - & 17x &   &    & - &  5z & = 2
%\end{eqnarray}
% \end{demo}
%
% Choosing a more up-to-date example, here's one demonstrating the \lit{:}
% column specifier from the \textit{\LaTeX\ Companion}.
%
% \begin{demo}[w]{Lots of equations}
%\begin{eqnarray}[rl:rl:l]
% V_i &= v_i - q_i v_j,	& X_i &= x_i - q_i x_j,	&
%       U_i = u_i, \qquad \mbox{for $i \ne j$}  \label{eq:A} \\
% V_j &= v_j,           & X_j &= x_j            &
%       U_j u_j + \sum_{i \ne j} q_i u_i.
%\end{eqnarray}
% \end{demo}
%
% We can make things more interesting by adding a plain text column.  Here we
% go:
%
% \begin{demo}[w]{Plain text column}
%\begin{eqnarray}[rlqqTl]
%     x  &= y           & by (\ref{eq:A}) \\
%     x' &= y'          & by definition \\
% x + x' &= y + y'      & by Axiom~1
%\end{eqnarray}
% \end{demo}
%
% The new features also mean that you don't need to mess about with
% |\lefteqn| any more.  This is handled by the \lit{L} column type:
%
% \begin{demo}{Splitting example}
%\begin{eqnarray*}[Ll]
%   w+x+y+z = \\
%    & a+b+c+d+e+ \\
%    & f+g+h+i+j
%\end{eqnarray*}
% \end{demo}
%
% Finally, just to prove that the spacing's right at last, here's another one
% from the \textit{Companion}.
%
% \begin{demo}{Spacing demonstration}
%\begin{equation}
%  x^2 + y^2 = z^2
%\end{equation}
%\begin{eqnarray}[rl]
%  x^2 + y^2 &= z^2 \\
%        y^2 &< z^2
%\end{eqnarray}
% \end{demo}
%
% Well, that was easy enough.  Now on to numbering.  As you've noticed, the
% equations above are numbered.  You can use the \env{eqnarray$*$}
% environment to turn off the numbering in the whole environment, or say
% |\nonumber| on a line to suppress numbering of that one in particular.
% More excitingly, you can say \syntax{"\\nonumber["<text>"]"} to choose
% what text to display.
%
% A note for cheats: you can use the sparkly new \env{eqnarray} for simple
% equations simply by specifying \lit{x} as the column description.  Who
% needs \AmSTeX? |;-)|
%
% \end{old-eqnarray}
%
% \implementation
%
% \section{Implementation}
%
% This isn't really complicated (honest) although it is a lot hairier than I
% think it ought to be.
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \subsection{Square roots}
%
% \subsubsection{Where is the square root sign?}
%
% \LaTeX\ hides the square root sign away somewhere without telling anyone
% where it is.  I extract it forcibly by peeking inside the |\sqrtsign| macro
% and scrutinising the contents.  Here we go: prepare for yukkiness.
%
%    \begin{macrocode}
\newcount\sq@sqrt
\begingroup
  \catcode`\|0 \catcode`\\12
  |def|sq@readrad#1"#2\#3|relax{|global|sq@sqrt"#2|relax}
  |expandafter|sq@readrad|meaning|sqrtsign|relax
|endgroup
\def\sq@delim{\delimiter\sq@sqrt\relax}
%    \end{macrocode}
%
% \subsubsection{Drawing fake square root signs}
%
% \TeX\ absolutely insists on drawing square root signs with a vinculum over
% the top.  In order to get the same effect, we have to attempt to emulate
% \TeX's behaviour.
%
% \begin{macro}{\sqrtdel}
%
% This does the main job of typesetting a vinculum-free radical.\footnote{^^A
%   Note for chemists: this is nothing to do with short-lived things which
%   don't have their normal numbers of electrons.  And it won't reduce the
%   appearance of wrinkles either.}
% It's more or less a duplicate of what \TeX\ does internally, so it might be
% a good plan to have a copy of Appendix~G open while you examine this.
%
% We start off by using |\mathpalette| to help decide how big things should
% be.
%
%    \begin{macrocode}
\def\sqrtdel{\mathpalette\sqrtdel@i}
%    \end{macrocode}
%
% Read the contents of the radical into a box, so we can measure it.
%
%    \begin{macrocode}
\def\sqrtdel@i#1#2{%
  \setbox\z@\hbox{$\m@th#1#2$}% %%% Bzzzt -- uncramps the mathstyle
%    \end{macrocode}
%
% Now try and sort out the values needed in this calculation.  We'll assume
% that $\xi_8$ is 0.6\,pt, the way it usually is.  Next try to work out the
% value of $\varphi$.
%
%    \begin{macrocode}
  \ifx#1\displaystyle%
    \@tempdima1ex%
  \else%
    \@tempdima.6\p@%
  \fi%
%    \end{macrocode}
%
% That was easy.  Now for $\psi$.
%
%    \begin{macrocode}
  \@tempdimb.6\p@%
  \advance\@tempdimb.25\@tempdima%
%    \end{macrocode}
%
% Build the `delimiter' in a box of height $h(x)+d(x)+\psi+\xi_8$, as
% requested.  Box~2 will do well for this purpose.
%
%    \begin{macrocode}
  \dimen@.6\p@%
  \advance\dimen@\@tempdimb%
  \advance\dimen@\ht\z@%
  \advance\dimen@\dp\z@%
  \setbox\tw@\hbox{%
    $\left\sq@delim\vcenter to\dimen@{}\right.\n@space$%
  }%
%    \end{macrocode}
%
% Now we need to do some more calculating (don't you hate it?).  As far as
% Appendix~G is concerned, $\theta=h(y)=0$, because we want no rule over the
% top.  
%
%    \begin{macrocode}
  \@tempdima\ht\tw@%
  \advance\@tempdima\dp\tw@%
  \advance\@tempdima-\ht\z@%
  \advance\@tempdima-\dp\z@%
  \ifdim\@tempdima>\@tempdimb%
    \advance\@tempdima\@tempdimb%
    \@tempdimb.5\@tempdima%
  \fi%
%    \end{macrocode}
%
% Work out how high to raise the radical symbol.  Remember that Appendix~G
% thinks that the box has a very small height, although this is untrue here.
%
%    \begin{macrocode}
  \@tempdima\ht\z@%
  \advance\@tempdima\@tempdimb%
  \advance\@tempdima-\ht\tw@%
%    \end{macrocode}
%
% Build the output (finally).  The brace group is there to turn the output
% into a mathord, one of the few times that this is actually desirable.
%
%    \begin{macrocode}
  {\raise\@tempdima\box\tw@\vbox{\kern\@tempdimb\box\z@}}%
}
%    \end{macrocode}
%
% \end{macro}
%
% \subsubsection{The new square root command}
%
% This is where we reimplement all the square root stuff.  Most of this stuff
% comes from the \PlainTeX\ macros, although some is influenced by \AmSTeX\
% and \LaTeXe, and some is original.  I've tried to make the spacing vaguely
% automatic, so although it's not configurable like \AmSTeX's version, the
% output should look nice more of the time.  Maybe.
%
% \begin{macro}{\sqrt}
%
% \LaTeX\ says this must be robust, so we make it robust.  The first thing to
% do is to see if there's a star and pass the appropriate squareroot-drawing
% command on to the rest of the code.
%
%    \begin{macrocode}
\DeclareRobustCommand\sqrt{\@ifstar{\sqrt@i\sqrtdel}{\sqrt@i\sqrtsign}}
%    \end{macrocode}
%
% Now we can sort out an optional argument to be displayed on the root.
%
%    \begin{macrocode}
\def\sqrt@i#1{\@ifnextchar[{\sqrt@ii{#1}}{\sqrt@iv{#1}}}
%    \end{macrocode}
%
% Stages~2 and~3 below are essentially equivalents of \PlainTeX's
% |\root|\dots|\of| and |\r@@t|.  Here we also find the first wrinkle: the
% |\rootbox| used to store the number is spaced out on the left if necessary.
% There's a backspace after the end so that the root can slip underneath, and
% everything works out nicely.  Unfortunately size is fixed here, although
% doesn't actually seem to matter.
%
%    \begin{macrocode}
\def\sqrt@ii#1[#2]{%
  \setbox\rootbox\hbox{$\m@th\scriptscriptstyle{#2}$}%
  \ifdim\wd\rootbox<6\p@%
    \setbox\rootbox\hb@xt@6\p@{\hfil\unhbox\rootbox}%
  \fi%
  \mathpalette{\sqrt@iii{#1}}%
}
%    \end{macrocode}
%
% Now we can actually build everything.  Note that the root is raised by its
% depth -- this prevents a common problem with letters with descenders.
%
%    \begin{macrocode}
\def\sqrt@iii#1#2#3{%
  \setbox\z@\hbox{$\m@th#2#1{#3}$}%
  \dimen@\ht\z@%
  \advance\dimen@-\dp\z@%
  \dimen@.6\dimen@%
  \advance\dimen@\dp\rootbox%
  \mkern-3mu%
  \raise\dimen@\copy\rootbox%
  \mkern-10mu%
  \box\z@%
}
%    \end{macrocode}
%
% Finally handle a non-numbered root.  We read the rooted text in as an
% argument, to stop problems when people omit the braces.  (\AmSTeX\ does
% this too.)
%
%    \begin{macrocode}
\def\sqrt@iv#1#2{#1{#2}}
%    \end{macrocode}
%
% \end{macro}
%
% \begin{macro}{\root}
%
% We also re-implement \PlainTeX's |\root| command, just in case someone uses
% it, and supply a star-variant.  This is all very trivial.
%
%    \begin{macrocode}
\def\root{\@ifstar{\root@i\sqrtdel}{\root@i\sqrtsign}}
\def\root@i#1#2\of{\sqrt@ii{#1}[#2]}
%    \end{macrocode}
%
% \end{macro}
%
% \subsection{Some magic new maths characters}
%
% This is all really easy.
%
%    \begin{macrocode}
\DeclareMathSymbol{&}{\mathbin}{operators}{`\&}
\DeclareMathSymbol{\bitand}{\mathbin}{operators}{`\&}
\def\bitor{\mathbin\mid}
\def\dblor{\mathbin{\mid\mid}}
\def\dbland{\mathbin{\mathrel\bitand\mathrel\bitand}}
%    \end{macrocode}
%
% \subsection{Biggles}
%
% Now for some user-controlled delimiter sizing.  The standard bigness of
% plain \TeX's delimiters are all right, but it's a little limiting.
%
% The biggness of delimiters is based on the size of the current |\strut|,
% which \LaTeX\ keeps up to date all the time.  This will make the various
% delimiters grow in proportion when the text gets bigger.  Actually, I'm
% not sure that this is exactly right -- maybe it should be nonlinear,
%
% \begin{macro}{\bbigg}
% \begin{macro}{\bbiggl}
% \begin{macro}{\bbiggr}
% \begin{macro}{\bbiggm}
%
% This is where the bigness is done.  This is more similar to the plain \TeX\
% big delimiter stuff than to the \package{amsmath} stuff, although there's
% not really a lot of difference.
%
% The two arguments are a multiplier for the delimiter size, and a small
% increment applied \emph{before} the multiplication (which is optional).
%
% This is actually a front for a low-level interface which can be called
% directly for efficiency.
%
%    \begin{macrocode}
\def\bbigg{\@bbigg\mathord}
\def\bbiggl{\@bbigg\mathopen}
\def\bbiggr{\@bbigg\mathclose}
\def\bbiggm{\@bbigg\mathrel}
%    \end{macrocode}
%
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@bbigg}
%
% This is an optional argument parser providing a front end for the main
% macro |\bbigg@|.
%
%    \begin{macrocode}
\def\@bbigg#1{\@ifnextchar[{\@bigg@i{#1}}{\@bigg@i{#1}[\z@]}}
\def\@bigg@i#1[#2]#3#4{#1{\bbigg@{#2}{#3}{#4}}}
%    \end{macrocode}
%
% \end{macro}
%
% \begin{macro}{\bbigg@}
%
% This is it, at last.  The arguments are as described above: an addition
% to be made to the strut height, and a multiplier.  Oh, and the delimiter,
% of course.
%
% This is a bit messy.  The smallest `big' delimiter, |\big|, is the same
% height as the current strut box.  Other delimiters are~$1\frac12$, $2$
% and~$2\frac12$ times this height.  I'll set the height of the delimiter by
% putting in a |\vcenter| of the appropriate size.
%
% Given an extra height~$x$, a multiplication factor~$f$ and a strut
% height~$h$ and depth~$d$, I'll create a vcenter with total height
% $f(h+d+x)$.  Easy, isn't it?
%
%    \begin{macrocode}
\def\bbigg@#1#2#3{%
  \hbox{$%
    \dimen@\ht\strutbox\advance\dimen@\dp\strutbox%
    \advance\dimen@#1%
    \dimen@#2\dimen@%
    \left#3\vcenter to\dimen@{}\right.\n@space%
  $}%
}
%    \end{macrocode}
%
% \end{macro}
%
% \begin{macro}{\big}
% \begin{macro}{\Big}
% \begin{macro}{\bigg}
% \begin{macro}{\Bigg}
%
% Now for the easy macros.
%
%    \begin{macrocode}
\def\big{\bbigg@\z@\@ne}
\def\Big{\bbigg@\z@{1.5}}
\def\bigg{\bbigg@\z@\tw@}
\def\Bigg{\bbigg@\z@{2.5}}
%    \end{macrocode}
%
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% 
%
% \begin{ignore}
% The following is the original definition of the enhanced eqnarray
% environment.  It's not supported, although if you can figure out how to
% extract it, it's all yours.
% \end{ignore}
%
% \begin{old-eqnarray}
%
% \subsection{The sparkly new \env{eqnarray}}
%
% Start off by writing a different package.
%
%    \begin{macrocode}
%</package>
%<*oldeqnarray>
%    \end{macrocode}
%
% \subsubsection{Options handling}
%
% We need to be able to cope with \textsf{fleqn} and \textsf{leqno} options.
% This will adjust our magic modified \env{eqnarray} environment
% appropriately.
%
%    \begin{macrocode}
\newif\if@fleqn
\newif\if@leqno
\DeclareOption{fleqn}{\@fleqntrue}
\DeclareOption{leqno}{\@leqnotrue}
\ProcessOptions
%    \end{macrocode}
%
% This is all really different to the \LaTeX\ version.  I've looked at the
% various \env{tabular} implementations, the original \env{eqnarray} and the
% \textit{\TeX book} to see how best to do this, and then went my own way.
% If it doesn't work it's all my fault.
%
% \subsubsection{Some useful registers}
%
% The old \LaTeX\ version puts the equation numbers in by keeping a count of
% where it is in the alignment.  Since I don't know how may columns there are
% going to be, I'll just use a switch in the preamble to tell me to stop
% tabbing.
%
%    \begin{macrocode}
\newif\if@eqalast
%    \end{macrocode}
%
% Now define some useful length parameters.  First allocate them:
%
%    \begin{macrocode}
\newskip\eqaopenskip
\newskip\eqacloseskip
\newskip\eqacolskip
\newskip\eqainskip
%    \end{macrocode}
%
% Now assign some default values.  Users can play with these if they really
% want although I can't see the point myself.
%
%    \begin{macrocode}
\if@fleqn
  \AtBeginDocument{\eqaopenskip\leftmargini}
\else
  \eqaopenskip\@centering
\fi
\eqacloseskip\@centering
\eqacolskip\@centering
\eqainskip\z@
%    \end{macrocode}
%
% We allow the user to play with the style if this is really wanted.  I dunno
% why, really.  Maybe someone wants very small alignments.
%
%    \begin{macrocode}
\let\eqa@style\displaystyle
%    \end{macrocode}
%
% \subsubsection{The main environments}
%
% We define the toplevel commands here.  They just add in default arguments
% and then call |\@eqnarray| with a preamble string.  The only difference is
% the last column they add in -- \env{eqnarray$*$} throws away the last
% column by sticking it in box~0.  (I used to |\@gobble| it but that caused
% the |\cr| to be lost.)
%
%    \begin{macrocode}
\def\eqnarray{\@ifnextchar[\eqnarray@i{\eqnarray@i[rcl]}}
\def\eqnarray@i[#1]{%
  \@eqnarray{#1!{\hb@xt@\z@{\hss##}\tabskip\z@}}
}
\@namedef{eqnarray*}{\@ifnextchar[\eqnarray@s@i{\eqnarray@s@i[rcl]}}
\def\eqnarray@s@i[#1]{%
  \@eqnarray{#1!{\nonumber\setbox\z@\hbox{##}\tabskip\z@}}%
}
%    \end{macrocode}
%
% \subsubsection{Set up the initial display}
%
% \begin{macro}{\@eqnarray}
%
% The |\@eqnarray| command does most of the initial work.  It sets up some
% flags and things, builds the |\halign| preamble, and returns.
%
%    \begin{macrocode}
\def\@eqnarray#1{%
%    \end{macrocode}
%
% Start playing with the counter here.  The original does some icky internal
% playing, which isn't necessary.  The |\if@eqnsw| switch is |true| if the
% user hasn't supplied an equation number.  The |\if@eqalast| switch is
% |true| in the final equation-number column.
%
%    \begin{macrocode}
  \refstepcounter{equation}%
  \@eqalastfalse%
  \global\@eqnswtrue%
  \m@th%
%    \end{macrocode}
%
% Set things up for the |\halign| which is coming up.
%
%    \begin{macrocode}
  \openup\jot%
  \tabskip\eqaopenskip%
  \let\\\@eqncr%
  \everycr{}%
  $$%
%    \end{macrocode}
%
% We'll build the real |\halign| and preamble in a token register.  All we
% need to do is stuff the header in the token register, clear a switch
% (that'll be explained later), parse the preamble and then expand the
% tokens we collected.  Easy, no?
%
%    \begin{macrocode}
  \toks@{\halign to\displaywidth\bgroup}%
  \@tempswafalse%
  \eqa@preamble#1\end%
  \the\toks@\cr%
}
%    \end{macrocode}
%
% \end{macro}
%
% \subsubsection{Parsing the preamble}
%
% All this actually involves is reading the next character and building a
% command from it.  That can pull off an argument if it needs it.  Just make
% sure we don't fall off the end and we'll be OK.
%
%    \begin{macrocode}
\def\eqa@preamble#1{%
  \ifx\end#1\else\csname eqa@char@#1\expandafter\endcsname\fi%
}
%    \end{macrocode}
%
% Adding stuff to the preamble tokens is a simple matter of using
% |\expandafter| in the correct way.\footnote{^^A
%   I have no idea why \LaTeX\ uses \cmd\edef\ for building its preamble.  It
%   seems utterly insane to me -- the amount of bodgery that \env{tabular}
%   has to go through to make everything expand at the appropriate times is
%   scary.  Maybe Messrs~Lamport and Mittelbach just forgot about token
%   registers when they were writing the code.  Maybe I ought to rewrite the
%   thing properly some time.  Sigh.
%
%   As a sort of postscript to the above, I \emph{have} rewritten the
%   \env{tabular} environment, and made a damned fine job of it, in my
%   oh-so-humble opinion.  All this \env{eqnarray} stuff has been remoulded
%   in terms of the generic column-defining things in \package{mdwtab}.
%   You're reading the documentation of the old version, which isn't
%   supported any more, so any bugs here are your own problem.}
%
%    \begin{macrocode}
\def\eqa@addraw#1{\expandafter\toks@\expandafter{\the\toks@#1}}
%    \end{macrocode}
%
% Now for some cleverness again.  In order to put all the right bits of
% |\tabskip| glue in the right places we must \emph{not} terminate each
% column until we know what the next one is.  We set |\if@tempswa| to be
% |true| if there's a column waiting to be closed (so it's initially
% |false|).  The following macro adds a column correctly, assuming we're in
% a formula.  Other column types make their own arrangements.
%
%    \begin{macrocode}
\def\eqa@add#1{%
  \if@tempswa%
    \eqa@addraw{\tabskip\eqainskip&#1}%
  \else%
    \eqa@addraw{#1}%
  \fi%
  \@tempswatrue%
}
%    \end{macrocode}
%
% Now to defining column types.  Let's define a macro which allows us to
% define column types:
%
%    \begin{macrocode}
\def\eqa@def#1{\expandafter\def\csname eqa@char@#1\endcsname}
%    \end{macrocode}
%
% Now we can define the column types.  Each column type must loop back to
% |\eqa@preamble| once it's finished, to read the rest of the preamble
% string.  Note the positioning of ord atoms in the stuff below.  This will
% space out relations and binops correctly when they occur at the edges of
% columns, and won't affect ord atoms at the edges, because ords pack
% closely.
%
% First the easy onces.  Just stick |\hfil| in the right places and
% everything will be all right.
%
%    \begin{macrocode}
\eqa@def r{\eqa@add{\hfil$\eqa@style##{}$}\eqa@preamble}
\eqa@def c{\eqa@add{\hfil$\eqa@style{}##{}$\hfil}\eqa@preamble}
\eqa@def l{\eqa@add{$\eqa@style{}##$\hfil}\eqa@preamble}
\eqa@def x{\eqa@add{\hfil$\eqa@style##$\hfil}\eqa@preamble}
%    \end{macrocode}
%
% Now for the textual ones.  This is also fairly easy.
%
%    \begin{macrocode}
\eqa@def T#1{%
  \eqa@add{}%
  \if#1l\else\eqa@addraw{\hfil}\fi%
  \eqa@addraw{##}%
  \if#1r\else\eqa@addraw{\hfil}\fi%
  \eqa@preamble%
}
%    \end{macrocode}
%
% Sort of split types of equations.  I mustn't use |\rlap| here, or
% everything goes wrong -- |\\| doesn't get noticed by \TeX\ in the same way
% as |\cr| does.
%
%    \begin{macrocode}
\eqa@def L{\eqa@add{\hb@xt@\z@{$\eqa@style##$\hss}\qquad}\eqa@preamble}
%    \end{macrocode}
%
% The \lit{:} column type is fairly simple.  We set |\tabskip| up to make
% lots of space and close the current column, because there must be one.^^A
% \footnote{This is an assumption.}
%
%    \begin{macrocode}
\eqa@def :{%
  \eqa@addraw{\tabskip\eqacolskip&}\@tempswafalse\eqa@preamble%
}
\eqa@def q{\eqa@add{\quad}\@tempswafalse\eqa@preamble}
%    \end{macrocode}
%
% The other column types just insert given text in an appropriate way.
%
%    \begin{macrocode}
\eqa@def >#1{\eqa@add{#1}\@tempswafalse\eqa@preamble}
\eqa@def <#1{\eqa@addraw{#1}\eqa@preamble}
%    \end{macrocode}
%
% Finally, the magical \lit{!} column type, which sets the equation number.
% We set up the |\tabskip| glue properly, tab on, and set the flag which
% marks the final column.
%
%    \begin{macrocode}
\eqa@def !#1{%
  \eqa@addraw{\tabskip\eqacloseskip&\@eqalasttrue#1}\eqa@preamble%
}
%    \end{macrocode}
%
% \subsubsection{Newline codes}
%
% Newline sequences (|\\|) get turned into calls of |\@eqncr|.  The job is
% fairly simple, really.  However, to avoid reading `|&|' characters
% prematurely, we set up a magic brace (from the \package{array} package --
% this avoids creating ord atoms and other nastyness).
%
%    \begin{macrocode}
\def\@eqncr{%
  \iffalse{\fi\ifnum0=`}\fi%
  \@ifstar{\eqacr@i{\@M}}{\eqacr@i{\interdisplaylinepenalty}}%
}
\def\eqacr@i#1{\@ifnextchar[{\eqacr@ii{#1}}{\eqacr@ii{#1}[\z@]}}
\def\eqacr@ii#1[#2]{%
  \ifnum0=`{}\fi%
  \eqa@eqnum%
  \noalign{\penalty#1\vskip#2\relax}%
}
%    \end{macrocode}
%
% \subsubsection{Setting equation numbers}
%
% Before we start, we need to generalise the flush-left number handling bits.
% The macro |\eqa@eqpos| will put its argument in the right place.
%
%    \begin{macrocode}
\if@leqno
  \def\eqa@eqpos#1{%
    \hb@xt@.01\p@{}\rlap{\normalfont\normalcolor\hskip-\displaywidth#1}%
  }
\else
  \def\eqa@eqpos#1{\normalfont\normalcolor#1}
\fi
%    \end{macrocode}
%
% First we need to move into the right column.  Then we just set the equation
% number appropriately.  There is some subtlety here, ish.  The |\relax| is
% important, to delay expansion of the |\if|\dots\ until the new column has
% been started.  The two helper macros are important too, to hide `|&|'s and
% `|\cr|'s from \TeX's scanner until the right time.
%
%    \begin{macrocode}
\def\eqa@eqnum{%
  \relax%
  \if@eqalast\expandafter\eqa@eqnum@i\else\expandafter\eqa@eqnum@ii\fi%
}
\def\eqa@eqnum@i{%
  \if@eqnsw%
    \eqa@eqpos{(\theequation)}\stepcounter{equation}%
  \else%
    \eqa@eqpos\eqa@number%
  \fi%
  \global\@eqnswtrue%
  \cr%
}
\def\eqa@eqnum@ii{&\eqa@eqnum}
%    \end{macrocode}
%
% \subsubsection{Numbering control}
%
% This is trivial.  We set the |\if@eqnsw| flag to be |false| and store the
% text in a macro.
%
%    \begin{macrocode}
\let\nonumber\relax
\newcommand\nonumber[1][]{\global\@eqnswfalse\global\def\eqa@number{#1}}
%    \end{macrocode}
%
% \subsubsection{Closing the environments off}
%
% This is really easy.  Set the final equation number, close the |\halign|,
% tidy up the equation counter (it's been stepped once too many times) and
% close the display.
%
%    \begin{macrocode}
\def\endeqnarray{%
  \eqa@eqnum%
  \egroup%
  \global\advance\c@equation\m@ne%
  $$%
  \global\@ignoretrue%
}
\expandafter\let\csname endeqnarray*\endcsname\endeqnarray
%    \end{macrocode}
%
% Now start up the other package again.
%
%    \begin{macrocode}
%</oldeqnarray>
%<*package>
%    \end{macrocode}
%
% \end{old-eqnarray}
%
% That's all there is.  Byebye.
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \hfill Mark Wooding, \today
%
% \Finale
\endinput