% \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} %% %% 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>\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 % % % \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}[""]" \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[""]"} 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} % %<*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}% \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} % %<*package> % \end{macrocode} % % \end{old-eqnarray} % % That's all there is. Byebye. % % \begin{macrocode} % % \end{macrocode} % % \hfill Mark Wooding, \today % % \Finale \endinput