mdwmath.dtx: Add `\defop' for defining new operators, and use it.
[mdwtools] / mdwmath.dtx
1 % \begin{meta-comment} <general public licence>
2 %%
3 %% mdwmath package -- various nicer mathematical things
4 %% Copyright (c) 2003, 2020 Mark Wooding
5 %%
6 %% This file is part of the `mdwtools' LaTeX package collection.
7 %%
8 %% `mdwtools' is free software: you can redistribute it and/or modify it
9 %% under the terms of the GNU General Public License as published by the
10 %% Free Software Foundation; either version 2 of the License, or (at your
11 %% option) any later version.
12 %%
13 %% `mdwtools' is distributed in the hope that it will be useful, but
14 %% WITHOUT ANY WARRANTY; without even the implied warranty of
15 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 %% General Public License for more details.
17 %%
18 %% You should have received a copy of the GNU General Public License
19 %% along with `mdwtools'. If not, write to the Free Software Foundation,
20 %% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 %%
22 % \end{meta-comment}
23 %
24 % \begin{meta-comment} <Package preamble>
25 %<+package>\NeedsTeXFormat{LaTeX2e}
26 %<+package>\ProvidesPackage{mdwmath}
27 %<+package> [2020/09/06 1.14.0 Nice mathematical things]
28 %<+oldeqnarray>\NeedsTeXFormat{LaTeX2e}
29 %<+oldeqnarray>\ProvidesPackage{eqnarray}
30 %<+oldeqnarray> [2020/09/06 1.14.0 Old enhanced eqnarray]
31 % \end{meta-comment}
32 %
33 % \CheckSum{728}
34 %% \CharacterTable
35 %% {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
36 %% 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
37 %% Digits \0\1\2\3\4\5\6\7\8\9
38 %% Exclamation \! Double quote \" Hash (number) \#
39 %% Dollar \$ Percent \% Ampersand \&
40 %% Acute accent \' Left paren \( Right paren \)
41 %% Asterisk \* Plus \+ Comma \,
42 %% Minus \- Point \. Solidus \/
43 %% Colon \: Semicolon \; Less than \<
44 %% Equals \= Greater than \> Question mark \?
45 %% Commercial at \@ Left bracket \[ Backslash \\
46 %% Right bracket \] Circumflex \^ Underscore \_
47 %% Grave accent \` Left brace \{ Vertical bar \|
48 %% Right brace \} Tilde \~}
49 %%
50 %
51 % \begin{meta-comment}
52 %
53 %<*driver>
54 \input{mdwtools}
55 \let\opmod\pmod
56 \usepackage{amssymb}
57 \describespackage{mdwmath}
58 %\describespackage{eqnarray}
59 \ignoreenv{old-eqnarray}
60 %\unignoreenv{old-eqnarray}
61 \mdwdoc
62 %</driver>
63 %
64 % \end{meta-comment}
65 %
66 % \section{User guide}
67 %
68 % \subsection{Square root typesetting}
69 %
70 % \DescribeMacro{\sqrt}
71 % The package supplies a star variant of the |\sqrt| command which omits the
72 % vinculum over the operand (the line over the top). While this is most
73 % useful in simple cases like $\sqrt*{2}$ it works for any size of operand.
74 % The package also re-implements the standard square root command so that it
75 % positions the root number rather better.
76 %
77 % \begin{figure}
78 % \begin{demo}[w]{Examples of the new square root command}
79 %\[ \sqrt*{2} \quad \mbox{rather than} \quad \sqrt{2} \]
80 %\[ \sqrt*[3]{2} \quad \mbox{ rather than } \quad \sqrt[3]{2} \]
81 %\[ \sqrt{x^3 + \sqrt*[y]{\alpha}} - \sqrt*[n+1]{a} \]
82 %\[ x = \sqrt*[3]{\frac{3y}{7}} \]
83 %\[ q = \frac{2\sqrt*{2}}{5}+\sqrt[\frac{n+1}{2}]{2x^2+3xy-y^2} \]
84 % \end{demo}
85 % \end{figure}
86 %
87 % [Note that omission of the vinculum was originally a cost-cutting exercise
88 % because the radical symbol can just fit in next to its operand and
89 % everything ends up being laid out along a line. However, I find that the
90 % square root without vinculum is less cluttered, so I tend to use it when
91 % it doesn't cause ambiguity.]
92 %
93 % \subsection{Modular arithmetic}
94 %
95 % In standard maths mode, there's too much space before the parentheses in
96 % the output of the |\pmod| command. Suppose that $x \equiv y^2 \opmod n$:
97 % then the spacing looks awful. Go on, admit it.
98 %
99 % It looks OK in a display. For example, if
100 % \[ c \equiv m^e \opmod n \]
101 % then it's fine. The package redefines the |\pmod| command to do something
102 % more sensible. So now $c^d \equiv m^{ed} \equiv m \pmod n$ and all looks
103 % fine.
104 %
105 % \subsection{Some maths symbols you already have}
106 %
107 % \DescribeMacro\bitor
108 % \DescribeMacro\bitand
109 % \DescribeMacro\dblor
110 % \DescribeMacro\dbland
111 % Having just tried to do some simple things, I've found that there are maths
112 % symbols missing. Here they are, in all their glory:
113 % \begin{center} \unverb\| \begin{tabular}{cl|cl|cl}
114 % $\&$ & "\&" & $\bitor$ & "\bitor" & $\dbland$ & "\dbland" \\
115 % $\bitand$ & "\bitand" & $\dblor$ & "\dblor" &
116 % \end{tabular} \end{center}
117 %
118 % \DescribeMacro\xor
119 % \DescribeMacro\cat
120 % I also set up the |\xor| command to typeset `$\xor$', which is commonly
121 % used to represent the bitsize exclusive-or operation among cryptographers.
122 % The command |\cat| typesets `$\cat$', which is a common operator indicating
123 % concatenation of strings.
124 %
125 % \DescribeMacro\lsl
126 % \DescribeMacro\lsr
127 % \DescribeMacro\rol
128 % \DescribeMacro\ror
129 % The commands |\lsl| and |\lsr| typeset binary operators `$\lsl$' and
130 % `$\lsr$' respectively, and |\rol| and |\ror| typeset `$\rol$' and `$\ror$'.
131 % Note that these are spaced as binary operators, rather than relations.
132 %
133 % \DescribeMacro\compose
134 % \DescribeMacro\implies
135 % \DescribeMacro\vect
136 % The |\compose| command typesets `$\compose$', which is usually used to
137 % denote function composition. The |\implies| command is made to typeset
138 % `$\implies$'. And \syntax{"\\vect{"<x>"}"} typesets `$\vect{x}$'.
139 %
140 % \DescribeMacro\statclose
141 % \DescribeMacro\compind
142 % The |\statclose| command typesets `$\statclose$', which indicates
143 % `statistical closeness' of probability distributions; |\compind| typesets
144 % `$\compind$', which indicates computational indistinguishability.
145 %
146 % \subsection{Fractions}
147 %
148 % \DescribeMacro\fracdef
149 % We provide a general fraction system, a little tiny bit like
150 % \package{amsmath}'s |\genfrac|. Say
151 % \syntax{"\\fracdef{"<name>"}{"<frac-params>"}"} to define a new
152 % |\frac|-like operator. The \<frac-params> are a comma-separated list of
153 % parameters:
154 % \begin{description}
155 % \item[\lit*{line}] Include a horizontal line between the top and bottom
156 % (like |\frac|).
157 % \item[\lit*{line=}\<length>] Include a horizontal line with width
158 % \<length>.
159 % \item[\lit*{noline}] Don't include a line (like |\binom|).
160 % \item[\lit*{leftdelim=}\<delim>] Use \<delim> as the left-hand delimiter.
161 % \item[\lit*{rightdelim=}\<delim>] Use \<delim> as the right-hand delimiter.
162 % \item[\lit*{nodelims}] Don't include delimiters.
163 % \item[\lit*{style=}\<style>] Typeset the fraction in \<style>, which is one
164 % of |display|, |text|, |script| or |scriptscript|.
165 % \item[\lit*{style}] Use the prevailing style for the fraction.
166 % \item[\lit*{innerstyle=}\<style>] Typeset the \emph{components} of the
167 % fraction in \<style>.
168 % \item[\lit*{innerstyle}] Typeset the fraction components according to the
169 % prevailing style.
170 % \end{description}
171 % The commands created by |\fracdef| have the following syntax:
172 % \syntax{<name>"["<frac-params>"]{"<top>"}{"<bottom>"}"}. Thus, you can use
173 % the optional argument to `tweak' the fraction if necessary. This isn't
174 % such a good idea to do often.
175 %
176 % \DescribeMacro\frac
177 % \DescribeMacro\binom
178 % \DescribeMacro\jacobi
179 % The macros |\frac|, |\binom| and |\jacobi| are defined using |\fracdef|.
180 % They typset $\frac{x}{y}$, $\binom{n}{k}$ and $\jacobi{x}{n}$ respectively.
181 % (The last may be of use to number theorists talking about Jacobi or
182 % Lagrange symbols.)
183 %
184 % By way of example, these commands were defined using
185 %\begin{verbatim}
186 %\fracdef\frac{nodelims, line}
187 %\fracdef\binom{leftdelim = (, rightdelim = ), noline}
188 %\fracdef\jacobi{leftdelim = (, rightdelim = ), line}
189 %\end{verbatim}
190 %
191 % \subsection{Rant about derivatives}
192 %
193 % \DescribeMacro\d
194 % There is a difference between UK and US typesetting of derivatives.
195 % Americans typeset
196 % \[ \frac{dy}{dx} \]
197 % while the British want
198 % \[ \frac{\d y}{\d x}. \]
199 % The command |\d| command is fixed to typeset a `$\d$'. (In text mode,
200 % |\d{x}| still typesets `\d{x}'.)
201 %
202 % \subsection{New operator names}
203 %
204 % \DescribeMacro\keys
205 % \DescribeMacro\dom
206 % \DescribeMacro\ran
207 % \DescribeMacro\supp
208 % \DescribeMacro\lcm
209 % \DescribeMacro\ord
210 % \DescribeMacro\poly
211 % \DescribeMacro\negl
212 % A few esoteric new operator names are supplied.
213 % \begin{center} \unverb\| \begin{tabular}{cl|cl|cl}
214 % $\keys$ & "\keys" & $\dom$ & "\dom" & $\ran$ & "\ran" \\
215 % $\supp$ & "\supp" & $\lcm$ & "\lcm" & $\ord$ & "\ord" \\
216 % $\poly$ & "\poly" & $\negl$ & "\negl"
217 % \end{tabular} \end{center}
218 % I think |\lcm| ought to be self-explanatory. The |\dom| and |\ran|
219 % operators pick out the domain and range of a function, respectively; thus,
220 % if $F\colon X \to Y$ is a function, then $\dom F = X$ and $\ran F = Y$.
221 % The \emph{support} of a probability distribution $\mathcal{D}$ is the set
222 % of objects with nonzero probability; i.e., $\supp{D} = \{\, x \in
223 % \dom\mathcal{D} \mid \mathcal{D}(x) > 0 \,\}$. If $g \in G$ is a group
224 % element then $\ord g$ is the \emph{order} of $g$; i.e., the smallest
225 % positive integer $i$ where $g^i$ is the identity element, or $0$ if there
226 % is no such $i$. $\poly(n)$ is some polynomial function of $n$. A function
227 % $\nu(\cdot)$ is \emph{negligible} if, for every polynomial function
228 % $p(\cdot)$, there is an integer $N$ such that $\nu(n) < 1/p(n)$ for all $n
229 % > N$; $\negl(n)$ is some negligible function of $n$.
230 %
231 % \DescribeMacro\defop
232 % New operators can be defined using |\defop|:
233 % \begin{quote} \syntax{"\\defop"["*"]"{"<command>"}{"<text>"}"} \end{quote}
234 % defines \<command> to be an operator which typesets \<text>. By default,
235 % limits will be placed above and below the operator in display style; with
236 % |*|, limits are always written as super- and subscripts.
237 %
238 % \subsection{Standard set names}
239 %
240 % \DescribeMacro\Z
241 % \DescribeMacro\Q
242 % \DescribeMacro\R
243 % \DescribeMacro\C
244 % \DescribeMacro\N
245 % \DescribeMacro\F
246 % \DescribeMacro\powerset
247 % \DescribeMacro\gf
248 % If you have a |\mathbb| command defined, the following magic is revealed:
249 % \begin{center} \unverb\| \begin{tabular}{cl|cl|cl}
250 % $\Z$ & "\Z" & $\Q$ & "\Q" & $\R$ & "\R" \\
251 % $\N$ & "\N" & $\F$ & "\F" & $\C$ & "\C"
252 % \end{tabular} \end{center}
253 % which are handy for various standard sets of things. Also the |\powerset|
254 % command typesets `$\powerset$', and \syntax{"\\gf{"<q>"}"}, which by default
255 % typesets $\gf{\syntax{<q>}}$ but you might choose to have it set
256 % $\mathrm{GF}(\syntax{<q>})$ intead.
257 %
258 % \subsection{Biggles}
259 %
260 % \DescribeMacro\bbigg
261 % \DescribeMacro\bbiggl
262 % \DescribeMacro\bbiggr
263 % \DescribeMacro\bbiggm
264 % The |\bbigg| commands generalizes the Plain \TeX\ |\bigg| family of
265 % macros. |\bbigg| produces an `ordinary' symbol; |\bbiggl| and |\bbiggr|
266 % produce left and right delimiters; and |\bbiggm| produces a relation. They
267 % produce symbols whose size is related to the prevailing text size -- so
268 % they adjust correctly in chapter headings, for example.
269 %
270 % The syntax is straightforward:
271 % \syntax{"\\"<bigop>"["$a$"]{"$n$"}{"<delim>"}"}. Describing it is a bit
272 % trickier. The size is based on the current |\strut| height. If |\strut|
273 % has a height of $h$ and a depth of $d$, then the delimiter produced has a
274 % height of $n \times (h + d + a)$.
275 %
276 % The old |\big| commands have been redefined in terms of |\bbigg|.
277 %
278 % \subsection{The `QED' symbol}
279 %
280 % \DescribeMacro\qed
281 % \DescribeMacro\qedrule
282 % For use in proofs of theorems, we provide a `QED' symbol which behaves well
283 % under bizarre line-splitting conditions. To use it, just say |\qed|. The
284 % little `\qedrule' symbol is available on its own, by saying |\qedrule|.
285 % This also sets |\qedsymbol| if it's not set already.
286 % \qed
287 %
288 % \subsection{Punctuation in displays}
289 %
290 % It's conventional to follow displayed equations with the necessary
291 % punctuation for them to fit into the surrounding prose. This isn't
292 % universal: Ian Stewart says in the preface to the third edition of his
293 % \emph{Galois Theory}:\footnote{^^A
294 % Chapman \& Hall/CRC Mathematics, 2004; ISBN 1-58488-393-6.} ^^A
295 % \begin{quote}
296 % Along the way I made once change that may raise a few eyebrows. I have
297 % spent much of my career telling students that written mathematics should
298 % have punctuation as well as symbols. If a symbol or a formula would be
299 % followed by a comma if it were replaced by a word or phrase, then it
300 % should be followed by a comma; however strange the formula then looks.
301 %
302 % I still think that punctuation is essential for formulas in the main body
303 % of the text. If the formula is $t^2 + 1$, say, then it should have its
304 % terminating comma. But I have come to the conclusion that eliminating
305 % visual junk from the printed page is more important than punctuatory
306 % pedantry, so that when the same formula is \emph{displayed}, for example
307 % \[ t^2 + 1 \]
308 % then it looks silly if the comma is included, like this,
309 % \[ t^2 + 1 \mpunct{,} \]
310 % and everything is much cleaner and less ambiguous without punctuation.
311 %
312 % Purists will hate this, though many of them would not have noticed had I
313 % not pointed it out here. Until recently, I would have agreed. But I
314 % think it is time we accepted that the act of displaying a formula equips
315 % it with \emph{implicit} (invisible) punctuation. This is the 21st
316 % century, and typography has moved on.
317 % \end{quote}%
318 %
319 % \DescribeMacro\mpunct
320 % I tended to agree with Prof.\ Stewart, even before I read his preface; but
321 % now I'm not so sure, and it's clear that we're in the minority. Therefore,
322 % the command |\mpunct| sets its argument as text, a little distance from
323 % the preceding mathematics.
324 %
325 % \begin{ignore}
326 % There used to be an eqnarray here, but that's migrated its way into the
327 % \package{mdwtab} package. Maybe the original version, without dependency
328 % on \package{mdwtab} ought to be releasable separately. I'll keep it around
329 % just in case.
330 %
331 % The following is the documentation for the original version. There's an
332 % updated edition in \package{mdwtab}.
333 % \end{ignore}
334 %
335 % \begin{old-eqnarray}
336 %
337 % \subsection{A new \env{eqnarray} environment}
338 %
339 % \LaTeX's built-in \env{eqnarray} is horrible -- it puts far too much space
340 % between the items in the array. This environment is rather nearer to the
341 % \env{amsmath} \env{align} environments, although rather less capable.
342 %
343 % \bigskip
344 % \DescribeEnv{eqnarray}
345 % {\synshorts
346 % \setbox0\hbox{"\\begin{eqnarray}["<preamble>"]" \dots "\\end{eqnarray}"}
347 % \leavevmode \hskip-\parindent \fbox{\box0}
348 % }
349 % \smallskip
350 %
351 % The new version of \env{eqnarray} tries to do everything which you really
352 % want it to. The \synt{preamble} string allows you to define the column
353 % types in a vaguely similar way to the wonderful \env{tabular} environment.
354 % The types provided (and it's easy-ish to add more) are:
355 %
356 % \def\ch{\char`}
357 % \begin{description} \setdescriptionlabel{\normalfont\ttfamily#1}
358 % \item [r] Right aligned equation
359 % \item [c] Centre-aligned equation
360 % \item [l] Left aligned equation
361 % \item [\textrm{\texttt{Tr}, \texttt{Tc} and \texttt{Tl}}] Right, centre and
362 % left aligned text (not maths)
363 % \item [L] Left aligned zero-width equation
364 % \item [x] Centred entire equation
365 % \item [:] Big gap separating sets of equations
366 % \item [q] Quad space
367 % \item [>\ch\{\synt{text}\ch\}] Insert text before column
368 % \item [<\ch\{\synt{text}\ch\}] Insert text after column
369 % \end{description}
370 %
371 % Some others are also defined: don't use them because they do complicated
372 % things which are hard to explain and they aren't much use anyway.
373 %
374 % The default preamble, if you don't supply one of your own, is \lit{rcl}.
375 % Most of the time, \lit{rl} is sufficient, although compatibility is more
376 % important to me.
377 %
378 % By default, there is no space between columns, which makes formul\ae\ in an
379 % \env{eqnarray} environment look just like formul\ae\ typeset on their own,
380 % except that things get aligned in columns. This is where the default
381 % \env{eqnarray} falls down: it leaves |\arraycolsep| space between each
382 % column making the thing look horrible.
383 %
384 % An example would be good here, I think. This one's from exercise 22.9 of
385 % the \textit{\TeX book}.
386 %
387 % \begin{demo}[w]{Simultaneous equations}
388 %\begin{eqnarray}[rcrcrcrl]
389 % 10w & + & 3x & + & 3y & + & 18z & = 1 \\
390 % 6w & - & 17x & & & - & 5z & = 2
391 %\end{eqnarray}
392 % \end{demo}
393 %
394 % Choosing a more up-to-date example, here's one demonstrating the \lit{:}
395 % column specifier from the \textit{\LaTeX\ Companion}.
396 %
397 % \begin{demo}[w]{Lots of equations}
398 %\begin{eqnarray}[rl:rl:l]
399 % V_i &= v_i - q_i v_j, & X_i &= x_i - q_i x_j, &
400 % U_i = u_i, \qquad \mbox{for $i \ne j$} \label{eq:A} \\
401 % V_j &= v_j, & X_j &= x_j &
402 % U_j u_j + \sum_{i \ne j} q_i u_i.
403 %\end{eqnarray}
404 % \end{demo}
405 %
406 % We can make things more interesting by adding a plain text column. Here we
407 % go:
408 %
409 % \begin{demo}[w]{Plain text column}
410 %\begin{eqnarray}[rlqqTl]
411 % x &= y & by (\ref{eq:A}) \\
412 % x' &= y' & by definition \\
413 % x + x' &= y + y' & by Axiom~1
414 %\end{eqnarray}
415 % \end{demo}
416 %
417 % The new features also mean that you don't need to mess about with
418 % |\lefteqn| any more. This is handled by the \lit{L} column type:
419 %
420 % \begin{demo}{Splitting example}
421 %\begin{eqnarray*}[Ll]
422 % w+x+y+z = \\
423 % & a+b+c+d+e+{} \\
424 % & f+g+h+i+j
425 %\end{eqnarray*}
426 % \end{demo}
427 %
428 % Finally, just to prove that the spacing's right at last, here's another one
429 % from the \textit{Companion}.
430 %
431 % \begin{demo}{Spacing demonstration}
432 %\begin{equation}
433 % x^2 + y^2 = z^2
434 %\end{equation}
435 %\begin{eqnarray}[rl]
436 % x^2 + y^2 &= z^2 \\
437 % y^2 &< z^2
438 %\end{eqnarray}
439 % \end{demo}
440 %
441 % Well, that was easy enough. Now on to numbering. As you've noticed, the
442 % equations above are numbered. You can use the \env{eqnarray$*$}
443 % environment to turn off the numbering in the whole environment, or say
444 % |\nonumber| on a line to suppress numbering of that one in particular.
445 % More excitingly, you can say \syntax{"\\nonumber["<text>"]"} to choose
446 % what text to display.
447 %
448 % A note for cheats: you can use the sparkly new \env{eqnarray} for simple
449 % equations simply by specifying \lit{x} as the column description. Who
450 % needs \AmSTeX? |;-)|
451 %
452 % \end{old-eqnarray}
453 %
454 % \implementation
455 %
456 % \section{Implementation}
457 %
458 % This isn't really complicated (honest) although it is a lot hairier than I
459 % think it ought to be.
460 %
461 % \begin{macrocode}
462 %<*package>
463 \RequirePackage{amssymb}
464 \RequirePackage{mdwkey}
465 % \end{macrocode}
466 %
467 % \subsection{Square roots}
468 %
469 % \subsubsection{Where is the square root sign?}
470 %
471 % \LaTeX\ hides the square root sign away somewhere without telling anyone
472 % where it is. I extract it forcibly by peeking inside the |\sqrtsign| macro
473 % and scrutinising the contents. Here we go: prepare for yukkiness.
474 %
475 % \begin{macrocode}
476 \newcount\sq@sqrt \begingroup \catcode`\|0 \catcode`\\12
477 |def|sq@readrad#1"#2\#3|relax{|global|sq@sqrt"#2|relax}
478 |expandafter|sq@readrad|meaning|sqrtsign|relax |endgroup
479 \def\sq@delim{\delimiter\sq@sqrt\relax}
480 % \end{macrocode}
481 %
482 % \subsubsection{Drawing fake square root signs}
483 %
484 % \TeX\ absolutely insists on drawing square root signs with a vinculum over
485 % the top. In order to get the same effect, we have to attempt to emulate
486 % \TeX's behaviour.
487 %
488 % \begin{macro}{\sqrtdel}
489 %
490 % This does the main job of typesetting a vinculum-free radical.\footnote{^^A
491 % Note for chemists: this is nothing to do with short-lived things which
492 % don't have their normal numbers of electrons. And it won't reduce the
493 % appearance of wrinkles either.}
494 % It's more or less a duplicate of what \TeX\ does internally, so it might be
495 % a good plan to have a copy of Appendix~G open while you examine this.
496 %
497 % We start off by using |\mathpalette| to help decide how big things should
498 % be.
499 %
500 % \begin{macrocode}
501 \def\sqrtdel{\mathpalette\sqrtdel@i}
502 % \end{macrocode}
503 %
504 % Read the contents of the radical into a box, so we can measure it.
505 %
506 % \begin{macrocode}
507 \def\sqrtdel@i#1#2{%
508 \setbox\z@\hbox{$\m@th#1#2$}% %%% Bzzzt -- uncramps the mathstyle
509 % \end{macrocode}
510 %
511 % Now try and sort out the values needed in this calculation. We'll assume
512 % that $\xi_8$ is 0.6\,pt, the way it usually is. Next try to work out the
513 % value of $\varphi$.
514 %
515 % \begin{macrocode}
516 \ifx#1\displaystyle%
517 \@tempdima1ex%
518 \else%
519 \@tempdima.6\p@%
520 \fi%
521 % \end{macrocode}
522 %
523 % That was easy. Now for $\psi$.
524 %
525 % \begin{macrocode}
526 \@tempdimb.6\p@%
527 \advance\@tempdimb.25\@tempdima%
528 % \end{macrocode}
529 %
530 % Build the `delimiter' in a box of height $h(x)+d(x)+\psi+\xi_8$, as
531 % requested. Box~2 will do well for this purpose.
532 %
533 % \begin{macrocode}
534 \dimen@.6\p@%
535 \advance\dimen@\@tempdimb%
536 \advance\dimen@\ht\z@%
537 \advance\dimen@\dp\z@%
538 \setbox\tw@\hbox{%
539 $\left\sq@delim\vcenter to\dimen@{}\right.\n@space$%
540 }%
541 % \end{macrocode}
542 %
543 % Now we need to do some more calculating (don't you hate it?). As far as
544 % Appendix~G is concerned, $\theta=h(y)=0$, because we want no rule over the
545 % top.
546 %
547 % \begin{macrocode}
548 \@tempdima\ht\tw@%
549 \advance\@tempdima\dp\tw@%
550 \advance\@tempdima-\ht\z@%
551 \advance\@tempdima-\dp\z@%
552 \ifdim\@tempdima>\@tempdimb%
553 \advance\@tempdima\@tempdimb%
554 \@tempdimb.5\@tempdima%
555 \fi%
556 % \end{macrocode}
557 %
558 % Work out how high to raise the radical symbol. Remember that Appendix~G
559 % thinks that the box has a very small height, although this is untrue here.
560 %
561 % \begin{macrocode}
562 \@tempdima\ht\z@%
563 \advance\@tempdima\@tempdimb%
564 \advance\@tempdima-\ht\tw@%
565 % \end{macrocode}
566 %
567 % Build the output (finally). The brace group is there to turn the output
568 % into a mathord, one of the few times that this is actually desirable.
569 %
570 % \begin{macrocode}
571 {\raise\@tempdima\box\tw@\vbox{\kern\@tempdimb\box\z@}}%
572 }
573 % \end{macrocode}
574 %
575 % \end{macro}
576 %
577 % \subsubsection{The new square root command}
578 %
579 % This is where we reimplement all the square root stuff. Most of this stuff
580 % comes from the \PlainTeX\ macros, although some is influenced by \AmSTeX\
581 % and \LaTeXe, and some is original. I've tried to make the spacing vaguely
582 % automatic, so although it's not configurable like \AmSTeX's version, the
583 % output should look nice more of the time. Maybe.
584 %
585 % \begin{macro}{\sqrt}
586 %
587 % \LaTeX\ says this must be robust, so we make it robust. The first thing to
588 % do is to see if there's a star and pass the appropriate squareroot-drawing
589 % command on to the rest of the code.
590 %
591 % \begin{macrocode}
592 \DeclareRobustCommand\sqrt{\@ifstar{\sqrt@i\sqrtdel}{\sqrt@i\sqrtsign}}
593 % \end{macrocode}
594 %
595 % Now we can sort out an optional argument to be displayed on the root.
596 %
597 % \begin{macrocode}
598 \def\sqrt@i#1{\@ifnextchar[{\sqrt@ii{#1}}{\sqrt@iv{#1}}}
599 % \end{macrocode}
600 %
601 % Stages~2 and~3 below are essentially equivalents of \PlainTeX's
602 % |\root|\dots|\of| and |\r@@t|. Here we also find the first wrinkle: the
603 % |\rootbox| used to store the number is spaced out on the left if necessary.
604 % There's a backspace after the end so that the root can slip underneath, and
605 % everything works out nicely. Unfortunately size is fixed here, although
606 % doesn't actually seem to matter.
607 %
608 % \begin{macrocode}
609 \def\sqrt@ii#1[#2]{%
610 \setbox\rootbox\hbox{$\m@th\scriptscriptstyle{#2}$}%
611 \ifdim\wd\rootbox<6\p@%
612 \setbox\rootbox\hb@xt@6\p@{\hfil\unhbox\rootbox}%
613 \fi%
614 \mathpalette{\sqrt@iii{#1}}%
615 }
616 % \end{macrocode}
617 %
618 % Now we can actually build everything. Note that the root is raised by its
619 % depth -- this prevents a common problem with letters with descenders.
620 %
621 % \begin{macrocode}
622 \def\sqrt@iii#1#2#3{%
623 \setbox\z@\hbox{$\m@th#2#1{#3}$}%
624 \dimen@\ht\z@%
625 \advance\dimen@-\dp\z@%
626 \dimen@.6\dimen@%
627 \advance\dimen@\dp\rootbox%
628 \mkern-3mu%
629 \raise\dimen@\copy\rootbox%
630 \mkern-10mu%
631 \box\z@%
632 }
633 % \end{macrocode}
634 %
635 % Finally handle a non-numbered root. We read the rooted text in as an
636 % argument, to stop problems when people omit the braces. (\AmSTeX\ does
637 % this too.)
638 %
639 % \begin{macrocode}
640 \def\sqrt@iv#1#2{#1{#2}}
641 % \end{macrocode}
642 %
643 % \end{macro}
644 %
645 % \begin{macro}{\root}
646 %
647 % We also re-implement \PlainTeX's |\root| command, just in case someone uses
648 % it, and supply a star-variant. This is all very trivial.
649 %
650 % \begin{macrocode}
651 \def\root{\@ifstar{\root@i\sqrtdel}{\root@i\sqrtsign}}
652 \def\root@i#1#2\of{\sqrt@ii{#1}[#2]}
653 % \end{macrocode}
654 %
655 % \end{macro}
656 %
657 % \subsection{Modular programming}
658 %
659 % \begin{macro}{\pmod}
660 %
661 % Do some hacking if not |\ifouter|.
662 %
663 % \begin{macrocode}
664 \def\pmod#1{%
665 \ifinner\;\else\allowbreak\mkern18mu\fi%
666 ({\operator@font mod}\,\,#1)%
667 }
668 % \end{macrocode}
669 %
670 % \end{macro}
671 %
672 % \subsection{Some magic new maths characters}
673 %
674 % \begin{macro}{\bitor}
675 % \begin{macro}{\bitand}
676 % \begin{macro}{\dblor}
677 % \begin{macro}{\dbland}
678 % \begin{macro}{\xor}
679 % \begin{macro}{\lor}
680 % \begin{macro}{\ror}
681 % \begin{macro}{\lsl}
682 % \begin{macro}{\lsr}
683 %
684 % The new boolean operators.
685 %
686 % \begin{macrocode}
687 \DeclareMathSymbol{&}{\mathbin}{operators}{`\&}
688 \DeclareMathSymbol{\bitand}{\mathbin}{operators}{`\&}
689 \def\bitor{\mathbin\mid}
690 \def\dblor{\mathbin{\mid\mid}}
691 \def\dbland{\mathbin{\mathrel\bitand\mathrel\bitand}}
692 \let\xor\oplus
693 \def\lsl{\mathbin{<\!\!<}}
694 \def\lsr{\mathbin{>\!\!>}}
695 \def\rol{\mathbin{<\!\!<\!\!<}}
696 \def\ror{\mathbin{>\!\!>\!\!>}}
697 \AtBeginDocument{\ifx\lll\@@undefined\else
698 \def\lsl{\mathbin{\ll}}
699 \def\lsr{\mathbin{\gg}}
700 \def\rol{\mathbin{\lll}}
701 \def\ror{\mathbin{\ggg}}
702 \fi}
703 % \end{macrocode}
704 %
705 % \end{macro}
706 % \end{macro}
707 % \end{macro}
708 % \end{macro}
709 % \end{macro}
710 % \end{macro}
711 % \end{macro}
712 % \end{macro}
713 % \end{macro}
714 %
715 % \begin{macro}{\cat}
716 % \begin{macro}{\compose}
717 % \begin{macro}{\implies}
718 % \begin{macro}{\vect}
719 % \begin{macro}{\d}
720 % \begin{macro}{\jacobi}
721 %
722 % A mixed bag of stuff.
723 %
724 % \begin{macrocode}
725 \def\cat{\mathbin{\|}}
726 \let\compose\circ
727 \def\implies{\Rightarrow}
728 \def\vect#1{\mathord{\mathbf{#1}}}
729 \def\d{%
730 \ifmmode\mathord{\operator@font d}%
731 \else\expandafter\a\expandafter d\fi%
732 }
733 \def\jacobi#1#2{{{#1}\overwithdelims()#2}}
734 % \end{macrocode}
735 %
736 % \end{macro}
737 % \end{macro}
738 % \end{macro}
739 % \end{macro}
740 % \end{macro}
741 % \end{macro}
742 %
743 % \begin{macro}{\statclose}
744 % \begin{macro}{\compind}
745 %
746 % Fancy new relations for probability distributions.
747 %
748 % \begin{macrocode}
749 \def\statclose{\mathrel{\mathop{=}\limits^{\scriptscriptstyle s}}}
750 \def\compind{\mathrel{\mathop{\approx}\limits^{\scriptscriptstyle c}}}
751 % \end{macrocode}
752 %
753 % \end{macro}
754 % \end{macro}
755 %
756 % \begin{macro}{\defop}
757 % Defining new operator names.
758 % \begin{macrocode}
759 \def\defop{\@ifstar{\defop@\nolimits}{\defop@\limits}}
760 \def\defop@#1#2#3{\def#2{\mathop{\operator@font #3}#1}}
761 % \end{macrocode}
762 % \end{macro}
763 %
764 % \begin{macro}{\keys}
765 % \begin{macro}{\dom}
766 % \begin{macro}{\ran}
767 % \begin{macro}{\supp}
768 % \begin{macro}{\lcm}
769 % \begin{macro}{\poly}
770 % \begin{macro}{\negl}
771 % \begin{macro}{\ord}
772 %
773 % And the new operator names.
774 %
775 % \begin{macrocode}
776 \defop*\keys{keys}
777 \defop*\dom{dom}
778 \defop*\ran{ran}
779 \defop*\supp{supp}
780 \defop*\lcm{lcm}
781 \defop*\poly{poly}
782 \defop*\negl{negl}
783 \defop*\ord{ord}
784 % \end{macrocode}
785 %
786 % \end{macro}
787 % \end{macro}
788 % \end{macro}
789 % \end{macro}
790 % \end{macro}
791 % \end{macro}
792 % \end{macro}
793 % \end{macro}
794 %
795 % \subsection{Fractions}
796 %
797 % \begin{macro}{\@frac@parse}
798 %
799 % \syntax{"\\@frac@parse{"<stuff>"}{"<frac-params>"}"} -- run \<stuff>
800 % passing it three arguments: an infix fraction-making command, the `outer'
801 % style, and the `inner' style.
802 %
803 % This is rather tricky. We clear a load of parameters, parse the parameter
804 % list, and then build a token list containing the right stuff. Without the
805 % token list fiddling, we end up expanding things at the wrong times -- for
806 % example, |\{| expands to something terribly unpleasant in a document
807 % preamble.
808 %
809 % All of the nastiness is contained in a group.
810 %
811 % \begin{macrocode}
812 \def\@frac@parse#1#2{%
813 \begingroup%
814 \let\@wd\@empty\def\@ldel{.}\def\@rdel{.}%
815 \def\@op{over}\let\@dim\@empty\@tempswafalse%
816 \let\@is\@empty\let\@os\@empty%
817 \mkparse{mdwmath:frac}{#2}%
818 \toks\tw@{\endgroup#1}%
819 \toks@\expandafter{\csname @@\@op\@wd\endcsname}%
820 \if@tempswa%
821 \toks@\expandafter{\the\expandafter\toks@\@ldel}%
822 \toks@\expandafter{\the\expandafter\toks@\@rdel}%
823 \fi%
824 \expandafter\toks@\expandafter{\the\expandafter\toks@\@dim}%
825 \toks@\expandafter{\the\toks\expandafter\tw@\expandafter{\the\toks@}}
826 \toks@\expandafter{\the\expandafter\toks@\expandafter{\@os}}
827 \toks@\expandafter{\the\expandafter\toks@\expandafter{\@is}}
828 \the\toks@%
829 }
830 % \end{macrocode}
831 %
832 % The keyword definitions are relatively straightforward now. The error
833 % handling for \textsf{style} and \textsf{innerstyle} could do with
834 % improvement.
835 %
836 % \begin{macrocode}
837 \def\@frac@del#1#2{\def\@wd{withdelims}\@tempswatrue\def#1{#2}}
838 \mkdef{mdwmath:frac}{leftdelim}{\@frac@del\@ldel{#1}}
839 \mkdef{mdwmath:frac}{rightdelim}{\@frac@del\@rdel{#1}}
840 \mkdef{mdwmath:frac}{nodelims}*{\let\@wd\@empty\@tempswafalse}
841 \mkdef{mdwmath:frac}{line}{%
842 \def\@op{above}\setlength\dimen@{#1}\edef\@dim{\the\dimen@\space}%
843 }
844 \mkdef{mdwmath:frac}{line}*{\def\@op{over}\let\@dim\@empty}
845 \mkdef{mdwmath:frac}{noline}*{\def\@op{atop}\let\@dim\@empty}
846 \def\@frac@style#1#2{%
847 \ifx\q@delim#2\q@delim\let#1\@empty%
848 \else%
849 \expandafter\ifx\csname #2style\endcsname\relax%
850 \PackageError{mdwmath}{Bad maths style `#2'}\@ehc%
851 \else%
852 \edef#1{\csname#2style\endcsname}%
853 \fi%
854 \fi%
855 }
856 \mkdef{mdwmath:frac}{style}[]{\@frac@style\@os{#1}}
857 \mkdef{mdwmath:frac}{innerstyle}[]{\@frac@style\@is{#1}}
858 % \end{macrocode}
859 %
860 % \end{macro}
861 %
862 % \begin{macro}{\fracdef}
863 %
864 % Here's where the rest of the pain is. We do a preliminary parse of the
865 % parameters and `compile' the result into the output macro. If there's no
866 % optional argument, then we don't need to do any really tedious formatting
867 % at the point of use.
868 %
869 % \begin{macrocode}
870 \def\fracdef#1#2{\@frac@parse{\fracdef@i{#1}{#2}}{#2}}
871 \def\fracdef@i#1#2#3#4#5{\def#1{\@frac@do{#2}{#3}{#4}{#5}}}
872 \def\@frac@do#1#2#3#4{%
873 \@ifnextchar[{\@frac@complex{#1}}{\@frac@simple{#2}{#3}{#4}}%
874 }
875 \def\@frac@complex#1[#2]{\@frac@parse\@frac@simple{#1,#2}}
876 \def\@frac@simple#1#2#3#4#5{{#2{{#3#4}#1{#3#5}}}}
877 % \end{macrocode}
878 %
879 % \end{macro}
880 %
881 % \begin{macro}{\frac@fix}
882 % \begin{macro}{\@@over}
883 % \begin{macro}{\@@atop}
884 % \begin{macro}{\@@above}
885 % \begin{macro}{\@@overwithdelims}
886 % \begin{macro}{\@@atopwithdelims}
887 % \begin{macro}{\@@abovewithdelims}
888 %
889 % Finally, we need to fix up |\@@over| and friends. Maybe \package{amsmath}
890 % has hidden the commands away somewhere unhelpful. If not, we make the
891 % requisite copies.
892 %
893 % \begin{macrocode}
894 \def\q@delim{\q@delim}
895 \def\frac@fix#1{\expandafter\frac@fix@i\string#1\q@delim}
896 \def\frac@fix@i#1#2\q@delim{\frac@fix@ii{#2}\frac@fix@ii{#2withdelims}}
897 \def\frac@fix@ii#1{%
898 \expandafter\ifx\csname @@#1\endcsname\relax%
899 \expandafter\let\csname @@#1\expandafter\endcsname\csname#1\endcsname%
900 \fi%
901 }
902 \frac@fix\over \frac@fix\atop \frac@fix\above
903 % \end{macrocode}
904 %
905 % \end{macro}
906 % \end{macro}
907 % \end{macro}
908 % \end{macro}
909 % \end{macro}
910 % \end{macro}
911 % \end{macro}
912 %
913 % \begin{macro}{\frac}
914 % \begin{macro}{\binom}
915 % \begin{macro}{\jacobi}
916 %
917 % And finally, we define the fraction-making commands.
918 %
919 % \begin{macrocode}
920 \fracdef\frac{nodelims, line}
921 \fracdef\binom{leftdelim = (, rightdelim = ), noline}
922 \fracdef\jacobi{leftdelim = (, rightdelim = ), line}
923 % \end{macrocode}
924 %
925 % \end{macro}
926 % \end{macro}
927 % \end{macro}
928 %
929 % \subsection{Blackboard bold stuff}
930 %
931 % \begin{macro}{\Z}
932 % \begin{macro}{\Q}
933 % \begin{macro}{\R}
934 % \begin{macro}{\C}
935 % \begin{macro}{\N}
936 % \begin{macro}{\F}
937 % \begin{macro}{\powerset}
938 % \begin{macro}{\gf}
939 %
940 % First of all, the signs.
941 %
942 % \begin{macrocode}
943 \def\Z{\mathbb{Z}}
944 \def\Q{\mathbb{Q}}
945 \def\R{\mathbb{R}}
946 \def\C{\mathbb{C}}
947 \def\N{\mathbb{N}}
948 \def\F{\mathbb{F}}
949 \def\powerset{\mathbb{P}}
950 \def\gf#1{\F_{#1}}
951 %\def\gf#1{\mathrm{GF}({#1})}
952 % \end{macrocode}
953 %
954 % \end{macro}
955 % \end{macro}
956 % \end{macro}
957 % \end{macro}
958 % \end{macro}
959 % \end{macro}
960 % \end{macro}
961 % \end{macro}
962 %
963 % And now, define |\mathbb| if it's not there already.
964 %
965 % \begin{macrocode}
966 \AtBeginDocument{\ifx\mathbb\@@undefined\let\mathbb\mathbf\fi}
967 % \end{macrocode}
968 %
969 % \subsection{Biggles}
970 %
971 % Now for some user-controlled delimiter sizing. The standard bigness of
972 % plain \TeX's delimiters are all right, but it's a little limiting.
973 %
974 % The biggness of delimiters is based on the size of the current |\strut|,
975 % which \LaTeX\ keeps up to date all the time. This will make the various
976 % delimiters grow in proportion when the text gets bigger. Actually, I'm
977 % not sure that this is exactly right -- maybe it should be nonlinear,
978 %
979 % \begin{macro}{\bbigg}
980 % \begin{macro}{\bbiggl}
981 % \begin{macro}{\bbiggr}
982 % \begin{macro}{\bbiggm}
983 %
984 % This is where the bigness is done. This is more similar to the plain \TeX\
985 % big delimiter stuff than to the \package{amsmath} stuff, although there's
986 % not really a lot of difference.
987 %
988 % The two arguments are a multiplier for the delimiter size, and a small
989 % increment applied \emph{before} the multiplication (which is optional).
990 %
991 % This is actually a front for a low-level interface which can be called
992 % directly for efficiency.
993 %
994 % \begin{macrocode}
995 \def\bbigg{\@bbigg\mathord} \def\bbiggl{\@bbigg\mathopen}
996 \def\bbiggr{\@bbigg\mathclose} \def\bbiggm{\@bbigg\mathrel}
997 % \end{macrocode}
998 %
999 % \end{macro}
1000 % \end{macro}
1001 % \end{macro}
1002 % \end{macro}
1003 %
1004 % \begin{macro}{\@bbigg}
1005 %
1006 % This is an optional argument parser providing a front end for the main
1007 % macro |\bbigg@|.
1008 %
1009 % \begin{macrocode}
1010 \def\@bbigg#1{\@ifnextchar[{\@bigg@i{#1}}{\@bigg@i{#1}[\z@]}}
1011 \def\@bigg@i#1[#2]#3#4{#1{\bbigg@{#2}{#3}{#4}}}
1012 % \end{macrocode}
1013 %
1014 % \end{macro}
1015 %
1016 % \begin{macro}{\bbigg@}
1017 %
1018 % This is it, at last. The arguments are as described above: an addition
1019 % to be made to the strut height, and a multiplier. Oh, and the delimiter,
1020 % of course.
1021 %
1022 % This is a bit messy. The smallest `big' delimiter, |\big|, is the same
1023 % height as the current strut box. Other delimiters are~$1\frac12$, $2$
1024 % and~$2\frac12$ times this height. I'll set the height of the delimiter by
1025 % putting in a |\vcenter| of the appropriate size.
1026 %
1027 % Given an extra height~$x$, a multiplication factor~$f$ and a strut
1028 % height~$h$ and depth~$d$, I'll create a vcenter with total height
1029 % $f(h+d+x)$. Easy, isn't it?
1030 %
1031 % \begin{macrocode}
1032 \def\bbigg@#1#2#3{%
1033 {\hbox{$%
1034 \dimen@\ht\strutbox\advance\dimen@\dp\strutbox%
1035 \advance\dimen@#1%
1036 \dimen@#2\dimen@%
1037 \left#3\vcenter to\dimen@{}\right.\n@space%
1038 $}}%
1039 }
1040 % \end{macrocode}
1041 %
1042 % \end{macro}
1043 %
1044 % \begin{macro}{\big}
1045 % \begin{macro}{\Big}
1046 % \begin{macro}{\bigg}
1047 % \begin{macro}{\Bigg}
1048 %
1049 % Now for the easy macros.
1050 %
1051 % \begin{macrocode}
1052 \def\big{\bbigg@\z@\@ne}
1053 \def\Big{\bbigg@\z@{1.5}}
1054 \def\bigg{\bbigg@\z@\tw@}
1055 \def\Bigg{\bbigg@\z@{2.5}}
1056 % \end{macrocode}
1057 %
1058 % \end{macro}
1059 % \end{macro}
1060 % \end{macro}
1061 % \end{macro}
1062 %
1063 % \subsection{The `QED' symbol}
1064 %
1065 % \begin{macro}{\qed}
1066 % \begin{macro}{\qedrule}
1067 % \begin{macro}{\qedsymbol}
1068 %
1069 % This is fairly simple. Just be careful will the glue and penalties. The
1070 % size of the little box is based on the current font size.
1071 %
1072 % The horizontal list constructed by the macro is like this:
1073 %
1074 % \begin{itemize}
1075 % \item A |\quad| of space. This might get eaten if there's a break here or
1076 % before. That's OK, though.
1077 % \item An empty box, to break a run of discardable items.
1078 % \item A |\penalty 10000| to ensure that the spacing glue isn't discarded.
1079 % \item |\hfill| glue to push the little rule to the end of the line.
1080 % \item A little square rule `\qedrule', with some small kerns around it.
1081 % \item A glue item to counter the effect of glue added at the paragraph
1082 % boundary.
1083 % \end{itemize}
1084 %
1085 % The vertical mode case is simpler, but less universal. It copes with
1086 % relatively simple cases only.
1087 %
1088 % A |\qed| commend ends the paragraph.
1089 %
1090 % \begin{macrocode}
1091 \def\qed{%
1092 \ifvmode%
1093 \unskip%
1094 \setbox\z@\hb@xt@\linewidth{\hfil\strut\qedsymbol}%
1095 \prevdepth-\@m\p@%
1096 \ifdim\prevdepth>\dp\strutbox%
1097 \dimen@\prevdepth\advance\dimen@-\dp\strutbox%
1098 \kern-\dimen@%
1099 \fi%
1100 \penalty\@M\vskip-\baselineskip\box\z@%
1101 \else%
1102 \unskip%
1103 \penalty\@M\hfill%
1104 \hbox{}\penalty200\quad%
1105 \hbox{}\penalty\@M\hfill\qedsymbol\hskip-\parfillskip\par%
1106 \fi%
1107 }
1108 \def\qedrule{{%
1109 \dimen@\ht\strutbox%
1110 \advance\dimen@\dp\strutbox%
1111 \dimen@ii1ex%
1112 \advance\dimen@-\dimen@ii%
1113 \divide\dimen@\tw@%
1114 \advance\dimen@-\dp\strutbox%
1115 \advance\dimen@\dimen@ii%
1116 \advance\dimen@ii-\dimen@%
1117 \kern\p@%
1118 \vrule\@width1ex\@height\dimen@\@depth\dimen@ii%
1119 \kern\p@%
1120 }}
1121 \providecommand\qedsymbol{\qedrule}
1122 % \end{macrocode}
1123 %
1124 % \end{macro}
1125 % \end{macro}
1126 % \end{macro}
1127 %
1128 % \subsection{Punctuation in displays}
1129 %
1130 % \begin{macro}{\mpunct}
1131 %
1132 % This is actually a little more subtle than you'd expect. If the
1133 % \package{amstext} package is loaded, or something else has defined the
1134 % |\text| command, then we should use that; otherwise, just drop a box in and
1135 % hope for the best.
1136 %
1137 % \begin{macrocode}
1138 \def\mpunct#1{%
1139 \,%
1140 \ifx\text\@@undefined\hbox%
1141 \else\expandafter\text\fi%
1142 {#1}%
1143 }
1144 % \end{macrocode}
1145 %
1146 %\end{macro}
1147 %
1148 % \begin{ignore}
1149 % The following is the original definition of the enhanced eqnarray
1150 % environment. It's not supported, although if you can figure out how to
1151 % extract it, it's all yours.
1152 % \end{ignore}
1153 %
1154 % \begin{old-eqnarray}
1155 %
1156 % \subsection{The sparkly new \env{eqnarray}}
1157 %
1158 % Start off by writing a different package.
1159 %
1160 % \begin{macrocode}
1161 %</package>
1162 %<*oldeqnarray>
1163 % \end{macrocode}
1164 %
1165 % \subsubsection{Options handling}
1166 %
1167 % We need to be able to cope with \textsf{fleqn} and \textsf{leqno} options.
1168 % This will adjust our magic modified \env{eqnarray} environment
1169 % appropriately.
1170 %
1171 % \begin{macrocode}
1172 \newif\if@fleqn
1173 \newif\if@leqno
1174 \DeclareOption{fleqn}{\@fleqntrue}
1175 \DeclareOption{leqno}{\@leqnotrue}
1176 \ProcessOptions
1177 % \end{macrocode}
1178 %
1179 % This is all really different to the \LaTeX\ version. I've looked at the
1180 % various \env{tabular} implementations, the original \env{eqnarray} and the
1181 % \textit{\TeX book} to see how best to do this, and then went my own way.
1182 % If it doesn't work it's all my fault.
1183 %
1184 % \subsubsection{Some useful registers}
1185 %
1186 % The old \LaTeX\ version puts the equation numbers in by keeping a count of
1187 % where it is in the alignment. Since I don't know how may columns there are
1188 % going to be, I'll just use a switch in the preamble to tell me to stop
1189 % tabbing.
1190 %
1191 % \begin{macrocode}
1192 \newif\if@eqalast
1193 % \end{macrocode}
1194 %
1195 % Now define some useful length parameters. First allocate them:
1196 %
1197 % \begin{macrocode}
1198 \newskip\eqaopenskip
1199 \newskip\eqacloseskip
1200 \newskip\eqacolskip
1201 \newskip\eqainskip
1202 % \end{macrocode}
1203 %
1204 % Now assign some default values. Users can play with these if they really
1205 % want although I can't see the point myself.
1206 %
1207 % \begin{macrocode}
1208 \if@fleqn
1209 \AtBeginDocument{\eqaopenskip\leftmargini}
1210 \else
1211 \eqaopenskip\@centering
1212 \fi
1213 \eqacloseskip\@centering
1214 \eqacolskip\@centering
1215 \eqainskip\z@
1216 % \end{macrocode}
1217 %
1218 % We allow the user to play with the style if this is really wanted. I dunno
1219 % why, really. Maybe someone wants very small alignments.
1220 %
1221 % \begin{macrocode}
1222 \let\eqa@style\displaystyle
1223 % \end{macrocode}
1224 %
1225 % \subsubsection{The main environments}
1226 %
1227 % We define the toplevel commands here. They just add in default arguments
1228 % and then call |\@eqnarray| with a preamble string. The only difference is
1229 % the last column they add in -- \env{eqnarray$*$} throws away the last
1230 % column by sticking it in box~0. (I used to |\@gobble| it but that caused
1231 % the |\cr| to be lost.)
1232 %
1233 % \begin{macrocode}
1234 \def\eqnarray{\@ifnextchar[\eqnarray@i{\eqnarray@i[rcl]}}
1235 \def\eqnarray@i[#1]{%
1236 \@eqnarray{#1!{\hb@xt@\z@{\hss##}\tabskip\z@}}
1237 }
1238 \@namedef{eqnarray*}{\@ifnextchar[\eqnarray@s@i{\eqnarray@s@i[rcl]}}
1239 \def\eqnarray@s@i[#1]{%
1240 \@eqnarray{#1!{\nonumber\setbox\z@\hbox{##}\tabskip\z@}}%
1241 }
1242 % \end{macrocode}
1243 %
1244 % \subsubsection{Set up the initial display}
1245 %
1246 % \begin{macro}{\@eqnarray}
1247 %
1248 % The |\@eqnarray| command does most of the initial work. It sets up some
1249 % flags and things, builds the |\halign| preamble, and returns.
1250 %
1251 % \begin{macrocode}
1252 \def\@eqnarray#1{%
1253 % \end{macrocode}
1254 %
1255 % Start playing with the counter here. The original does some icky internal
1256 % playing, which isn't necessary. The |\if@eqnsw| switch is |true| if the
1257 % user hasn't supplied an equation number. The |\if@eqalast| switch is
1258 % |true| in the final equation-number column.
1259 %
1260 % \begin{macrocode}
1261 \refstepcounter{equation}%
1262 \@eqalastfalse%
1263 \global\@eqnswtrue%
1264 \m@th%
1265 % \end{macrocode}
1266 %
1267 % Set things up for the |\halign| which is coming up.
1268 %
1269 % \begin{macrocode}
1270 \openup\jot%
1271 \tabskip\eqaopenskip%
1272 \let\\\@eqncr%
1273 \everycr{}%
1274 $$%
1275 % \end{macrocode}
1276 %
1277 % We'll build the real |\halign| and preamble in a token register. All we
1278 % need to do is stuff the header in the token register, clear a switch
1279 % (that'll be explained later), parse the preamble and then expand the
1280 % tokens we collected. Easy, no?
1281 %
1282 % \begin{macrocode}
1283 \toks@{\halign to\displaywidth\bgroup}%
1284 \@tempswafalse%
1285 \eqa@preamble#1\end%
1286 \the\toks@\cr%
1287 }
1288 % \end{macrocode}
1289 %
1290 % \end{macro}
1291 %
1292 % \subsubsection{Parsing the preamble}
1293 %
1294 % All this actually involves is reading the next character and building a
1295 % command from it. That can pull off an argument if it needs it. Just make
1296 % sure we don't fall off the end and we'll be OK.
1297 %
1298 % \begin{macrocode}
1299 \def\eqa@preamble#1{%
1300 \ifx\end#1\else\csname eqa@char@#1\expandafter\endcsname\fi%
1301 }
1302 % \end{macrocode}
1303 %
1304 % Adding stuff to the preamble tokens is a simple matter of using
1305 % |\expandafter| in the correct way.\footnote{^^A
1306 % I have no idea why \LaTeX\ uses \cmd\edef\ for building its preamble. It
1307 % seems utterly insane to me -- the amount of bodgery that \env{tabular}
1308 % has to go through to make everything expand at the appropriate times is
1309 % scary. Maybe Messrs~Lamport and Mittelbach just forgot about token
1310 % registers when they were writing the code. Maybe I ought to rewrite the
1311 % thing properly some time. Sigh.
1312 %
1313 % As a sort of postscript to the above, I \emph{have} rewritten the
1314 % \env{tabular} environment, and made a damned fine job of it, in my
1315 % oh-so-humble opinion. All this \env{eqnarray} stuff has been remoulded
1316 % in terms of the generic column-defining things in \package{mdwtab}.
1317 % You're reading the documentation of the old version, which isn't
1318 % supported any more, so any bugs here are your own problem.}
1319 %
1320 % \begin{macrocode}
1321 \def\eqa@addraw#1{\expandafter\toks@\expandafter{\the\toks@#1}}
1322 % \end{macrocode}
1323 %
1324 % Now for some cleverness again. In order to put all the right bits of
1325 % |\tabskip| glue in the right places we must \emph{not} terminate each
1326 % column until we know what the next one is. We set |\if@tempswa| to be
1327 % |true| if there's a column waiting to be closed (so it's initially
1328 % |false|). The following macro adds a column correctly, assuming we're in
1329 % a formula. Other column types make their own arrangements.
1330 %
1331 % \begin{macrocode}
1332 \def\eqa@add#1{%
1333 \if@tempswa%
1334 \eqa@addraw{\tabskip\eqainskip&#1}%
1335 \else%
1336 \eqa@addraw{#1}%
1337 \fi%
1338 \@tempswatrue%
1339 }
1340 % \end{macrocode}
1341 %
1342 % Now to defining column types. Let's define a macro which allows us to
1343 % define column types:
1344 %
1345 % \begin{macrocode}
1346 \def\eqa@def#1{\expandafter\def\csname eqa@char@#1\endcsname}
1347 % \end{macrocode}
1348 %
1349 % Now we can define the column types. Each column type must loop back to
1350 % |\eqa@preamble| once it's finished, to read the rest of the preamble
1351 % string. Note the positioning of ord atoms in the stuff below. This will
1352 % space out relations and binops correctly when they occur at the edges of
1353 % columns, and won't affect ord atoms at the edges, because ords pack
1354 % closely.
1355 %
1356 % First the easy onces. Just stick |\hfil| in the right places and
1357 % everything will be all right.
1358 %
1359 % \begin{macrocode}
1360 \eqa@def r{\eqa@add{\hfil$\eqa@style##{}$}\eqa@preamble}
1361 \eqa@def c{\eqa@add{\hfil$\eqa@style{}##{}$\hfil}\eqa@preamble}
1362 \eqa@def l{\eqa@add{$\eqa@style{}##$\hfil}\eqa@preamble}
1363 \eqa@def x{\eqa@add{\hfil$\eqa@style##$\hfil}\eqa@preamble}
1364 % \end{macrocode}
1365 %
1366 % Now for the textual ones. This is also fairly easy.
1367 %
1368 % \begin{macrocode}
1369 \eqa@def T#1{%
1370 \eqa@add{}%
1371 \if#1l\else\eqa@addraw{\hfil}\fi%
1372 \eqa@addraw{##}%
1373 \if#1r\else\eqa@addraw{\hfil}\fi%
1374 \eqa@preamble%
1375 }
1376 % \end{macrocode}
1377 %
1378 % Sort of split types of equations. I mustn't use |\rlap| here, or
1379 % everything goes wrong -- |\\| doesn't get noticed by \TeX\ in the same way
1380 % as |\cr| does.
1381 %
1382 % \begin{macrocode}
1383 \eqa@def L{\eqa@add{\hb@xt@\z@{$\eqa@style##$\hss}\qquad}\eqa@preamble}
1384 % \end{macrocode}
1385 %
1386 % The \lit{:} column type is fairly simple. We set |\tabskip| up to make
1387 % lots of space and close the current column, because there must be one.^^A
1388 % \footnote{This is an assumption.}
1389 %
1390 % \begin{macrocode}
1391 \eqa@def :{%
1392 \eqa@addraw{\tabskip\eqacolskip&}\@tempswafalse\eqa@preamble%
1393 }
1394 \eqa@def q{\eqa@add{\quad}\@tempswafalse\eqa@preamble}
1395 % \end{macrocode}
1396 %
1397 % The other column types just insert given text in an appropriate way.
1398 %
1399 % \begin{macrocode}
1400 \eqa@def >#1{\eqa@add{#1}\@tempswafalse\eqa@preamble}
1401 \eqa@def <#1{\eqa@addraw{#1}\eqa@preamble}
1402 % \end{macrocode}
1403 %
1404 % Finally, the magical \lit{!} column type, which sets the equation number.
1405 % We set up the |\tabskip| glue properly, tab on, and set the flag which
1406 % marks the final column.
1407 %
1408 % \begin{macrocode}
1409 \eqa@def !#1{%
1410 \eqa@addraw{\tabskip\eqacloseskip&\@eqalasttrue#1}\eqa@preamble%
1411 }
1412 % \end{macrocode}
1413 %
1414 % \subsubsection{Newline codes}
1415 %
1416 % Newline sequences (|\\|) get turned into calls of |\@eqncr|. The job is
1417 % fairly simple, really. However, to avoid reading `|&|' characters
1418 % prematurely, we set up a magic brace (from the \package{array} package --
1419 % this avoids creating ord atoms and other nastyness).
1420 %
1421 % \begin{macrocode}
1422 \def\@eqncr{%
1423 \iffalse{\fi\ifnum0=`}\fi%
1424 \@ifstar{\eqacr@i{\@M}}{\eqacr@i{\interdisplaylinepenalty}}%
1425 }
1426 \def\eqacr@i#1{\@ifnextchar[{\eqacr@ii{#1}}{\eqacr@ii{#1}[\z@]}}
1427 \def\eqacr@ii#1[#2]{%
1428 \ifnum0=`{}\fi%
1429 \eqa@eqnum%
1430 \noalign{\penalty#1\vskip#2\relax}%
1431 }
1432 % \end{macrocode}
1433 %
1434 % \subsubsection{Setting equation numbers}
1435 %
1436 % Before we start, we need to generalise the flush-left number handling bits.
1437 % The macro |\eqa@eqpos| will put its argument in the right place.
1438 %
1439 % \begin{macrocode}
1440 \if@leqno
1441 \def\eqa@eqpos#1{%
1442 \hb@xt@.01\p@{}\rlap{\normalfont\normalcolor\hskip-\displaywidth#1}%
1443 }
1444 \else
1445 \def\eqa@eqpos#1{\normalfont\normalcolor#1}
1446 \fi
1447 % \end{macrocode}
1448 %
1449 % First we need to move into the right column. Then we just set the equation
1450 % number appropriately. There is some subtlety here, ish. The |\relax| is
1451 % important, to delay expansion of the |\if|\dots\ until the new column has
1452 % been started. The two helper macros are important too, to hide `|&|'s and
1453 % `|\cr|'s from \TeX's scanner until the right time.
1454 %
1455 % \begin{macrocode}
1456 \def\eqa@eqnum{%
1457 \relax%
1458 \if@eqalast\expandafter\eqa@eqnum@i\else\expandafter\eqa@eqnum@ii\fi%
1459 }
1460 \def\eqa@eqnum@i{%
1461 \if@eqnsw%
1462 \eqa@eqpos{(\theequation)}\stepcounter{equation}%
1463 \else%
1464 \eqa@eqpos\eqa@number%
1465 \fi%
1466 \global\@eqnswtrue%
1467 \cr%
1468 }
1469 \def\eqa@eqnum@ii{&\eqa@eqnum}
1470 % \end{macrocode}
1471 %
1472 % \subsubsection{Numbering control}
1473 %
1474 % This is trivial. We set the |\if@eqnsw| flag to be |false| and store the
1475 % text in a macro.
1476 %
1477 % \begin{macrocode}
1478 \let\nonumber\relax
1479 \newcommand\nonumber[1][]{\global\@eqnswfalse\global\def\eqa@number{#1}}
1480 % \end{macrocode}
1481 %
1482 % \subsubsection{Closing the environments off}
1483 %
1484 % This is really easy. Set the final equation number, close the |\halign|,
1485 % tidy up the equation counter (it's been stepped once too many times) and
1486 % close the display.
1487 %
1488 % \begin{macrocode}
1489 \def\endeqnarray{%
1490 \eqa@eqnum%
1491 \egroup%
1492 \global\advance\c@equation\m@ne%
1493 $$%
1494 \global\@ignoretrue%
1495 }
1496 \expandafter\let\csname endeqnarray*\endcsname\endeqnarray
1497 % \end{macrocode}
1498 %
1499 % Now start up the other package again.
1500 %
1501 % \begin{macrocode}
1502 %</oldeqnarray>
1503 %<*package>
1504 % \end{macrocode}
1505 %
1506 % \end{old-eqnarray}
1507 %
1508 % That's all there is. Byebye.
1509 %
1510 % \begin{macrocode}
1511 %</package>
1512 % \end{macrocode}
1513 %
1514 % \hfill Mark Wooding, \today
1515 %
1516 % \Finale
1517 \endinput