mdwmath.dtx 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. % \begin{meta-comment}
  2. %
  3. % $Id$
  4. %
  5. % Various nicer mathematical things
  6. %
  7. % (c) 1996 Mark Wooding
  8. %
  9. %----- Revision history -----------------------------------------------------
  10. %
  11. % $Log$
  12. % Revision 1.1 2000-07-13 09:10:21 michael
  13. % + Initial import
  14. %
  15. % Revision 1.1 1998/09/21 10:19:01 michael
  16. % Initial implementation
  17. %
  18. % Revision 1.1 1996/11/19 20:53:21 mdw
  19. % Initial revision
  20. %
  21. %
  22. % \end{meta-comment}
  23. %
  24. % \begin{meta-comment} <general public licence>
  25. %%
  26. %% mdwmath package -- various nicer mathematical things
  27. %% Copyright (c) 1996 Mark Wooding
  28. %%
  29. %% This program is free software; you can redistribute it and/or modify
  30. %% it under the terms of the GNU General Public License as published by
  31. %% the Free Software Foundation; either version 2 of the License, or
  32. %% (at your option) any later version.
  33. %%
  34. %% This program is distributed in the hope that it will be useful,
  35. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  36. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  37. %% GNU General Public License for more details.
  38. %%
  39. %% You should have received a copy of the GNU General Public License
  40. %% along with this program; if not, write to the Free Software
  41. %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  42. %%
  43. % \end{meta-comment}
  44. %
  45. % \begin{meta-comment} <Package preamble>
  46. %<+package>\NeedsTeXFormat{LaTeX2e}
  47. %<+package>\ProvidesPackage{mdwmath}
  48. %<+package> [1996/04/11 1.1 Nice mathematical things]
  49. %<+oldeqnarray>\NeedsTeXFormat{LaTeX2e}
  50. %<+oldeqnarray>\ProvidesPackage{eqnarray}
  51. %<+oldeqnarray> [1996/04/11 1.1 Old enhanced eqnarray]
  52. % \end{meta-comment}
  53. %
  54. % \CheckSum{259}
  55. % \begin{old-eqnarray}
  56. % \CheckSum{484}
  57. % \end{old-eqnarray}
  58. %% \CharacterTable
  59. %% {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
  60. %% 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
  61. %% Digits \0\1\2\3\4\5\6\7\8\9
  62. %% Exclamation \! Double quote \" Hash (number) \#
  63. %% Dollar \$ Percent \% Ampersand \&
  64. %% Acute accent \' Left paren \( Right paren \)
  65. %% Asterisk \* Plus \+ Comma \,
  66. %% Minus \- Point \. Solidus \/
  67. %% Colon \: Semicolon \; Less than \<
  68. %% Equals \= Greater than \> Question mark \?
  69. %% Commercial at \@ Left bracket \[ Backslash \\
  70. %% Right bracket \] Circumflex \^ Underscore \_
  71. %% Grave accent \` Left brace \{ Vertical bar \|
  72. %% Right brace \} Tilde \~}
  73. %%
  74. %
  75. % \begin{meta-comment}
  76. %
  77. %<*driver>
  78. \input{mdwtools}
  79. \describespackage{mdwmath}
  80. % \describespackage{eqnarray}
  81. \ignoreenv{old-eqnarray}
  82. % \unignoreenv{old-eqnarray}
  83. \mdwdoc
  84. %</driver>
  85. %
  86. % \end{meta-comment}
  87. %
  88. % \section{User guide}
  89. %
  90. % \subsection{Square root typesetting}
  91. %
  92. % \DescribeMacro{\sqrt}
  93. % The package supplies a star variant of the |\sqrt| command which omits the
  94. % vinculum over the operand (the line over the top). While this is most
  95. % useful in simple cases like $\sqrt*{2}$ it works for any size of operand.
  96. % The package also re-implements the standard square root command so that it
  97. % positions the root number rather better.
  98. %
  99. % \begin{figure}
  100. % \begin{demo}[w]{Examples of the new square root command}
  101. %\[ \sqrt*{2} \quad \mbox{rather than} \quad \sqrt{2} \]
  102. %\[ \sqrt*[3]{2} \quad \mbox{ rather than } \quad \sqrt[3]{2} \]
  103. %\[ \sqrt{x^3 + \sqrt*[y]{\alpha}} - \sqrt*[n+1]{a} \]
  104. %\[ x = \sqrt*[3]{\frac{3y}{7}} \]
  105. %\[ q = \frac{2\sqrt*{2}}{5}+\sqrt[\frac{n+1}{2}]{2x^2+3xy-y^2} \]
  106. % \end{demo}
  107. % \end{figure}
  108. %
  109. % [Note that omission of the vinculum was originally a cost-cutting exercise
  110. % because the radical symbol can just fit in next to its operand and
  111. % everything ends up being laid out along a line. However, I find that the
  112. % square root without vinculum is less cluttered, so I tend to use it when
  113. % it doesn't cause ambiguity.]
  114. %
  115. % \subsection{Some maths symbols you already have}
  116. %
  117. % Having just tried to do some simple things, I've found that there are maths
  118. % symbols missing. Here they are, in all their glory:
  119. %
  120. % \begin{center} \unverb\| \begin{tabular}{cl|cl|cl}
  121. % $\&$ & "\&" & $\bitor$ & "\bitor" & $\dbland$ & "\dbland" \\
  122. % $\bitand$ & "\bitand" & $\dblor$ & "\dblor" &
  123. % \end{tabular} \end{center}
  124. %
  125. % \begin{ignore}
  126. % There used to be an eqnarray here, but that's migrated its way into the
  127. % \package{mdwtab} package. Maybe the original version, without dependency
  128. % on \package{mdwtab} ought to be releasable separately. I'll keep it around
  129. % just in case.
  130. %
  131. % The following is the documentation for the original version. There's an
  132. % updated edition in \package{mdwtab}.
  133. % \end{ignore}
  134. %
  135. % \begin{old-eqnarray}
  136. %
  137. % \subsection{A new \env{eqnarray} environment}
  138. %
  139. % \LaTeX's built-in \env{eqnarray} is horrible -- it puts far too much space
  140. % between the items in the array. This environment is rather nearer to the
  141. % \env{amsmath} \env{align} environments, although rather less capable.
  142. %
  143. % \bigskip
  144. % \DescribeEnv{eqnarray}
  145. % {\synshorts
  146. % \setbox0\hbox{"\\begin{eqnarray}["<preamble>"]" \dots "\\end{eqnarray}"}
  147. % \leavevmode \hskip-\parindent \fbox{\box0}
  148. % }
  149. % \smallskip
  150. %
  151. % The new version of \env{eqnarray} tries to do everything which you really
  152. % want it to. The \synt{preamble} string allows you to define the column
  153. % types in a vaguely similar way to the wonderful \env{tabular} environment.
  154. % The types provided (and it's easy-ish to add more) are:
  155. %
  156. % \def\ch{\char`}
  157. % \begin{description} \def\makelabel{\hskip\labelsep\normalfont\ttfamily}
  158. % \item [r] Right aligned equation
  159. % \item [c] Centre-aligned equation
  160. % \item [l] Left aligned equation
  161. % \item [\textrm{\texttt{Tr}, \texttt{Tc} and \texttt{Tl}}] Right, centre and
  162. % left aligned text (not maths)
  163. % \item [L] Left aligned zero-width equation
  164. % \item [x] Centred entire equation
  165. % \item [:] Big gap separating sets of equations
  166. % \item [q] Quad space
  167. % \item [>\ch\{\synt{text}\ch\}] Insert text before column
  168. % \item [<\ch\{\synt{text}\ch\}] Insert text after column
  169. % \end{description}
  170. %
  171. % Some others are also defined: don't use them because they do complicated
  172. % things which are hard to explain and they aren't much use anyway.
  173. %
  174. % The default preamble, if you don't supply one of your own, is \lit{rcl}.
  175. % Most of the time, \lit{rl} is sufficient, although compatibility is more
  176. % important to me.
  177. %
  178. % By default, there is no space between columns, which makes formul\ae\ in an
  179. % \env{eqnarray} environment look just like formul\ae\ typeset on their own,
  180. % except that things get aligned in columns. This is where the default
  181. % \env{eqnarray} falls down: it leaves |\arraycolsep| space between each
  182. % column making the thing look horrible.
  183. %
  184. % An example would be good here, I think. This one's from exercise 22.9 of
  185. % the \textit{\TeX book}.
  186. %
  187. % \begin{demo}[w]{Simultaneous equations}
  188. %\begin{eqnarray}[rcrcrcrl]
  189. % 10w & + & 3x & + & 3y & + & 18z & = 1 \\
  190. % 6w & - & 17x & & & - & 5z & = 2
  191. %\end{eqnarray}
  192. % \end{demo}
  193. %
  194. % Choosing a more up-to-date example, here's one demonstrating the \lit{:}
  195. % column specifier from the \textit{\LaTeX\ Companion}.
  196. %
  197. % \begin{demo}[w]{Lots of equations}
  198. %\begin{eqnarray}[rl:rl:l]
  199. % V_i &= v_i - q_i v_j, & X_i &= x_i - q_i x_j, &
  200. % U_i = u_i, \qquad \mbox{for $i \ne j$} \label{eq:A} \\
  201. % V_j &= v_j, & X_j &= x_j &
  202. % U_j u_j + \sum_{i \ne j} q_i u_i.
  203. %\end{eqnarray}
  204. % \end{demo}
  205. %
  206. % We can make things more interesting by adding a plain text column. Here we
  207. % go:
  208. %
  209. % \begin{demo}[w]{Plain text column}
  210. %\begin{eqnarray}[rlqqTl]
  211. % x &= y & by (\ref{eq:A}) \\
  212. % x' &= y' & by definition \\
  213. % x + x' &= y + y' & by Axiom~1
  214. %\end{eqnarray}
  215. % \end{demo}
  216. %
  217. % The new features also mean that you don't need to mess about with
  218. % |\lefteqn| any more. This is handled by the \lit{L} column type:
  219. %
  220. % \begin{demo}{Splitting example}
  221. %\begin{eqnarray*}[Ll]
  222. % w+x+y+z = \\
  223. % & a+b+c+d+e+ \\
  224. % & f+g+h+i+j
  225. %\end{eqnarray*}
  226. % \end{demo}
  227. %
  228. % Finally, just to prove that the spacing's right at last, here's another one
  229. % from the \textit{Companion}.
  230. %
  231. % \begin{demo}{Spacing demonstration}
  232. %\begin{equation}
  233. % x^2 + y^2 = z^2
  234. %\end{equation}
  235. %\begin{eqnarray}[rl]
  236. % x^2 + y^2 &= z^2 \\
  237. % y^2 &< z^2
  238. %\end{eqnarray}
  239. % \end{demo}
  240. %
  241. % Well, that was easy enough. Now on to numbering. As you've noticed, the
  242. % equations above are numbered. You can use the \env{eqnarray$*$}
  243. % environment to turn off the numbering in the whole environment, or say
  244. % |\nonumber| on a line to suppress numbering of that one in particular.
  245. % More excitingly, you can say \syntax{"\\nonumber["<text>"]"} to choose
  246. % what text to display.
  247. %
  248. % A note for cheats: you can use the sparkly new \env{eqnarray} for simple
  249. % equations simply by specifying \lit{x} as the column description. Who
  250. % needs \AmSTeX? |;-)|
  251. %
  252. % \end{old-eqnarray}
  253. %
  254. % \implementation
  255. %
  256. % \section{Implementation}
  257. %
  258. % This isn't really complicated (honest) although it is a lot hairier than I
  259. % think it ought to be.
  260. %
  261. % \begin{macrocode}
  262. %<*package>
  263. % \end{macrocode}
  264. %
  265. % \subsection{Square roots}
  266. %
  267. % \subsubsection{Where is the square root sign?}
  268. %
  269. % \LaTeX\ hides the square root sign away somewhere without telling anyone
  270. % where it is. I extract it forcibly by peeking inside the |\sqrtsign| macro
  271. % and scrutinising the contents. Here we go: prepare for yukkiness.
  272. %
  273. % \begin{macrocode}
  274. \newcount\sq@sqrt
  275. \begingroup
  276. \catcode`\|0 \catcode`\\12
  277. |def|sq@readrad#1"#2\#3|relax{|global|sq@sqrt"#2|relax}
  278. |expandafter|sq@readrad|meaning|sqrtsign|relax
  279. |endgroup
  280. \def\sq@delim{\delimiter\sq@sqrt\relax}
  281. % \end{macrocode}
  282. %
  283. % \subsubsection{Drawing fake square root signs}
  284. %
  285. % \TeX\ absolutely insists on drawing square root signs with a vinculum over
  286. % the top. In order to get the same effect, we have to attempt to emulate
  287. % \TeX's behaviour.
  288. %
  289. % \begin{macro}{\sqrtdel}
  290. %
  291. % This does the main job of typesetting a vinculum-free radical.\footnote{^^A
  292. % Note for chemists: this is nothing to do with short-lived things which
  293. % don't have their normal numbers of electrons. And it won't reduce the
  294. % appearance of wrinkles either.}
  295. % It's more or less a duplicate of what \TeX\ does internally, so it might be
  296. % a good plan to have a copy of Appendix~G open while you examine this.
  297. %
  298. % We start off by using |\mathpalette| to help decide how big things should
  299. % be.
  300. %
  301. % \begin{macrocode}
  302. \def\sqrtdel{\mathpalette\sqrtdel@i}
  303. % \end{macrocode}
  304. %
  305. % Read the contents of the radical into a box, so we can measure it.
  306. %
  307. % \begin{macrocode}
  308. \def\sqrtdel@i#1#2{%
  309. \setbox\z@\hbox{$\m@th#1#2$}% %%% Bzzzt -- uncramps the mathstyle
  310. % \end{macrocode}
  311. %
  312. % Now try and sort out the values needed in this calculation. We'll assume
  313. % that $\xi_8$ is 0.6\,pt, the way it usually is. Next try to work out the
  314. % value of $\varphi$.
  315. %
  316. % \begin{macrocode}
  317. \ifx#1\displaystyle%
  318. \@tempdima1ex%
  319. \else%
  320. \@tempdima.6\p@%
  321. \fi%
  322. % \end{macrocode}
  323. %
  324. % That was easy. Now for $\psi$.
  325. %
  326. % \begin{macrocode}
  327. \@tempdimb.6\p@%
  328. \advance\@tempdimb.25\@tempdima%
  329. % \end{macrocode}
  330. %
  331. % Build the `delimiter' in a box of height $h(x)+d(x)+\psi+\xi_8$, as
  332. % requested. Box~2 will do well for this purpose.
  333. %
  334. % \begin{macrocode}
  335. \[email protected]\p@%
  336. \advance\dimen@\@tempdimb%
  337. \advance\dimen@\ht\z@%
  338. \advance\dimen@\dp\z@%
  339. \setbox\tw@\hbox{%
  340. $\left\sq@delim\vcenter to\dimen@{}\right.\n@space$%
  341. }%
  342. % \end{macrocode}
  343. %
  344. % Now we need to do some more calculating (don't you hate it?). As far as
  345. % Appendix~G is concerned, $\theta=h(y)=0$, because we want no rule over the
  346. % top.
  347. %
  348. % \begin{macrocode}
  349. \@tempdima\ht\tw@%
  350. \advance\@tempdima\dp\tw@%
  351. \advance\@tempdima-\ht\z@%
  352. \advance\@tempdima-\dp\z@%
  353. \ifdim\@tempdima>\@tempdimb%
  354. \advance\@tempdima\@tempdimb%
  355. \@tempdimb.5\@tempdima%
  356. \fi%
  357. % \end{macrocode}
  358. %
  359. % Work out how high to raise the radical symbol. Remember that Appendix~G
  360. % thinks that the box has a very small height, although this is untrue here.
  361. %
  362. % \begin{macrocode}
  363. \@tempdima\ht\z@%
  364. \advance\@tempdima\@tempdimb%
  365. \advance\@tempdima-\ht\tw@%
  366. % \end{macrocode}
  367. %
  368. % Build the output (finally). The brace group is there to turn the output
  369. % into a mathord, one of the few times that this is actually desirable.
  370. %
  371. % \begin{macrocode}
  372. {\raise\@tempdima\box\tw@\vbox{\kern\@tempdimb\box\z@}}%
  373. }
  374. % \end{macrocode}
  375. %
  376. % \end{macro}
  377. %
  378. % \subsubsection{The new square root command}
  379. %
  380. % This is where we reimplement all the square root stuff. Most of this stuff
  381. % comes from the \PlainTeX\ macros, although some is influenced by \AmSTeX\
  382. % and \LaTeXe, and some is original. I've tried to make the spacing vaguely
  383. % automatic, so although it's not configurable like \AmSTeX's version, the
  384. % output should look nice more of the time. Maybe.
  385. %
  386. % \begin{macro}{\sqrt}
  387. %
  388. % \LaTeX\ says this must be robust, so we make it robust. The first thing to
  389. % do is to see if there's a star and pass the appropriate squareroot-drawing
  390. % command on to the rest of the code.
  391. %
  392. % \begin{macrocode}
  393. \DeclareRobustCommand\sqrt{\@ifstar{\sqrt@i\sqrtdel}{\sqrt@i\sqrtsign}}
  394. % \end{macrocode}
  395. %
  396. % Now we can sort out an optional argument to be displayed on the root.
  397. %
  398. % \begin{macrocode}
  399. \def\sqrt@i#1{\@ifnextchar[{\sqrt@ii{#1}}{\sqrt@iv{#1}}}
  400. % \end{macrocode}
  401. %
  402. % Stages~2 and~3 below are essentially equivalents of \PlainTeX's
  403. % |\root|\dots|\of| and |\r@@t|. Here we also find the first wrinkle: the
  404. % |\rootbox| used to store the number is spaced out on the left if necessary.
  405. % There's a backspace after the end so that the root can slip underneath, and
  406. % everything works out nicely. Unfortunately size is fixed here, although
  407. % doesn't actually seem to matter.
  408. %
  409. % \begin{macrocode}
  410. \def\sqrt@ii#1[#2]{%
  411. \setbox\rootbox\hbox{$\m@th\scriptscriptstyle{#2}$}%
  412. \ifdim\wd\rootbox<6\p@%
  413. \setbox\rootbox\hb@xt@6\p@{\hfil\unhbox\rootbox}%
  414. \fi%
  415. \mathpalette{\sqrt@iii{#1}}%
  416. }
  417. % \end{macrocode}
  418. %
  419. % Now we can actually build everything. Note that the root is raised by its
  420. % depth -- this prevents a common problem with letters with descenders.
  421. %
  422. % \begin{macrocode}
  423. \def\sqrt@iii#1#2#3{%
  424. \setbox\z@\hbox{$\m@th#2#1{#3}$}%
  425. \dimen@\ht\z@%
  426. \advance\dimen@-\dp\z@%
  427. \[email protected]\dimen@%
  428. \advance\dimen@\dp\rootbox%
  429. \mkern-3mu%
  430. \raise\dimen@\copy\rootbox%
  431. \mkern-10mu%
  432. \box\z@%
  433. }
  434. % \end{macrocode}
  435. %
  436. % Finally handle a non-numbered root. We read the rooted text in as an
  437. % argument, to stop problems when people omit the braces. (\AmSTeX\ does
  438. % this too.)
  439. %
  440. % \begin{macrocode}
  441. \def\sqrt@iv#1#2{#1{#2}}
  442. % \end{macrocode}
  443. %
  444. % \end{macro}
  445. %
  446. % \begin{macro}{\root}
  447. %
  448. % We also re-implement \PlainTeX's |\root| command, just in case someone uses
  449. % it, and supply a star-variant. This is all very trivial.
  450. %
  451. % \begin{macrocode}
  452. \def\root{\@ifstar{\root@i\sqrtdel}{\root@i\sqrtsign}}
  453. \def\root@i#1#2\of{\sqrt@ii{#1}[#2]}
  454. % \end{macrocode}
  455. %
  456. % \end{macro}
  457. %
  458. % \subsection{Some magic new maths characters}
  459. %
  460. % This is all really easy.
  461. %
  462. % \begin{macrocode}
  463. \DeclareMathSymbol{&}{\mathbin}{operators}{`\&}
  464. \DeclareMathSymbol{\bitand}{\mathbin}{operators}{`\&}
  465. \def\bitor{\mathbin\mid}
  466. \def\dblor{\mathbin{\mid\mid}}
  467. \def\dbland{\mathbin{\mathrel\bitand\mathrel\bitand}}
  468. % \end{macrocode}
  469. %
  470. % \subsection{Biggles}
  471. %
  472. % Now for some user-controlled delimiter sizing. The standard bigness of
  473. % plain \TeX's delimiters are all right, but it's a little limiting.
  474. %
  475. % The biggness of delimiters is based on the size of the current |\strut|,
  476. % which \LaTeX\ keeps up to date all the time. This will make the various
  477. % delimiters grow in proportion when the text gets bigger. Actually, I'm
  478. % not sure that this is exactly right -- maybe it should be nonlinear,
  479. %
  480. % \begin{macro}{\bbigg}
  481. % \begin{macro}{\bbiggl}
  482. % \begin{macro}{\bbiggr}
  483. % \begin{macro}{\bbiggm}
  484. %
  485. % This is where the bigness is done. This is more similar to the plain \TeX\
  486. % big delimiter stuff than to the \package{amsmath} stuff, although there's
  487. % not really a lot of difference.
  488. %
  489. % The two arguments are a multiplier for the delimiter size, and a small
  490. % increment applied \emph{before} the multiplication (which is optional).
  491. %
  492. % This is actually a front for a low-level interface which can be called
  493. % directly for efficiency.
  494. %
  495. % \begin{macrocode}
  496. \def\bbigg{\@bbigg\mathord}
  497. \def\bbiggl{\@bbigg\mathopen}
  498. \def\bbiggr{\@bbigg\mathclose}
  499. \def\bbiggm{\@bbigg\mathrel}
  500. % \end{macrocode}
  501. %
  502. % \end{macro}
  503. % \end{macro}
  504. % \end{macro}
  505. % \end{macro}
  506. %
  507. % \begin{macro}{\@bbigg}
  508. %
  509. % This is an optional argument parser providing a front end for the main
  510. % macro |\bbigg@|.
  511. %
  512. % \begin{macrocode}
  513. \def\@bbigg#1{\@ifnextchar[{\@bigg@i{#1}}{\@bigg@i{#1}[\z@]}}
  514. \def\@bigg@i#1[#2]#3#4{#1{\bbigg@{#2}{#3}{#4}}}
  515. % \end{macrocode}
  516. %
  517. % \end{macro}
  518. %
  519. % \begin{macro}{\bbigg@}
  520. %
  521. % This is it, at last. The arguments are as described above: an addition
  522. % to be made to the strut height, and a multiplier. Oh, and the delimiter,
  523. % of course.
  524. %
  525. % This is a bit messy. The smallest `big' delimiter, |\big|, is the same
  526. % height as the current strut box. Other delimiters are~$1\frac12$, $2$
  527. % and~$2\frac12$ times this height. I'll set the height of the delimiter by
  528. % putting in a |\vcenter| of the appropriate size.
  529. %
  530. % Given an extra height~$x$, a multiplication factor~$f$ and a strut
  531. % height~$h$ and depth~$d$, I'll create a vcenter with total height
  532. % $f(h+d+x)$. Easy, isn't it?
  533. %
  534. % \begin{macrocode}
  535. \def\bbigg@#1#2#3{%
  536. \hbox{$%
  537. \dimen@\ht\strutbox\advance\dimen@\dp\strutbox%
  538. \advance\dimen@#1%
  539. \dimen@#2\dimen@%
  540. \left#3\vcenter to\dimen@{}\right.\n@space%
  541. $}%
  542. }
  543. % \end{macrocode}
  544. %
  545. % \end{macro}
  546. %
  547. % \begin{macro}{\big}
  548. % \begin{macro}{\Big}
  549. % \begin{macro}{\bigg}
  550. % \begin{macro}{\Bigg}
  551. %
  552. % Now for the easy macros.
  553. %
  554. % \begin{macrocode}
  555. \def\big{\bbigg@\z@\@ne}
  556. \def\Big{\bbigg@\z@{1.5}}
  557. \def\bigg{\bbigg@\z@\tw@}
  558. \def\Bigg{\bbigg@\z@{2.5}}
  559. % \end{macrocode}
  560. %
  561. % \end{macro}
  562. % \end{macro}
  563. % \end{macro}
  564. % \end{macro}
  565. %
  566. %
  567. % \begin{ignore}
  568. % The following is the original definition of the enhanced eqnarray
  569. % environment. It's not supported, although if you can figure out how to
  570. % extract it, it's all yours.
  571. % \end{ignore}
  572. %
  573. % \begin{old-eqnarray}
  574. %
  575. % \subsection{The sparkly new \env{eqnarray}}
  576. %
  577. % Start off by writing a different package.
  578. %
  579. % \begin{macrocode}
  580. %</package>
  581. %<*oldeqnarray>
  582. % \end{macrocode}
  583. %
  584. % \subsubsection{Options handling}
  585. %
  586. % We need to be able to cope with \textsf{fleqn} and \textsf{leqno} options.
  587. % This will adjust our magic modified \env{eqnarray} environment
  588. % appropriately.
  589. %
  590. % \begin{macrocode}
  591. \newif\if@fleqn
  592. \newif\if@leqno
  593. \DeclareOption{fleqn}{\@fleqntrue}
  594. \DeclareOption{leqno}{\@leqnotrue}
  595. \ProcessOptions
  596. % \end{macrocode}
  597. %
  598. % This is all really different to the \LaTeX\ version. I've looked at the
  599. % various \env{tabular} implementations, the original \env{eqnarray} and the
  600. % \textit{\TeX book} to see how best to do this, and then went my own way.
  601. % If it doesn't work it's all my fault.
  602. %
  603. % \subsubsection{Some useful registers}
  604. %
  605. % The old \LaTeX\ version puts the equation numbers in by keeping a count of
  606. % where it is in the alignment. Since I don't know how may columns there are
  607. % going to be, I'll just use a switch in the preamble to tell me to stop
  608. % tabbing.
  609. %
  610. % \begin{macrocode}
  611. \newif\if@eqalast
  612. % \end{macrocode}
  613. %
  614. % Now define some useful length parameters. First allocate them:
  615. %
  616. % \begin{macrocode}
  617. \newskip\eqaopenskip
  618. \newskip\eqacloseskip
  619. \newskip\eqacolskip
  620. \newskip\eqainskip
  621. % \end{macrocode}
  622. %
  623. % Now assign some default values. Users can play with these if they really
  624. % want although I can't see the point myself.
  625. %
  626. % \begin{macrocode}
  627. \if@fleqn
  628. \AtBeginDocument{\eqaopenskip\leftmargini}
  629. \else
  630. \eqaopenskip\@centering
  631. \fi
  632. \eqacloseskip\@centering
  633. \eqacolskip\@centering
  634. \eqainskip\z@
  635. % \end{macrocode}
  636. %
  637. % We allow the user to play with the style if this is really wanted. I dunno
  638. % why, really. Maybe someone wants very small alignments.
  639. %
  640. % \begin{macrocode}
  641. \let\eqa@style\displaystyle
  642. % \end{macrocode}
  643. %
  644. % \subsubsection{The main environments}
  645. %
  646. % We define the toplevel commands here. They just add in default arguments
  647. % and then call |\@eqnarray| with a preamble string. The only difference is
  648. % the last column they add in -- \env{eqnarray$*$} throws away the last
  649. % column by sticking it in box~0. (I used to |\@gobble| it but that caused
  650. % the |\cr| to be lost.)
  651. %
  652. % \begin{macrocode}
  653. \def\eqnarray{\@ifnextchar[\eqnarray@i{\eqnarray@i[rcl]}}
  654. \def\eqnarray@i[#1]{%
  655. \@eqnarray{#1!{\hb@xt@\z@{\hss##}\tabskip\z@}}
  656. }
  657. \@namedef{eqnarray*}{\@ifnextchar[\eqnarray@s@i{\eqnarray@s@i[rcl]}}
  658. \def\eqnarray@s@i[#1]{%
  659. \@eqnarray{#1!{\nonumber\setbox\z@\hbox{##}\tabskip\z@}}%
  660. }
  661. % \end{macrocode}
  662. %
  663. % \subsubsection{Set up the initial display}
  664. %
  665. % \begin{macro}{\@eqnarray}
  666. %
  667. % The |\@eqnarray| command does most of the initial work. It sets up some
  668. % flags and things, builds the |\halign| preamble, and returns.
  669. %
  670. % \begin{macrocode}
  671. \def\@eqnarray#1{%
  672. % \end{macrocode}
  673. %
  674. % Start playing with the counter here. The original does some icky internal
  675. % playing, which isn't necessary. The |\if@eqnsw| switch is |true| if the
  676. % user hasn't supplied an equation number. The |\if@eqalast| switch is
  677. % |true| in the final equation-number column.
  678. %
  679. % \begin{macrocode}
  680. \refstepcounter{equation}%
  681. \@eqalastfalse%
  682. \global\@eqnswtrue%
  683. \m@th%
  684. % \end{macrocode}
  685. %
  686. % Set things up for the |\halign| which is coming up.
  687. %
  688. % \begin{macrocode}
  689. \openup\jot%
  690. \tabskip\eqaopenskip%
  691. \let\\\@eqncr%
  692. \everycr{}%
  693. $$%
  694. % \end{macrocode}
  695. %
  696. % We'll build the real |\halign| and preamble in a token register. All we
  697. % need to do is stuff the header in the token register, clear a switch
  698. % (that'll be explained later), parse the preamble and then expand the
  699. % tokens we collected. Easy, no?
  700. %
  701. % \begin{macrocode}
  702. \toks@{\halign to\displaywidth\bgroup}%
  703. \@tempswafalse%
  704. \eqa@preamble#1\end%
  705. \the\toks@\cr%
  706. }
  707. % \end{macrocode}
  708. %
  709. % \end{macro}
  710. %
  711. % \subsubsection{Parsing the preamble}
  712. %
  713. % All this actually involves is reading the next character and building a
  714. % command from it. That can pull off an argument if it needs it. Just make
  715. % sure we don't fall off the end and we'll be OK.
  716. %
  717. % \begin{macrocode}
  718. \def\eqa@preamble#1{%
  719. \ifx\end#1\else\csname eqa@char@#1\expandafter\endcsname\fi%
  720. }
  721. % \end{macrocode}
  722. %
  723. % Adding stuff to the preamble tokens is a simple matter of using
  724. % |\expandafter| in the correct way.\footnote{^^A
  725. % I have no idea why \LaTeX\ uses \cmd\edef\ for building its preamble. It
  726. % seems utterly insane to me -- the amount of bodgery that \env{tabular}
  727. % has to go through to make everything expand at the appropriate times is
  728. % scary. Maybe Messrs~Lamport and Mittelbach just forgot about token
  729. % registers when they were writing the code. Maybe I ought to rewrite the
  730. % thing properly some time. Sigh.
  731. %
  732. % As a sort of postscript to the above, I \emph{have} rewritten the
  733. % \env{tabular} environment, and made a damned fine job of it, in my
  734. % oh-so-humble opinion. All this \env{eqnarray} stuff has been remoulded
  735. % in terms of the generic column-defining things in \package{mdwtab}.
  736. % You're reading the documentation of the old version, which isn't
  737. % supported any more, so any bugs here are your own problem.}
  738. %
  739. % \begin{macrocode}
  740. \def\eqa@addraw#1{\expandafter\toks@\expandafter{\the\toks@#1}}
  741. % \end{macrocode}
  742. %
  743. % Now for some cleverness again. In order to put all the right bits of
  744. % |\tabskip| glue in the right places we must \emph{not} terminate each
  745. % column until we know what the next one is. We set |\if@tempswa| to be
  746. % |true| if there's a column waiting to be closed (so it's initially
  747. % |false|). The following macro adds a column correctly, assuming we're in
  748. % a formula. Other column types make their own arrangements.
  749. %
  750. % \begin{macrocode}
  751. \def\eqa@add#1{%
  752. \if@tempswa%
  753. \eqa@addraw{\tabskip\eqainskip&#1}%
  754. \else%
  755. \eqa@addraw{#1}%
  756. \fi%
  757. \@tempswatrue%
  758. }
  759. % \end{macrocode}
  760. %
  761. % Now to defining column types. Let's define a macro which allows us to
  762. % define column types:
  763. %
  764. % \begin{macrocode}
  765. \def\eqa@def#1{\expandafter\def\csname eqa@char@#1\endcsname}
  766. % \end{macrocode}
  767. %
  768. % Now we can define the column types. Each column type must loop back to
  769. % |\eqa@preamble| once it's finished, to read the rest of the preamble
  770. % string. Note the positioning of ord atoms in the stuff below. This will
  771. % space out relations and binops correctly when they occur at the edges of
  772. % columns, and won't affect ord atoms at the edges, because ords pack
  773. % closely.
  774. %
  775. % First the easy onces. Just stick |\hfil| in the right places and
  776. % everything will be all right.
  777. %
  778. % \begin{macrocode}
  779. \eqa@def r{\eqa@add{\hfil$\eqa@style##{}$}\eqa@preamble}
  780. \eqa@def c{\eqa@add{\hfil$\eqa@style{}##{}$\hfil}\eqa@preamble}
  781. \eqa@def l{\eqa@add{$\eqa@style{}##$\hfil}\eqa@preamble}
  782. \eqa@def x{\eqa@add{\hfil$\eqa@style##$\hfil}\eqa@preamble}
  783. % \end{macrocode}
  784. %
  785. % Now for the textual ones. This is also fairly easy.
  786. %
  787. % \begin{macrocode}
  788. \eqa@def T#1{%
  789. \eqa@add{}%
  790. \if#1l\else\eqa@addraw{\hfil}\fi%
  791. \eqa@addraw{##}%
  792. \if#1r\else\eqa@addraw{\hfil}\fi%
  793. \eqa@preamble%
  794. }
  795. % \end{macrocode}
  796. %
  797. % Sort of split types of equations. I mustn't use |\rlap| here, or
  798. % everything goes wrong -- |\\| doesn't get noticed by \TeX\ in the same way
  799. % as |\cr| does.
  800. %
  801. % \begin{macrocode}
  802. \eqa@def L{\eqa@add{\hb@xt@\z@{$\eqa@style##$\hss}\qquad}\eqa@preamble}
  803. % \end{macrocode}
  804. %
  805. % The \lit{:} column type is fairly simple. We set |\tabskip| up to make
  806. % lots of space and close the current column, because there must be one.^^A
  807. % \footnote{This is an assumption.}
  808. %
  809. % \begin{macrocode}
  810. \eqa@def :{%
  811. \eqa@addraw{\tabskip\eqacolskip&}\@tempswafalse\eqa@preamble%
  812. }
  813. \eqa@def q{\eqa@add{\quad}\@tempswafalse\eqa@preamble}
  814. % \end{macrocode}
  815. %
  816. % The other column types just insert given text in an appropriate way.
  817. %
  818. % \begin{macrocode}
  819. \eqa@def >#1{\eqa@add{#1}\@tempswafalse\eqa@preamble}
  820. \eqa@def <#1{\eqa@addraw{#1}\eqa@preamble}
  821. % \end{macrocode}
  822. %
  823. % Finally, the magical \lit{!} column type, which sets the equation number.
  824. % We set up the |\tabskip| glue properly, tab on, and set the flag which
  825. % marks the final column.
  826. %
  827. % \begin{macrocode}
  828. \eqa@def !#1{%
  829. \eqa@addraw{\tabskip\eqacloseskip&\@eqalasttrue#1}\eqa@preamble%
  830. }
  831. % \end{macrocode}
  832. %
  833. % \subsubsection{Newline codes}
  834. %
  835. % Newline sequences (|\\|) get turned into calls of |\@eqncr|. The job is
  836. % fairly simple, really. However, to avoid reading `|&|' characters
  837. % prematurely, we set up a magic brace (from the \package{array} package --
  838. % this avoids creating ord atoms and other nastyness).
  839. %
  840. % \begin{macrocode}
  841. \def\@eqncr{%
  842. \iffalse{\fi\ifnum0=`}\fi%
  843. \@ifstar{\eqacr@i{\@M}}{\eqacr@i{\interdisplaylinepenalty}}%
  844. }
  845. \def\eqacr@i#1{\@ifnextchar[{\eqacr@ii{#1}}{\eqacr@ii{#1}[\z@]}}
  846. \def\eqacr@ii#1[#2]{%
  847. \ifnum0=`{}\fi%
  848. \eqa@eqnum%
  849. \noalign{\penalty#1\vskip#2\relax}%
  850. }
  851. % \end{macrocode}
  852. %
  853. % \subsubsection{Setting equation numbers}
  854. %
  855. % Before we start, we need to generalise the flush-left number handling bits.
  856. % The macro |\eqa@eqpos| will put its argument in the right place.
  857. %
  858. % \begin{macrocode}
  859. \if@leqno
  860. \def\eqa@eqpos#1{%
  861. \hb@[email protected]\p@{}\rlap{\normalfont\normalcolor\hskip-\displaywidth#1}%
  862. }
  863. \else
  864. \def\eqa@eqpos#1{\normalfont\normalcolor#1}
  865. \fi
  866. % \end{macrocode}
  867. %
  868. % First we need to move into the right column. Then we just set the equation
  869. % number appropriately. There is some subtlety here, ish. The |\relax| is
  870. % important, to delay expansion of the |\if|\dots\ until the new column has
  871. % been started. The two helper macros are important too, to hide `|&|'s and
  872. % `|\cr|'s from \TeX's scanner until the right time.
  873. %
  874. % \begin{macrocode}
  875. \def\eqa@eqnum{%
  876. \relax%
  877. \if@eqalast\expandafter\eqa@eqnum@i\else\expandafter\eqa@eqnum@ii\fi%
  878. }
  879. \def\eqa@eqnum@i{%
  880. \if@eqnsw%
  881. \eqa@eqpos{(\theequation)}\stepcounter{equation}%
  882. \else%
  883. \eqa@eqpos\eqa@number%
  884. \fi%
  885. \global\@eqnswtrue%
  886. \cr%
  887. }
  888. \def\eqa@eqnum@ii{&\eqa@eqnum}
  889. % \end{macrocode}
  890. %
  891. % \subsubsection{Numbering control}
  892. %
  893. % This is trivial. We set the |\if@eqnsw| flag to be |false| and store the
  894. % text in a macro.
  895. %
  896. % \begin{macrocode}
  897. \let\nonumber\relax
  898. \newcommand\nonumber[1][]{\global\@eqnswfalse\global\def\eqa@number{#1}}
  899. % \end{macrocode}
  900. %
  901. % \subsubsection{Closing the environments off}
  902. %
  903. % This is really easy. Set the final equation number, close the |\halign|,
  904. % tidy up the equation counter (it's been stepped once too many times) and
  905. % close the display.
  906. %
  907. % \begin{macrocode}
  908. \def\endeqnarray{%
  909. \eqa@eqnum%
  910. \egroup%
  911. \global\advance\c@equation\m@ne%
  912. $$%
  913. \global\@ignoretrue%
  914. }
  915. \expandafter\let\csname endeqnarray*\endcsname\endeqnarray
  916. % \end{macrocode}
  917. %
  918. % Now start up the other package again.
  919. %
  920. % \begin{macrocode}
  921. %</oldeqnarray>
  922. %<*package>
  923. % \end{macrocode}
  924. %
  925. % \end{old-eqnarray}
  926. %
  927. % That's all there is. Byebye.
  928. %
  929. % \begin{macrocode}
  930. %</package>
  931. % \end{macrocode}
  932. %
  933. % \hfill Mark Wooding, \today
  934. %
  935. % \Finale
  936. \endinput