TexCommons/diagrams.sty
2023-04-25 16:11:20 +02:00

8514 lines
316 KiB
TeX

\message{==================================================================}%
\message{<Paul Taylor's commutative diagrams - version 3.96, December 2019>}%
%%
%%
%% This code runs the LaTeX \ProvidesPackage command iff it is defined.
%% included at the request of Michael Downes <mjd@ams.org> March 2002.
%% Put \listfiles in your LaTeX preamble to see what this is for.
\expandafter\ifx\csname ProvidesPackage\endcsname\relax\toks0=\expandafter{\fi
\ProvidesPackage
{diagrams}[2019/12/31 v3.96 Paul Taylor's commutative diagrams]%%
\toks0=\bgroup}%%
%%======================================================================%
%% TeX macros for drawing category-theoretic diagrams %
%% %
%% Paul Taylor %
%% %
%% www.PaulTaylor.EU/diagrams %
%% www.ctan.org/tex-archive/macros/generic/diagrams/taylor/ %
%% diagrams@PaulTaylor.EU %
%% %
%% PLEASE READ THE MANUAL! %
%% %
%% Please ensure that you are registered with me as a user so that %
%% you can be informed of future releases. Any electronic mail %
%% message with "commutative" or "diagram" in the subject line %
%% (such as your request for the package, a question about it, or %
%% even an otherwise blank message) automatically registers you. %
%% %
%% %
%% CONTENTS: %
%% (O) corruption-sensitive hacks (to approx line 318) %
% (1) dimensions and counts %
% (2) make arrow parts %
% (3) new arrow %
% (4) horizontal state checking and arrow setup %
% (5) syntax of arrow commands %
% (6) positioning and optional arguments %
% (7) the diagram - options and output %
% (8) the matrix %
% (9) horizontals %
% (10) piles %
% (11) verticals %
% (12) transfer to box arrays %
% (13) paragraph bombing %
% (14) reformatting objects and crosses %
% (15) LaTeX line characters %
% (16) diagonals %
% (17) stretchable diagonals %
% (18) PostScript arrows %
% (19) trigonometry %
% (20) PDF-TeX support %
% (21) error recovery %
%% Arrow components & commands - starts approx line 1234 %
%% (22) auxillary macros for adjustment of components %
%% (23) bits of arrows (\rhvee etc) %
%% (24) arrow commands (\rTo etc) %
%% (25) miscellaneous %
%% Apart from these five sections, the rest is intended to be totally %
%% meaningless in the undocumented version, which is approximately %
%% 1922 lines long. Please do not waste trees by printing it out. %
% This is because I regard my code as private. The comments contain a %
% lot of fossils, ideas and other notes to myself which I do not wish %
% to make available to others. If you're reading this, please stop now.%
%% %
%% COPYRIGHT NOTICE: %
%% This package may be copied and used freely for any academic %
%% (not commercial or military) purpose, on condition that it %
%% is not altered in any way, and that an acknowledgement is %
%% included in any published work making substantial use of it. %
%% %
%% IT IS SUPPLIED "AS IS", WITHOUT WARRANTY, EXPRESS OR IMPLIED. %
%% %
%% If you are doing something where mistakes cost money (or where %
%% success brings financial profit) then you must use commercial %
%% software, not this package. In any case, please remember to %
%% keep several backup copies of all files, and check everything %
%% visually before sending final copy to the publishers. %
%% %
%% You may use this package as a (substantial) aid to writing an %
%% academic research or text book on condition that %
%% (i) you contact me at a suitable time to ensure that you have %
%% an up-to-date version (and any infelicities can be fixed), %
%% (ii) you send me a copy of the book when it's published. %
%% %
%% HISTORY %
%% 3.95 Released 31 December 2014 %
%% Fixed spurious extra vertical space when running under LuaTeX %
% by adding \baselineskip\z@ to \bomb@parameters 14 May 2014 %
%% with help from Linas Stonys. %
%% 3.94 Released 11 May 2011 %
%% defined <= tail %
%% 3.93 Released 9 June 2009 %
% added \pdfsyncstop to avoid clash with pdfsync %
% \ifx\diagram\isundefined %
% removed obsolete \laf \lad \xlad \lahh \lat \xlat \xlahh %
% changed \lq and \rq back to ` and ' for catcodes and octals. %
%% Added support for XeTeX, with help from Apostolos Syropoulos. %
%% 3.92 Released 31 December 2007 %
% Made noPS and noPostScript just generate error messages. %
% Unknown PS translator is just ignored. %
% Swapped \Yup and \Ydown %
% Two-year (instead of one-year) time-bombs. %
%% 3.91 Released 31 August 2006 %
%% Renamed "noPostScript" option as "UglyObsolete". %
% Fixed? "PostScript translator `' unknown" %
% \everymath{}\everyhbox{} since pdfsync sets them %
%% 3.90 Released 11 April 2004 %
%% use PostScript=Rokicki not pure DVI by default %
% pass PS prog name to \bad@ps@prog as #1 not as \@value %
% always warn that "labels as positional arguments are obsolete" %
% as ``superscript'' labels were introduced 14 years ago %
% test \ifx\pdfoutput\relax as well as \undefined %
%% 3.89 Released 7 July 2002 %
%% Added support for pdftex, which is recognised automatically. %
%% 3.88 Released 1 September 2000 %
%% Square hook tail: \newarrow{SquareInto}{sqhook}---> %
%% 3.87 Released 1 September 1999 %
%% This version was used for the final 1200dpi PS copy of my book %
%% ``Practical Foundations of Mathematics'' (Cambridge Univ Press) %
%% see http://www.PaulTaylor.EU/Practical_Foundations %
%% 3.86 Released 1 September 1998 %
%% New options hug and nohug in PostScript mode: [PS,nohug] uses %
%% PS for the arrows without rotating the labels, but the way of %
%% calculating the actual position of these horizontal labels on %
%% will remain subject to alteration for some period of time --- %
%% please send me examples if you feel that adjustment is needed. %
%% %
% flushleft/leftflush with no value retains old one, not 0pt %
% Suppress indentation of following text (due to LaTeX change) %
% inserted \global before \@ignoretrue %
% Mangle \left@label and \right@label (conflict with Elsevier). %
%% midvshaft and snake for vertical arrows %
% labels on verticals are now inside the lower \vbox %
%% New option [gap=width] (default=shortfall) to use instead of %
%% ~{\;} on horizontals and PS diagonals, as this caused ^ and _ %
%% labels to be moved too far away from the shaft. %
% Corrected position of hook in \dInto (see \shifthook). %
% Added 2pt space separating labels from vertical arrows. %
% Corrections to \lhtriangle \dhtriangle \newarrowtail{boldhook} %
%% Added >-> and <-< heads and tails, same as >> and << but the %
%% shaft goes *through* the extra arrowhead. %
% Identify the cell in which a second-pass error occurs. %
% Corrected dot spacing with [dotted] option. %
% (It was using \hfdot or \vfdot not \rf:. or \df:.) %
%% 3.85 Released 20 August 1997 %
%% New option [crab=distance] shifts horizontals and PS diagonals %
%% transversally by the specified distance (positive=upward). %
%% New option [snake=distance] shifts midshaft horizontals and %
%% PS diagonals longitudinally by the specified distance. %
% Set \catcode of :;!? as babel package makes them \active. %
% \dblvert for ``Practical Foundations'' %
% Moved pullback symbols slightly further away. %
% Fixed uneven \pile spacing. %
% Treat empty row as \noalign{\advance\prevdepth-\baselineskip} %
% Unknown PostScript translator names recognised. %
% Parse space in $A\rTo^a _b B$ correctly. %
% Big \LaTeX arrowheads with [thick] option. %
%% New option [leftflush], like [flushleft] but reckons alignment %
%% from multiple verticals, or from text if there's no vertical. %
% Crude implementation of nohug. %
%% Most of the history has been suppressed from the user version. %
% 3.84 Released 2 September 1996 %
% Fixed undefined control sequence in \luOnto[dotted,PS] %
% moved \let\fill@dot\hfdot from \Horizontal@Map to \@setup@horiz %
% Use \AtEndDocument to give once only warnings. %
% Report unknown grid correctly. %
% Provided \NWclck etc 2-cell arrows. %
%% 3.83 Released 18 May 1995 %
%% "dotted" option (set dot filler on maps) %
% repositionpullbacks moved 0.25em horizontally %
% fixed bug when \v@grid is longer than required %
% added \relax in \over@print to avoid premature expansion %
% (to fix bug with repositionpullbacks \NWpbk and \SWpbk) %
% Fixed bug with interaction with amslatex/equation. %
% reported by Bruce Pollack; caused by \everycr. %
%% Parallel maps (\pile) outside diagrams stretch correctly. %
% Added test \ifinpile to glue in horizontal maps. %
% Avoid stepped lines in PostScript by restricting the slopes. %
% Define \default@max@fraction=\default@size/5\pixel@size. %
% Rightmost width now calculated correctly. %
% \reoutput@cell had spurious \box\cd@cell in it. %
% Fewer "arrow too short" errors (the l> option for eliminating %
% birds' feet arrows is only applied in text, l>.5em in diagrams).%
% Setting \dimen2 in \@setup@horiz, \default@args, \calc@horiz. %
% Recovery from "\rTo_\hbox{a}" no longer loops. %
% Match TeX's inserted { with \eegroup instead of \egroup. %
% "midshaft" option now works; "midvshaft" ignored. %
%% Option "LaTeXeqno" uses LaTeX's equation number and style %
%% for "eqno"; LaTeX's \label command picks this up. %
%% Suppress warnings & 2nd pass errors with "silent" option. %
% Warning if extra material in \pile cell. %
% Recover from square brackets mis-interpreted as options. %
% 3.82 %
%% 3.81 Second alpha release 18 July 1994 %
% Fixed displaced parenthesis instead of hook tails in manual p8. %
% By changing \box0 to \box3 in \raisehook (LaTeX2e \boldmath). %
% Parentheses and braces (not quite right): see end of source. %
%% \overprint{text} sets text in maths and overprints it in the %
%% current cell, centered in the column irrespective of other stuff%
%% "repositionpullbacks" option uses this for \SEpbk etc %
%% \newdiagramgrid declaration, grid option and pentagon grid. %
%% 3.80 Alpha release for adjusted diagonals 15 July 1994. %
% Some options can now take (x,y) values. %
% Position during input as (\cd@row,\cd@cell); top left is (1,1). %
% Name of DVI->PS translator as argument to PostScript option. %
% Preliminary code for stretchable diagonals and overprints: %
% \missive#1(x,y) anywhere in the diagram overprints #1 at (x,y). %
% The extra boxes are added to the left of each cell, delimited %
% by \penalty-9990; this caused the paragraph builder to discard %
% the \hfil\kern(shortfall) on the left, so added \null. %
% Improved recovery from missing {} in labels. %
% Recovers from \rTo~\rTo, \rTo^\hat, \rTo^\macro, {\rTo^}, %
% \rTo^ {&, ... %
% Removed error message from \across since this works now. %
% Set \boxmaxdepth=\maxdimen for interaction with an old LaTeX. %
% Loading after \begin{document} in LaTeX2e possible. %
% (By testing whether \DeclareOption has been disabled (yuck). %
% Loading before \documentstyle or \documentclass possible. %
% (By defaulting \MapBreath and \default@mapbreadth to 0.4pt; %
% the latter is \edef'd in \size@dependencies. %
% Equilateral triangle or regular hexagon size options. %
% \mathon and \mathoff correctly matched now, it seems. %
% Corrected Morse code for "P" (Ralph Loader) %
% Changed all \new@if to \if@blah@. Added \if@in@matrix@. %
% Introduced landscape and portrait options. %
% Define PS commands once for each (outermost) diagram needing %
% them; previously they were defined for every map. %
% Don't hide width of vertical middle components. %
% (Changed \make@vert@part to \hbox in \newarrowmiddle.) %
% Negative stretchability in right half of horizontal arrows. %
% Added "." map qualifier to set dot filler. %
% Only set \@diagonals@used@ for those set on first pass. %
% Parse []-options during label processing. %
% Signal midhshaft with extra \penalty1 just before bomb. %
% Made midhshaft work; always set it for single-row diagrams. %
% Rewrote \widen@horiz, changing tests for space and handling of %
% through and centred horizontals. %
% Maintain distance of each row from the top as \ht\cd@row on %
% rows which have been reformatted; used to calculate height of %
% diagonals. %
% \diagramstyle may be used within diagrams. %
% (Continuation, \after@opt@arg, not set, so did \@@@diagram.) %
% \objectwidth reduced from 3em to 1em; was destroying fixed %
% diagonals. %
% Fixed "very" thick lines by changing \cds@thick. %
% All inter-row glue contributes to space. %
% Vertical maps targetted at labels of horizontals avoid them. %
% Wide object on right no longer causes "increase width" warning. %
% (Initialise \far@end@cell=1000 on right, don't complain about %
% insufficient space between objects if it still has this value.) %
% Make these warnings more accurate and informative. %
% Fixed decapitated arrows (I think!). %
% Now use \wd\cd@donat for \column@placing ie x-coord of centre. %
% Diagonals adjusted to meet their endpoints, at last!!!! %
% \min@map@length=0pt inside diagrams (?). %
% Option showfirstpass[=depth]. %
% Fixed intermittent "lower part of vertical too short" errors: %
% wasn't collecting the vertical glue below missives. %
% Missive aimed at horizontal map caused huge \right@donated: was %
% overwriting \dimen2; moved most of the code within an \hbox. %
% 3.29 Released 11 March 1994 %
% Corrected error message when "&" or object is inserted before %
% horizontal maps etc outside diagram. %
% \last@map@type initialised to \empty, when we just say "before".%
% Also when label missing after <>^_~. %
% Switch to centredisplay if flushleft doesn't fit on the page. %
% The code was ok when the diagram didn't fit at all, but not in %
% the case where it would fit in centredisplay mode. %
% Added Y head & tail from St. Mary Rd. font (not yet adjusted). %
% First attempt to support LaTeX2e \usepackage options. %
% Fixed bug (missing \endgroup and no arrow) with \rTo[opt][opt]. %
% (The continuation, \after@opt@arg, had got overwritten.) %
% Set \mathsurround=0pt for everything within our code. %
% Already set in \inner@environment and in \make@horiz@part but %
% not when \math@on & math@off are (re)made in \size@dependencies.%
% Also set it in \default@args for horiz maps outside diagrams. %
% 3.28 Released 30 November 1993 %
% Fixed bug causing diagram to disappear in vert mode in LaTeX %
% caused by \everypar overwriting \box0 - use \box2 instead. %
% Peter Freyd's \puncture symbol provided. %
% 3.27 Released 26 March 1993 %
% Fixed bug which forced LaTeX slopes on PostScript diagonals. %
% Got \max@fraction wrong: moved to condition in \exec@diagonal. %
% Renamed \put@PS@horiz as \exec@PS@diagonal. Made \exec@horiz %
% exclusively horizontal, moving "extra text" test there. %
% Call \calc@horiz and \label@horiz from \exec@diagonal instead. %
% Restored \max@fraction{255} to PostScript arrows. %
% 3.26 Released 11 February 1993 %
% Added [defaultsize=] to set \default@size, used if size unset. %
% Added 1pt space between label (strut) and horizontal shaft. %
% 3.25 Released 30 January 1993 %
% Resolution-dependent fudge (dpi) applied to horizontal arrows. %
% Removal of glue from before to after applied to display as well %
% as textflow, but didn't deal with spurious space after diagram. %
% Fixed extra height in \rhla. %
% Fixed \HmeetV vertical profile - bug caused by pixel fudge. %
% Defined \if@ignore outside LaTeX, use to control \ignorespaces %
% at end of diagram: to cure spurious space in text after %
% notextflow diagram. %
% Added \kern-\displayindent inside $$/$$ to over-ride prevailing %
% paragraph indentation: to cure shift and over-full \hbox in %
% itemized diagram. %
% Added \make@end@at@line after \egroup in \output@diagram so that%
% "too wide for page" and "flushleft in $$" can give line numbers.%
% LaTeX heads made default (unless \tenln undefined, when vee) %
% and set (by new \set@default@arrowhead) in horiz outside cd too.%
% Also cures zero-length shafts of arrows in text in footnotes. %
% Made \labelstyle and \objectstyle available as options. %
% Diagram options and output as new section; some reorganisation. %
% New display options give warning if used within maths. %
% Catch missing bracket at end of label and misplaced (but not %
% missing) bracket at end of \pile. %
% Small adjustments on some heads and tails. hbox option. %
% Braces and parentheses as arrows (bits from cmex) commented out.%
% Bits of double vert arrows use cmex not \Vert\Uparrow\Downarrow %
% Circle, cross, little vee, little black triangle heads. %
% Fixed spaces before & after diagram in display and textflow. %
% Catch em-braced arrow commands. %
% Adjusted hook tails yet again (some theory behind horizontals!).%
% Smashed height of \rhla \lhla \rtla and \ltla. %
% Default \MapBreadth as TeXbook p447; pixel round on input. %
% Apply pixel rounding to \make@vert@part and \shifthook. %
% First-use warning when defaulted diagonal components are used. %
% Warning if diagonals used & columns stretched significantly. %
% Warning if diagonals with repeating components are too short. %
% Added \@use@TPIC@false to diagonal dot repeater. %
% Changed setup of diagonal maps; now \+To gets immediate control,%
% sets defaults, calls \rTo (having changed \Horizontal@Map) and %
% the test to use PS is after the arguments have been read. %
% Local PostScript option (PS, noPS), disabled by noPostScript. %
% Collected all size-dependent initialisations in one macro, which%
% is executed before \diagram, \diagramstyle or text arrows. %
% Allowed curly instead of square brackets in \diagramstyle. %
% Also \diagramsstyle. %
% AMSTEX emulation - works at least when amstex not present. %
% Check for \diagram options changed to \futurelet (the earlier %
% problem with this lay in using \next@token twice), so it now %
% catches a blank line after \diagram or \begin{diagram}. %
% Fixed \HmeetV yet again. %
% Added Morse Code signature to every 20th suitable horizontal. %
% Position horizontal labels using strut rather than \baselineskip%
% Change definitions of default components from \def to \let. %
% This brought lower \scriptstyle labels closer to horizontals. %
% Use \boldmath for littlevee and hooks, if available. (DUBIOUS) %
% Vertical position of labels on diagonals had been unset! %
% Increased interim assumed \objectheight from .5ex to 1.8ex and %
% isolated \interim@shortfall. %
% Removed \outer from \diagramstyle. %
% Lots of adjustments to bits of arrows (drives me mad!). %
%% 3.24 Release 7 Sept 1992 advertised to users. %
% Continued fractions, sine, cosine & pythagorean sum. %
% \newarrow etc also define \+To \-To \nwTo %
% Rewrote LaTeX diagonal code: %
% uses continued fractions to find nearest slope and selects %
% character; diagonals touch a square around the (maths axis) %
% centre of the endpoints; middles; through diagonals. %
% \lq and \rq (instead of ` and ') for catcodes and octals. %
% Made it consistent with texinfo - for loading, at least. %
% PostScript option introduced: %
% \Rising@Map and \Falling@Map choose the horizontal command and %
% run \put@PS@horiz; %
% labels are rotated together with the arrow, %
% which is set in the first pass %
% meets a circle and is not yet adjusted for its endpoints. %
% LaTeX, vee, curlyvee, triangle & blacktriangle heads & tails %
% provided and correctly adjusted; double heads & tails all made %
% with \make@double@head. %
% TPIC option introduced as an alternative to \LaTeX@make@line. %
% 3.23 (14.5.92) experimental release on 10 July 1992 %
% Fixed pilespacing, and horizontal positioning of verticals %
% (bugs which arose from Seely's challenge). Also made need extra %
% message work. Discovered that \get@arg finds \end@cell, not &, %
% so removed {} from \tokcase and \catcase, so the \mathord{}s %
% disappeared. %
% Fixed vmiddle positioning of one-row diagrams. %
% Fixed catastrophic error of empty first cell in nested diagram %
% by using \bbgroup\eegroup around the diagram. %
% Moved making of \math@on@box to inside \bombparameters because %
% it caused "math formula deleted - insufficient fonts" if loaded %
% before \documentstyle. deleted \defaultarrowhead{vee} for same. %
% 3.22 (14.5.92) experimental release %
% 3.21 (1.5.92) %
% Extra line of paragraph, to contain profile information. %
% Implemented \shift (\cd@hshift). %
% Use \wd\cd@donat for column widths. %
% New reformatting program. %
% Re-arranged the code. %
% Optional arguments on \diagram, maps and \diagramstyle. %
% Horizontal \shift; tight cell width and height (option). %
% top, vmiddle, bottom positioning - aligns chosen maths axes %
% origin, balance, nobalance horizontal positioning %
% Made \PileSpacing between verticals local. %
% Fixed \HonV and \HmeetV profile. Included verticals in width. %
% Piles vertically centered ignoring outer labels. %
% Labels on horizontal maps positioned using \baselineskip 1.3ex. %
% Extra .2ex spacing around labels removed, .2em reduced to .1em %
% midshaft option to centre labels in horizontal arrow shaft. %
% Through horizontals and verticals. %
% \@and\sp\sb\space in \switch@arg; local catcode &,$ %
% Re-wrote mangletex to substitute our internal command names. %
% \CellSize=default on entry, in case the font size is different. %
% \across adds its with to \cd@hshift %
% Fixed unterminated verticals and cross profiles. %
% Move labels away from wide vertical arrow middles. %
% Added strut in \get@label to stop verts hitting middle labels. %
% Re-wrote \newif to make it manglable. %
% 3.20 (29.4.92) early release of version 4 %
% 3.19 (9.4.92) %
% Ensure \enddiagram occurs only at correct {}-level %
% by using \aftergroup. %
% Blank line and \par within diagram =\enddiagram. %
% Clashing (horizontal) arrows detected at first pass %
% using an automaton; %
% "&" (etc) inserted, with error & help messages. %
% \Pythagorean@sum. %
% Postscript arrows (basic code). %
% Implemented \newarrow \newarrowhead etc. %
% Corruption-sensitive characters avoided wherever possible. %
% Reloading prevented. %
% Horizontal arrows outside diagram can stretch by wordspacing. %
% 3.18 (18.12.90) bugfix %
% Diagonals (other than basic ones) moved to extra-diagonals.tex. %
% Changed \lt and \gt to \lessthan and \greaterthan for Roy Crole.%
% Added < and > for labels on left and right of arrow; %
% also [] for optional arguments on arrows (not used yet); %
% also displaced \catcase\bgroup (positional label) to speed up a %
% bit as this is obsolete. %
% 3.17 (10.9.90) bugfix %
% \offinterlineskip in \make@vert@part %
% \endgraf instead of \par (because LaTeX changes it) %
% \leavevmode before diagram to fix LaTeX-interaction bug %
% \cong as a middle (problem was \mathpalatte within \edef) %
% 3.16 (20.7.90) as mass mailed; only have mangled version %
% \DiagonalLineSegments=\ObsCount %
% \dmcornervert et seq commented out %
% 3.15 (1.7.90) numbered boxes for columns %
% left part of horiz arrow in \box2 (\across not yet fixed) %
% bugfixes: %
% spacing of \pile's %
% horizontal alignment of top of verticals - remove spurious space%
% horizontal alignment of verticals - \make@vert@part %
% zero height & depth of vertical parts to not force lines apart %
% 3.14 (1.7.90) bugfix: %
% parsing \across - remove spurious & %
% horizontal alignment of bottom of multiple verticals. %
% \lhla arrow the right way round. %
% add \MapShortFall and \MapCorner %
% 3.13 (2.6.90) A lot? %
% 3.11 (18.4.90) %
% Catch obsolete parameters, rename some dimensions, added to %
% \bombparameters. Changed template. %
% 3.03 (18.4.90) re-arranged code; a lot of changes? %
% 3.02 (3-7.2.90) %
% 3.01 (9.1.90) vertical reformatting; only have mangled version %
%% -- all following version numbers are post-facto -- %
%% 3 (Jan 90) stretching vertical arrows %
% 2.8 (2.1.90) new reformatting %
% 2.6 (30.12.89) added \pile %
%% 2 (Sept 89) horizontals stretch to objects; "superscript" labels %
%% 1 (1987) horizontal arrows stretch to edge of cell %
%% 0 (1986) implementation of Knuth's TeXercise 18.46 for my thesis %
% %
%%======================================================================%
% BUGS
% mangle \@name
% "Commutative Diagram: "&*&" inserted between horizontal map and pile."
% in inline diagram
% Silvio Levy <levy@msri.org> 13 Sept 2006 - see examples
% width of diagram takes account of labels on arrows but not
% the width of the last row of objects
% signature on squashed arrow
% re-sort the obfuscation list, as Robin Houston has found the macros.
% missing } after \pile doesn't recover
% \across doesn't work with grid
% this code wasn't updated when we changed the use of \column@placing
% \ldTo^~p
% \begin{diagram} ended by \end{displaymath} causes havoc!
% When a diagram is immedately followed by a footnote, there is no
% space between the bottom of the diagram and the footnote rule.
% \begin{diagram}[htriangleheight] with default \DiagramCellHeight
% - Volker Schubert <volli@tunix.mathematik.uni-stuttgart.de> 5 Feb 1997
% midshaft on objects in a \pile
% $R:X\rEmbed[heads=littlevee,l>=1.5em] Y$ is not very pretty:
% \verb/$R:X\rEmbed[heads=littlevee,l>=1.5em] Y$/.
% make the rule in \verb/\upperBrace/ thicker and shorter;
% the vertical brace is also ugly.
% switch to balance within flushleft doesn't work
% make bottom right of negative gradient diagonals 2pt less shortfall
% doesn't insert } correctly in
% \uInto<{b_!={!_L^*} \adjoint \dOnto>{b^*}
% TO DO THIS TIME
% - locate option to define origin of coordinates for diagonals
% - text in the middle of right triangles
% - diagonal pullback symbols
% - handle \verb/\qed/
% - \verb/vtriangle/ is too narrow (or too tall).
% - we really ought to have curved arrows!
% - define \verb/\Nanti/ and \verb/\Sclck/ 3/8-circle little arrows
% - do ``\verb/=/'' middle using two ruled lines.
% - wavy diagonal lines.
% - check interaction of landscape with other positioning options
% - option to set left or right width of object, rather than the shift
% 2-cells near vertices, offset annotation of vertices.
% - annotation on arrowheads and XYpic adjustable positioning of labels
% - Font sizes (line10) & \CellSize for slitex and 11pt/12pt (scaling?)
% default rule breadth in slitex.
% - give co-ordinates of cells (their line numbers?) in error messages
% TO DO NEXT TIME
% DIAGONALS
% - steep \rdTo_u places the label very low down
% - dashed diagonal should perhaps be dotted outside PS
% - with shallow LaTeX diagonals, measure the width, not the height
% - option to link diagonals to corners of objects instead of
% aiming at the centres of the cells.
% OUTPUT OPTIONS
% - argument to origin option
% - re-calculate \prevgraf based on height of diagram and \baselineskip
% - allow for short line before displayed diagram
% - \output@cell doesn't take account of everything that sticks out.
% - textflow diagram disappears immediately after displaymath envt.
% - some rows remain unreformatted: one-line diagram enclosed in
% \begin{diagram} \end{displaymath} in ptbook.sty.
% - textflow generating horizontal space in paragraph (manual, page 3)
% BITS OF ARROWS
% - make test file for all arrow styles and measure shortfall
% - LaTeX diagonal double tails need to be brought in a bit
% - option for shaft to go through double arrowhead; use difference in
% width of head and tail to choose spacing of double heads
% - curved corners on \HmeetV and half arrows; jumps and solders.
% - loops on vertices: see Pino's bits
% - electronic components
% - \nwarrow etc as (1,1) LaTeX diagonals
% - horizontal shaft one pixel too low for LaTeX heads and one pixel
% too high for curlyvee, at 300dpi
% - pixel adjustment on LaTeX diagonals
% - move the dots closer together
% DIAGNOSTICS
% - count number of lines since last & (\end@cell is more accurate)
% we do this (\cell@at@line), but what for?
% - make manual a LaTeX2e document.
% - "maps must never be enclosed in braces" from shifted diagonal
% - decide and document how much unterminated arrows stretch
% - lower unterminated downward verticals
% - allow unterminated maps to stretch to their natural width
% - classified summary of options in manual; list of errors,
% shift labels in options description to right
% - option not to load error messages (ask how many users care about this)
% - new display options should detect $$ not $ (probably useless in latex)
% - missing \endcsname in various places:
% in LaTeX2e \usepackage[flushleft=\mainindent]{diagrams}
% in zed.sty from <> in diagrams.tex and \newarrow{blah}---->
% IDEAS
% - make midvshaft work
% all of the labels on a system of parallel verticals must align
% - parametrise size of pullback symbols and crosses
% - rewrite amscd.sty
% - half arrows
% - adjunction environment
% - time bomb
% - Lamstex & xypic fonts
% - private version of \def with option to check re-definition; also
% re- & \global loading - with the aim of doing it on first use
% - \protect to arrows in section headings
% - more space around labels on in-text arrows if in \displaystyle
% UNREPEATABLE BUGS
% - \pile{text\rTo\\text\rTo} doesn't stretch correctly
% seems to work.
% - missives addressed to empty cells are lost - give error message
% they appear to be handled ok.
% COMPLAINTS AND WISHES
% - \hidewidth in objects causes arrows to overprint
% - \rTo{}{} puts struts in both labels - forces \pile apart (obsolete)
% - can't catch runaway argument to \pile
% - multi-line labels with embedded arrays
% this would have same problem as \pile in catching missing closing brace
% long objects doing this automatically (paragraph?)
% set up complete environment for labels
% allow Sb and Sp environments for label? can't see any way!
% - LaTeX center environment is unrestricted horizontal
% may want restricted horizontal mode behaviour there.
% - could \catcode`\&=\active etc and re\catcode (for texinfo)
% - write size information to .aux? what?
% - draft mode - what should(n't) it do?
% - strings, Feynman diagrams, ...
% - curved lines: see /home/leonardo/tex/contrib/Gnu/gs23/escher.ps
% sorry, this doesn't work with dvips because it does ``bind def''
% - \diagram[notextflow]..\enddiagram\begin{something}..\end{something}
% makes \end{something} do \ignorespaces.
% - prevent pagebreak before textflow diagram? penalties seem ok
% - Dusko wants automatic hidden line elimination
% - option to set the width of each column individually using missives
% (grid option does this ok, I think)
% - (probably) cannot work with TeX-XeT because of extra whatits
% - macros as diagram options (Volker Schubert)
%
%%======================================================================%
%% %
%% (1) CORRUPTION-SENSITIVE HACKS %
% AND PROGRAMMING FEATURES %
%% %
%%======================================================================%
%% CORRUPTION & \catcode WARNING
%% BITNET (IBM) machines may corrupt certain important characters
%% in transmission by electronic mail:
%% 0123456789=digits, abcdefghijklmnopqrstuvwxyz=lowers,
%% ABCDEFGHIJKLMNOPQRSTUVWXYZ=uppers, @=at (internal names),
%% {}=curly braces (grouping), \=backslash (keywords),
%% %=percent (comment), #=hash/sharp (argument), +=plus, -=minus,
%% <>=angle brackets (relations \ifnum,\ifdim), ==equals,
%% ,=comma, .=dot, :=colon, ;=semicolon, =space
%% $=dollar (maths) is only used in the "bits of maps" section
%% The following characters are marked by a comment including the word "ASCII",
%% except in comments and messages:
%% &=and (alignment), ~=tilde, |=vertical, []=square brackets,
%% ^=caret (superscript), _=underline (subscript),
%% "=double quote (hex), ()=round brackets,
%% /=slash, ?=query, !=pling/bang,
%% The following are no longer flagged:
%% `=grave/backquote (catcodes), '=acute/single quote (octal),
% check by the command:
% sed -e 's/.*%ascii.*//' -e 's/%.*$//' < diagrams.tex |\
% grep -n '[][&()*?|~^_/\!\"']
% Andrew Molitor <amolitor@wesleyan.earn> 27.3.91 says:
% caret became a space or was eaten entirely, not sure which,
% and tilde became a caret.
% changed \lq and \rq back to ` and ' 15.10.2008 (v3.93)
% as part of the adaptation to XeTeX proposed by
% Apostolos Sypopoulos <ijdt.editor@gmail.com>
%% The \catcode's marked * are assumed for reading this file:
%% \=0* {=1* }=2* $=3 &=4 return=5* #=6 ^=7 _=8 ignored=9*
%% space=10* letter=11* other=12 active=13 %=14* invalid=15
%% If you want to load this package inside Stallman's "texinfo", you must do
%% @catcode`@\=0 \catcode`\%=14 \input diagrams \catcode`\%=12 \catcode`\\=13
%% and then use @diagram @rTo @\ @enddiagram etc. (braces {} stay the same).
%% Also need @catcode`@&=4.
%%*** You *MUST NOT* use the internal commands (with names beginning \CD@)****
%! p \CD@
%! m \across@cells
% m \actually@braces@missing@around@macro@in@label
%! m \add@and
%! m \add@and@and
%! m \add@cr
%! m \add@dollar
%! m \add@empty@and
%! m \add@endpile@and
%! m \add@relax@before@square@bracket
%! m \@adjust@flush@left@false
%! m \@adjust@flush@left@true
%! m \after@diagram
%! m \after@name
%! m \after@names
%! m \after@opt@arg
%! m \amstex@diagram@setup
%! m \amstex@prefix
%! m \@and
%! m \and@in@pile
%! m \and@name
%! m \assign@at
%! m \assign@five
% m \at@
%! m \at@least
%! m \at@line
%! m \at@most
%! m \avoid@object
% m \axisheight
%! m \axis@profile
%! m \@back
%! m \bad@arrow
%! m \bad@end@label
%! m \bad@group@after@map
%! m \bad@pair@opt
%! m \bad@ps@prog
%! m \bbgroup
%! m \begin@at@line
%! m \@begin@cell
%! m \begin@cell
%! m \begin@maths
%! m \begin@pile
%! m \begin@square@name
%! m \better@use@ps
%! m \bgroup@name
%! m \body@
%! m \body@@
%! m \body@@@
%! m \@bomb
%! m \bomb@parameters
%! m \boxc@unt
% m \@brace
%! m \braced@label
% m \break@args
%! m \buffer@to@row
% m \@c
%! m \calc@horiz
% m \@catcode
%! m \@cd@a@false
%! m \cd@and
%! m \@cd@a@true
%! m \cd@balance
%! m \@cd@b@false
%! m \cd@bottom
%! m \cd@box@g
%! m \@cd@b@true
%! m \cd@cell
%! m \@cd@centre@display@false
%! m \@cd@centre@display@true
%! m \@cd@centre@hlabel@false
%! m \@cd@centre@hlabel@true
%! m \@cd@centre@vlabel@false
%! m \@cd@centre@vlabel@true
%! m \cd@cross
%! m \cd@diag@zer
%! m \cd@dim@a
%! m \cd@dim@b
%! m \cd@dim@g
%! m \cd@dim@h
%! m \cd@dim@k
%! m \cd@display
%! m \cd@display@box
%! m \cd@donat
%! m \cd@environment
%! m \cd@eqno
%! m \cd@error
%! m \cd@first@use
%! m \cd@fullwidth
%! m \@cd@g@false
%! m \cdgh@
%! m \@cd@g@true
%! m \cdgv@
%! m \@cd@hbox@false
%! m \@cd@hbox@true
%! m \cd@horiz@positioning
%! m \cd@hshift
%! m \@cd@landscape@false
%! m \@cd@landscape@true
%! m \cd@left
%! m \cd@left@donat
%! m \cd@left@margin
%! m \@cd@leqno@false
%! m \@cd@leqno@true
%! m \@cd@missive@false
%! m \@cd@missive@true
%! m \cd@mode@outside
%! m \cd@name
%! m \cd@num@a
%! m \cd@num@b
%! m \cd@num@c
%! m \cd@num@d
%! m \cd@num@g
%! m \cd@num@h
%! m \cd@obs@count
%! m \cd@obs@dim
%! m \cd@obs@dimq
%! m \cd@obs@msg
%! m \@cd@one@liner@false
%! m \@cd@one@liner@true
%! m \cd@opt@prefix
%! m \cd@penalty
%! m \cdps@ don't mangle any of these!
% m \cdps@Bechtolsheim
% m \cdps@Clark
% m \cdps@dvips
% m \cdps@dvitops
% m \cdps@dvitps
%! m \@cd@PS@horiz@false
%! m \@cd@PS@horiz@true
% m \cdps@IntegratedComputerSystems
% m \cdps@oztex
% m \cdps@RadicalEye
% m \cdps@Rokicki
% m \cdps@Trevorrow
%! m \cd@refmt@error
%! m \cd@right
%! m \cd@right@donat
%! m \cd@row
% m \cds@ don't mangle any of these!
% m \cd@shouldnt
%! m \cd@state
%! m \cd@switch@arg
%! m \cd@text@flow
%! m \@cd@text@flow@false
%! m \@cd@text@flow@true
%! m \@cd@through@false
%! m \@cd@through@true
%! m \@cd@tight@false
%! m \@cd@tight@true
%! m \cd@top
%! m \cd@top@height
%! m \@cd@use@PS@false
%! m \@cd@use@PS@true
%! m \cd@vbottom
%! m \cd@vcentre
%! m \cd@vert@positioning
%! m \cd@vmiddle
%! m \cd@vtop
%! m \cd@warning
%! m \cd@with@opt
%! m \cd@zerowidth
%! m \cell@at@line
%! m \cell@height@to@width
%! m \cell@missive
%! m \check@fated@enddiagram
%! m \check@horiz
%! m \check@part
%! m \check@vert
%! m \Climbingfalse
%! m \Climbingtrue
% m \@cmex
%! m \cmex@vert@part
%! m \column@placing
%! m \completed@depth
%! m \complete@horizontal
%! m \complete@last@row
%! m \@complete@vertical
%! m \complete@vertical
%! m \@complete@vspace
%! m \cont@frac@done
%! m \cont@frac@swap
%! m \co@ordinates
%! m \correct@for@width
%! m \crab@
%! m \cr@name
%! m \cross@names
%! m \cross@profile
%! m \cross@strut
%! m \@d
% m \d@brace
%! m \declared@at@cell
%! m \deepen@donations
%! m \default@args
%! m \default@diagonal
%! m \default@mapbreadth
%! m \default@max@fraction
%! m \default@profile
%! m \default@size
%! m \def@name
%! m \def@ps@turn
%! m \denominator@
%! m \diag@is@horiz
%! m \diag@is@vert
%! m \diagonal@box
%! m \@diagonals@used@false
%! m \@diagonals@used@true
%! m \@@@diagram
%! m \@@diagram
%! m \@diagram
%! m \diagram@cr
% m \diagram@help@messages
%! m \diagram@name
%! m \@di@dah
%! m \dim@in@pts
%! m \div@cclvi
%! m \div@dii
%! m \divide@
%! m \do@after@opt@arg
%! m \do@case
%! m \do@cont@frac
%! m \do@fated@enddiagram
%! m \dollar@name
%! m \do@message@at@end@doc
%! m \do@opt@arg
%! m \do@opt@arg@then
%! m \do@pile@row
%! m \do@set@dot@filler
%! m \dot@filler
%! m \double@LaTeX
% m \d@parenth
% m \eat@space
%! m \edef@name
%! m \eegroup
%! m \egroup@missing@label
%! m \egroup@name
%! m \@em
%! m \empty@filler
%! m \empty@name
%! m \empty@parts
%! m \end@at@line
%! m \end@cell
%! m \@enddiagram
%! m \@enddiagram@endpile
%! m \enddiagram@endpile
%! m \end@diagram@name
%! m \@end@diagram@ok@false
%! m \@end@diagram@ok@true
%! m \end@get@csname
%! m \@end@label
%! m \end@label
%! m \end@maths
%! m \end@mess
%! m \@end@pile
%! m \end@pile
%! m \end@square@name
% m \endswitch
%! m \exec@cross
%! m \exec@diagonal
%! m \execDiagonalLine
%! m \@exec@diagram
%! m \exec@diagram
%! m \exec@horiz
%! m \exec@LaTeX@diagonal
%! m \exec@map
%! m \exec@missive
%! m \exec@PS@diagonal
%! m \exec@vert
%! m \exit@diagram
%! m \expanded@ps@special
%! m \expanded@tpic@special
%! m \far@end@cell
%! m \fated@enddiagram
%! m \@filla
%! m \@fillb
% m \fill@dot % don't mangle as we \let@names{fill@dot}{}
%! m \@filler
% m \@fillh
% m \@fillv
%! m \finish@pile
%! m \first@occur
%! m \firstpass@showboxdepth
%! m \@first@positional@false
%! m \@first@positional@true
%! m \five@args
%! m \found@end@diagram
%! m \gdef@name
%! m \get@arg
%! m \@getcoords
%! m \get@csname
%! m \get@interrow@glue
%! m \@get@label
%! m \get@label
%! m \get@mand@value
%! m \@@getoptarg
%! m \get@opt@arg@list
%! m \get@opt@value
%! m \get@profile@info
% m \get@round@pair
% m \get@square@arg
%! m \glet
%! m \glet@names
% m \greaterthan
%! m \group@after@map
%! m \g@tmp
%! m \@h
%! m \handle@at
%! m \handle@at@
%! m \handle@matrix@row
% m \hbox@maths
%! m \@head
%! m \help@and
%! m \help@and@in@pile
%! m \help@bad@group
%! m \help@endlabel
%! m \help@hext
%! m \help@hpile
%! m \help@newarrow
%! m \help@pilecr
%! m \help@pile@enddiagram
%! m \help@undef@map
%! m \help@vext
%! m \help@vpile
% m \h@grid
%! m \horiz@add
%! m \horiz@extra
% m \horizhtdp
% m \Horizontal@Map
% m \Horizontal@Map
%! m \horizontal@name
%! m \horiz@repeater
%! m \horiz@state
%! m \@hug@false
%! m \@hug@true
%! m \if@adjust@flush@left@
%! m \if@cd@a@
%! m \if@cd@b@
%! m \if@cd@centre@display@
%! m \if@cd@centre@hlabel@
%! m \if@cd@centre@vlabel@
%! m \if@cd@g@
%! m \if@cd@hbox@
%! m \if@cd@landscape@
%! m \if@cd@leqno@
%! m \if@cd@missive@
%! m \if@cd@one@liner@
%! m \if@cd@PS@horiz@
%! m \if@cd@text@flow@
%! m \if@cd@through@
%! m \if@cd@tight@
%! m \if@cd@use@PS@
%! m \if@diagonals@used@
%! m \if@end@diagram@ok@
%! m \if@first@positional@
%! m \if@hug@
%! m \if@in@matrix@
%! m \if@need@PS@lib@
%! m \@@ifoptarg
%! m \@ifoptarg
%! m \if@reformatting@
%! m \if@use@TPIC@
%! m \if@was@pair@
% m \ignore@false
% m \ignore@true
% m \incommdiagfalse
% m \incommdiagtrue
%! m \info@at@end
%! m \@in@matrix@false
%! m \@in@matrix@true
%! m \inner@environment
%! m \inner@pile
%! m \intended@breadth
%! m \interim@shortfall
%! m \inter@row
%! m \iterate@
%! m \iterate@@
%! m \iterate@@@
%! m \@junk
%! m \@l
%! m \label@eat@space
%! m \label@egroup
%! m \label@egroups
%! m \label@horiz
%! m \label@optional
%! m \last@map@type
%! m \LaTeX@arrow@char
%! m \@@LaTeX@diagonal
%! m \LaTeX@dot@filler
%! m \LaTeX@line@char
%! m \LaTeX@make@line
%! m \LaTeX@name
%! m \LaTeX@NE
%! m \LaTeX@SW
% m \l@brace
%! m \left@donated
%! m \left@label
%! m \left@LaTeX@tail
%! m \left@over
%! m \left@part
%! m \left@width
% m \lessthan
%! m \let@names
%! m \lift@map@part
%! m \lift@map@parts
%! m \line@char
%! m \line@font
%! m \loop@on@cells
%! m \loop@on@maps
%! m \loop@on@rows
% m \lower@label
% m \l@parenth
% m \@m
%! m \make@diag@part
%! m \@make@double@head
%! m \make@double@head
%! m \@make@double@through@head
%! m \make@end@at@line
%! m \make@filler
%! m \make@found@end@diagram
%! m \make@horiz@part
%! m \make@line
%! m \makeline
%! m \make@old@fill
% m \make@pbk
%! m \make@profile
%! m \make@vert@part
%! m \math@off
%! m \math@off@box
%! m \math@on
%! m \math@on@box
%! m \maths@display
%! m \matrix@row@to@buffer
%! m \matrix@to@buffer
%! m \max@fraction
%! m \message@at@end@doc
%! m \@middle
% m \middle@label
%! m \min@map@length
%! m \misplaced@enddiagram
% m \missing@label
%! m \missive@diagonal
%! m \missive@outside
%! m \missive@to@cell
%! m \missive@to@row
%! m \mk@new@donat
%! m \modify@cell
%! m \monomial@
%! m \more@dim
%! m \more@donations
%! m \@morse
%! m \multiply@
%! m \multiply@@
% m \@name
%! m \name@prefix
%! m \need@extra
%! m \@need@PS@lib@false
%! m \@need@PS@lib@true
%! m \@new@arrow
%! m \newarrow@mmode
%! m \newarrow@name
%! m \new@arrow@part
%! m \new@diagonal
%! m \new@five@map
%! m \new@half@rpt@map
%! m \new@half@rule@map
%! m \new@help
%! m \new@horiz@map
%! m \new@if
%! m \new@line
%! m \new@map
%! m \new@rule@map
%! m \new@simple@map
%! m \new@slant@map
%! m \new@slope@map
%! m \new@thru@map
%! m \new@vector@map
%! m \new@vert@map
%! m \next
%! m \next@opt@arg
%! m \next@token
% m \no@cd@help
%! m \no@check@vert
%! m \no@error@context
%! m \nohcheck
%! m \no@make@line
%! m \@noptcmd
%! m \no@tenln
%! m \numerator@
% m \objectheight
%! m \object@profile
% m \objectwidth
%! m \obs@across
%! m \@obs@countq
%! m \obs@display
%! m \obs@positional
%! m \odef
%! m \old@horiz@fill
%! m \old@horiz@map
%! m \old@horiz@part
%! m \old@vert@fill
%! m \old@vert@map
%! m \one@sp
%! m \@optcmd
% m \optional@
% m \@outer@active
%! m \outer@empty
%! m \outer@environment
%! m \output@cell
%! m \output@diagram
%! m \outside@diagram
%! m \over@print
%! m \overprint@pbk
%! m \@p
%! m \pair@diagram@end
%! m \@par@enddiagram
%! m \par@enddiagram
% m \@parenth
%! m \par@name
%! m \par@not@allowed
%! m \@parse@opt@arg
%! m \parse@opt@arg
%! m \@parse@pair
%! m \pbk@osh
%! m \pbk@sh
%! m \pbk@shsh
%! m \pending@left
%! m \pending@right
%! m \@pile
%! m \pile@cr
%! m \pile@empty@row
%! m \pile@junk
%! m \pile@state
%! m \pixel@round
%! m \pixel@size
%! m \polar@to@rect
% m \positional@
%! m \PositiveGradientfalse
%! m \PositiveGradienttrue
%! m \ps@prog
%! m \push@queue
%! m \push@stack
%! m \put@cd@box
%! m \put@horiz
%! m \pyth@add@term
%! m \Pythagorean@sum
%! m \@pyth@sum
%! m \@r
% m \r@brace
%! m \reassign@filler
%! m \reassign@parts
%! m \receive@cell@type
%! m \reformat@cell
%! m \reformat@complex
%! m \reformat@empty
%! m \reformat@HmeetV
%! m \reformat@HonV
%! m \@reformat@horiz
%! m \reformat@horiz
%! m \reformat@matrix
%! m \reformat@object
%! m \reformat@pile
%! m \reformat@row
%! m \@reformatting@false
%! m \@reformatting@true
%! m \reformat@vert
%! m \reformat@VonH
%! m \reoutput@cell
%! m \resend@missive
%! m \reset@map@breadth
%! m \right@donated
%! m \right@label
%! m \right@LaTeX@tail
%! m \right@over
%! m \right@part
%! m \right@width
%! m \Rotated@Horizontal
%! m \rounded@breadth
%! m \row@depth
%! m \row@height
%! m \row@to@buffer
% m \r@parenth
% m \@rTo
%! m \rule@depth
%! m \rule@height
%! m \save@begin@at@line
%! m \save@cell@at@line
%! m \save@row@no
% m \@scriptaxis
% m \@scriptaxis
% m \script@axisheight
%! m \see@above
%! m \send@cell@type
%! m \separate@verticals
%! m \set@arrowhead
%! m \set@axis
%! m \set@cmex@axis
%! m \set@cmex@offset@axis
%! m \set@col@width
%! m \set@currentlabel
%! m \set@currentlabel@to@equation
%! m \@set@default@part
%! m \set@default@part
%! m \set@default@parts
%! m \set@dot@filler
%! m \set@fraction
%! m \set@h@grid
%! m \set@map@parts
%! m \set@max@fraction
%! m \set@mil
%! m \set@new@display
%! m \set@offset@axis
%! m \set@resolution
%! m \set@resultion
%! m \@setup@horiz
%! m \setup@pile
%! m \set@v@grid
%! m \showboxname
%! m \showname
%! m \show@prevgraf
%! m \showthename
%! m \@signature
%! m \signature@countdown
%! m \size@dependencies
%! m \skip@case
% m \Slant@Map
% m \Slant@Map
% m \Slope@Map
% m \Slope@Map
%! m \snake@
%! m \spAn
%! m \split@pile@row
%! m \square@fraction
% m \@ssaxis
% m \ss@axisheight
%! m \start@bomb@vlist
%! m \stretch@PS@diagonal
%! m \stretch@vert
%! m \@sub
% m \@super
% m \@super
% m \switch@arg
%! m \switch@label@arg
%! m \@szdep
%! m \@tail
%! m \test@loose@diagonals
%! m \test@signature
%! m \the@bomb
%! m \the@default@head
%! m \then
%! m \the@signature
%! m \this@map@type
% m \tmp
%! m \total@donated
% m \to@z
%! m \tpic@make@line
%! m \@u
% m \u@brace
%! m \unbraced@label
% m \undefined
% m \u@parenth
% m \upper@label
% m \Use@line@char
% m \Use@line@char
%! m \use@line@char
%! m \use@name
%! m \use@newarrow
%! m \@use@TPIC@false
%! m \@use@TPIC@true
%! m \using@ps
%! m \@v
%! m \@value
% m \Vector@Map
% m \Vector@Map
%! m \@vector@setup
%! m \verbatim@ps@special
%! m \vert@extra
% m \Vertical@Map
% m \Vertical@Map
%! m \vertical@name
%! m \vert@outside
%! m \vert@repeater
%! m \vert@wd@in@leftmost
% m \v@grid
%! m \@VonH
%! m \@was@pair@false
%! m \@was@pair@true
%! m \widen@hbox
%! m \widen@horiz
%! m \widen@pile
%! m \word@shrink
%! m \word@stretch
% m \@x % don't mangle as we \let@names{@x}{}
%! m \x@coord
%! m \xlc@ii
%! m \xlc@iv
%! m \x@offset
%! m \y@coord
%! m \y@offset
%! m \@pdf@false
%! m \@pdf@true
%! m \denom@@
%! m \div@@
%! m \do@eturn
%! m \if@pdf@
%! m \make@division
%! m \mk@@div
%! m \mnum@@
%! m \num@@
%! m \rotate@box@z
%! m \use@ps
%! m \dont@use@ps
%! m \use@pdf
%! m \undefined
%! m \cd@nonoPS
%! m \test@pdf
%! m \pdf@literal
%% don't load me twice!
% 19.9.2008 Terrence Bisson <bisson@canisius.edu>
% \undefined had been mangled to \CD@qK
% but in plain TeX, @=other, so got "@qK" in the output.
\ifx\diagram\isundefined\else\message
{WARNING: the \string\diagram\space command is already defined and
will not be loaded again}%
\expandafter\endinput\fi
%% make @ letter, saving its old code to restore at the end of this file
%% look for this on the last line of the file if you think something's missing!
%% the other \catcode assignments are to make it work with texinfo.
\edef\cdrestoreat{%%
\noexpand\catcode`\noexpand\@=\the\catcode`\@%%
\noexpand\catcode`\noexpand\#=\the\catcode`\#%%
\noexpand\catcode`\noexpand\$=\the\catcode`\$%%
\noexpand\catcode`\noexpand\<=\the\catcode`\<%%
\noexpand\catcode`\noexpand\>=\the\catcode`\>%%
\noexpand\catcode`\noexpand\:=\the\catcode`\:%% Johannes L. Braams's
\noexpand\catcode`\noexpand\;=\the\catcode`\;%% Babel languages package
\noexpand\catcode`\noexpand\!=\the\catcode`\!%% makes these \active.
\noexpand\catcode`\noexpand\?=\the\catcode`\?%%
\noexpand\catcode`\noexpand\+=\the\catcode'53%% texinfo @+ is @outer@active
}\catcode`\@=11
\catcode`\#=6 \catcode`\<=12 \catcode`\>=12 \catcode'53=12
\catcode`\:=12 \catcode`\;=12 \catcode`\!=12 \catcode`\?=12
%% Change y to n if pool_size in your implementation of TeX is small.
%% This is reasonable if you have a small ("personal") computer, but if you
%% have a sun, dec, hp, ... workstation or a mainframe, complain to your local
%% system manager and get him/her to install a version of TeX with bigger
%% parameters. The "hash size" (number of command names) gets you next.
\ifx\diagram@help@messages\undefined\let\diagram@help@messages y\fi
%% The following macro is used to include literal PostScript commands in the
%% DVI file for rotation, etc. Since this goes beyond standard TeX, it is
%% dependent on the convention used by your local DVI-to-PostScript translator.
%% Choose whichever line applies to the program used at your site, or, if
%% yours is not listed, consult the manual, experiment with this macro and
%% (please) tell me what is needed to make it work.
%%
%%
%% dvips (Tomas Rokicki, Radical Eye) labrea.stanford.edu /pub/dvips9999.tar.Z
%% CTAN: dviware/dvips
\def\cdps@Rokicki#1{\special{ps:#1}}%
\let\cdps@dvips\cdps@Rokicki
\let\cdps@RadicalEye\cdps@Rokicki\let\cdps@\cdps@Rokicki
\let\verbatim@ps@special\cdps@Rokicki\let\cdps@\cdps@Rokicki
%%
%% I'm not sure that the rest work.
%%
%% dvitps (Stephan Bechtolsheim, Integrated Computer Systems)
%% arthur.cs.purdue.edu /pub/TeXPS-9.99.tar.Z
\def\cdps@Bechtolsheim#1{\special{dvitps: Literal "#1"}}%% ASCII two dbl quotes
\let\cdps@dvitps\cdps@Bechtolsheim
\let\cdps@IntegratedComputerSystems\cdps@Bechtolsheim
%%
%% dvitops (James Clark)
%% CTAN: dviware/dvitops
\def\cdps@Clark#1{\special{dvitops: inline #1}}%%
\let\cdps@dvitops\cdps@Clark
%%
%% OzTeX (Andrew Trevorrow) cannot be used
\let\cdps@OzTeX\empty\let\cdps@oztex\empty\let\cdps@Trevorrow\empty
%%
%% dvi3ps (Kevin Coombes)
%% CTAN: dviware/dvi2ps/dvi3ps
\def\cdps@Coombes#1{\special{ps-string #1}}%
%\let@names{cdps@dvi3ps}{cdps@Coombes}%
%%
%% psprint (Trevorrow) CTAN: dviware/psprint
%% dvi2ps (Senn) CTAN: dviware/dvi2ps
%% psdvi (Elwell) CTAN: dviware/dvi2ps/psdvi
% there's also an expiry (and \endinput) message further down
\count@=\year\multiply\count@12 \advance\count@\month%%
\ifnum\count@>24300 %% (December 2024)
\message{***********************************************************}%%ascii
\message{! YOU HAVE AN OUT OF DATE VERSION OF COMMUTATIVE DIAGRAMS! *}%%
\message{! it expired in December 2024 and is time-bombed for April *}%%
\message{! You may get an up to date version of this package from *}%%ascii
\message{! either www.ctan.org or www.PaulTaylor.EU/diagrams/ *}%%
\message{***********************************************************}%%ascii
\ifnum\count@>24303 %% (March 2025)
\errhelp{You may press RETURN and carry on for the time being.}%
\message{! It is embarrassing to see papers in conference proceedings}%
\message{! and journals containing bugs which I had fixed years before.}%
\message{! It is easy to obtain and install a new version, which will}%
\errmessage{! remain compatible with your files. Please get it NOW.}%
\fi\fi
\def\glet{\global\let}\def\odef{\outer\def}%
% \let\@let\let\let\@edef\edef\let\@def\def
% \def\glet{\global\@let}%
% \def\odef{\outer\@def}%
% \@def\make@show@define#1{\expandafter\@let\csname\string#1\endcsname#1%
% \@edef#1##1{\noexpand\message{\string#1\noexpand\string##1^^J}%
% \csname\string#1\endcsname##1}}%
% \make@show@define\glet\make@show@define\let\make@show@define\def
% \make@show@define\gdef\make@show@define\edef\make@show@define\xdef
% \make@show@define\odef
%% safe names for braces, tab (&) and maths ($), as commands and for messages
{\escapechar\m@ne\xdef\bgroup@name{\string\{}\xdef\egroup@name{\string\}}%%
%%
%% three ASCII ampersands (ands) (&&&) appear on the next line
\catcode`\&=4 \glet\@and=&\xdef\and@name{\string\&}%%ascii three ands
%%
%% ASCII ^ and _ each appear twice on next line
%% six ASCII dollars ($$$$$$) appear on the next two lines.
\catcode`\$=3 \glet\begin@maths=$\glet\end@maths=$%%ascii three dollars
\xdef\dollar@name{\string\$}\gdef\maths@display{$$}%%ascii three dollars
%%
%% two ASCII underlines (__) appear on the next line.
\catcode`\_=8 \glet\@sub=_%%ascii two underlines
%%
%% eight ASCII carets (^^^^^^^^) appear on the next three lines.
\obeylines\catcode`\^=7 \glet\@super=^%%ascii two carets
\ifnum \newlinechar=10 \gdef\new@line{^^J}%%ascii two carets
\else \ifnum\newlinechar=13 \gdef\new@line{^^M}%%ascii two carets
\else \ifnum\newlinechar=-1 \gdef\new@line{^^J}%%ascii two carets
\else \glet\new@line\space
\expandafter\message{! input error: \noexpand%ascii
\newlinechar\space is ASCII \the\newlinechar, not LF=10 or CR=13.}%%
\fi\fi\fi}%%
%% avoid using <> (because I personally re-define them to mean \langle\rangle)
\mathchardef\lessthan='30474 \mathchardef\greaterthan='30476
%% LaTeX line and arrowhead font
%% the "hit return" comments show up if the font is missing.
% size option?
\ifx\tenln\undefined%%
\font\tenln=line10\relax%% Hit return - who needs diagonals?
\fi
\ifx\tenlnw\undefined
\ifx\tenln\nullfont
\let\tenlnw\nullfont
\else%%
\font\tenlnw=linew10\relax%% Hit return - who needs diagonals?
\fi \fi%%
%% report line numbers in TeX3 only
% \newcount is \outer so cannot appear in skipped or definition text.
\ifx\inputlineno\undefined
\csname newcount\endcsname\inputlineno\inputlineno\m@ne
\message{***************************************************}%
\message{! Obsolete TeX (version 2). You should upgrade to *}%
\message{! version 3, which has been available since 1990. *}%
\message{***************************************************}%
\fi
\def\cd@shouldnt#1{\cd@refmt@error{* THIS (#1) SHOULD NEVER HAPPEN! *}}%ascii
%% turn round- and square-bracketed arguments into curly-bracketed
\def\get@round@pair#1(#2,#3){#1{#2}{#3}}%%ascii round brackets ()
\def\get@square@arg#1[#2]{#1{#2}}%%ascii square brackets []
\def\get@opt@arg@list#1{%
\@was@pair@false
\let\next@opt@arg\@@getoptarg
\@@getoptarg#1,],}%%ascii sq brackets
\def\begin@square@name{[}\def\end@square@name{]}%ascii
\def\commdiag#1{{\let\enddiagram\relax\diagram[]#1\enddiagram}}%ascii
%% ASCII open square bracket occurs on next line
\def\@@ifoptarg{{\ifx\next@token[%]%ascii
\aftergroup\get@square@arg\aftergroup\@optcmd
\else
\aftergroup\@noptcmd
\fi}}%%
% switch on presence of optional argument:
% \@ifoptarg{\y}{\n}[arg] does \y{arg}
% \@ifoptarg{\y}{\n} does \n
% are the braces actually necessary to avoid &?
\def\@ifoptarg#1#2{\def\@optcmd{#1}\def\@noptcmd{#2}%
\futurelet\next@token\@@ifoptarg}%
%% ASCII vertical bar (|) occurs on the next line
\def\vertical@name{|}%ascii
% idea: test & separately
% idea: use \meaning
% 14.5.92 DON'T GET & - GET \end@cell ANYWAY!
\def\cd@switch@arg{%% arguments to maps inside diagrams
\tokcase\end@cell:\@cd@a@false% no text between tip and &
\break@args ;%
\catcase\@super:\upper@label ;% superscript
\catcase \@sub:\lower@label ;% subscript
\tokcase {~}:\middle@label;%%ascii tilde
\tokcase <:\left@label ;%%ascii less-than
\tokcase >:\right@label ;%%ascii greater-than
\tokcase (:\co@ordinates;%%)%ascii open round bracket
\tokcase [:\optional@ ;%%]%ascii open square bracket
\tokcase .:\set@dot@filler;%%ascii dot 12.7.94
\catcase \space:\eat@space ;% space (ignore)
\catcase\bgroup:\positional@ ;% obsolete positional labels
\default :\@cd@a@true % extra text between tip and &
\break@args ;% (anything else terminates labels)
\endswitch}
% Since maps are never bombed outside diagrams, glue compensation works
% and we don't have to abort through maps.
\def\switch@arg{%% arguments to horizontal maps outside diagrams
\catcase\@super:\upper@label ;% superscript
\catcase \@sub:\lower@label ;% subscript
\tokcase [:\optional@ ;%%]%ascii open square bracket
\tokcase .:\set@dot@filler;%%ascii dot 12.7.94 % ; was : before 15.6.97
\catcase\space:\eat@space ;% space (ignore)
\catcase\bgroup:\positional@;% obsolete positional labels
\tokcase {~}:\middle@label;%%ascii tilde (questionable!)
\default :\@cd@a@false % no need to allow for extra text
\break@args ;% (anything else terminates labels)
\endswitch}
%% That's as much as you get to read "in clear" - the rest is private!
%************************ program constructs *******************
%
\let\then\relax % makes \if...\then...\else...\fi more readable
\ifx\protect\undefined\let\protect\relax\fi
%
\ifx\AtEndDocument\undefined
\def\message@at@end@doc{\cd@warning}%
\def\info@at@end#1#2{}%
%
\else % messages to output at the end of the run (28.7.95)
\def\message@at@end@doc#1{%
\edef\next{#1}%
\expandafter\do@message@at@end@doc\next\end@mess}%
\def\do@message@at@end@doc#1\end@mess{%
\AtEndDocument{\typeout{\cd@name: #1}}}%
\def\info@at@end#1#2{\gdef#1{#2}\AtEndDocument{#1}}%
\fi
% make warning to be given at first use only
\def\cd@first@use#1#2{%
\def#1{\message@at@end@doc{#2\first@occur\at@line}%
\glet#1\relax}}%
%
% TeX does not provide for nested loops in same scope!
% Warning: the \relax is needed in case the last command in the body reads
% ahead, for example "\advance\count@ 1".
%
% Why can't you put conditionals inside loops? Try with \toks.
%
\def\loop@on@rows#1\repeat{\def\body@{#1}\iterate@}%
\def\iterate@{\body@\relax\expandafter\iterate@\fi}%
\def\loop@on@cells#1\repeat{\def\body@@{#1}\iterate@@}%
\def\iterate@@{\body@@\relax\expandafter\iterate@@\fi}%
\def\loop@on@maps#1\repeat{\def\body@@@{#1}\iterate@@@}%
\def\iterate@@@{\body@@@\relax\expandafter\iterate@@@\fi}%
%
% as \newif, but simpler and manglable; initialised to false
\def\new@if#1#2#3{\def#2{\let#1\iftrue}\def#3{\let#1\iffalse}#3}%
%
% as \newhelp, but with a suppression option
\if y\diagram@help@messages
\def\new@help#1#2{%
\csname newtoks\endcsname#1%
#1=\expandafter{%
% I wanted to avoid the \ but it doesnt work
%\expandafter\escapechar\expandafter\m@ne\expandafter\string
\csname#2\endcsname}}%
\else
\csname newtoks\endcsname\no@cd@help
\no@cd@help{See the manual}%
\def\new@help#1#2{\let#1\no@cd@help}%
\fi
%
% box definitions used during reformatting
\chardef\left@part=1
\chardef\right@part=2
\chardef\object@profile=5
\chardef\pending@right=6
\chardef\pending@left=7
\chardef\default@profile=9
\dimendef\right@donated=2
\dimendef\left@donated=3
\dimendef\left@width=4
\dimendef\right@width=5
\dimendef\total@donated=6
\dimendef\rule@height=8
\dimendef\rule@depth=9
\skipdef\completed@depth=1
\skipdef\inter@row=2
\skipdef\column@placing=3
\skipdef\horiz@extra=4
\skipdef\vert@extra=5
\skipdef\right@over=6
\skipdef\left@over=7
\skipdef\row@height=8
\skipdef\row@depth=9
\countdef\declared@at@cell=9
\countdef\far@end@cell=8
\countdef\across@cells=7
%
\def\sdef#1#2{\def#1{#2}}%
\def\after@name#1{\expandafter\aftergroup\csname #1\endcsname}%
\def\def@name#1{\expandafter\def\csname #1\endcsname}%
\def\gdef@name#1{\expandafter\gdef\csname #1\endcsname}%
\def\edef@name#1{\expandafter\edef\csname #1\endcsname}%
\def\let@names#1#2{\expandafter\let\csname#1\expandafter\endcsname
\csname#2\endcsname}%
\def\glet@names#1#2{\expandafter\glet\csname#1\expandafter
\endcsname\csname#2\endcsname}%
\def\use@name#1{\csname #1\endcsname}%
\def\showname#1{\expandafter\show\csname #1\endcsname}%
\def\showthename#1{\expandafter\showthe\csname #1\endcsname}%
\def\showboxname#1{\expandafter\showbox\csname #1\endcsname}%
%
\def\cd@name{Commutative Diagram}%
\edef\par@name{\string\par}%
\edef\diagram@name{\string\diagram}%
\edef\end@diagram@name{\string\enddiagram}%
\edef\cr@name{\string\\}%
\def\LaTeX@name{LaTeX}%
%
% LaTeX's switch to do \ignorespaces after an environment
% 11.10.97 inserted \global because LaTeX2e has changed the
% point at which \if@ignore\@ignorefalse\ignorespace\fi
% is executed. (Reported by Arthus Ogus ogus@math.berkeley.edu).
\ifx\@ignoretrue\undefined
\expandafter\new@if\csname if@ignore\endcsname\ignore@true\ignore@false
\def\@ignoretrue{\global\ignore@true}%
\def\@ignorefalse{\global\ignore@false}%
\fi
%
%***************** aside on brace hacking (TeXbook p385) *****************
\def\bbgroup{{\ifnum0=`}\fi}\def\eegroup{\ifnum0=`{\fi}}%
% This is from latex.tex; it does \noalign{\hrule}, but if the next token
% is another \hrule it does \noalign{\hrule\vskip\hrule}.
% The reason why brace-backing is needed is that \ifx\@tempa\hline might
% encounter an & or \cr or \omit or \span. Our version of the same doesn't
% need this; it gets round it by putting the \ifx in braces.
% \def\hline{\noalign{\ifnum0=`}\fi\hrule \@height \arrayrulewidth \futurelet
% \@tempa\@xhline}
%\def\@xhline{\ifx\@tempa\hline\vskip \doublerulesep\fi
% \ifnum0=`{\fi}}
% there are other more complex examples for \\ commands for arrays, tables,
% etc. They need brace-hacking to protect \@ifstar - ie for the same reason.
%************************************************************************
% \hbox and \halign need {} or \bgroup\egroup, not \begingroup\endgroup
%************************************************************************
%
%
% % % **** implement a case-switch construct ****
% % % Note that to protect & and \cr from recognition
% % % we have to em-brace them - \begingroup\endgroup doesn't work.
% % % This is probably the cause of the empty \mathord{} items.
% % % Also tried \def\catcase#1{\expandafter\eat@one{...}}\def\eat@one#1{}.
% % \def\catcase#1:{{%
% % \ifcat \noexpand\next@token#1%
% % \then \aftergroup\do@case
% % \else \aftergroup\skip@case
% % \fi}}%
% % \def\tokcase#1:{{%
% % \ifx \next@token#1%
% % \then \aftergroup\do@case
% % \else \aftergroup\skip@case
% % \fi}}%
% We never got & as \next@token anyway! The \mathord{}s have gone!
\def\catcase#1:{%
\ifcat \noexpand\next@token#1%
\then \expandafter\do@case
\else \expandafter\skip@case
\fi}%
\def\tokcase#1:{%
\ifx \next@token#1%
\then \expandafter\do@case
\else \expandafter\skip@case
\fi}%
\def\do@case#1;#2\endswitch{#1}%
\def\skip@case#1;{}%
\let\endswitch\relax
\def\default:#1;#2\endswitch{#1}% must come last
%
%idea
% \checklist<list><token>
% \def\checklist#1\expand\thenexttoken#2\endlist{%
% \def\rest{##2}%
% \ifx\rest\empty
% \then <not in list>
% \else <is in list>
% \fi}
%
% my initials in Morse code
%\def\@di@dah{\begin@maths{\cdot}{-}{\cdot}\;\;{-}\end@maths}%
%\def@name{rt:dah}{\rlap{\@di@dah}}%
%
%\edef\x{\meaning\year}\edef\y{\string\year} agree
%
% ***************** amstex emulation ***************
%
\ifx\at@\undefined\def\at@{@}\fi% amstex handling of @ defaults to letter
%\edef\amstex@prefix{pt@amstex@at@}%
\edef\amstex@prefix{\bgroup@name pt\egroup@name}%
\def@name{\amstex@prefix>}#1>#2>{\cd@and\rTo\sp{#1}\sb{#2}\cd@and}% horizontals
\def@name{\amstex@prefix<}#1<#2<{\cd@and\lTo\sp{#1}\sb{#2}\cd@and}%
\def@name{\amstex@prefix)}#1)#2){\cd@and\rTo\sp{#1}\sb{#2}\cd@and}%%ascii round
\def@name{\amstex@prefix(}#1(#2({\cd@and\lTo\sp{#1}\sb{#2}\cd@and}%%ascii brack
%
\def\amstex@diagram@setup{%
\def\endCD{\enddiagram}%
\def@name{\amstex@prefix A}##1A##2A{\uTo<{##1}>{##2}\cd@and\cd@and}%
\def@name{\amstex@prefix V}##1V##2V{\dTo<{##1}>{##2}\cd@and\cd@and}%
\def@name{\amstex@prefix=}{\cd@and\hEq\cd@and}%
\def@name{\amstex@prefix\vertical@name}{\vEq\cd@and\cd@and}%
\def@name{\amstex@prefix\string\vert}{\vEq\cd@and\cd@and}%
\def@name{\amstex@prefix.}{\cd@and\cd@and}%
\let\cd@and\@and
}%
%
\def\handle@at{%
\let\tmp\handle@at@
\ifcat A\noexpand\next\else
\ifcat =\noexpand\next\else
\ifcat\relax\noexpand\next\else
\let\tmp\at@\fi\fi\fi
\tmp}%
\def\handle@at@#1{\let@names{tmp}{\amstex@prefix\string#1}%
\ifx\tmp\relax\def\tmp{\at@#1}\fi\tmp}%
%
\def\cd@and{}%
%
\begingroup\aftergroup
\def \aftergroup
\assign@at \aftergroup
{%
\aftergroup
\def \catcode`\@\active\aftergroup
@%
\endgroup
{\futurelet\next\handle@at}}%
%
%=======================================================================%
% %
% (2) DIMENSIONS AND COUNTS %
% %
%=======================================================================%
%
% define some scratch variables for our own use
% "gh" means global - use others and box/dimen 0...9 locally only
\newcount\cd@num@a\newcount\cd@num@b\newcount\cd@num@c\newcount\cd@num@d
\newdimen\cd@dim@a\newdimen\cd@dim@b
\new@if\if@cd@a@\@cd@a@true\@cd@a@false
\new@if\if@cd@b@\@cd@b@true\@cd@b@false
\newdimen\cd@dim@h\newdimen\cd@dim@k
\newcount\cd@num@g\newcount\cd@num@h
\newdimen\cd@dim@g\newbox\cd@box@g
\new@if\if@cd@g@\@cd@g@true\@cd@g@false
\newcount\numerator@\newcount\denominator@
%
% make #1 at least (resp at most) #2
\def\at@least#1#2{\ifdim#1<#2\relax#1=#2\relax\fi}%
\def\at@most #1#2{\ifdim#1>#2\relax#1=#2\relax\fi}%
%
\newdimen\one@sp\one@sp=1sp
\newdimen\@em\@em\z@
%
% check whether \@em has changed
% it was initialised to zero, and if "1em" is still zero
% that means there is no font loaded.
\def\size@dependencies{\ifdim\@em=1em\else\@szdep\fi}%
%
% if so, reset default arrowhead and \mathon & \mathoff
\def\@szdep{%
\@em1em%
\def\default@mapbreadth{\fontdimen8\textfont3 }%
\set@arrowhead\set@max@fraction
%
% Can't see how to get \mathoff on its own without \null,
% as it disappears at line breaks.
% ! Math formula deleted: Insufficient symbol fonts
\setbox0=\vbox{\bomb@parameters
\noindent\begin@maths\null\penalty-9993\null\end@maths\null\endgraf
\setbox0=\lastbox\unskip\unpenalty\setbox1=\lastbox
\global\setbox\math@off@box=\hbox
{\unhbox0\unskip\unskip\unpenalty\setbox0=\lastbox}%
\global\setbox\math@on@box=\hbox
{\unhbox1\unskip\unpenalty\setbox1=\lastbox}}%
}%
%
%\def\to@z{to\z@}%
%
% anticipate the pixel positioning
\newdimen\pixel@size\pixel@size=1true in \divide\pixel@size 300
%
% round #1 (a dimension or number) to pixels
\def\pixel@round#1{%
\multiply#1\tw@
\advance#1\ifnum#1<\z@-\else+\fi\pixel@size
\divide#1\tw@
\divide#1\pixel@size
\multiply#1\pixel@size
}%
%
\def\MapBreadth{\afterassignment\reset@map@breadth\intended@breadth}%
\newdimen\intended@breadth % of ruled lines
\newdimen\rounded@breadth % \intended@breadth rounded to pixels
\def\reset@map@breadth{%
\rounded@breadth\intended@breadth
\at@least\pixel@size{4\one@sp}% make sure we can divide by it
\at@most\pixel@size\p@ % pixel smaller than point
\pixel@round\rounded@breadth
\ifdim\intended@breadth>\z@\at@least\rounded@breadth\pixel@size\fi
\size@dependencies}%
\def\set@resolution#1{%
\get@mand@value\count@
\pixel@size#1%
\ifnum\count@>\z@\divide\pixel@size\count@\fi
\reset@map@breadth\set@max@fraction}%
\def\set@max@fraction{% 6 April 1995
\dimen@\default@size
\count@\dimen@\divide\count@ 5\divide\count@\pixel@size
\edef\default@max@fraction{\the\count@}%
%\expandafter\message
%{max fraction=\default@max@fraction=\the\dimen@/5x\the\pixel@size}%
}%
%
% set up for rule centred on maths axis
\def\set@axis{\set@offset@axis\z@}%
\def\set@offset@axis#1{%
\rule@height\axisheight
\advance\rule@height#1\relax
\advance\rule@height-.5\rounded@breadth
\pixel@round\rule@height
\rule@depth-\rule@height
\advance\rule@height\intended@breadth
}%
%
% transverse and longitudinal offset for arrows
\newdimen\crab@\crab@\z@\newdimen\snake@\snake@\z@
%
% set up for rule used with cmex parts (on baseline) 17.7.94
\def\set@cmex@offset@axis#1{%
\rule@depth#1\relax
\rule@height\rule@depth
\advance\rule@height\intended@breadth\relax
}%
%
\def\horizhtdp{height\rule@height depth\rule@depth}%
\def\axisheight{\fontdimen22\the\textfont\tw@}% maths axis from symbols family
\def\script@axisheight{\fontdimen22\the\scriptfont\tw@}% script axis ditto
\def\ss@axisheight{\fontdimen22\the\scriptscriptfont\tw@}% scriptscript axis
\def\default@mapbreadth{0.4pt}%
\def\word@stretch{\fontdimen3\textfont\z@}%
\def\word@shrink{\fontdimen3\textfont\z@}%
%
%
\newdimen\PileSpacing
\newdimen\cd@left@margin \cd@left@margin\z@
%\newdimen\min@map@length
\def\min@map@length{\ifincommdiag 1.3em\else 2em\fi}%
\newdimen\cd@top@height
%
\def\CellSize{\afterassignment\cell@height@to@width\DiagramCellHeight}%
\newdimen\DiagramCellHeight \DiagramCellHeight-\maxdimen
\newdimen\DiagramCellWidth \DiagramCellWidth-\maxdimen
\def\cell@height@to@width{\DiagramCellWidth\DiagramCellHeight}%
%
\def\default@size{3em}%
%
\newdimen\MapShortFall
\def\MapsAbut{\MapShortFall\z@\objectheight\z@\objectwidth\z@}%
%
\newdimen\cd@hshift\cd@hshift\z@ % amount to shift object right in cell
%
% %% this is a mega-hack for extracting as text the value of a \dimen in points
% {\catcode`p=12 \catcode`0=12 \catcode`.=12 \catcode` t=12
% \gdef\rem@z#1.0.#2,{#1}%
% \gdef\dim@sans@uni#1pt{\rem@z#1.0.,}}%
% \def\dim@in@pts#1{\expandafter\dim@sans@uni\the#1 }
%\def\axis@height@in@pts{\dim@in@pts\axisheight}%
%
%------------------------------------------------------------------------
% 25 Aug 2006: PS & PDF switches moved here
%
% test whether \ifUglyObsoleteDiagrams has been defined and set to \iftrue
%
%\showname{ifUglyObsoleteDiagrams}%
\new@if\if@cd@use@PS@\@cd@use@PS@true\@cd@use@PS@false
\expandafter
\ifx\expandafter\iftrue\csname ifUglyObsoleteDiagrams\endcsname
\@cd@use@PS@false
\else\@cd@use@PS@true
\fi
\let@names{ifUglyObsoleteDiagrams}{relax}%
\newif\ifUglyObsoleteDiagrams
\def\use@ps{\@cd@use@PS@true\UglyObsoleteDiagramsfalse}%
\def\dont@use@ps{\@cd@use@PS@false\UglyObsoleteDiagramstrue}%
\if@cd@use@PS@\use@ps\else\dont@use@ps\fi
%
%
% are we using PDF-TeX?
\new@if\if@pdf@\@pdf@true\@pdf@false\@pdf@false
%
% On Fri, 11 Jul 2003, Volodymyr Lyubashenko wrote:
% it seems that version 2002/03/15 v3.89 is incompatible with
% latex commands like
% \usepackage[dvips]{graphics}
% or \usepackage{color}
% which also uses package `graphics'. It mistakes latex for pdflatex.
% This is ... MiKTeX 2.2 (preloaded format=latex 2000.11.28)
% ! Missing number, treated as zero.
% ! Missing = inserted for \ifnum.
% ! Illegal unit of measure (pt inserted).
% -- so I tried testing for \pdfoutput=\relax
%
\def\test@pdf{%
\ifx\pdfoutput\undefined\else
\ifx\pdfoutput\relax\else
\ifnum\pdfoutput>\z@\use@pdf
\fi\fi\fi
}
\def\use@pdf{%
\global\@pdf@true
\global\@cd@use@PS@true
\global\UglyObsoleteDiagramsfalse
\global\let\better@use@ps\empty
\global\let\dont@use@ps\relax
\global\let\use@pdf\relax
\global\let\test@pdf\relax
}%
%\def\pdf@literal#1{\message{pdf: literal #1}\special{pdf: literal #1}}%
\def\pdf@literal#1{\special{pdf: literal #1}}%
\ifx\pdfliteral\undefined\else
\ifx\pdfliteral\relax\else
\let\pdf@literal\pdfliteral
\fi\fi
%
% are we running under XeTeX?
\ifx\XeTeXrevision\undefined\else
\ifx\XeTeXrevision\relax\else
\ifdim\XeTeXrevision pt<.996pt
\expandafter\message{! XeTeX version \XeTeXrevision\space
does not support PDF literals, so diagonals will not work!}%
\else
\expandafter\message{RUNNING UNDER XETEX \XeTeXrevision}%
\use@pdf
\fi\fi\fi
%
% are we running under pdftex? (this is repeated in the first diagram)
\test@pdf
%
%=======================================================================%
% %
% (2) MAKE ARROW PARTS %
% %
%=======================================================================%
%
% \newarrowhead{name}{right}{left}{down}{up}
% #5 #6 #7 #8 #9
%
\def\newarrowhead {\new@arrow@part h\make@horiz@part\make@vert@part>}%
\def\newarrowtail {\new@arrow@part t\make@horiz@part\make@vert@part>}%
\def\newarrowmiddle{\new@arrow@part m\make@horiz@part\hbox@maths\empty}%
\def\newarrowfiller{\new@arrow@part f\horiz@repeater \vert@repeater -}%
% #1 #2 #3 #4
% 12.7.94 removed \make@vert@part from vertical middle,
% because it was hiding the width of wide middles (eg transitors).
%
% idea: []-option to set something instead of #4
% idea: check whether #5 is already defined
\def\new@arrow@part#1#2#3#4#5#6#7#8#9{%
\def@name{r#1:#5}{#2{#6}}%
\def@name{l#1:#5}{#2{#7}}%
\def@name{d#1:#5}{#3{#8}}%
\def@name{u#1:#5}{#3{#9}}%
\edef@name{-#1:#5}{\expandafter\noexpand\csname-#1:#4\endcsname
\noexpand\default@diagonal}%
\edef@name{+#1:#5}{\expandafter\noexpand\csname+#1:#4\endcsname
\noexpand\default@diagonal}%
% \let@names{+#1:#5}{+#1:#4}%
% \let@names{-#1:#5}{-#1:#4}%
}%
\cd@first@use\default@diagonal{\LaTeX@name\space diagonals are used unless
PostScript is set}%
%
% ****************** choose default components *****************
%
% 32 arrow parts in 16 boxes
\def\defaultarrowhead#1{\edef\the@default@head{#1}\set@arrowhead}%
\def\set@arrowhead{%
\set@default@parts \the@default@head <>ht% single arrowheads
%\set@default@parts{double\the@default@head}{<<}{>>}ht% double heads
\set@default@parts \the@default@head <>th% single tails
%\set@default@parts{double\the@default@head}{<<}{>>}th% double tails
}%
%
% 8 arrow parts in 4 boxes
\def\set@default@parts#1#2#3#4#5{% #1=choice #2=tailname #3=headname #4=h #5=t
\set@default@part{r#4}{#3}{l#5}{#2}{r#4:#1}%
\set@default@part{r#5}{#2}{l#4}{#3}{l#4:#1}%
\set@default@part{d#4}{#3}{u#5}{#2}{d#4:#1}%
\set@default@part{d#5}{#2}{u#4}{#3}{u#4:#1}%
}%
%
% do: if \#1+:#2 is not defined then \newbox\#1+:#2 \fi
% \def\#1:#2{\copy\#1::#2}
% \def\#3:#4{\copy\#1::#2}
% \setbox\#1::#2=\#5
%
\def\set@default@part#1#2#3#4#5{%
\begingroup
%\expandafter\ifx\csname #1+:#2\endcsname\relax %ascii
% \after@name{newbox}\after@name{#1+:#2}%ascii
%\fi
\aftergroup\@set@default@part
\after@name{#1+:#2}\after@name{#1:#2}\after@name{#3:#4}\after@name{#5}%ascii
\endgroup}%
%
% use this code first to define the boxes and macros
\def\@set@default@part#1#2#3#4{% #1=boxname #2=partname #3=synonym #4=value
\csname newbox\endcsname#1%
\def#2{\copy#1}%
\def#3{\copy#1}%
\setbox#1=\box\voidb@x}%
%
\def\the@default@head{}%
\set@arrowhead% do it with empty boxes
%
% now re-define the macro so that it just sets the box
\def\@set@default@part#1#2#3#4{\setbox#1=#4}%
%
\ifx\tenln\nullfont
\def\the@default@head{vee}%
\else\let\the@default@head\LaTeX@name
\fi
%
\def\make@double@head#1#2#3{%
\begingroup
\aftergroup\@make@double@head\after@name{#1#2:#3#3}\after@name{#1#2:#3}%
\aftergroup\@make@double@through@head\after@name{#1#2:#3-#3}\after@name{#1#2:#3}%
\endgroup}%
%
\def\@make@double@head#1#2{\def#1{\hbox{\rlap{#2}\kern.4\@em#2}}}%
\def\@make@double@through@head#1#2{%
\def#1{\hbox{\rlap{#2}\kern.4\@em#2\kern-.4\@em}}}%
\make@double@head lh>%
\make@double@head rt>%
\make@double@head rh<%
\make@double@head rt<%
\def\@make@double@through@head#1#2{%
\def#1{\hbox{\kern-.4\@em\rlap{#2}\kern.4\@em#2}}}%
\make@double@head rh>%
\make@double@head lh<%
\make@double@head lt>%
\make@double@head lt<%
%
\def\@make@double@head#1#2{%
\def#1{\vbox{\vbox to\z@{#2\vss}\nointerlineskip\kern.4\@em#2}}}%
\def\@make@double@through@head#1#2{%
\def#1{\vbox{\vbox to\z@{#2\vss}\nointerlineskip\kern.4\@em#2\kern-.4\@em}}}%
\make@double@head uh>%
\make@double@head dt>%
\make@double@head dh<%
\make@double@head dt<%
\def\@make@double@through@head#1#2{%
\def#1{\vbox{\kern-.4\@em\vbox to\z@{#2\vss}\nointerlineskip\kern.4\@em#2}}}%
\make@double@head dh>%
\make@double@head ut>%
\make@double@head uh<%
\make@double@head ut<%
%
% old version that did both together every time
% NB \csname undefined\endcsname=\relax LOCALLY - \aftergroup it's \undefined
%\def\@set@default@part#1#2#3#4{% #1=boxname #2=partname #3=synonym #4=value
%\ifx#1\undefined\csname newbox\endcsname#1\fi %if #1 is undefined \newbox#1 fi
%\def#2{\copy#1}\def#3{\copy#1}%
%\setbox#1=#4}%
%
%
% ******************* MAKE MAP PARTS ***********************
%
% idea: use \mathsurround
%
% Clip the margins off Computer Modern symbols.
\def\make@horiz@part#1{%
\hbox{\mathsurround\z@\offinterlineskip
\begin@maths\mkern-1.5mu{#1}\mkern-1.5mu\end@maths
}}%
%
% Put vertical arrow part into a box, centering it.
% However since there's nothing we can do about the fact the
% reference point of \vrule width\intended@breadth is on the left,
% we make the other repeating boxes compatible with it,
% by centering them (smashed) in a box of the same width.
%
\def\hbox@maths#1{\hbox{\begin@maths#1\end@maths}}% 17.7.94
\def\make@vert@part#1{\hbox to\intended@breadth{%
\setbox0=\hbox{%
\offinterlineskip
\mathsurround\z@
\begin@maths{#1}\end@maths % set the vertical arrow part
}%
\dimen0.5\wd0\advance\dimen0-.5\rounded@breadth
\pixel@round{\dimen0}%
\kern-\dimen0\unhbox0\hss}}%
%
% version for use with cmex parts 17.7.94
\def\cmex@vert@part#1{\hbox to2\intended@breadth{% don't understand "2"
\hss
\offinterlineskip
\mathsurround\z@
\begin@maths{#1}\end@maths % set the vertical arrow part
\hss}}%
%\def\cmex@vert@part#1{\hbox to\z@{\hss\begin@maths#1\end@maths\hss}}%
%
%\def\make@vert@part#1{%
%\hbox to\intended@breadth{% arrow-part: centered in 0 to \MapB
%\offinterlineskip\mathsurround\z@
%\hss\begin@maths%\kern\intended@breadth
%{#1}\end@maths\hss}}%
%\def\make@vert@part#1{%
%\hbox to\z@{% arrow-part
%\setbox0=\hbox{\offinterlineskip\mathsurround\z@\begin@maths{#1}\end@maths}%
%\count@\wd0\advance\count@-\intended@breadth\advance\count@\pixel@size
%\divide\count@2\divide\count@\pixel@size
%\dimen0\wd0\advance\dimen0.5\pixel@size\divide\dimen0\pixel@size
%\dimen1\intended@breadth\advance\dimen1.5\pixel@size\divide\dimen1\pixel@size
%\advance\dimen0-\dimen1\divide\dimen0 2\count@\dimen0%
%\kern-\count@\pixel@size\box0\hss}}%
%
\def\make@diag@part#1{\hbox{\mathsurround\z@\begin@maths{#1}\end@maths}}%
%
\def\horiz@repeater#1{\hbox{\kern-.15\@em\begin@maths{#1}\end@maths
\kern-.15\@em}}%
%
\def\vert@repeater #1{%
\vbox{\offinterlineskip
\kern-.2ex%
\make@vert@part{#1}%
%\hbox to\intended@breadth{\hss\begin@maths{#1}\end@maths\hss}%
\kern-.2ex}}%
%
% also dot filler
%
\def\@fillh{\xleaders\vrule\horizhtdp}% default rule filler
\def\@fillv{\xleaders\hrule width\intended@breadth}%
\let@names{rf:-}{@fillh}\let@names{lf:-}{@fillh}%
\let@names{df:-}{@fillv}\let@names{uf:-}{@fillv}%
%
% ****************** empty components *****************
%
% empty arrowhead and middle
\let@names{rh:}{null}\let@names{rm:}{null}\let@names{rt:}{null}%
\let@names{lh:}{null}\let@names{lm:}{null}\let@names{lt:}{null}%
\let@names{dh:}{null}\let@names{dm:}{null}\let@names{dt:}{null}%
\let@names{uh:}{null}\let@names{um:}{null}\let@names{ut:}{null}%
\let@names{+h:}{null}\let@names{+m:}{null}\let@names{+t:}{null}%
\let@names{-h:}{null}\let@names{-m:}{null}\let@names{-t:}{null}%
%
% empty filler (nontrivial size, to avoid division by zero in \xleaders)
% 17.7.94 changed from \def to \let
% 4.7.97 \empty@filler and \empty@parts
\def\empty@filler{\hbox{\vrule height 1pt depth-1pt width 1pt}}%
\def@name{rf:}{\empty@filler}\let@names{lf:}{rf:}\let@names{+f:}{rf:}%
\def@name{df:}{\empty@filler}\let@names{uf:}{df:}\let@names{-f:}{df:}%
\def\empty@parts{\assign@five\null\empty@filler\null\empty@filler\null}%
%
%
%=======================================================================%
% %
% (3) NEW ARROW %
% %
%=======================================================================%
%
% define a family of arrow commands
% \newarrow{Name}{tail}{filler}{middle}{filler}{head}
%
% idea: \catcode`\\ to catch non-text names
% idea: \renewarrow etc, also synonyms & head/tail synonyms
% idea: optional argument to list directions, eg [r,l,d,u] or [nw,ne,sw,se]
%
\edef\newarrow@name{\string\newarrow}% do this now because it's \outer
%
% ******************* \newarrow *******************************
%
\def\newarrow#1#2#3#4#5#6{%
\begingroup
% ----- components and defaults -----
%
\edef\@name{#1}%
\edef\@tail{#2}\edef\@filla{#3}%
\edef\@middle{#4}\edef\@fillb{#5}\edef\@head{#6}%
\let\@h\new@horiz@map
\let\@v\new@vert@map
\let\@x\new@vector@map % LaTeX vector
%
% ----- normalise the components -----
%
% if the tips are the same as the corresponding fillers
% make them empty instead
\ifx\@tail\@filla\let\@tail\empty\fi
\ifx\@head\@fillb\let\@head\empty\fi
%
% if the head is empty and the tail isn't (funny!), swap everything around
\def\@r{r}\def\@l{l}\def\@d{d}\def\@u{u}\def\@p{+}\def\@m{-}%
% \ifx\@head\empty\ifx\@tail\empty\else
% \let\@r\@filla % wrong way round, so switch components
% \let\@filla\@fillb
% \let\@fillb\@r
% \let\@head\@tail % \@head was \empty anyway
% \let\@tail\empty
% \def\@r{l}\def\@l{r}\def\@d{u}\def\@u{d}\def\@p{-}\def\@m{+}%
% \fi\fi
%
\ifx\@filla\@fillb
%
% ----- same filler fore and aft -----
%
% normalise middle to empty if also same
\ifx\@middle\@filla\let\@middle\empty\fi
%
\ifx\@head\empty
\ifx\@filla\horizontal@name
\let\@x\new@slant@map % LaTeX \line
\else
\let\@x\new@slope@map % unrestricted
\fi\fi
%
\else\edef\@back{\@filla\@tail}%
\ifx\@back\empty
%
% ----- half-length maps -----
%
\ifx\@middle\@fillb\let\@middle\empty\fi % normalise middle if same
%\let\@h\new@half@horiz
%\let\@v\new@half@vert
\fi\fi
%
% ----- are the components actually there? -----
\ifmmode
\aftergroup\newarrow@mmode
\else
\@cd@a@true
\check@part rh{head\space\space}\@head
\check@part rf{filler}\@filla
\check@part rm{middle}\@middle
\ifx\@fillb\@filla\else
\check@part rf{filler}\@fillb
\fi
\check@part rt{tail\space\space}\@tail
%
\if@cd@a@
%
% ----- yes - output the definitions -----
%
\@h % make horizontals
\@v % make verticals
\@x % make diagonals
%
\new@diagonal l-2+2{lu}{nw}\NorthWest % \diagonal@setup
\new@diagonal r+2+2{ru}{ne}\NorthEast
\new@diagonal l-2-2{ld}{sw}\SouthWest
\new@diagonal r+2-2{rd}{se}\SouthEast
\else
% ----- no - output an error message -----
%
\aftergroup\bad@arrow\after@name{r\@name}%
\fi\fi
\endgroup % \aftergroup collects all the actual definitions here
}%
%
% ******************* \newarrow internals **************************
%
%
\def\new@horiz@map {\new@map\@r\@l rl\Horizontal@Map}%
\def\new@vert@map {\new@map\@d\@u du\Vertical@Map}%
\def\new@vector@map{\new@map\@p\@m +-\Vector@Map}% LaTeX \vector
\def\new@slant@map {\new@map\@p\@m +-\Slant@Map}% LaTeX \line
\def\new@slope@map {\new@map\@p\@m +-\Slope@Map}% unrestricted
%\def\new@half@horiz{\new@half@map\@r r\setup@right@half
% \new@half@map\@l l\setup@left@half}%
%\def\new@half@vert {\new@half@map\@d d\setup@bottom@half
% \new@half@map\@u u\setup@top@half}%
%
%
% ----- make one or two user arrow commands -----
%
\catcode`\/=\active %ascii avoid clash in use of slash delimiter/
%
\def\new@map#1#2#3#4#5{%
\@new@arrow#1#3#5t:\@tail/f:\@filla/m:\@middle/f:\@fillb/h:\@head//%ascii
\@new@arrow#2#4#5h:\@head/f:\@fillb/m:\@middle/f:\@filla/t:\@tail//}%ascii
%
%\def\new@half@map#1#2#3{\@new@arrow#1#2#3m:\@middle/f:\@fillb/h:\@head//}%
%
% internals:
% #1=name prefix, #2=argument prefix, #3=direction command, #4=arguments
\def\@new@arrow#1#2#3#4//{%ascii slash is \active here/
\edef\name@prefix{#2}%
\aftergroup\sdef\after@name{#1\@name}\aftergroup{%
\aftergroup#3% % setup
%\after@name{#1\@name}% give it its name (?)
\after@names#4//%ascii% arguments slash is \active/
\aftergroup}}%
%
\def\after@names#1/{%ascii /-separated, //-terminated list slash is \active/
\edef\next@token{#1}%
\ifx \next@token\empty
\else \after@name{\name@prefix#1}%
\expandafter\after@names%
\fi}%
%
\catcode`\/=12 %ascii restore slash/
%
% ----- make a user diagonal command -----
%
% #1=orthogonal direction to use for rotation
% (#2#3,#4#5) vectorial form of direction
% #6 #7 direction prefix for user command name
% #8 direction setup
% do: \def\#6name{\#2name \signGradient \#1name (#3,#5)}
\def\new@diagonal#1#2#3#4#5#6#7#8{%
\aftergroup\sdef\after@name{#6\@name}\aftergroup{% \def\#6name
\after@name{#2\@name}% diagonal map command eg \+To
\if#2#4%
\aftergroup\PositiveGradienttrue
\else\aftergroup\PositiveGradientfalse
\fi
\after@name{#1\@name}% orthogonal map to rotate eg \rTo
%% ASCII round brackets and comma (,) appear on the next line
\aftergroup(\aftergroup#3\aftergroup,\aftergroup#5\aftergroup)%ascii
\aftergroup}%
}%
%
% do: \def\#6name{\diag@setup #7 \#1name \#2name (#3,#5)}
%\def\new@diagonal#1#2#3#4#5#6#7#8{%
% \aftergroup\sdef\after@name{#6\@name}\aftergroup{% \def\#6name
% \if#2#4%
% \aftergroup\Rising@Map
% \else\aftergroup\Falling@Map
% \fi
% %\aftergroup\Diagonal@Map\aftergroup#7% % \Diagonal@Map #7
% \after@name{#1\@name}\after@name{#2\@name}% \#1name \#2name
% % ASCII round brackets and comma (,) appear on the next line
% \aftergroup(\aftergroup#3\aftergroup,\aftergroup#5\aftergroup)%ascii
% \aftergroup}%
%}%
%
% ----- existence of components -----
\def\check@part#1#2#3#4{%
\expandafter\ifx\csname #1#2:#4\endcsname\relax
\@cd@a@false\cd@warning{arrow#3 "#4" undefined}%ascii
\fi}%
%
\new@help\help@undef@map{All five components must be defined before an arrow.}%
\new@help\help@newarrow{\newarrow@name, unlike \string\HorizontalMap, is a
declaration.}%
%
\def\bad@arrow#1{\cd@error{Arrows \string#1 etc could not be defined}%
\help@undef@map}%
%
\def\newarrow@mmode{\cd@error{misplaced \newarrow@name}\help@newarrow}%
%
%
%=======================================================================%
% %
% (3A) NEW GRID %
% %
%=======================================================================%
%
\def\newdiagramgrid#1#2#3{%
\def@name{cdgh@#1}{#2,],}%% ASCII close square bracket
\def@name{cdgv@#1}{#3,],}}%% ASCII close square bracket
%
%=======================================================================%
% %
% (4) HORIZONTAL STATE CHECKING AND ARROW SETUP %
% %
%=======================================================================%
%
% We use \cd@donat (during the first pass, locally to each cell) to hold a
% "horizontal map state". Each map type inserts the missing text (giving an
% appropriate error message) shown for each state and changes to the new state.
%
% donated half maps?
%
% end of \rTo or \VonH or
% state cell \pile \dTo \HonV \HmeetV
% 0 outside diagram - ($) 0 forbid forbid forbid
% 1 space donated 1 5 3 4 4
% 2 arrow donated 1 {}& 5 3 5 4
% 3 verticals (in) 1 & 5 3 & 4 & 4
% 4 junction (this) 1 & 5 & 3 & 4 & 4
% 5 horizontal (cell) 2 &{}& 5 & 3 & 4 & 4
% 6 pile } 2 7 }& 3 }& 4 }& 4
% 7 pile horizontal } 2 \\ 7 }& 3 }& 4 }& 4
%
% initial states outside diagram, inside diagram and inside \pile
% signal we're outside \commdiag
\new@if\ifincommdiag\incommdiagtrue\incommdiagfalse
\new@if\if@in@matrix@\@in@matrix@true\@in@matrix@false % 12.7.94
\newcount\cd@donat
\cd@donat=0
\def\pile@state{\cd@donat6 }%
% idea: check number of rows and columns
% assign to \cd@num@g in case the first cell is empty, so \end@cell
% (and hence \send@cell@type) is not called.
% changed to \empty (and initialised as such) from {left edge} 27.12.93
\def\cd@state{\cd@donat1 \global\cd@num@g1 \glet\last@map@type\empty}%
\def\last@map@type{}%
%
% The automaton for horizontal maps; also used by \pile.
% #1="horizontal map" or "pile".
\def\check@horiz#1{\relax
\end@label % in case of missing close brace at end of label
\edef\this@map@type{#1}%
\begingroup
\if@cd@PS@horiz@\else
\ifcase\cd@donat\ifmmode\else% 0% 0 in maths outside diagram ok
\modify@cell\add@dollar 0\fi%0% 0 outside maths
\or\horiz@state 5% 1 accept space donation ok
\or\modify@cell\add@empty@and 5% 2 empty object between two horizontals
\or\modify@cell\add@and 5% 3 new cell after vertical
\or\modify@cell\add@and 5% 4 new cell after junction
\or\modify@cell\add@and@and 5% 5 two horizontals (perhaps \pile intended?)
\or\horiz@state 7% 6 in pile ok
\or\modify@cell\add@cr 7% 7 new row of pile after horizontal
\fi\fi\endgroup % save up commands to here with \aftergroup
\xdef\last@map@type{#1}}%
%
% The automaton for verticals; also used by \HonV, \VonH and \HmeetV.
% #1=least state requiring insertion, #2=usual new state, #3=exceptional one,
% #4=map type text, #5=command (will do no-op with error in forbidden case).
\def\check@vert#1#2#3#4#5{\relax
\end@label % in case of missing close brace at end of label
\xdef\this@map@type{#4}%
\begingroup
\ifnum \cd@donat<#1
\expandafter\horiz@state\ifcase\cd@donat0\or#2\or#3\else#2\fi%
\else \ifnum \cd@donat<6
\then \modify@cell\add@and #2%
\else \modify@cell\add@endpile@and #2%
\fi \fi
\endgroup % \aftergroup saves up commands to do here
\glet\last@map@type\this@map@type
\ifincommdiag
\let\exec@map#5%
\else \let\exec@map\vert@outside
\fi}%
%
% idea: compare with a global variable to check for (wrongly) em-braced maps.
% idea: count no. of rows & columns to check for overflow
%
% Pass the new horizontal state across cell boundary using global variable;
% this is picked up and assigned to \cd@donat in the next template.
\def\send@cell@type{\global\cd@num@g=\ifnum\cd@donat<5 1\else2\fi\relax}%
\def\receive@cell@type{\cd@donat\cd@num@g}%
%
% Set the new state (after \endgroup).
\def\horiz@state#1{\aftergroup\cd@donat\aftergroup#1\aftergroup\relax}%
%
% skip the check ("time nlatex manual")
% with check: 24.7u 1.0s 0:31 83% 0+1568k 0+13io 0pf+0w
% without: 24.6u 0.9s 0:30 83% 0+1572k 0+13io 0pf+0w
\def\nohcheck{%
\def\check@horiz##1{\relax}%
\let\check@vert\no@check@vert
\let\pile@state\relax
\let\cd@state\relax
\let\send@cell@type\relax
\let\receive@cell@type\relax
}%
\def\no@check@vert#1#2#3#4#5{%
\ifincommdiag
\let\exec@map#5%
\else \xdef\this@map@type{#4}\let\exec@map\vert@outside
\fi}%
%
% Do insertion, with error message (then change state), after \endgroup.
% [Remember that insertion of & or \\ within #1 causes a lot of extra commands
% like \begin@cell \end@cell to be executed.
% We are careful to ensure that conditionals are completed with our own cell.
% Note sure why, but it does at least mean that the user does not see \fi in
% the error context.]
\def\modify@cell#1{\aftergroup#1\aftergroup\relax\horiz@state}%
%
% The insertion commands.
\def\add@and{\horiz@add\and@name\help@and\@and}%
\def\add@endpile@and{\horiz@add{\egroup@name\and@name}\help@vpile%
\end@pile\@and}%
% How can we tell (in the next case) whether there is already an object in
% the cell, so it's just a & which is missing? Perhaps test whether \next@token
% is the first of \check@horiz? [\relax is too common for this]
\def\add@empty@and{\horiz@add{*\and@name}\help@hpile\clubsuit\@and}%ascii
\def\add@and@and{\horiz@add{\and@name*\and@name}\help@hpile\@and\clubsuit%ascii
\@and}%
\def\add@cr{\horiz@add\cr@name\help@pilecr\\}%
\def\add@dollar{\horiz@add\dollar@name\help@hext\begin@maths}%
\def\vert@outside{\cd@error{\this@map@type\space ignored \outside@diagram}%
\help@vext}%
%
% Within the $..$ of diagram & pile cells we assign \bad@group@after@map
% to \group@after@map, but make it \empty again in the diagram and pile
% environments. Then \aftergroup\group@after@map at the end of the arrow
% command (in \break@args) causes an error if the next end-of-group occurs
% strictly within the $; the $ itself is supposed to be the end-of-group.
\def\group@after@map{}%
\def\bad@group@after@map{\cd@error{maps must never be enclosed in braces}%
\help@bad@group}%
%
% This version also complains if you do ${\rTo}$ in text.
% \def\group@after@map{\ifmmode\expandafter\bad@group@after@map\fi}%
% but I had the following example in my book:
% $$\denote{\Gamma\rTo^{[f:=\hat g]}(f:(\hat A\to\hat B))}= ... $$
% which seems a reasonable use of braces around arrows in text.
% The only effect is to prevent them stretching with the paragraph.
%
% Help messages
\def\outside@diagram{outside diagram}%
\def\cross@names{\string\HonV, \string\VonH\space and \string\HmeetV}%
\new@help\help@and{The way that horizontal and vertical arrows are terminated
implicitly means\new@line that they cannot be mixed with each other or with
\cross@names.}%
\new@help\help@vpile{\string\pile\space is for parallel horizontal arrows;
verticals can just be put together in\new@line a cell. \cross@names\space
are not meaningful in a \string\pile.}%
\new@help\help@hpile{The horizontal maps must point to an object, not each
other (I've put in\new@line one which you're unlikely to want).
Use \string\pile\space if you want them parallel.}%
\new@help\help@pilecr{Parallel horizontal arrows must be in separate layers
of a \string\pile.}%
\new@help\help@hext{Horizontal arrows may be used \outside@diagram s, but must
still be in maths.}%
\new@help\help@vext{Vertical arrows, \cross@names\space\outside@diagram s
don't know where\new@line where to terminate.}%ascii
\new@help\help@bad@group{This prevents them from stretching correctly.}%
%
% The actual message.
% Before 27.12.93 this tested \ifincommdiag.
\def\horiz@add#1{\cd@error{"#1" inserted %ascii
\ifx\last@map@type\empty
before \this@map@type
\else between \last@map@type
\ifx \last@map@type\this@map@type s%
\else \space and \this@map@type
\fi
\fi}}%
%
\count@=\year\multiply\count@12 \advance\count@\month
\ifnum\count@>24307 \message{because this one expired in July 2025!}%
\expandafter\endinput\fi
%
%=======================================================================%
% %
% (5) SYNTAX OF ARROW COMMANDS %
% %
%=======================================================================%
%
%
% ************************* MAP SETUP ********************************
%
% The following are available when \exec@map is called, except:
% * indicates \set@map@parts does the assignment
%
% @cd@a@ = there's text between the last argument and the end of the cell
% @cd@through = whether \@filla and \@fillb agree
% \exec@map = command to execute
% \dimen 1 = left or lower shortfall
% \@head = leading tip (macro)
%*\box 1 = leading tip (set)
% \@filler = default filler against which to test for rule
% \@filla = leading filler: box or rule leaders (empty for right half map)
%*\box 2 = leading repeater, or void for rule
% \dimen 2 = minimum length of arrow (tip-to-tip)
% \skip 2 = glue for leading filler
% \box 3 = middle
% \cd@penalty = penalty code value
% \@fillb = trailing (right or lower) filler
%*\box 4 = trailing repeater, or void if rule
% \skip 4 = glue for trailing filler
% \@tail = trailing tip (macro)
%*\box 5 = trailing tip (set)
% \dimen 5 = right or upper shortfall
% \box 6 = leading label or void
% \box 7 = trailing label or void
%
% diagonals only:
% \x@coord = number of cells through which to pass horizontally
% \DiagramCellWidth = width of current column
% \y@coord = number of cells through which to pass vertically
% \DiagramCellHeight = height of current row
%
% \rTo -> \Horizontal@Map \rt: \rf:- \rm: \rf:- \rh:>
% \five@args picks up the five components and calls \get@arg,
% which parses the labels and options and calls \exec@horiz
%
\def\Horizontal@Map{%
\check@horiz{horizontal map}% % avoid clashes
\default@args\@setup@horiz % default parameters
%\let\fill@dot\hfdot % 12.7.94; moved to \@setup@horiz 28.7.95
\five@args}%
%
\def\@setup@horiz{%
\cd@penalty-9999 % \penalty code for default horizontal
\let\exec@map\exec@horiz % continuation for \get@arg
\ifincommdiag
% \baselineskip 1.4ex % for positioning of labels in diagrams
% \lineskip .3ex
% \lineskiplimit .3ex
\else \size@dependencies
% \dimen2=\min@map@length% min tip-to-tip arrow len 15.4.95
% \baselineskip .6ex % much closer in text
% \lineskip .2ex
% \lineskiplimit .2ex
\ifinpile\else
\skip2\z@
plus 1.5\word@stretch % whole map stretches like three words
minus .5\word@shrink % but shrinks like one
\skip4\skip2
\fi\fi
\let\@filler\@fillh
%\let\fill@dot\hfdot % 28.7.95
\let@names{fill@dot}{rf:.}% 30.7.98
}%
%
% \ruTo -> \+To \PositiveGradienttrue \rTo (2,2)
% \+To -> \Vector@Map \+t: \+f:- \+m: \+f:- \+h:>
% \@vector@setup sets \max@fraction and collects the five diagonal parameters.
% then \rTo is run with an altered definition of \Horizontal@Map
%
%\def\Rising@Map#1#2{\PositiveGradienttrue
% \if@cd@use@PS@\@cd@PS@horiz@true\expandafter#1\else\expandafter#2\fi}%
%\def\Falling@Map#1#2{\PositiveGradientfalse
% \if@cd@use@PS@\@cd@PS@horiz@true\expandafter#1\else\expandafter#2\fi}%
\def\Vector@Map{\@vector@setup 4}%
\def\Slant@Map {\@vector@setup{\if@use@TPIC@255\else6\fi}}%
\def\Slope@Map {\@vector@setup\default@max@fraction}% 7.4.95
%
% #1=maxfraction #2=tail #3=filler #4=middle #5=filler #6=head followed by
% gradient assignment and horizontal map to use in PostScript mode
\def\@vector@setup#1#2#3#4#5#6{%
\default@args
\def\x@coord{2}\def\y@coord{2}% coordinates for diagonals
\def\x@offset{1}\def\y@offset{1}% diagonalbase
%\global\@diagonals@used@true 12.7.94 moved to \exec@diagonal
\let\Horizontal@Map\Rotated@Horizontal
\def\max@fraction{#1}%
\def\reassign@parts{\assign@five#2#3#4#5#6}%
}%
%
\def\Rotated@Horizontal{%
\@setup@horiz
\@cd@PS@horiz@true
\let\exec@map\exec@diagonal
\five@args}%
%
\new@if\if@cd@missive@\@cd@missive@true\@cd@missive@false\@cd@missive@true
\def\cds@missives{\@cd@missive@true}%
\def\exec@diagonal{%
\if@cd@use@PS@
\let\max@fraction\default@max@fraction
\calc@horiz
% attach labels to horizontal arrow if hug option
\if@hug@\label@horiz\fi % hug option 4.7.97
\setbox0\hbox{\incommdiagfalse\put@horiz}%
\if@cd@missive@
% use missives to stretch the arrow in second pass
% (\box0 and the labels are sent as the data)
\exec@missive
\else\global\@diagonals@used@true % 12.7.94
% set the PS diagonal here on the first pass
% (only uses \box0, so no labels unless they're in \box0)
\exec@PS@diagonal
\fi
\ifvoid6 \ifvoid7 \@hug@true\fi\fi
\if@hug@\else
% 4.7.97 lazy implmentation of nohug option
% assign empty parts to a LaTeX diagonal arrow
\empty@parts
\global\@diagonals@used@true
\let\make@line\no@make@line % hack!
\exec@LaTeX@diagonal
\fi
\else\reassign@parts
\reassign@filler
\global\@diagonals@used@true % 12.7.94
\exec@LaTeX@diagonal
\fi}%
%
%
% default labels etc appropriate to all kinds of arrows
\def\default@args{%
\begingroup %
\dimen1=\MapShortFall % leading shortfall
%\dimen2.5em % min tip-to-tip arrow len within diagrams 15.4.95
\dimen2=\min@map@length% minimum tip-to-tip length of arrow
\dimen5=\MapShortFall % trailing shortfall
\setbox3=\box\voidb@x % middle label
\setbox6=\box\voidb@x % upper or left label
\setbox7=\box\voidb@x % lower or right label
\@first@positional@true % haven't done \positional@ yet
\mathsurround\z@ %
\skip2\z@ plus1fill minus 1000pt% amount to fill on left
\skip4\skip2 % and right
\@cd@through@false}%
%
\new@if\if@cd@through@\@cd@through@true\@cd@through@false
%
\def\assign@five#1#2#3#4#5{%
\let\@tail#1\let\@filla#2\let\@middle#3\let\@fillb#4\let\@head#5%
\@cd@through@false\ifx\@filla\@fillb\@cd@through@true\fi}%
%
\def\five@args#1#2#3#4#5{\assign@five#1#2#3#4#5\get@arg}%
%
%
%\def\front@args#1#2#3{%
%\let\@tail#3\let\@filla#2\setbox3=#1\let\@fillb\empty\let\@head\null\get@arg}%
%
%\def\back@args#1#2#3{%
%\let\@tail\null\let\@filla\empty\setbox3=#1\let\@fillb#2\let\@head#3\get@arg}%
%
%
% \dTo -> \Vertical@Map \dt: \df:- \dm: \df:- \df:>
% \five@args picks up these five parameters and calls \get@arg
% which calls \exec@vert
%
\def\Vertical@Map{%
\check@vert433{vertical map}\exec@vert
\default@args
\cd@penalty-9995
\let\@filler\@fillv
%\let\fill@dot\vfdot % 12.7.94
\let@names{fill@dot}{df:.}% 30.7.98
\five@args}%
%
\def\break@args{%
% If \get@arg happens to be called again,
% make it do its continuation straight away.
\def\get@arg{\exec@map}%
\exec@map % do the continuation
\endgroup % close the map environment
\aftergroup\group@after@map}% check for enclosing braces
%
\def\set@map@parts{%
\setbox1=\@tail\setbox5=\@head
\ifvoid3 \ifx\@middle\null\else\setbox3=\@middle\fi\fi
\make@filler 2\@filla
\make@filler 4\@fillb
}%
%
%
\def\lift@map@parts#1{%
% lift all map parts by #1
\ifvoid 1\else\lift@map@part 1#1\fi
\ifvoid 2\else\lift@map@part 2#1\fi
\ifvoid 3\else\lift@map@part 3#1\fi
\ifvoid 4\else\lift@map@part 4#1\fi
\ifvoid 5\else\lift@map@part 5#1\fi
}
%
% lift map part #1 by #2
\def\lift@map@part#1#2{\setbox#1\vbox{%
\offinterlineskip
\box#1%
\dimen@\prevdepth
\advance\dimen@-#2\relax
\setbox0\null\dp0\dimen@\ht0-\dimen@
\box0}}%
%
\def\make@filler#1#2{%
\ifx#2\@filler
\setbox#1=\box\voidb@x
\else
\setbox#1=#2%
\def#2{\xleaders\box#1}%
\fi}%
%
%
% ****************** OLD-STYLE MAP SETUP *****************
%
\cd@first@use\use@newarrow{\string\HorizontalMap, \string\VerticalMap\space
and \string\DiagonalMap\new@line are obsolete - use \newarrow@name\space
to pre-define maps}%
%
\def\HorizontalMap#1#2#3#4#5{%
\use@newarrow
\check@horiz{old horizontal map}% avoid clashes
\default@args
\@setup@horiz
\def\@tail{\old@horiz@part{#1}}% left tip, eg \rthookb
\old@horiz@fill\@filla{#2}% filler
\def\@middle{\old@horiz@part{#3}}% middle
\old@horiz@fill\@fillb{#4}% filler
\def\@head{\old@horiz@part{#5}}% right tip, eg \rhvee
\get@arg}%
%
\def\VerticalMap#1#2#3#4#5{%
\use@newarrow
\check@vert433{vertical map}\exec@vert
\default@args
\cd@penalty-9995
\let\@filler\@fillv
\def\@tail{\make@vert@part{#1}}% upper tip, eg \dthooka
\old@vert@fill\@filla{#2}% filler
\def\@middle{\make@vert@part{#3}}% middle
\old@vert@fill\@fillb{#4}% filler
\def\@head{\make@vert@part{#5}}% lower tip, eg \dharrow
\get@arg}%
%
\def\DiagonalMap#1#2#3#4#5{%
\use@newarrow
\default@args
\def\max@fraction{4}%
\let\@filler\undefined
\let\exec@map\exec@LaTeX@diagonal
\def\x@coord{2}\def\y@coord{2}% coordinates for diagonals\default@args
\def\x@offset{1}\def\y@offset{1}% diagonalbase
\def\@middle{\make@diag@part{#3}}%
\ifPositiveGradient
\let\mv\raise
\def\@tail{\make@diag@part{#5}}%
\def\@filla{\make@diag@part{#4}}%
\def\@fillb{\make@diag@part{#2}}%
\def\@head{\make@diag@part{#1}}%
\else\let\mv\lower
\def\@tail{\make@diag@part{#1}}%
\def\@filla{\make@diag@part{#2}}%
\def\@fillb{\make@diag@part{#4}}%
\def\@head{\make@diag@part{#5}}%
\fi
\get@arg}%
%
% \vertical@name was in the "corruption-sensitive" section
\def\horizontal@name{-}\def\empty@name{\empty}%\def\vertical@name{|}
\def\old@horiz@fill{\make@old@fill\horiz@repeater\horizontal@name\@fillh}%
\def\old@vert@fill {\make@old@fill\vert@repeater \vertical@name \@fillv}%
%
\def\make@old@fill#1#2#3#4#5{\def\next{#5}%
\ifx \next#2%
\let#4#3% rule filler
\else \let#4\null % empty filler
\ifx \next\empty\else
\ifx \next\empty@name
\else \let#4\next% other filler
\fi\fi\fi}%
%
\def\old@horiz@part#1{%
\hbox{\mathsurround\z@\offinterlineskip
\def\next{#1}%
\ifx\next\empty\else\ifx\next\empty@name\else
\begin@maths\mkern-1.5mu{\next}\mkern-1.5mu\end@maths
\fi\fi
}}%
%
%
%=======================================================================%
% %
% (5A) LABELS %
% %
%=======================================================================%
%
% \get@arg -> \switch@arg -> various -> \break@args -> \exec@map
% ^_<>~ -> \left@label etc -> \get@label -> \@get@label ->
% \switch@label@arg -> \(un)braced@label -> \@end@label -> \get@arg
%
% Pick up following label and assign it appropriately.
% idea: force expansion of #3 before we read it (but this may execute & or \cr)
% idea: ensure that \box3 (in particular) doesn't shrink
% (\exec@horiz does this)
% vertical positioning of labels with descenders?
%
\def\get@label#1#2{% put label #3 in box #1 (#2 is ^_<>~-)
\setbox#1=\hbox\bgroup
\setbox0=\hbox{\begin@maths\labelstyle()\end@maths}%% ASCII round brackets
\setbox1=\null\ht1\ht0\dp1\dp0\box1
\kern.1\@em%
\begin@maths
\bgroup % matches user's close brace (\begingroup wouldn't)
\labelstyle
\aftergroup\@end@label
\@get@label}%
%
%#3%
%\egroup supplied by the user or in \unbraced@label
\def\@end@label{%
\end@maths
\kern.1\@em%
\egroup
% We used to do the following to the finished box:
% \dimen0=\ht#1\advance\dimen0.4ex\ht#1=\dimen0
% \dimen0=\dp#1\advance\dimen0.4ex\dp#1=\dimen0
\get@arg % continue processing of further arguments
}%
%
% The text of the label is read in the same way as is that of a footnote
% (TeXbook page 363), ie we look at the next token, swallowing it if it is
% an open brace, and use \aftergroup to regain control after the close.
% At various places we do \end@label just in case the closing brace has been
% omitted; this is \empty outside the label text, but causes an error and
% inserts the closing brace inside it. We choose \empty rather than \relax
% because the latter would inhibit correct expansion of \cr\enddiagram.
%
\def\@get@label{\futurelet\next@token\switch@label@arg}%
%
\def\switch@label@arg{%% qualifiers on label arguments
\catcase\bgroup:\braced@label;% label text enclosed in {}
\catcase\egroup:\missing@label;%
\catcase\space:\label@eat@space;% ignore space
\tokcase [:\label@optional;%%]%ascii close square bracket
\default :\unbraced@label;% single token label text without {}
\endswitch}%
%
%\def\@get@label{%
% \ifcat\bgroup\noexpand\next@token
% \expandafter\braced@label
% \else\expandafter\unbraced@label
% \fi}%
%
\def\braced@label{%
\let\end@label\bad@end@label
\let\next % pick up and discard user's opening brace (cf \footnote)
}%
%
%\def\unbraced@label#1{\labelstyle#1\@end@label}% before 28.12.93
%
\def\unbraced@label#1{%
\let\label@egroup\egroup
{%
\let\actually@braces@missing@around@macro@in@label\outer@empty
\let\end@label\egroup@missing@label
\let\label@egroup\label@egroups
#1%
\actually@braces@missing@around@macro@in@label
}%
\label@egroup
}%
\def\actually@braces@missing@around@macro@in@label{\let\next=}%
\def\missing@label{\egroup\cd@error{missing label}\help@endlabel}%
\def\egroup@missing@label{\egroup\missing@label}%
\outer\def\outer@empty{}%
% 14.4.94
% normally, \eat@egroup does nothing and
% \label@egroup expands (once) to \egroup matching \bgroup above
% if #1 is \egroup, \eat@egroup eats following }, then
% \label@egroup matches { and then \bgroup (no error message)
% if #1 is \rTo (or some other diagram command beginning \end@label)
% then \end@label matches { and \bgroup with "missing label" error;
% later \eat@egroup eats the following } and \label@egroup does nothing.
% if #1 is a macro it takes \missing@braces@around@label@macro as its first
% argument; however as this is \outer there is an error message;
% the } prevents the macro from taking \label@egroup as a second
% argument (it gets \par instead)
% then } matches { and \label@egroup matches \bgroup.
% if TeX inserts { after #1 (as it does e.g. for \hat), the } matches this
% and \label@egroup inserts an explicit } token (as many as TeX inserted })
% until it becomes \egroup, which matches the \bgroup above.
% (If we had assigned \egroup\label@egroup to \label@group the first time,
% the final (empty) \label@egroup would be left to be parsed as the next
% label argument and would fall through \switch@arg.)
% Unfortunately this doesn't pick up the *real* macro arguments,
% and TeX's error recovery is rather messy, but at least doesn't loop.
\def\label@egroup{}%
\def\label@egroups{\eegroup\label@egroup}% 15/4/95 changed from \egroup
%
\def\end@label{}%
%
\def\label@optional% 12.7.94
{\let\after@opt@arg\@get@label\get@square@arg\get@opt@arg@list}%
%
\new@help\help@endlabel{The text which has just been read is not allowed
within map labels.}%
\def\bad@end@label{\egroup
\cd@error{missing \egroup@name\space inserted after label}\help@endlabel}%
%
% OLD VERSION
% Catch missing label before closing bracket. ?When can this happen?
% TeX would insert \par for the missing argument, which would then become
% \enddiagram. Perhaps we should just redefine \par locally instead.
% Come to think of it, such a closing bracket has no business to be there
% anyway.
% Other cases can look after themselves by inserting \end@label.
% Could recognise (any kind of) \bgroup and change it to
% \bgroup\aftergroup\end@label to allow label environments.
% \def\@get@label{%
% \ifcat \next@token\egroup
% \expandafter\label@is@egroup
% \else \expandafter\@@get@label
% \fi}%
%\def\@get@label#1{#1\end@label}% was \@@get@label
%\def\label@is@egroup{\cd@error{arrow commands must not be em-braced}
%\help@brace
% \end@label}%
%\new@help\help@label{A closing bracket followed \string
% ^, \string
% _, \string
% <, \string
% > or \string~.}%
%
% ******************* arrow argument parsing ********************
%
% ----- Fetch particular labels -----
%
% \hbox6 gets first/upper/left label & disables positional assignment to it
\def\upper@label {\@first@positional@false\get@label6}%
% \hbox7 gets second/lower/right label label & disables all positional
\def\lower@label {\def\positional@{\@cd@a@true\break@args}\get@label7}%
\def\middle@label{\get@label3}% \hbox3 is (middle of arrow or) middle label
\new@if\if@first@positional@\@first@positional@true\@first@positional@false
%
\def\left@label{%
\ifPositiveGradient
\then \expandafter\upper@label
\else \expandafter\lower@label
\fi}%
\def\right@label{%
\ifPositiveGradient
\then \expandafter\lower@label
\else \expandafter\upper@label
\fi}%
\def\positional@{\cd@warning{labels as positional arguments are obsolete}%
\if@first@positional@
\then %\@first@positional@false
\expandafter\upper@label
\else %\let\positional@\break@args % third positional argument terminates
\expandafter\lower@label
\fi-}% provide dummy second argument (^_<>~) to \getlabel
%
%
% ----- other argument parsing subroutines -----
%
% Get following token, perform case analysis and repeat or do \exec@map.
\def\get@arg{\futurelet\next@token\switch@arg}%
%
% discard following space and re-read token
\def\eat@space{\afterassignment\get@arg\let\next@token= }%
\def\label@eat@space{\afterassignment\@get@label\let\next@token= }%
%
% get a pair of coordinates, and an optional argument
\def\co@ordinates{\get@round@pair\@getcoords}%
\def\@getcoords#1#2{\def\x@coord{#1}\def\y@coord{#2}\get@arg}%
\def\optional@{\let\after@opt@arg\get@arg\get@square@arg\get@opt@arg@list}%
\def\set@dot@filler.{\do@set@dot@filler\get@arg}% 12.7.94
\def\do@set@dot@filler{% 13.11.94
\let\@filla\fill@dot\let\@fillb\fill@dot % horizontals or verticals
\def\reassign@filler{\let\@filla\dfdot\let\@fillb\dfdot}}% diagonals
\def\reassign@filler{}%
%
%=======================================================================%
% %
% (6) OPTIONAL ARGUMENTS %
% %
%=======================================================================%
%
%
% - width of each cell individually
%
% blobs: define . o x O !
% poset (Hasse):size=2em,abut,blobs
% adjunction:
%
%\def\@@getoptarg#1,{%
% \parse@opt@arg#1,%
% \let\next\do@opt@arg@then
% \ifx\@name\end@square@name
% \let\next\after@opt@arg
% \let\after@opt@arg\relax
% \if@was@pair@\bad@pair@opt\fi
% \fi
% \next
%}%
%
%\def\do@opt@arg@then{\do@opt@arg\@@getoptarg}%
%
\def\@@getoptarg#1,{%
\parse@opt@arg#1,%
\begingroup
\ifx\@name\end@square@name
\if@was@pair@\aftergroup\bad@pair@opt\fi
\aftergroup\do@after@opt@arg
\else
%\batchmode
\expandafter\def\expandafter\@junk\expandafter{%
\csname
\@name%
\endcsname}%
%\scrollmode
\expandafter\get@csname\@junk\end@get@csname
\ifx\@junk\empty
\aftergroup\do@opt@arg
\expandafter\aftergroup\csname\cd@opt@prefix\@name\endcsname
\expandafter\aftergroup\csname\cd@opt@prefix @\@name\endcsname
\else
\gdef\g@tmp{#1}%
\cd@warning{\string\relax\space inserted before `[\g@tmp'}%
\message{(I was trying to read this as a \cd@name\ option.)}%ascii
\aftergroup\add@relax@before@square@bracket
\fi
\fi
\endgroup}%
%
\def\get@csname#1#2\end@get@csname{\def\@junk{#2}}%
\def\do@after@opt@arg{\let\next\after@opt@arg\let\after@opt@arg\relax\next}%
%
\def\add@relax@before@square@bracket#1],{%% ASCII close square bracket
\do@after@opt@arg\relax
\def\@junk{#1}%
\ifx\@junk\empty
\def\@junk{[\g@tmp]}%% ASCII open and close square bracket
\else\def\@junk{[\g@tmp,#1]}%% ASCII open and close square bracket
\fi
\@junk}%
%
\def\do@opt@arg#1#2{%
%\expandafter\let\expandafter\next\csname\cd@opt@prefix @\@name\endcsname
% \next=#1=\csname cds@\@name\endcsname
% #2=\csname cds@@\@name\endcsname
\ifx#2\undefined
\ifx#1\undefined
% neither \cds@name nor \cds@@name is defined
\cd@warning{option `\@name' undefined}%
\else
% \cds@name is defined but \cds@@name isn't: execute without pair
#1%
\fi
\else
% \cds@@name#1#2 is defined - the command takes a pair value
\if@was@pair@
% this is the second half - execute and reset
\expandafter#2\@value
\@was@pair@false
\else
% this is the first half - set flag and wait
\@was@pair@true
\fi \fi
\next@opt@arg}%
%
\new@if\if@was@pair@\@was@pair@true\@was@pair@false
%
\def\parse@opt@arg#1,{%
\if@was@pair@
\ifx\@value\undefined\bad@pair@opt\else
\expandafter
\@parse@pair
\@value
,#1,(,),(,)[]%%ASCII 5commas two pairs round, pair square
\fi\fi
\if@was@pair@ % tries again if parsing as a pair failed
\else\@parse@opt@arg#1==,%
\fi
}%
\def\bad@pair@opt{%
\cd@warning{option `\@name' needs (x,y) value}%
\@was@pair@false
\let\@name\empty}%
%
\def\@parse@opt@arg#1=#2=#3,{%
\def\@name{#1}\def\@value{#2}\def\@junk{#3}%
\ifx\@junk\empty\let\@value\undefined\fi
}%
%% ASCII 2commas 2pair round, pair square on next line
\def\@parse@pair#1(#2,#3)#4,(#5,#6)#7[]{%ascii
\def\@value{{#2}{#3}}%
\def\@junk{#1#4#5#6}%
\ifx\@junk\empty
\def\@junk{#7}%
\ifx\@junk\empty\bad@pair@opt\fi
\else\bad@pair@opt
\fi
}%
%
\def\cd@opt@prefix{cds@}\let\after@opt@arg\relax
%
%
%
\def\get@mand@value#1{%
\ifx\@value\undefined
\cd@warning{option `\@name' needs a value}%
\else
#1\@value\relax
\fi}%
%
\def\get@opt@value#1#2{%
\ifx\@value\undefined
#1#2\relax
\else
#1\@value\relax
\fi}%
%
\def\cds@@showpair#1#2{\message{x=#1,y=#2}}%
\def\cds@@diagonalbase#1#2{\edef\x@offset{#1}\edef\y@offset{#2}}%
%
\def\ps@prog#1{%
\def\next{#1}%
\let@names{@x}{cdps@#1}%
%\message{PostScript translator `#1` requested.}%
\ifx\next\empty\bad@ps@prog\next{cannot be used}%
\else\ifx\next\relax % \csname undefined\endcsname = \relax
\bad@ps@prog\next{unknown}%
\else\let\verbatim@ps@special\@x
\fi\fi
}%
\def\bad@ps@prog#1#2{% 24.8.2003 pass name as #1 instead of \@value
\cd@warning{PostScript translator `#1' #2}}%
%\dont@use@ps\let\cds@PS\empty\let\cds@noPS\empty}% removed 30.12.07
%
%
\def\obs@display{}%
\def\set@new@display{\@cd@hbox@false\edef\obs@display{\noexpand
\cd@refmt@error{\@name\space ignored within maths}}}%
%
\def\diagramstyle{%
\size@dependencies
\let\after@opt@arg\relax % 13.7.94
\@ifoptarg\get@opt@arg@list\get@opt@arg@list}%
\let\diagramsstyle\diagramstyle
%
% ********************** THE ACTUAL OPTIONS *************************
%
%
\new@if\if@cd@text@flow@\@cd@text@flow@true\@cd@text@flow@false
\new@if\if@cd@one@liner@\@cd@one@liner@true\@cd@one@liner@false
\new@if\if@cd@leqno@\@cd@leqno@true\@cd@leqno@false
\new@if\if@cd@centre@display@\@cd@centre@display@true\@cd@centre@display@false
\@cd@centre@display@true
\new@if\if@cd@centre@hlabel@\@cd@centre@hlabel@true\@cd@centre@hlabel@false
\new@if\if@cd@centre@vlabel@\@cd@centre@vlabel@true\@cd@centre@vlabel@false
\new@if\if@use@TPIC@\@use@TPIC@true\@use@TPIC@false
\new@if\if@cd@PS@horiz@\@cd@PS@horiz@true\@cd@PS@horiz@false
\new@if\if@cd@hbox@\@cd@hbox@true\@cd@hbox@false
\new@if\if@cd@landscape@\@cd@landscape@true\@cd@landscape@false % 10.7.94
\new@if\if@need@PS@lib@\@need@PS@lib@true\@need@PS@lib@false % 10.7.94
%
\def@name{cds@ }{}\def@name{cds@}{}% spaces are no-ops
\def@name{cds@1em}{\CellSize1\@em}\def@name{cds@1.5em}{\CellSize1.5\@em}%
\def@name{cds@2em}{\CellSize2\@em}\def@name{cds@2.5em}{\CellSize2.5\@em}%
\def@name{cds@3em}{\CellSize3\@em}\def@name{cds@3.5em}{\CellSize3.5\@em}%
\def@name{cds@4em}{\CellSize4\@em}\def@name{cds@4.5em}{\CellSize4.5\@em}%
\def@name{cds@5em}{\CellSize5\@em}\def@name{cds@6em}{\CellSize6\@em}%
\def@name{cds@7em}{\CellSize7\@em}\def@name{cds@8em}{\CellSize8\@em}%
\def\cds@abut{\MapsAbut\dimen1\z@\dimen5\z@}%
\def\cds@alignlabels{\@cd@centre@hlabel@false\@cd@centre@vlabel@false}%
\def\cds@amstex{%
\ifincommdiag
\amstex@diagram@setup
\else\def\CD{\diagram[amstex]}%%ascii square brackets []
\fi
\assign@at\catcode`\@\active
}%
\def\cds@b{\let\cd@vert@positioning\cd@vbottom}%
\def\cds@balance{\let\cd@horiz@positioning\cd@balance}%
\let\cds@bottom\cds@b
\def\cds@center{\cds@vcentre\cds@nobalance}%
\let\cds@centre\cds@center
\def\cds@centerdisplay{%
\@cd@centre@display@true\set@new@display\cds@balance}%
\let\cds@centredisplay\cds@centerdisplay
\def\cds@crab{\get@opt@value\crab@{.5\PileSpacing}}%
\def@name{cds@crab-}{\crab@-.5\PileSpacing}%
\def@name{cds@crab+}{\crab@.5\PileSpacing}%
\def@name{cds@crab++}{\crab@1.5\PileSpacing}%
\def@name{cds@crab--}{\crab@-1.5\PileSpacing}%
\def\cds@defaultsize{\get@opt@value{\let\default@size}{3em}\set@max@fraction}%
\def\cds@displayoneliner{\@cd@one@liner@false}%
\let\cds@dotted\do@set@dot@filler
\def\cds@dpi{\set@resolution{1truein}}%
\def\cds@dpm{\set@resolution{100truecm}}%
\let\cd@eqno\undefined
\def\cds@eqno{%
\let\cd@eqno\@value
\let\set@currentlabel\empty}%
\def\cds@fixed{\@cd@missive@false}%
\new@if\if@adjust@flush@left@\@adjust@flush@left@true\@adjust@flush@left@false
\def\cds@flushleft{%
\@adjust@flush@left@false % 15.6.97
\@cd@centre@display@false\set@new@display\cds@nobalance
\get@opt@value\cd@left@margin\cd@left@margin}%
\def\cds@gap{\set@axis%
\setbox3=\null\ht3=\rule@height\dp3=\rule@depth
\get@opt@value{\wd3=}\MapShortFall}
\def\cds@grid{%
\ifx\@value\undefined
\let\h@grid\relax\let\v@grid\relax
\else
\let@names{h@grid}{cdgh@\@value}%
\let@names{v@grid}{cdgv@\@value}%
\ifx\h@grid\relax
\cd@warning{unknown grid `\@value'}%
\else\@cd@tight@true
\fi\fi}%
\let\h@grid\relax\let\v@grid\relax
\def\cds@gridx{\ifx\@value\undefined\else\cds@grid\fi
\let\next\h@grid\let\h@grid\v@grid\let\v@grid\next}%
\def\cds@h{\get@mand@value\DiagramCellHeight}%
\def\cds@hcenter{\let\cd@horiz@positioning\cd@fullwidth}%
\let\cds@hcentre\cds@hcenter
\def\cds@heads{%
\get@opt@value{\let\the@default@head}\the@default@head
\set@arrowhead
\if@cd@use@PS@\else\ifx\the@default@head\LaTeX@name\else
\default@diagonal
\fi\fi
}%
\let\cds@height\cds@h
\let\cds@hmiddle\cds@balance
\def\cds@htriangleheight{\get@opt@value\DiagramCellHeight\DiagramCellHeight
\DiagramCellWidth1.73205\DiagramCellHeight}%
\def\cds@htrianglewidth{\get@opt@value\DiagramCellWidth\DiagramCellWidth
\DiagramCellHeight.57735\DiagramCellWidth}%
\new@if\if@hug@\@hug@true\@hug@false\@hug@true
\def\cds@hug{\@hug@true}
\def\cds@inline{\@cd@hbox@true\let\obs@display\empty}%
\def\cds@inlineoneliner{\@cd@one@liner@true}%
\def@name{cds@l>}{\get@mand@value{\let\min@map@length}\dimen2=\min@map@length}%
\def\cds@labelstyle{\get@mand@value{\let\labelstyle}}%
\def\cds@landscape{\@cd@landscape@true}% 10.7.94
\def\cds@large{\CellSize5\@em}%
\let\set@currentlabel\empty
\def\set@currentlabel@to@equation{%
\refstepcounter{equation}%
\def\cd@eqno{\hbox{\@eqnnum}}}%
\def\cds@LaTeXeqno{\let\set@currentlabel\set@currentlabel@to@equation}%
\def\cds@lefteqno{\@cd@leqno@true}%
\def\cds@leftflush{\cds@flushleft\@adjust@flush@left@true}% 15.6.97
\def\cds@leftshortfall{\get@mand@value{\dimen1 }}%
% \def\cds@locate
\def\cds@lowershortfall{\ifPositiveGradient\cds@leftshortfall\else
\cds@rightshortfall\fi}%
\def\cds@loose{\@cd@tight@false}%
\def\cds@midhshaft{\@cd@centre@hlabel@true}%
\def\cds@midshaft{\@cd@centre@hlabel@true}%
\def\cds@midvshaft{\@cd@centre@vlabel@true}%
%\def\cds@midvshaft{\cd@warning{midvshaft option doesn't work}}%
\def\cds@moreoptions{\@cd@a@true}% tested in \@@@diagram
\let\cds@nobalance\cds@hcenter
\def\cds@nohcheck{\nohcheck}%
\def\cds@nohug{\@hug@false}
\def\cds@nooptions{\def\@@diagram{\exec@diagram}}%
\let\cds@noorigin\cds@nobalance
\def\cds@nopixel{\pixel@size 4\one@sp\size@dependencies}%
\def\cds@UO{\dont@use@ps\global\let\better@use@ps\empty}%
\def\cds@UglyObsolete{\cds@UO\let\cds@PS\empty}% \let\cds@noPS\empty}% 30.12.07
\def\cd@nonoPS#1{\cd@warning{option `#1' renamed as `UglyObsolete'}}% 30.12.07
\def\cds@noPostScript{\cd@nonoPS{noPostScript}}% 30.12.07
\def\cds@noPS{\cd@nonoPS{noPostScript}}% 30.12.07
\def\cds@notextflow{\@cd@text@flow@false}%
\def\cds@noTPIC{\@use@TPIC@false}%
\def\cds@objectstyle{\get@mand@value{\let\objectstyle}}%
\def\cds@origin{\let\cd@horiz@positioning\cd@zerowidth}%
\def\cds@p{\get@mand@value\PileSpacing}%
\let\cds@pilespacing\cds@p
\def\cds@pixelsize{\get@mand@value\pixel@size\reset@map@breadth}%
\def\cds@portrait{\@cd@landscape@false}% 10.7.94
\def\cds@PostScript{\use@ps\global\let\better@use@ps\empty
\get@opt@value\ps@prog\empty}%
\def\cds@PS{\use@ps\global\let\better@use@ps\empty}%
\info@at@end\better@use@ps{\typeout{\cd@name: try the PostScript option for better results}}%
\def\cds@repositionpullbacks{%
\let\make@pbk\overprint@pbk\let\pbk@sh\pbk@osh}% 14.11.94
\def\cds@righteqno{\@cd@leqno@false}%
\def\cds@rightshortfall{\get@mand@value{\dimen5 }}%
\def\cds@ruleaxis{\get@mand@value{\let\axisheight}}% 17.7.94
\def\cds@cmex{\let\make@vert@part\cmex@vert@part
\let\set@offset@axis\set@cmex@offset@axis}%
\def\cds@s{\cds@height\DiagramCellWidth\DiagramCellHeight}%
\def\cds@scriptlabels{\let\labelstyle\scriptstyle}%
\def\cds@shortfall{\get@mand@value\MapShortFall
\dimen1\MapShortFall\dimen5\MapShortFall}%
\def\cds@showfirstpass{\get@opt@value{\let\firstpass@showboxdepth}\z@}%
\def\cds@silent{\def\cd@refmt@error##1{}\def\cd@warning##1{}}%
\let\cds@size\cds@s
\def\cds@small{\CellSize2\@em}%
\def\cds@snake{\get@opt@value\snake@\z@}% 4.7.97
\def\cds@t{\let\cd@vert@positioning\cd@vtop}%
\def\cds@textflow{\@cd@text@flow@true\set@new@display}%
\def\cds@thick{\let\line@font\tenlnw
\intended@breadth\default@mapbreadth
\get@opt@value\MapBreadth{2\intended@breadth}%
\set@arrowhead}% 15.6.97
\def\cds@thin{\let\line@font\tenln
\get@opt@value\MapBreadth{\default@mapbreadth}%
\set@arrowhead}% 15.6.97
\def\cds@tight{\@cd@tight@true}%
\let\cds@top\cds@t
\def\cds@TPIC{\@use@TPIC@true}%
\def\cds@uppershortfall{\ifPositiveGradient\cds@rightshortfall\else
\cds@leftshortfall\fi}%
\def\cds@vcenter{\let\cd@vert@positioning\cd@vcentre}%
\let\cds@vcentre\cds@vcenter
\def\cds@vtriangleheight{\get@opt@value\DiagramCellHeight\DiagramCellHeight
\DiagramCellWidth.577035\DiagramCellHeight}%
\def\cds@vtrianglewidth{\get@opt@value\DiagramCellWidth\DiagramCellWidth
\DiagramCellHeight1.73205\DiagramCellWidth}%
\def\cds@vmiddle{\let\cd@vert@positioning\cd@vmiddle}%
\def\cds@w{\get@mand@value\DiagramCellWidth}%
\let\cds@width\cds@w
%
%
%=======================================================================%
% %
% (7) THE DIAGRAM - OPTIONS AND OUTPUT %
% %
%=======================================================================%
%
%
% The following macros are preparatory to the diagram, picking up optional
% arguments and beginning the main \vbox.
%
% \diagram -> \@diagram -> \@@diagram [-> \@@@diagram] -> \exec@diagram
% -> \@exec@diagram -> \enddiagram=\@end@diagram -> \after@diagram
% (\matrix@to@buffer, \reformat@matrix) -> \output@diagram -> \exit@diagram
%
\def\diagram{\relax\protect\@diagram}%
\def\enddiagram{\protect\misplaced@enddiagram}% real one in \inner@environment
%
\def\diagraminline{\diagram[inline,moreoptions]}%
\def\enddiagraminline{\enddiagram}%
%
\def\@diagram{%
\bbgroup % {} closed in \exit@diagram
\save@begin@at@line % line number for reformatting error messages
\incommdiagtrue
\edef\save@row@no{\the\cd@row}% save row number
\global\cd@row\z@
%
% LaTeX pre 15/12/87 had \maxboxdepth\z@; this found its way into
% a journal style with which Richard Kennaway had a problem.
\boxmaxdepth\maxdimen % added 3 June 1994
%
% amslatex's equation environment sets \everycr;
% reported by Bruce Pollock <pollock@newton.rutgers.edu> 5 April 1995
\everycr{}%
%
% test for (active) pdftex
\test@pdf
%
% pdfsync package also sets these: 3 Jan 2006
% Hubert.Flenner@ruhr-uni-bochum.de Fri May 14 14:31:36 2004
% Arthur Ogus <ogus@Math.Berkeley.EDU> Tue Jan 3 17:21:02 2006
\everymath{}%
\everyhbox{}%
%
% That was not enough. See email 25--30 Jan 2008 with
% jerome.laurens@u-bourgogne.fr (author of pdfsync)
% and Bernd Strieder <strieder@informatik.uni-kl.de> (user).
\ifx\pdfsyncstop\undefined\else\pdfsyncstop\fi
% \futurelet\next
\@@diagram}%
%
\def\@@diagram{%
\@cd@a@false
\let\after@opt@arg\@@@diagram
\@ifoptarg\get@opt@arg@list\exec@diagram}%
%
% \def\@@diagram{% % do we have options?
% \ifx[\next
% \expandafter\cd@with@opt % yes
% \else
% \expandafter\exec@diagram % no
% \fi
% }%
% %
% \def\cd@with@opt{%
% \@cd@a@false
% \let\after@opt@arg\@@@diagram
% \get@square@arg\get@opt@arg@list}% read and execute options
%
\def\@@@diagram{%
\if@cd@a@ % did we ask for more options?
\expandafter\@@diagram % yes (\cds@moreoptions)
\else \expandafter\exec@diagram % no
\fi}%
%
\def\exec@diagram{%
% \next may have been &, which is a dangerous thing to have around
\let\next@token\relax
%
\if@cd@landscape@\if@cd@use@PS@\else % 10.7.94
\if@pdf@\else % won't be needed when we're finished
\cd@refmt@error{landscape ignored without PostScript}%
\@cd@landscape@false
\fi\fi\fi
\set@currentlabel
%
\setbox2=\vbox\bgroup % avoid \box0 since overwritten by \everypar
\inner@environment
\@exec@diagram
}%
% \@exec@diagram is in the next section; it eventually calls
%
\def\output@diagram{%
%
% having provided the following positioning statistics:
% \expandafter\message{%
% interaxis=\the\dimen1, %
% topheight=\the\cd@top@height, %
% fullheight=\the\completed@depth, %
% bottomdepth=\the\row@depth, %
% dimen0=\the\dimen0, %
% dimen2=\the\dimen2, %
% dimen7=\the\dimen7, %
% right over=\the\right@over, %
% left over=\the\left@over%
% }%
%
% \dimen0: distance between leftmost and rightmost centres
% \dimen1: distance between top and bottom axes
% \dimen2: right width of rightmost column
% \rule@height : axis height
% \cd@top@height: height of top row
% \completed@depth : height from last baseline to top
% \right@over : from centre of leftmost to far edge of rightmost
% \left@over : left width
% \row@depth : depth of bottom row
% \cd@top: number of rows
% \cd@right: number of columns
% \vert@wd@in@leftmost: left width of (last) vertical system in column 1
% or \undefined if none (15.6.97)
%
%
% The commands \cd@horiz@positioning and \cd@vert@positioning are assigned
% by the positioning options to routines which adjust these statistics.
%
\if@cd@landscape@ % 10.7.94
\cd@vtop
\else\cd@vert@positioning
\fi
\cd@horiz@positioning
%
% Now force our box to have the required depth and right width.
\nointerlineskip
\setbox0=\null\ht0-\row@depth\dp0\row@depth\wd0\right@over
\box0
%
\global\cd@dim@g\left@over % save left width
\global\cd@num@g\cd@top % and number of rows
%
% alignment adjustment on left (15.6.97)
\ifx\vert@wd@in@leftmost\undefined
\global\cd@dim@h\left@over % no verticals - use edge of text
\else
\global\cd@dim@h\vert@wd@in@leftmost % width of multiple verticals
\fi
%
\egroup % end of \setbox2=\vbox\bgroup in \exec@diagram
\make@end@at@line %
%
% The following are now available:
% \box2: the completed diagram, with its left width smashed
% \cd@dim@g: the left width
% \cd@dim@h: the left width alignment adjustment
% \cd@num@g: number of rows
% mode: as in the text outside
%
\if@cd@landscape@ % 10.7.94
\setbox2=\hbox to\dp2{%
%\dp2=\cd@dim@g\ht2\wd2% replaced with vrule 6.10.2001
\vrule height\wd2 depth\cd@dim@g width\z@
\global\cd@dim@g\ht2%
\ht2\z@\dp2\z@\wd2\z@
\if@pdf@
\pdf@literal{q 0 1 -1 0 0 0 cm}%
\else
\global\@need@PS@lib@true
\verbatim@ps@special{0 1 bturn}%
\fi
\box 2%
\do@eturn %\verbatim@ps@special{eturn}%
\hss}%
\@cd@one@liner@false
\fi
%
\ifnum\cd@num@g=1 \else\@cd@one@liner@false\fi
%
\global\@ignorefalse
%
% decide what to do with the finished diagram
%
\if@cd@hbox@\leavevmode\fi
%
\ifvmode
% vertical mode:
% ie page \vbox or \vadjust, but \ifinner isn't a reliable indication
% of which it is, as it is \iftrue in \vbox and also \vadjust.
% This makes it difficult to see how we could handle floats.
%
% We must begin a paragraph. This is because LaTeX uses \trivlist for
% numerous purposes (center for instance). This sets a flag (\if@newlist)
% which is cleared (globally) in \everypar. It claims that there is a
% "missing item" if it finds it true at the end, ie if no paragraph has
% been created in the meantime.
%
% The usual way of forcing a paragraph is \leavevmode or \noindent,
% but \cd@display uses $$..$$ and LaTeX seems to be happy with this.
%
\cd@display
%
\else
\ifmmode % maths mode
%\ifinner\else % can't distinguish $/$$ within \bbgroup\eegroup
\obs@display
%\fi
\put@cd@box
%
\else % horizontal mode
\if@cd@one@liner@\@cd@hbox@true\fi
\ifinner\@cd@hbox@true\fi
%
\if@cd@hbox@ \put@cd@box % hbox or one-liner option
\else\if@cd@text@flow@
\cd@text@flow % --- flow
\else \cd@display % --- display
\fi\fi
\fi\fi
%
\exit@diagram}%
%
\def\exit@diagram{%
%
\global\cd@row\save@row@no\relax % restore row number
%
\if@end@diagram@ok@ % was \enddiagram deliberate or anticipated?
\global\@end@diagram@ok@false % deliberate
\else\aftergroup\do@fated@enddiagram % antipated - give error message
\fi
%
\if@ignore\aftergroup\ignorespaces\fi % ignore spaces after display
%
\eegroup % main {} begun in \@diagram
\ignorespaces%
}% and go home!
% That's REALLY the end of the diagram as far as we are concerned,
% although LaTeX will do further processing if \end{diagram} has been used;
% in particular it will do \ignorespaces conditionally on \if@ignore.
%
% ***************** positioning options ********************
%
% VERTICAL
\def\cd@vtop{\advance\row@depth\dimen1\relax}%
\def\cd@vmiddle{\advance\row@depth.5\dimen1\relax}%
\def\cd@vbottom{}%
\def\cd@vcentre{\cd@vtop\advance\row@depth\cd@top@height\divide\row@depth 2
\advance\row@depth-\axisheight\relax}%
%
% HORIZONTAL
\def\cd@fullwidth{}%
\def\cd@zerowidth{\left@over\z@}%
%
\def\cd@balance{%
\ifdim \dimen2>\left@over
\left@over \dimen2
\else \dimen2\left@over
\right@over \dimen0
\advance\right@over \dimen2
\fi}%
%
% ***************** output manipulation ********************
%
\def\cd@text@flow{%
%
% Remove all positive glue from before the diagram and save it.
% same as LaTeX's \@bsphack \@esphack
\skip0\z@\relax
\loop \skip1\lastskip
\ifdim \skip1>\z@
\unskip
\advance\skip0\skip1
\repeat
%
\vadjust{%
% Insert glue and penalties as if TeX
% had created the display itself.
\prevdepth\dp\strutbox
\penalty\predisplaypenalty
\vskip\abovedisplayskip
\cd@display@box
\penalty\postdisplaypenalty
\vskip\belowdisplayskip
}%
%
\ifdim\skip0=\z@\else % if there was any glue before the diagram,
\hskip\skip0 % put it back afterwards and
\global\@ignoretrue % do \ignorespaces after \end{diagram}
\fi
}%
%
% Our own display output when we have a single
% diagram to contribute to the horizontal list.
% ideas:
% What if preceding line of text is short (\predisplaysize)?
% Calculate \prevgraph based on height of diagram?
%
\def\cd@display{%
\maths@display % $$
\kern-\displayindent% undo any prevailing paragraph indentation
\cd@display@box % output the box
\maths@display% % $$
\global\@ignoretrue % do \ignorespaces after \end{diagram}
}%
%
\def\cd@display@box{\hbox to\hsize{%
%
% if [leftflush], adjust alignment (15.6.97)
\if@adjust@flush@left@\ifdim\cd@dim@h=\z@\else
\advance\cd@dim@g-\cd@dim@h
\setbox2=\hbox{\kern\cd@dim@h\box2}%
\fi\fi
%
% make the equation number
\setbox1=\hbox{\ifx\cd@eqno\undefined\else\begin@maths\cd@eqno\end@maths\fi}%
% insert it on the left if required
\if@cd@leqno@
\if@cd@centre@display@\else
\advance\cd@dim@g\wd1
\fi
\wd1\z@
\box1
\fi
% check that the diagram will fit on the page
\dimen0\wd2
\advance\dimen0\wd1
\advance\dimen0-\hsize
% does it fit on the page with the specified indentation? 2.3.94
\ifdim\dimen0>-\cd@left@margin
% no - switch from flushleft to centredisplay
\@cd@centre@display@true
\fi
% does it fit on the page at all?
\advance\dimen0\cd@dim@g
\ifdim\dimen0>\z@
\cd@refmt@error{wider than the page by \the\dimen0 }%
\@cd@centre@display@true
\fi
% space to the left of the diagram
\if@cd@centre@display@
\hss
\else \at@least\cd@dim@g\cd@left@margin
\fi
% output the diagram itself
\put@cd@box
% space to the right
\hss\kern-\wd1\box1 % right equation number (already void if left)
}}%
%
% Raw output used in maths, user display, \hbox (eg picture) and one-liner.
% 10.7.94 define PostScript commands here if needed
\def\put@cd@box{%
\if@need@PS@lib@\if@in@matrix@\else
\def@ps@turn
\global\@need@PS@lib@false
\fi\fi
\kern\cd@dim@g\box2 }%
%
%
% ***************** notes ********************
%
% For some reason the usual \futurelet method gets tied up
% if the next token is &.
% (Try again: there was another bug, with \cd@state)
%\def\@diagram{\begingroup\@ifoptarg\cd@with@opt\@@diagram}%
%\def\@@diagram{{%
% \aftergroup\exec@diagram
% \ifcat \next@token\@and
% \aftergroup\replace@and
% \fi
%}}%
%
%\def\replace@and{\omit\hskip 1sp plus1fil}\def\@@and{\@and}%
%
% nested diagram bug:
% $\begin{array}{ll}\begin{diagram}&A\\B\end{diagram}$
% causes: ! Emergency stop. <recently read> \endtemplate
% not fixed by \relax or by changing \begingroup\endgroup to \bgroup\egroup
% \@@diagram picks up $ (in right template of array) and the log file ends
% (interwoven alignment preambles are not allowed). (11 July 1992)
% but it is fixed by changing to \bbgroup\eegroup
%
% idea: forbid a list of commands within diagram
%
%\edef\cd@mode@outside {% code for external mode
% \ifmmode\ifinner0% $..$
% \else1\fi% $$..$$
% \else \ifhmode\ifinner2% \hbox{..}
% \else3\fi% paragraph (maybe in \vbox)
% \else \ifvmode\ifinner4% \vbox{..} or \vadjust{..}
% \else5\fi% current page
% \fi\fi\fi}%
%
%=======================================================================%
% %
% (8) THE MATRIX %
% %
%=======================================================================%
%
\new@if\if@diagonals@used@\@diagonals@used@true\@diagonals@used@false
%
\def\inner@environment{%
\size@dependencies
\ifdim\DiagramCellHeight=-\maxdimen\DiagramCellHeight\default@size\fi
\ifdim\DiagramCellWidth =-\maxdimen\DiagramCellWidth \default@size\fi
\global\@diagonals@used@false
\@in@matrix@true % 12.7.94
\let\group@after@map\empty
\let\cd@and\@and
\let\overprint\over@print
\let\@bomb\the@bomb % pull out the pin!
\let\enddiagram\@enddiagram
\let\\\diagram@cr % for LaTeX users
\let\par\par@enddiagram % deal with spurious \par inside diagram
\let\end@label\empty % we put these at the end
\let\switch@arg\cd@switch@arg % allow &<>() arguments to maps too
\let\shift\cd@hshift % shift objects
\baselineskip\DiagramCellHeight % minimum line spacing
\lineskip\z@ % otherwise, just stretch as necessary
\lineskiplimit\z@ %
\mathsurround\z@ % no unnecessary space in cells
\tabskip\z@ % or between them horizontally (ignored anyway)
\cd@state % set up automaton to check horizontal state
}%
%
%
\def\@exec@diagram{%
\penalty-123 % marker - checked in \matrix@to@buffer
\begingroup % confine the following to the text of the diagram
\@cd@landscape@false % don't rotate nested diagrams 12.7.94
\aftergroup\after@diagram% execute at corresponding \egroup
%\incommdiagtrue
%
\halign\bgroup % begin the matrix (see below for template)
\global\advance\cd@row1 % maintain row number in matrix
\vadjust{\penalty1}% % code below row picked up in \matrix@to@buffer
\global\cd@cell\z@ % initialise column number
\cd@state % horiz state (\cd@donat) at left is space donation
\begin@cell##\end@cell % template for leftmost cell
\@and\@and % "&&" means repeat following indefinitely
\receive@cell@type % recover horiz state from \send@cell@type
\begin@cell##\end@cell % template for subsequent cells
\cr % end of template
}%
%
% insert the matrix between calling these two macros
%
\def\@enddiagram{%
\end@label % catch missing close brace after label
\enddiagram@endpile % ditto after \pile
\crcr % catch missing \cr
\egroup % end of \halign
\global\@end@diagram@ok@true% signal we meant
\endgroup % to do \after@diagram (\aftergroup)
}%
%
%
%=======================================================================%
% %
% (8) CELLS %
% %
%=======================================================================%
%
%
%***************************** the template ****************************
%
% The main purpose of the template is to recognise empty cells quickly.
% The \hbox'es produced by the various types of cell are:
% - empty or white: \glue 1sp plus 1fil
% - \span (\across): completely empty
% - object: \hfil\mathon...\mathoff\hfil
% - arrow etc: \hfil\mathon...\penalty...\mathoff\hfil
%
% \save@cell@at@line?
% do \futurelet and eager expansion advance \inputlineno? - yes
% (may be better to do it during previous \end@cell instead)
\def\begin@cell{%
%\save@cell@at@line
\global\advance\cd@cell 1
\futurelet\next@token\@begin@cell}%
%
% A hack for future reference:
% Without \end@cell, we'd pick up \endtemplate as \thefirsttoken
% however it's \outer, so the only way of testing for it is by \ifx
% with something obtained in the same way. Moreover \theendtemplate
% must be used before it's defined, because it's \outer.
% Knuth is devious, but we've got round him!
% \def\gettheendtemplate{\glet\theendtemplate\thenexttoken}
% \halign{\futurelet\thenexttoken\gettheendtemplate#\cr\cr}
%
%
\def\@begin@cell{%
\ifx \next@token\end@cell
\then \hskip 1sp plus 1fil \relax
\let\end@cell\relax\save@cell@at@line
\else \hfil\begin@maths\objectstyle
\let\group@after@map\bad@group@after@map
\fi}%
%
%
% The \halign cell \hbox of an ordinary object cell is
% \hfil
% \mathon
% (text)
% \penalty -9993
% \mathoff
% \null
% \kern -2\cd@hshift
% \null
%
% Missing close brace between label and & will probably be picked up by
% TeX anyway.
%
\def\end@cell{% % idea: deal with crosses in the same way
\end@label\relax % in case of missing closing bracket
\send@cell@type % save new horiz state globally across cell boundary
\save@cell@at@line
\global\cd@dim@g\cd@hshift% save object right shift across $
\penalty-9993 % split off profiling info as last line of paragraph
\end@maths\hfil\null % $\hfil and protect following glue & penalties
%\penalty\profile@code % profiling option
\kern-2\cd@dim@g % balance to indicate right shift
\null % protect glue, kerns and penalties
}%
%
\def\diagram@cr{\cr}% optional argument? terminate horizontals?
% NB: vertical mode material in cells (\vadjust, \insert, \write) migrates
% when \cr is executed.
%
%************************ across several columns ***********************
%
% what happens if \across is used for all the the cells in some column?
% count cells
% \across must not follow verticals and crosses
%
% \mscount already defined by \multispan
%
% for some reason, \across3\cr doesn't work with the following definition,
% although \across2\cr, \across3 \cr and \across3& do work.
% \multispan appears to have a similar problem.
% \def\across{\span\omit\relax\afterassignment\spAns\mscount=}
% \def\spAns{\relax\loop\relax\ifnum\mscount>2 \spAn\repeat}
%
%\diagram
% x&\rTo^{\xi}{}\across3&x'\\
% \dTo^{u^x_y}{}&&&&\dTo_{u^{x'}_{y'}}\\
% y&&&&y'\\
% &\SE{\upsilon}{}&&\SW{}{\upsilon'}\\
% &&y''\\
%\enddiagram
% drives \rTo through x' and puts \xi near its right tip!
%
%\cd@first@use\obs@across{\string\across\space should be changed to multiple
%\and@name}%
\def\across#1{\span\omit\mscount=#1
\global\advance\cd@cell\mscount
\global\advance\cd@cell\m@ne
\loop@on@cells
\ifnum\mscount>2 \spAn\repeat
\ignorespaces}%
% use original plain TeX \sp@n? LaTeX version? count cells?
\def\spAn{\relax\span\omit\advance\mscount\m@ne}%
%
%\def\across#1{\message{%
% ! diagrams Warning: \string\across\ must be changed to multiple &}%
% \global\def\across#1{}}
%
% idea: back up one line (using \baselineskip\z@) or more (dunno)
%
%
%=======================================================================%
% %
% (8A) SIGNATURE %
% %
%=======================================================================%
%
% Now test whether we have enough space to put our Morse Code signature on the
% stretching horizontal. Only do it in diagrams, where both fillers are "-",
% there is no middle, there is enough space and the rule breadth is positive.
% Do it on the 10th and then every 20th subsequent such occasion.
%
\def\test@signature{%
\ifincommdiag
\ifx\@filla\@fillh
\ifx\@fillb\@fillh
\ifdim\dimen3>\z@\else
\ifdim\dimen2>93\pixel@size % corrected 24.6.94 for P
\ifdim\dimen2>18\p@ % added 24.6.94 for high resolution
\ifdim\intended@breadth>\z@
\count@\signature@countdown
\advance\count@\m@ne
\ifnum\count@<\z@
\count@ 20%
\let\@signature\the@signature
\fi
\xdef\signature@countdown{\the\count@}%
\fi\fi\fi\fi\fi\fi\fi
%\showthe\skip2 %\expandafter\message{\signature@countdown}%
}%
% Dots, dashes and spaces are 2, 6 and 2 pixels wide, 1 pixel high.
% However at over 596 dpi resolution this unit is increased:
% \dimen2= 3pixels=0.17pt at 1270dpi, and 6pixels=.17pt at 2540dpi
\def\@morse#1{\vrule\horizhtdp width#1\dimen@\kern2\dimen@}%
%
% Paul Taylor = .--. .- ..- .-.. - .- -.-- .-.. --- .-.
% Code for "P" corrected 24.6.94 (Ralph Loader)
\def\the@signature{\rlap{%
\dimen@\pixel@size\at@least\dimen@{.182\p@}\pixel@round\dimen@
\advance\rule@height\dimen@
\@morse0\@morse0% 4
\@morse2\@morse6\@morse6\@morse2\@morse0\@morse0% P 28
\@morse2\@morse6\@morse0\@morse0% A 16
\@morse2\@morse2\@morse6\@morse0\@morse0% U 20
\@morse2\@morse6\@morse2\@morse2\@morse0\@morse0% L 24
% \@morse0\@morse0% space 4
% \@morse6\@morse0\@morse0% T 12
% \@morse2\@morse6\@morse0\@morse0% A 16
% \@morse6\@morse2\@morse6\@morse6\@morse0\@morse0% Y 32
% \@morse2\@morse6\@morse2\@morse2\@morse0\@morse0% L 24
% \@morse6\@morse6\@morse6\@morse0\@morse0% O 28
% \@morse2\@morse6\@morse2\@morse0\@morse0%% R 20
% \@morse0\@morse0% space 4
}}%
\def\signature@countdown{10}%
\def\@signature{}%
%
%=======================================================================%
% %
% (9) HORIZONTALS %
% %
%=======================================================================%
%
% \dimen 0 = kern compensation for through-filler = \dimen5+\wd5
% \dimen 3 = half width of middle (exactly zero iff filler passes through)
% \skip 3 = glue compensation for through-filler - disappears at break
% \dimen 4 = fixed part of right glue
% \dimen 8 = height of rule filler (.5\rounded@breadth + \axisheight)
% \dimen 9 = depth of rule filler (.5\rounded@breadth - \axisheight)
%
% what is depth of \vbox{\hrule\horizhtdp}?
%
\def\exec@horiz{%
%\show\if@cd@a@\show\if@cd@through@
\if@cd@a@\@cd@through@false\fi % if more text in cell, disable "through"
\calc@horiz\label@horiz\put@horiz}%
%
%\def\shortfall{\kern\MapShortFall}\def\unshortfall{\kern-\MapShortFall}%
%
% ***************** calculations for horizontal arrows ****************
%
% Calculate (unstretched) dimensions of components of horizontal arrow.
\def\calc@horiz{%
\set@offset@axis\crab@ % set \rule@height and \rule@depth
\set@map@parts
\ifdim\crab@=\z@\else\lift@map@parts\crab@\fi
%
% Half width of middle.
% If this is zero and \@filla=\@fillb, can go straight through
% [don't know what to do if it's negative].
\ifvoid3
\setbox3=\null\ht3\rule@height \dp3\rule@depth
\else \at@least{\ht3}\rule@height\at@least{\dp3}\rule@depth
\fi
\dimen3=.5\wd3
\ifdim \dimen3=\z@
\if@cd@through@\else\dimen3-\one@sp\fi
\else \@cd@through@false
\fi
%
% Find the greater length of labels;
% \dimen2 has been set to minimum arrow length.
\at@least{\dimen2}{\wd7}% extend to label widths
\at@least{\dimen2}{\wd6}%
%\at@least{\dimen2}{.5em}% 15.7.94 removed 15.4.95
%
\test@signature
%
\advance\dimen2-2\dimen3 % middle accounts for some of it
\dimen4.5\dimen2
\dimen2\dimen4 % half each side
\advance\dimen2\snake@ % shift right for snake option 4.7.97
\advance\dimen4-\snake@ % doesn't work
\advance\dimen2-\wd1 % subtract tips
\advance\dimen4-\wd5
%
% make sure middle is as high and deep as the fillers
% and that leaders print at least one copy
\ifvoid2
\else \at@least{\ht3}{\ht2}%
\at@least{\dp3}{\dp2}%
\at@least{\dimen2}{\wd2}%
\fi
\ifvoid4
\else \at@least{\ht3}{\ht4}%
\at@least{\dp3}{\dp4}%
\at@least{\dimen4}{\wd4}%
\fi
% add stretchability to glue
\advance\skip2\dimen2
\advance\skip4\dimen4
%
% \dimen3=\z@ is a code to say that the filler can pass through.
% By manipulating glue, we make it stretch correctly whether or not the
% bomb explodes.
% (\total@donated, \left@donated and \right@donated are used like this
% during reformatting only)
% <------------------\total@donated----------------->
% short tip leaders-------------->---kern-->bomb
% -fall <-----negative glue-----
% short
% middle glue-->tip -fall
% <----\left@donated----><--\right@donated--->
% If the bomb does not explode, the negative glue compensates for the kern
% and the right glue (remember that the middle has zero width). The arrow
% may be re-set to any required length as if none of these hacks were there.
%
% If the bomb does explode, the glue (being after the break) automatically
% disappears. The natural and stretched widths of the part to the right of
% the bomb are as expected (with the negative glue they would be zero).
% The width of the part to the left is that of the whole arrow.
% The kern ensuring that the leaders go up to the right tip; the right part is
% still stretched to the right width, so that the middle is correctly placed.
%
% Line-breaking cannot occur at these \xleaders and \kern's outside
% a diagram because they're part of a maths formula (TeXbook p96).
% Inside, the bomb is used (by \reformat@cell) to recognise and split
% the arrow, enabling the halves to be stretched by different amounts.
%
% Since these calculations cannot take account of anything which follows
% the arrow command in the cell, \switch@arg suppresses "through" if
% the arrow command is terminated by anything other than \end@cell.
%
\if@cd@through@
% leaders can pass though - calculate compensating glue
\advance\skip2\skip4 % add width+glue of right to left
\dimen0\dimen5
\advance\dimen0\wd5 % compensating kern
\skip3-\skip4 % compensating glue
\advance\skip3-\dimen0 %
\let\@fillb\empty % print nothing on the right
\else \skip3\z@\relax % otherwise no compenating glue or kern
\dimen0\z@
\fi
%
}%
%
% ***************** Add sub & superscript (if any) ****************
%
% Add to middle,
% retaining baseline and width (2\dimen3) of original middle.
% TeX does this as \vbox{[\kern]\hbox\kern\hbox\kern\hbox[\kern]}
%
\def\label@horiz{%
\offinterlineskip\lineskip.2\@em
\ifvoid6
\else \setbox3=\vbox{%
\hbox to2\dimen3{\hss\box6\hss}%
\box3}%
\fi
\ifvoid7
\else \setbox3=\vtop{%
\box3
\hbox to2\dimen3{\hss\box7\hss}}%
\fi}%
%
% ***************** Output unstretched horizontal ****************
%
\def\put@horiz{% make the horizontal cell - here as seen by paragraph builder
%\hfil\mathon(text) % beginning of cell and text on left
\kern\dimen1 % space before
\box1 % left tip
\@signature
\@filla\hskip\skip2 % filler: glue, leader or rule
\kern\dimen0 % kern compensation
\ifincommdiag
\if@cd@centre@hlabel@\penalty1\fi % signal midhshaft 12.7.94
\kern\dimen3
\penalty\cd@penalty
\hskip\skip3
\null
\kern-\dimen3
\else \hskip\skip3
\fi
\box3 % middle part of arrow
\@fillb\hskip\skip4 % filler
\box5 % right tip
\kern\dimen5}% % space on right
%(text)\penalty-9993
% \mathoff\hfil\null\kern\z@\null
%\rightskip % text and \end@cell
%
% ***************** PostScript rotation of above ****************
%
%+++ INTERIM: ensure at least \objectheight or \objectwidth
\def\interim@shortfall{%
\ifnum\numerator@>\denominator@
\at@least{\dimen1}\objectheight
\at@least{\dimen5}\objectheight
\else
\at@least{\dimen1}\objectwidth
\at@least{\dimen5}\objectwidth
\fi
}%
%
% Make the (diagonal) \kern needed on a line
% of length \dimen2 width \dimen7 and height \dimen6
% in order to intersect the edge of a rectangle
% of height \dimen8 and width \dimen9
\def\avoid@object{%
\begingroup
%\expandafter\message{line=(\the\dimen7,\the\dimen6)=\the\dimen2 \space
% object=(\the\dimen9,\the\dimen8)}%
\ifdim\dimen7=\z@
\kern\dimen8 % vertical: use height
\else\ifdim\dimen6=\z@
\kern\dimen9 % horizontal: use width
\else
\dimen5\dimen6 % save height of line
\dimen6\dimen9 % width of rectangle
\set@fraction % proportion of length
\dimen4\dimen2
\multiply@{\dimen4}%
\dimen6\dimen5 % restore height of line
%
\dimen7\dimen8 % height of rectangle
\set@fraction % proportion of length
\divide@{\dimen2}%
%
%\expandafter\message{kern=(\the\dimen2,\the\dimen4)}%
\ifdim\dimen2<\dimen4
\kern\dimen2 % hit left or right edge
\else \kern\dimen4 % hit top or bottom edge
\fi\fi\fi
\endgroup
}%
% Stretch a horizontal arrow in \hbox0
% as the diagonal of a rectangle of height \dimen6 and width \dimen7
% avoiding objects
% above:
% below:
%
\def\stretch@PS@diagonal{%
\Pythagorean@sum % hypotenuse=\dimen2 x=\denominator@ y=\numerator@
\setbox\z@\hbox{%
\lower\axisheight\hbox to\dimen2{%
\if@reformatting@
% profile of left object
\ifPositiveGradient
% lower left
\dimen8\ht\object@profile
\dimen9\right@width
\else% upper left
\dimen8\dp3
\dimen9\dimen1
\fi
\else
\dimen8 \ifPositiveGradient\objectheight\else\z@\fi \dimen9\objectwidth
\fi
\advance\dimen8 \ifPositiveGradient-\fi\axisheight
\avoid@object%
\unhbox\z@
\if@reformatting@
% profile of right object
\ifPositiveGradient
% upper right
\dimen8\dp3
\dimen9\dimen0
\else% lower right
\dimen8\ht\object@profile
\dimen9\left@width
\fi
\else
\dimen8 \ifPositiveGradient\z@\else\objectheight\fi \dimen9\objectwidth
\fi
\advance\dimen8 \ifPositiveGradient\else-\fi\axisheight
\avoid@object%
}}}%
%
\def\exec@PS@diagonal{%
\dimen6 \y@coord\DiagramCellHeight
\dimen7 \x@coord\DiagramCellWidth
\stretch@PS@diagonal
%
\ifPositiveGradient
\advance\dimen7-\x@offset\DiagramCellWidth
\else\dimen7 \x@offset\DiagramCellWidth
\dimen6\z@
%\multiply\numerator@\m@ne % \rotate@box@z does this now
\fi
\advance\dimen6-\y@offset\DiagramCellHeight
%
\rotate@box@z
%
\setbox0=\rlap{%
\kern-\dimen7
\lower\dimen6\box\z@}%
\ht0\z@\dp0\z@\raise\axisheight\box0
}%
%
\def\rotate@box@z{%
\setbox0\hbox{%
\ht\z@\z@\dp\z@\z@\wd\z@\z@
\if@pdf@
\expandafter\pdf@literal{q
\denom@@\space\num@@\space\mnum@@\space\denom@@\space
0 0 cm}%
\else
\global\@need@PS@lib@true
\expanded@ps@special{%
\the\denominator@\space
\ifPositiveGradient\else-\fi\the\numerator@\space
bturn}%
\fi
\box\z@
\do@eturn}%
}%
%
% ***************** Complete reformatted horizontal ****************
%
% Initial processing of horizontal arrows at the point of declaration during
% reformatting is in the simple reformatting section.
%
% Output a completed horizontal arrow (see also \widen@pile).
% Result is appended to \box\cd@cell using \output@cell.
% Set up new horizontal donation to left.
%
% The pending horizontal arrow or space donation is saved in \box\pending@left
% (and \box\pending@right).
% space: \box\pending@left void (\box\pending@right undefined)
% \left@donated : accumulating amount of (left) donation (cell--a)
% single horizontal: \hbox\pending@left is left component,
% \hbox\pending@right right component
% pile: \vbox\pending@left is pile
% \right@donated : required right width of horizontals (a--b)
% \declared@at@cell: cell number where arrow was declared
% \far@end@cell: ditto for obstruction
%
\def\complete@horizontal{%
\advance\left@donated-\right@width
\total@donated\left@donated\advance\total@donated\right@donated
%
\ifvoid\pending@left
% no arrow, but check that there is some space between objects
\ifdim\total@donated<.1em\ifnum\far@end@cell=\@m\else
\more@dim h\total@donated<.1em:objects overprint:%
\cd@cell\far@end@cell
\fi\fi
\else \ifhbox\pending@left
\widen@horiz
\else \widen@pile
\fi
\advance\total@donated\right@width
\output@cell{-\right@width}{\box\pending@left}{\total@donated}\z@
\fi
\left@donated -\left@width % new space donation to left
% - \box\pending@left is already void
\far@end@cell\cd@cell % save our column number
\right@donated \z@
}%
%
% re-set single horizontal map, where
% \hbox\pending@left is left part, width required to be \left@donated,
% cols \cd@cell to \declared@at@cell
% \hbox\pending@right is right part, width \right@donated,
% cols \declared@at@cell to \far@end@cell
% \total@donated=\left@donated+\right@donated
%
% before entry:
% right: DO strip glue/penalty, restore \math@off and re-set naturally
% DON'T restore \math@on
% left: DON'T strip glue/penalty, restore \math@off, or re-set
% (already has \math@on anyway)
%
\def\widen@horiz{% reorganised 12.7.94
% reset parts to natural width, removing \rightskip & \penalty-9999
\setbox\pending@left=\hbox{\unhbox\pending@left\unskip\unpenalty}%
\setbox\pending@right=\hbox{\unhbox\pending@right\unskip\unpenalty}%
%\showbox\pending@left
%\showbox\pending@right
%
\setbox\pending@left=\hbox to\total@donated{%
%
% get the left part, saving its natural width
\cd@dim@a\wd\pending@left
\unhbox\pending@left
%\showboxbreadth=999 \showlists
%
% 15.4.95: swapped \kern with midshaft \penalty
% because penalties got lost at line breaks
% save the \kern in \cd@dim@b and restore it
%
% test for through filler (\kern 0pt)
\cd@dim@b\lastkern\unkern
\ifdim \cd@dim@b=\z@
\@cd@through@true
% calculate natural width of left part alone
\advance\cd@dim@a-\wd\pending@right
\else \@cd@through@false
\fi
%
% test for midhshaft (\penalty1)
\ifnum\lastpenalty=\z@\else
\@cd@centre@hlabel@true
\unpenalty
\fi
\kern\cd@dim@b
%
%\expandafter\message{^^J%
% midshaft=\if@cd@centre@hlabel@ true\else false\fi,
% through=\if@cd@through@ true\else false\fi,^^J%
% natural \the\cd@dim@a\space and \the\wd\pending@right^^J%
% donated \the\left@donated\space and \the\right@donated}%
%
% if insufficient space on either side, set midshaft
\ifdim\left@donated<\cd@dim@a\@cd@centre@hlabel@true\fi
\ifdim\right@donated<\wd\pending@right\@cd@centre@hlabel@true\fi
%
% adjust right length for midshaft
\if@cd@centre@hlabel@
\right@donated\total@donated
\advance\right@donated-\cd@dim@a
\advance\right@donated\wd\pending@right
%
\ifdim\right@donated<2\wd\pending@right % not enough
\more@dim h\right@donated<2\wd\pending@right:%
arrow too short:\cd@cell\far@end@cell
\fi
%
% give half of it to the right
\divide\right@donated\tw@
\left@donated\total@donated % don't need this
\advance\left@donated-\right@donated
%\expandafter\message{^^Jfinally
% \the\left@donated\space and \the\right@donated}%
\fi
%
% if "through" expand left into right
\if@cd@through@\kern-\right@donated\fi
%
\hbox to\right@donated{\unhbox\pending@right}%
\math@off
}}%
%
%=======================================================================%
% %
% (10) PILES %
% %
%=======================================================================%
%
%
% \hbox of cell containing \pile:
% \glue(\hfil)
% \mathon
% \vbox
% \hbox top line
% \glue\tabskip
% \hbox
% \glue\tabskip
% \glue\baselineskip
% \hbox second line
% ...
% \hbox bottom line
% \penalty-9998
% \rightskip added by paragraph builder
% \mathoff from here is discarded
% \glue(\hfil)
%
% uneven \pile separation, for example in
% X & \pile{\rOnto^p\\\\\lInto~n\\\\\rTo_v} & Y
% because .5\PileSpacing is too little to accommodate the label ``n'',
% so \lineskip is used in the \vbox instead of \baselineskip.
% Also, the empty line is
% \hss\kern\mathon\hfil\mathon\mathoff\kern\hss
%
%
%********************* phase 1 & 2 *****************************
%
% vertical position of pile?
% idea: optional argument to set width when outside diagram
% idea: get map labels and pass them to maps inside (eg adjunctions)
%
% It's not possible to catch a run-away argument to \pile.
% If we read it as an ordinary argument (#1), then if there is no matching
% closing brace anywhere before the end of the paragraph, the rest of the
% paragraph is lost and we get (a TeX error and) \par as the argument; this
% will expand to \enddiagram, which will at least close the \pile cleanly.
% On the other hand, if we do not read it as an argument, but leave the
% closing brace to TeX to parse later, it must end the \halign without giving
% us the opportunity to insert \crcr, and we can't regain control, because
% it is not possible to do \halign\bgroup\aftergroup.
%
% At various places we do \end@pile just in case the closing bracket has been
% put in too late. Since \pile{...\dTo...}\next translates into
% \begin@pile...\dTo...\end@pile\next we never see the original closing brace
% again, but \end@pile stands in for it. Since \dTo wants to force \end@pile,
% it inserts one and gives its own error message; the original becomes
% innocuous because (being no longer in the scope begun by \begin@pile) it is
% \empty. We choose this rather than \relax so that \\\enddiagram, which
% translates to \cr\end@pile\crcr\egroup, does not get an extra \cr.
% Perhaps these dummy \end@label and \end@pile commands should give error
% messages? Maybe, but it's quite likely that TeX or we have already given one.
% \let\end@label\empty
%
\new@if\ifinpile\inpiletrue\inpilefalse\inpilefalse
%
\def\pile{\protect\setup@pile\protect\@pile}%
\def\@pile#1{\begin@pile#1\end@pile}%
\def\setup@pile{%
\check@horiz{pile}% % ensure correct horizontal state
\setbox0=\vtop\bgroup % we want to know the height of the top level
\aftergroup\finish@pile % do this after the corresponding \egroup
%\incommdiagtrue % signal we're NOT inside \commdiag
\inpiletrue
\let\group@after@map\empty
\let\pile\inner@pile %
\let\end@pile\@end@pile %
\let\enddiagram@endpile\@enddiagram@endpile
\pile@state % horiz state (\cd@donat) within \pile is either 6 or 7
\baselineskip.5\PileSpacing%
\lineskip.1\@em\relax %
\lineskiplimit\lineskip %
\mathsurround\z@ % \m@th
\tabskip\z@ % \ialign
\let\\\pile@empty@row
}%
\def\begin@pile{%
\glet\last@map@type\empty% initialise horiz error message (27.12.93)
\halign\bgroup % matrix of 1-column rows [\ifincommdiag\else to..\fi]
\hfil
\begin@maths
\let\group@after@map\bad@group@after@map
\let\\\pile@cr
##\end@label
\end@maths
\hfil
\@and
\and@in@pile##\cr% the template
}%
% idea: use second column to catch misplaced &
%
\new@help\help@and@in@pile{pile only allows one column.}%
\new@help\help@pile@enddiagram{you left it out!}%ascii
\def\and@in@pile{\end@pile\@and\relax
\cd@error{missing \egroup@name\space inserted after \string\pile}%
\help@and@in@pile}%
%
\def\@end@pile{\end@label\crcr\egroup\egroup}%
\def\enddiagram@endpile{\end@label}%
\def\@enddiagram@endpile{\end@label\relax\end@pile
\cd@error{missing \egroup@name\space inserted between \string\pile\space
and \end@diagram@name}\help@pile@enddiagram}%
%
% no point in warning about misplaced or anticipated \end@pile, because
% we've already got to that line and should have given some error message,
% since the argument to \pile is em-braced.
\def\end@pile{\end@label}%
%
% have the pile in \vbox0; do \vcenter without regard to outer labels
\def\finish@pile{%
\vbox {\dimen1\dp0 % total height apart from this
\unvbox0 % re-set \pile
\setbox0=\lastbox % get bottom layer
\advance\dimen1\dp0 %
\nointerlineskip
\box0 % restore bottom layer
\nointerlineskip
\setbox0=\null\dp0.5\dimen1\ht0-\dp0
\box0}% % sink by half top-bottom axis distance
\ifincommdiag
\then \penalty-9998 % flag this was a \pile
\fi
\xdef\last@map@type{pile}%
}%
%
% \\ inside \pile after some text
\def\pile@cr{\cr}%
%
% empty row in \pile (\\ at beginning of cell)
% fiddle the depth of the previous row
% to make \baselineskip or \lineskip do the work
\def\pile@empty@row{\noalign{%
% this is really \advance\prevdepth-\baselineskip
\skip@\prevdepth
\advance\skip@-\baselineskip
\prevdepth\skip@}}%
%
% Nested pile generates its own matrix in the same way, contributing the
% result to the main pile vertical list using \noalign (yes, this works).
%\def\inner@pile#1{\noalign\bgroup\begin@pile#1\end@pile}%
\def\inner@pile#1{#1}% I'm sure this will do!
%
% % \def\Atop#1#2{{% upper and lower parts
% \setbox0\hbox{\strut\begin@maths#1\end@maths}\dp0\z@
% \setbox1\hbox{\strut\begin@maths#2\end@maths}\ht1\z@
% \vtop{\vbox{\kern-0.7ex\box0\hrule width\z@ height0.7ex depth0.93ex}
% \nointerlineskip\box1}
% }}
%
% The idea was to take apart (the definition of) the two arrows and
% re-assemble them. At the TeX end this wouldn't be very difficult to
% do, but it would have produced awful DVI (like visiting the houses
% in a street in numerical order, rather than going up the odds and down
% the evens). Experience has shown that all DVI drivers (it seems) are
% so careless with rounding DVI->pixel conversions that the result would
% be unspeakably ugly.
%
% \def\ExtractMapPartsA#1#2#3#4#5{%
% \def\mapA{#1}\def\tailA{#2}\def\headA{#3}\def\fillerA{#4}\def\middleA{#5}}
% \def\ExtractMapPartsB#1#2#3#4#5{%
% \def\mapB{#1}\def\tailB{#2}\def\headB{#3}\def\fillerB{#4}\def\middleB{#5}}
%
% % eg "\ParallelMap\rTo\bot\lTo f g" or
% "\ParallelMap\uTo\adjoint\dTo f g" f-|g
% % \def\ParallelMap#1#2#3{%
% \expandafter\ExtractMapPartsA #1% eg \rTo
% \setbox4=\hbox{\begin@maths#2\end@maths}% middle bit, eg \bot or \adjoint
% \setbox5=\hbox{}\wd5=\wd4\ht5=\ht4\dp5=\dp4
% \expandafter\ExtractMapPartsB #3% eg \lFrom
% \def\ke{\kern0.1\@em\copy5\kern0.1\@em}%
% \ifx\mapA\HorizontalMap\let\tbox\vcenter\else\let\tbox\hbox\fi
% \mapA{\tbox{\tailA\ke\tailB}}{\tbox{\headA\ke\headB}}%
%{\tbox{\fillerA\ke\fillerB}}
%{\tbox{\middleA\kern0.1\@em\box4\kern0.1\@em\middleB}}}
%
%
%********************* phase 4 *****************************
%
% \vbox\pending@left contains the pile, as created by \halign above.
% \left@donated is the required left width and \right@donated the right width
% \total@donated is sum of these
% Result goes back in \box\pending@left . (\vcenter, \hbox or what?)
% \hbox3, \hbox4, \dimen0, \cd@dim@a, \skip0 scratch - local to \vbox
%
% When splitting the \vbox, we first put it on the stack (current vertical
% list) adding the following:
% \penalty3 (stopper)
% \hbox (top map)
% \baselineskip
% ...
% \baselineskip
% \hbox (bottom map)
%
\def\widen@pile{%
\setbox\pending@left=\vbox{%
\unvbox\pending@left % turn \vbox into a vertical list
\setbox1=\lastbox % sinking box
\setbox0=\box\voidb@x % accumulate new pile
%
\loop@on@maps % in the list
\setbox\pending@left=\lastbox
\ifhbox\pending@left
\do@pile@row
\repeat
\unvbox0 % put it back in the vertical list
\global\cd@dim@g\horiz@extra % save extra cell width across closing braces
}% % complete \vbox
\horiz@extra\cd@dim@g}% % restore extra cell width
%
\def\do@pile@row{%
\if@cd@centre@hlabel@
% unwrap box from \hbox{\tabskip\hbox{<-+->}\tabskip}
\setbox\pending@left=\hbox{%
\unhbox\pending@left
\unskip
\setbox\pending@left=\lastbox\unskip\unhbox\pending@left}%
\ifdim\total@donated<\wd\pending@left
\more@dim h\total@donated<\wd\pending@left:%
arrow in pile too short:%
\cd@cell\far@end@cell
\else \setbox\pending@left =\hbox to\total@donated{\unhbox\pending@left}%
\fi
\else
\split@pile@row
\fi
\setbox0=\vbox{% add the stretched row to the top of the completed pile
\box\pending@left
\nointerlineskip
\ifvoid0
\then \box1 % bottom layer - restore sinking box
\else \vskip\skip0 % restore interlayer glue
\unvbox0
\fi}%
\skip0=\lastskip\unskip % save \baselineskip above this row
}%
%
% \box\pending@left =\hbox{
% \tabskip
% \hbox
% (left part)
% \penalty-9999
% (right part)
% \tabskip}
%
% Split each line of the pile, using the paragraph builder again, so
% the following is added to the stack (current vertical list):
% FOR A MAP FOR AN "OBJECT"
% \parskip \parskip
% \baselineskip \baselineskip
% \hbox (left part) \hbox (the object)
% \baselineskip
% \hbox (right part)
%
% \vbox0: completed pile
% \box1 box to sink depth to do \vcenter without regard to labels
% \hbox\pending@right : right part or object
% \hbox\pending@left : row to be split, then left part, then result
% \left@donated : the required left width
% \right@donated : the required right width
% \skip0: \baselineskip above it
%
\def\split@pile@row{%
\penalty7 % mark the \parskip
\noindent
\unhbox\pending@left % \tabskip\hbox\tabskip
\unskip % remove \tabskip
\setbox\pending@left=\lastbox % get the \hbox (cell)
\unskip % remove \tabskip
\unhbox\pending@left % split the box
\endgraf % using the paragraph builder
%
\setbox\pending@right=\lastbox\unskip% object or right part, and \baselineskip
\setbox\pending@right=\hbox{%
\math@on
\unhbox\pending@right
\unskip\unskip\unpenalty % \parfillskip\rightskip\penalty10000
}%
%
\ifcase\prevgraf\cd@shouldnt P% row of \pile contains wrong number of parts
%
% ONE line: a centered "object" between the maps
\or \ifdim\total@donated<\wd\pending@right
\more@dim h\total@donated<\wd\pending@left:%
object in pile too wide:%
\cd@cell\far@end@cell
\setbox\pending@left =\hbox to\total@donated{\hss
\unhbox\pending@right
\hss}%
\else
\setbox\pending@left =\hbox to\total@donated{\hss
\kern\left@donated
\unhbox\pending@right
\kern\right@donated
\hss}%
\fi
%
% TWO lines: a map
\or \setbox\pending@left=\lastbox\unskip
% get left part & discard \baselineskip
\widen@horiz
% re-set \hbox\pending@left using
% \box\pending@right \right@donated
% \box\pending@left \left@donated \total@donated
%
\else\cd@shouldnt Q\fi % row of \pile contains wrong number of parts
%
\unskip\unpenalty}% remove \parskip and marker (7)
%
%
%=======================================================================%
% %
% (11) VERTICALS %
% %
%=======================================================================%
%
%
% idea: amount to fill? don't think it's worth the trouble
% at least ht & dp of other boxes
% idea: rotate text of labels
\def\exec@vert{%
\set@map@parts
\ifvoid3
\setbox3=\null\ht3\axisheight\dp3-\ht3
\dimen3.5\intended@breadth
\else \dimen4\dp3
\dimen3.5\wd3
\setbox3=\make@vert@part{\box3}% re-center middle
\dp3\dimen4 % but preserve its depth
\ifdim\ht3=-\dp3 \else\@cd@through@false\fi
\fi
%
\dimen0\dimen3 % half original width of middle
\advance\dimen0-.5\intended@breadth
%
% attached labels to middle as overlaps
% preserving the size of \box3
% save widths for later phantom
\setbox0\null\ht0\ht3\dp0\dp3\wd0\wd3 % save size because we're reboxing
\ifvoid6\else
\setbox6\hbox{\unhbox6\kern\dimen0\kern 2pt}\dimen0\wd6
\fi
\ifvoid7\else
\setbox7\hbox{\kern 2pt\kern\dimen3\unhbox7}\dimen3\wd7
\fi
\setbox3\hbox{%
\ifvoid6\else\kern-\dimen0\unhbox6\fi
\unhbox3
\ifvoid7\else\unhbox7\kern-\dimen3\fi
}%
\ht3\ht0\dp3\dp0\wd3\wd0
\if@cd@through@
\dimen4=\ht\object@profile
\advance\dimen4\dp5
\advance\dimen4\dimen1 % lower tip plus shortfall
\let\@fillb\empty % lower filler is space
\else \dimen4\ht3 % phantom middle
\fi
\setbox0\null
\ht0\dimen4
\offinterlineskip
%
\setbox8=\vbox spread2ex{% % upper part with nominal extension
\kern\dimen5 % shortfall above
\box1 % upper tip
\@filla\vfill % filler
\if@cd@through@\else
\kern\snake@ % user's adjustment
\fi
\box0}% % phantom middle provides baseline (depth zero)
\ht8=\z@ % zero height so as not to force lines apart
\setbox9=\vtop spread2ex{% % lower part with nominal extension
\kern-\ht3 % top of box at baseline
\kern-\snake@ % user's adjustment
\box3 % middle
\@fillb\vfill % filler [amount to fill?]
\box5 % lower tip
\kern\dimen1}% % shortfall below (\vbox would put \dp=0)
\dp9=\z@ % zero depth so as not to force lines apart
%
\hskip\dimen0plus.0001fil % phantom left label plus a tiny amount of glue
\box9 % lower part
\kern-\intended@breadth % backspace to overprint the two parts
\box8 % upper part
\if@cd@centre@vlabel@\penalty2 \fi % code to say centre label vertically
\if@cd@through@\penalty1 \fi % code to say filler goes through
\kern\PileSpacing % code the locally required spacing
\kern-\PileSpacing % and undo its effect
\kern-.5\intended@breadth % centre penalty horizontally in shaft
\penalty\cd@penalty
\null
\kern\dimen3}% % phantom label (was \box7)
%
%
%********************* phase 3 *****************************
%
% \hbox\right@part is rightmost, \hbox\left@part next,
% rest as lines of paragraph on current vertical list
% transfer them to \hbox\cd@donat
% calculate widths
%
% The format of each arrow \hbox is
% \hfil
% \mathon
% \hbox(left label)
% \kern
% \vtop (lower part)
% \kern (space adjustment)
% \vbox (upper part)
% \penalty2 \if@cd@centre@vlabel@ (midvshaft)
% \penalty1 \if@cd@through@ (filler goes through)
% \kern\PileSpacing
% \kern-\PileSpacing
% \kern (space adjustment)
% \penalty-9995
% \rightskip
%
\def\reformat@vert{%
\ifhbox\cd@donat
\cd@refmt@error{clashing verticals}%
\ht\object@profile.5\dp\cd@donat
\dp\object@profile-\ht5
\complete@vertical
\ht\object@profile\z@\dp\object@profile\z@
\fi
% save what will be our height
\dimen1\dp\cd@donat
%
% initialise accumulation of parts
\cd@num@d\prevgraf
\unvbox\cd@donat
\cd@num@c\lastpenalty\unpenalty % row number of top
\setbox\cd@donat=\null
%
% re-set rightmost part to natural width
%\setbox\right@part\hbox{\math@on\unhbox\right@part\math@off}% should be enough
\setbox\right@part =\hbox{%
\math@on
\unhbox\right@part
\unskip % \rightskip
%\count@\lastpenalty % code -9993
\unpenalty
%\setbox\junk\lastbox % \hbox(right label)
%\unkern %
%\setbox\junk\lastbox % \null
\dimen0\lastkern\unkern % adjustment
\unkern % un\PileSpacing
%\global\cd@dim@g\lastkern % \PileSpacing
\unkern
\kern\dimen0 % replace adjustment
\math@off
}%
%
%
% and next-to-rightmost part, from which \rightskip and \penalty-9995
% have already been removed.
\setbox\left@part=\hbox{%
\unhbox\left@part
\dimen0\lastkern\unkern % adjustment
\unkern % un\PileSpacing
\global \cd@dim@g\lastkern % \PileSpacing
\unkern
\kern\dimen0 % replace adjustment
}%
%
% copy all but leftmost & rightmost parts to donations box
\loop@on@maps
\ifnum \cd@num@d>4
\separate@verticals
\repeat
%
% remove \baselineskip and \parskip from vertical list
\unskip\unskip
%
% start by centering arrow system without regard to outermost parts
% (\left@width and \right@width initialised by \get@profile@info)
\advance\left@width.5\wd\cd@donat
\advance\left@width\wd\left@part
\advance\right@width.5\wd\cd@donat
\advance\right@width\wd\right@part
%
% if this is the leftmost column of the diagram,
% remember how wide the system of verticals is (15.6.97)
\ifnum\cd@cell=\cd@left
\cd@dim@a .5\wd\cd@donat
\edef\vert@wd@in@leftmost{\the\cd@dim@a}%
\fi
%
% add outermost parts to donation, and codes for row numbers
\setbox\cd@donat=\hbox{%
\kern-\left@width % smash left width
\box\left@part % leftmost
\unhbox\cd@donat % middle
\box\right@part % rightmost
\kern-\right@width % smash right width
\penalty\cd@num@c % row number of top
\penalty\cd@row}% % row number of middle
%
% restore our height and depth, and the intercolumn width
\ht\cd@donat\dimen1
\dp\cd@donat\z@
\wd\cd@donat\column@placing
%
% use \left@width and \right@width to obstruct horizontal
\complete@horizontal
}%
%
\def\separate@verticals{%
\ifdim\wd\left@part<\cd@dim@g
\setbox\left@part=\hbox to\cd@dim@g{\math@on\unhbox\left@part}%
% stretch to \PileSpacing apart
\fi
\advance\cd@num@d\m@ne
\setbox\cd@donat=\hbox{\box\left@part\unhbox\cd@donat}%
% add back to donations box
\unskip % remove \baselineskip
\setbox\left@part=\lastbox
\setbox\left@part=\hbox{%
\unhbox\left@part
\unskip % \rightskip
%\count@\lastpenalty % code -9995
\unpenalty %
\dimen0\lastkern\unkern % adjustment
\unkern % un\PileSpacing
\global \cd@dim@g\lastkern % \PileSpacing
\unkern
\kern\dimen0 % replace adjustment
}%
}%
%
%*************************** phase 4 ****************************
%
% Format of \box\cd@donat
% either: space: \vbox{ \penalty(row no. of upper obstruction)}
% or: arrows: \hbox{ \hbox(leftmost arrow) -- see below
% ...
% \hbox(rightmost arrow)
% \hbox(right label)
% \penalty(row no. of upper obstruction)
% \penalty(row no. where declared)
% }
%
\def\complete@vertical{%
\dimen1\dp\cd@donat
\ifhbox\cd@donat
\@complete@vertical
\else \@complete@vspace
\fi
%
% make new space donation downwards
\setbox\cd@donat=\vbox{\penalty\cd@row}%save our row number
\dp\cd@donat-\dp\object@profile % amount of space
\wd\cd@donat\column@placing % intercolumn width to left
}%
%
\def\@complete@vspace{%
\unvbox\cd@donat
\cd@num@c\lastpenalty\unpenalty
\ifdim\dimen1<\ht\object@profile
\more@dim v\dimen1<\ht\object@profile:rows overprint:\cd@row\cd@num@c
\fi}%
%
\def\@complete@vertical{%
\dimen0=\ht\cd@donat % height
%\dimen1=\dp\cd@donat % depth
% vertical centering (questionable) - idea: make use of natural \ht & \dp
%\if@cd@centre@vlabel@
% \advance\dimen0\dimen1
% \dimen1.5\dimen0
% \dimen0\dimen1
%\else \cd@dim@b\z@
%\fi
%
\setbox\cd@donat=\hbox\bgroup
\advance\dimen1-\ht\object@profile %### forgot this in centre@vlabel!
\unhbox\cd@donat
\cd@num@d\lastpenalty\unpenalty % row number of middle
\cd@num@c\lastpenalty\unpenalty % and of top
\global \cd@dim@h-\lastkern\unkern % right width (local to \hbox)
\setbox0=\lastbox % right label (don't touch)
%
\loop@on@maps
\setbox\cd@donat=\hbox{\box0\unhbox\cd@donat}%
\setbox0=\lastbox
\ifhbox0
\stretch@vert
\repeat
\global \cd@dim@k-\lastkern\unkern % left width
\global \cd@dim@g\vert@extra % save extra cell height across \egroup
\unhbox\cd@donat
\egroup
\vert@extra \cd@dim@g % restore extra cell height
\output@cell{\cd@dim@k}{\box\cd@donat}{\cd@dim@h}{\dimen1}}%
%
% local to \hbox:
% \hbox0: upper part
% \dimen0: required height of upper part, depth \dimen2
% \hbox1: lower part
% \dimen1: required depth of lower part, height \dimen2
% \dimen2: adjustment for midvshaft
% \dimen7: right adjustment
% \dimen6: left adjustment
%
\def\stretch@vert{%
\setbox0=\hbox to\wd0\bgroup
\unhbox0
\unskip\unpenalty % \rightskip, \penalty-9995
\dimen7\lastkern\unkern % right adjustment
\ifnum \lastpenalty=1
\unpenalty
\@cd@through@true
\else \@cd@through@false
\fi
\ifnum \lastpenalty=2
\unpenalty
\dimen2.5\dimen0\advance\dimen2-.5\dimen1\advance\dimen2-\axisheight
\else \dimen2\z@
\fi
\setbox0=\lastbox % upper part
\dimen6\lastkern\unkern % left adjustment
\setbox1=\lastbox % lower part
%
% stretch upper part (\dp\z@ since ends in \hbox\dp\z@ or \kern)
\setbox0=\vbox{%
\unvbox0
\if@cd@through@
\kern-\dimen1 % for filler to go through
\else\ifdim\dimen2=\z@\else
\kern\dimen2 % for midvshaft
\fi\fi}%
\ifdim\dimen0<\ht0
\more@dim v\dimen0<\ht0:upper part of vertical too short:%
{\if@cd@through@\cd@row\else\cd@num@c\fi}\cd@num@d
\else \setbox0=\vbox to\dimen0{\unvbox0}%
\fi
%
% stretch lower part
% NB (see TeXbook p81)
% \vbox would make \dp=0 (because ends \kern\MapShortFall) so \ht=total;
% but \vtop makes \ht=0 (because begins \box), so \dp=total.
\setbox1=\vtop{\unvbox1}%
\ifdim\dimen1<\dp1
\more@dim v\dimen1<\dp1:lower part of vertical too short:\cd@row\cd@num@c
\else \setbox1=\vtop to\dimen1{%
\ifdim\dimen2=\z@\else
\kern-\dimen2
\fi
\unvbox1
}%
\fi
%
\box1 % put lower part back
\kern\dimen6 % left adjustment
\box0 % upper part
\kern\dimen7 % right adjustment
\math@off
\global\cd@dim@g\vert@extra % save extra cell height neede across \egroup
\egroup % end of \hbox
\vert@extra\cd@dim@g\relax}% %
%
%
%=======================================================================%
% %
% (12) TRANSFER TO BOX ARRAYS %
% %
%=======================================================================%
%
% TeX has 256 boxes, some (not, in fact, very many) of which are allocated
% (using \newbox and \newinsert)
% for specific purposes by plain.tex, latex.tex and other packages, including
% this one. Those from 10 to \boxc@unt have been allocated by \newbox and
% those from \insc@unt to 255 by \newinsert, but most of them are unused.
% We use those in between, allocated locally, as a scratch array for our
% reformatting. (\box0..\box9 are also used for scratch). By convention,
% the pointer to the loweset-numbered box in an allocation is to that box,
% whilst that to the highest is to the one above.
%
\countdef\boxc@unt=14 % [cf \insc@unt] number of last \box allocation
%
% \box0..9 available as scratch
% 10..\boxc@unt allocated to various packages
% \cd@bottom=\boxc@unt+1..\cd@top-1 used for rows of matrix
% \cd@left@donat=\cd@top..\cd@right@donat used for vertical donations
% \cd@right@donat+1..\cd@left-1 unused
% \cd@left..\cd@right-1 used for cells of current row
% \insc@unt=\cd@right..254 allocated for footnotes etc
% 255 is the current page
%
\newcount\cd@bottom % \box\cd@bottom is the bottom row
\newcount\cd@top % \box{\cd@top-1} is top row
\newcount\cd@row % \box\cd@row is current row
\let\cd@right\insc@unt % \box{\cd@right-1} is rightmost cell of current row
\newcount\cd@cell % \bot\cd@cell is current ditto
\newcount\cd@left % \bot\cd@left is leftmost ditto
\let\cd@left@donat\cd@top% \box\cd@left@donat is leftmost vertical donation
%\cd@donat already defd % \box\cd@donat is current ditto
\newcount\cd@right@donat% \box{\cd@right@donat-1} is rightmost ditto
%
% After each row has been reformatted and output, its height \ht\cd@row
% is set to the current value of \completed@depth, ie the distance from
% the top of the diagram. (10.7.94)
%
% This is called just after we've finished building the vertical list
% which comprises the matrix. The rows of the matrix may be extracted
% one by one in reverse order (with glue between them), and then each
% row is similarly decomposed, also in reverse order.
% At the beginning this vertical list looks like this:
% \penalty-123 % marker placed by \diagram
% \hbox % top row
% \glue\tabskip
% \hbox % leftmost cell (see template and maps for format)
% \glue\tabskip
% \hbox % second cell
% ...
% \glue\tabskip
% <<<<<<<<<<<<<<<<<<<<< \reformat@row is called here
% \penalty 1 % code that this is a row, mot a missive
% \glue\baselineskip
% \hbox % second row
% \penalty 1 % code that this is a row, mot a missive
% \glue\baselineskip
% ...
% \hbox % bottom row
% <<<<<<<<<<<<<<<<<<<<<<<<<< \reformat@matrix is called here
%
% reformatting goes from right to left in each row,
% top row to bottom row.
%
% IDEAS:
% - collect overprints and diagonals, adding them to the left of the
% appropriate row boxes (making new ones void first if necessary)
% - similar use column widths to set vertical donations (as \wd\vbox)
% void boxes for unspecied ones and warning for repeated specification
%
% MISSIVES:
% \vadjust{} called within a cell puts its material into the vertical list
% below the row (so it appears to \lastbox, \lastpenalty, etc before the row).
% Instead of the \hbox\penalty1 of the row, this is encoded as follows:
% \hbox{missive material}
% \penalty (column number; 1=leftmost)
% \penalty (row number; 1=topmost)
% \penalty (missive code number, >1)
% The missive material may contain overprints, diagonals, etc. In the case of
% diagonals, the row and column numbers are those of the upper (and, for
% horizontals, leftmost) cell involved; the other end of the arrow is
% encoded as penalties contained in the missive material.
%
% \missive@to@row is called when such a \penalty is found whilst the vertical
% list produced by \halign is being taken apart. It appends the missive to the
% left of the \hbox containing the row to which it is addressed in the format
% \hbox{missive material}
% \penalty (column number)
% \penalty (missive code)
% \missive@to@cell is called whilst the row \hbox is being taken apart.
% It appends the missive to the left of the cell \hbox in the format
% \hbox{missive material}
% \penalty (missive code)
%
%********************* transfer rows of matrix to array **********************
%
\new@if\if@reformatting@\@reformatting@true\@reformatting@false\@reformatting@false
%
\def\firstpass@showboxdepth{-1}%
%
\def\after@diagram{%
\ifnum\firstpass@showboxdepth<\z@\else % 15.7.94
\begingroup
\scrollmode % 17.7.94 %%% but this is now set globally 16/4/95
\showboxdepth\firstpass@showboxdepth
\showboxbreadth\maxdimen
\showlists
\endgroup
\fi
\@reformatting@true
\make@end@at@line
\cd@bottom=\boxc@unt % allocate array from \boxc@unt upwards
\advance\cd@bottom1 % for bottom and other rows of matrix
\cd@top=\cd@bottom %
% during the first pass, we counted the rows (globally) in \cd@row
% if only one row, center the labels on the horizontal maps 12.7.94
\ifnum\cd@row=1 \@cd@centre@hlabel@true\fi
\advance\cd@top\cd@row % top
\dimen1\z@ % height of previous row
\skip0\z@ % interline space below this row
\count@=\insc@unt
\advance\count@\boxc@unt
\divide\count@2 % greatest register which may be used for rows
%\showboxdepth999\showboxbreadth999%\showlists
%
\ifnum\cd@top>\count@
\cd@refmt@error
{The diagram has too many rows! It can't be reformatted.}%ascii
\else
\matrix@to@buffer % rows in boxes, collect diagonals, etc (easy to abort)
\reformat@matrix % re-align (skip this for draft mode?)
\fi
\output@diagram
}%
%
\def\matrix@to@buffer{%
\cd@row\cd@bottom
\loop@on@rows % clear rows
\ifnum\cd@row<\cd@top % 12.7.94
\setbox\cd@row\box\voidb@x
\advance\cd@row 1\relax
\repeat
%
\cd@row\cd@bottom
\skip\z@\z@ % inter-row glue
\loop@on@rows
\cd@penalty\lastpenalty\unpenalty % get the code
\ifnum\cd@penalty>\z@ % is anything there?
\handle@matrix@row
\repeat
%
\ifnum \cd@penalty=-123 % We inserted this check at the beginning
\then \unpenalty % of \diagram; now remove it.
\else \cd@shouldnt D% failed to unpack all of the rows of the matrix
\fi
%
% set row heights from grid
\ifx\v@grid\relax\else
\cd@row\cd@top\advance\cd@row\m@ne
%\tracingcommands1 \tracingmacros1
\expandafter\set@v@grid\v@grid
%\tracingcommands0 \tracingmacros0
\fi
%
%\cd@left@donat=\cd@top%(\let) % initialise donations buffer
\cd@right@donat\cd@left@donat %
\column@placing\z@
\mk@new@donat
%
% set column widths from grid
\ifx\h@grid\relax\else
%\tracingcommands1 \tracingmacros1
\expandafter\set@h@grid\h@grid
%\tracingcommands0 \tracingmacros0
\fi
%
\count@\cd@top
\advance\count@\m@ne
\cd@top@height\ht\count@
%\expandafter\message{left=\the\cd@left, right=\the\cd@right,
% left donat=\the\cd@left@donat, right donat=\the\cd@right@donat}%
}%
%
\def\handle@matrix@row{%
\ifcase\cd@penalty
\or \matrix@row@to@buffer
\else \cd@num@a-\lastpenalty\unpenalty % negative of row number
\cd@num@b\lastpenalty\unpenalty % column number
\setbox0=\lastbox
\missive@to@row
\fi
\get@interrow@glue % 13.7.94
}%
\def\get@interrow@glue{\skip1\lastskip\unskip\advance\skip0\skip1
\ifdim\skip1=\z@\else\expandafter\get@interrow@glue\fi}%
%
\def\matrix@row@to@buffer{%
\setbox0=\lastbox % get a row
\row@depth\dp0
\advance\row@depth\skip\z@\skip\z@\z@
\advance\inter@row\row@depth % between our baseline and next below
\if@cd@tight@\ifnum\cd@row>\cd@bottom
\inter@row\DiagramCellHeight % if tight, reset to prescribed amount
\row@depth\inter@row
\advance\row@depth-\row@height
\fi\fi
\row@height\ht0 % save height for next time
\inter@row\row@height
% save the row on the left hand end of the row box register
\setbox\cd@row\hbox{\unhbox\cd@row\unhbox0}%
\dp\cd@row\row@depth % include space in depth of row
\ht\cd@row\row@height
\advance\cd@row 1 % allocate a box register for it
}%
%
\def\missive@to@row{%
% \cd@num@a = -1 for top row, -2 for next, etc
%\expandafter\message{missive type \the\cd@penalty\space to
% (\the\cd@num@a,\the\cd@num@b)}%
\ifnum\cd@num@a<\z@
\advance\cd@num@a\cd@top % row number as a box number
\ifnum\cd@num@a<\cd@bottom
\missive@outside
\else
\cd@dim@a\dp\cd@num@a\cd@dim@b\ht\cd@num@a
\setbox\cd@num@a\hbox{%
\box\z@
\penalty\cd@num@b
\penalty\cd@penalty
\unhbox\cd@num@a}%
\dp\cd@num@a\cd@dim@a\ht\cd@num@a\cd@dim@b
\fi
\else
\missive@outside
\fi
}%
\def\missive@outside
{\cd@refmt@error{diagonal goes outside diagram (lost)}}%ascii
%
\def\resend@missive{%
%\expandafter\message{missive type \the\cd@penalty\space to
% (\the\cd@num@a,\the\cd@num@b)}%
\advance\cd@num@a\cd@top % row number as a box number
\ifnum\cd@num@a<\cd@bottom
\missive@outside
\else
\ifnum\cd@num@a=\cd@row
\missive@to@cell
\else
\ifnum\cd@num@a>\cd@row
\cd@shouldnt M% missive addresses in wrong order
\else
\cd@dim@a\dp\cd@num@a\cd@dim@b\ht\cd@num@a
\setbox\cd@num@a\hbox{%
\box\z@
\penalty\cd@num@b
\penalty\cd@penalty
\unhbox\cd@num@a}%
\dp\cd@num@a\cd@dim@a\ht\cd@num@a\cd@dim@b
\fi\fi\fi
}%
%
% State of program variables at point of loop test
% current vertical list: completed diagram so far
% \cd@row still points to row above
% \hbox(\cd@row-1): current row as illustrated above
% \completed@depth= vertical distance from top of matrix to next baseline
% above
% \inter@row := depth of next row above
%
%********************* reformat matrix **********************
%
\def\reformat@matrix{%
%\matrix@to@buffer % already have each row in a separate box register
\bomb@parameters % set up for our peculiar use of paragraph builder
\set@axis % profile height & depth for empty cells
\setbox\default@profile =\hbox{\begin@maths A\@super f\@sub f\end@maths}%
% object not to profile
\horiz@extra \z@\vert@extra \z@ % extra horizontal & vertical cell size needed
\right@over \z@\left@over \z@ % right and left widths of whole diagram
\cd@row=\cd@top % start from top row
\inter@row \z@\completed@depth \z@ % row and total depth
%
\loop@on@rows
\ifnum \cd@row>\cd@bottom
\advance\cd@row\m@ne
\row@height \ht\cd@row % save height of row
\row@depth \dp\cd@row % and depth
\advance\inter@row \row@height % distance to next baseline
\row@to@buffer % new vertical donations are down to next above
\advance\completed@depth \inter@row % depth so far
\deepen@donations % add depth to donations
\reformat@row
\buffer@to@row % collect completed cells
\ht\cd@row\row@height % restore height of row
\dp\cd@row\row@depth % and depth
\nointerlineskip %
\box\cd@row % output the completed row to the vertical list
\inter@row \row@depth % depth contributes to dist to next baseline
\setbox\cd@row\null % 10.7.94
\ht\cd@row\completed@depth % 10.7.94
\repeat % loop on rows
%
\complete@last@row
\nointerlineskip
\box\cd@row % output it
%
\need@extra\horiz@extra\DiagramCellWidth{width}%
\need@extra\vert@extra \DiagramCellHeight{height}%
%
% do some calculations to pass to \output@diagram
\cd@donat\cd@right\advance\cd@donat-\cd@left\advance\cd@donat\m@ne
\advance\cd@donat\cd@left@donat
\dimen0\wd\cd@donat % position of rightmost column
%
\rule@height \axisheight % axis height
\dimen1\completed@depth \advance\dimen1-\cd@top@height % top to bottom axis
\dimen2\right@over \advance\dimen2-\dimen0 % right width of right column
\advance\cd@top-\cd@bottom % number of rows
\advance\cd@right-\cd@left % number of columns
}%
%
%
\count@\year\multiply\count@12 \advance\count@\month
\ifnum\count@>24314 \loop\iftrue\message{gone February 2026!}\repeat\fi%
%
% \inter@row is now the depth of the bottom row (according to \halign)
\def\complete@last@row{%
\row@height-\inter@row
\row@depth\inter@row
\setbox\object@profile=\null
\dp\object@profile\inter@row
\ht\object@profile-\inter@row
\left@width\z@
\right@width\z@
\cd@left\cd@right
\advance\cd@left-\cd@right@donat
\advance\cd@left\cd@left@donat
\cd@cell\cd@right
\cd@donat\cd@right@donat
\loop@on@cells
\ifnum \cd@cell>\cd@left
\advance\cd@cell\m@ne
\advance\cd@donat\m@ne
\column@placing\wd\cd@donat
\setbox\cd@cell=\box\voidb@x
%\showbox\cd@donat
\complete@vertical
%\showbox\cd@cell
\repeat
\buffer@to@row%\showbox\cd@row
\ht\cd@row\row@height
\dp\cd@row\row@depth
}%
%
\def\need@extra#1#2#3{%
\ifdim#1>.01\@em
\cd@dim@b #2\relax
\advance\cd@dim@b #1\relax
\advance\cd@dim@b.99\@em
\count@\cd@dim@b
\divide\count@\@em
\cd@refmt@error{increase cell #3 to \the\count@ em}%
\fi}%
%
%
%********************* transfer cells of row to array **********************
%
% IDEAS
% - ignore \tabskip; shouldn't be any other glue penalties or kerns in row
% - diagonal and overprint items? somehow append to cells. what it past
% end of row?
% - what about orphan diagonals?
\def\row@to@buffer{%
% have \cd@right=\insc@unt
\cd@cell=\cd@right % clear array for cells to be processed
%\count@=\cd@right
%\advance\count@\cd@left@donat
%\divide\count@2 % lowest register allowed for cells
\penalty4 % mark the following \parskip
\noindent\unhbox\cd@row % make horizontal list (adds \parskip to vertical list)
%
% get the actual cells from the right hand side of \box\cd@row
\loop@on@cells
\unskip % remove \tabskip
\setbox0=\lastbox % get next (to left) cell
\ifhbox0 % anything there?
\advance\cd@cell\m@ne
\setbox\cd@cell\hbox to\wd0{\null\penalty-9990\null\unhbox0}%
% \ifnum\cd@cell>\count@\else
% \cd@refmt@error{Too many cells.}%
% \cd@cell=\cd@right % throw most of them away
% \fi
\repeat
\cd@left\cd@cell%\expandafter\message{cd@left=\the\cd@left}%
%
\advance\cd@cell\cd@right@donat %
\advance\cd@cell-\cd@left@donat % cell corresponding to possible new donation
\ifnum\cd@cell<\cd@right % is this row longer than the donations?
\count@\cd@cell
\advance\count@\m@ne % NB: was already at least one donation column
\dimen0=\wd\count@ % width of previous halign column
\count@\cd@right@donat
\advance\count@\m@ne
\column@placing\wd\count@ % x-coord of previous donation col
\loop@on@cells
\ifnum \cd@cell<\cd@right
\set@col@width
\mk@new@donat
\dimen0\wd\cd@cell % width of this column for next time
\advance\cd@cell 1
\repeat
\fi
%
% then the missives
\loop@on@cells
\cd@penalty\lastpenalty\unpenalty
\ifnum\cd@penalty>\z@
\cd@num@b\lastpenalty\unpenalty % column number
\missive@to@cell
\repeat
%
%
\endgraf % make paragraph from empty horizontal list
\unskip % remove \parskip glue
\ifnum\lastpenalty=4 % check we have the correct stopper
\unpenalty
\else
\cd@shouldnt S% didn't clear the stack
\fi
}%
\def\missive@to@cell{%
%\expandafter\message{missive type \the\cd@penalty\space to
% (\the\cd@num@a,\the\cd@num@b) cd@left=\the\cd@left}%
%\ifnum\cd@num@b<\z@
% \missive@outside
%\else
\advance\cd@num@b\cd@left\advance\cd@num@b\m@ne
\setbox0=\lastbox
\ifnum\cd@num@b<\cd@right
\setbox\cd@num@b\hbox{\box0\penalty\cd@penalty\unhbox\cd@num@b}%
\else
\missive@outside
\fi%\fi
%\showboxdepth 2 \showboxbreadth 999 \tracingonline1 \showbox\cd@num@b
}%
%
% extend donations to be at least as long as row
% calculate and save column widths here
\def\more@donations{%
}%
%
\new@if\if@cd@tight@\@cd@tight@true\@cd@tight@false
%
\def\set@col@width{%
% calculate halign's distance between centres
\advance\dimen0\wd\cd@cell
\divide\dimen0\tw@
%
% impose required size
\if@cd@tight@
\dimen0\DiagramCellWidth
\else \at@least{\dimen0}\DiagramCellWidth
\test@loose@diagonals
\fi
%
\advance\column@placing\dimen0
}%
\def\mk@new@donat{%
% make new vertical donation
\setbox\cd@right@donat=\vbox{}% % new space donation
\dp\cd@right@donat=\completed@depth % of the depth so far
%
% accumulate and save x-coordinate
\wd\cd@right@donat\column@placing
%\expandafter\message{^^Jcol \the\cd@right@donat\space at \the\column@placing}%
\advance\cd@right@donat 1
}%
%
\def\set@h@grid#1,{%
\def\@value{#1}%
\ifx\@value\end@square@name\else
\advance\column@placing\@value\DiagramCellWidth
\mk@new@donat
\expandafter\set@h@grid
\fi
}%
%
\def\set@v@grid#1,{%
\def\@value{#1}%
\ifx\@value\end@square@name\else
\ifnum\cd@row>\cd@bottom
\inter@row\@value\DiagramCellHeight
\advance\inter@row-\dp\cd@row
\advance\cd@row\m@ne
\ht\cd@row\inter@row
\fi % 4.12.94
\expandafter\set@v@grid
\fi
}%
%
%
% If diagonals have been used and we're widening a column by more
% than twice the short-fall, tell the user to use the tight option.
%
\def\test@loose@diagonals{%
\if@diagonals@used@
\cd@dim@a\dimen0
\advance\cd@dim@a-\DiagramCellWidth
\ifdim\cd@dim@a>2\MapShortFall
\cd@refmt@error{badly drawn diagonals (see manual)}%ascii 15.4.95
\let\test@loose@diagonals\empty
\fi
\else \let\test@loose@diagonals\empty
\fi}%
%
\def\deepen@donations{%
\cd@donat\cd@left@donat
\loop@on@cells
\ifnum\cd@donat<\cd@right@donat
\dimen0\dp\cd@donat
\advance\dimen0\inter@row
\dp\cd@donat\dimen0
\advance\cd@donat 1
\repeat
}%
% outside:
% \cd@dim@a: left width
% \left@over : left overlap of diagram
%
% local to \hbox:
% \box0: what we're going to print
% \dimen7: distance to raise
% \dimen8: right width
% \dimen9: kern between thing on left and us
%
% may be used as arguments:
% \dimen1,3,4,5 \z@ \box2,7 \box\cd@donat
%
\def\output@cell#1#2#3#4{% #1=left width, #2=box, #3=right width, #4=raise
\ifnum\cd@cell<\cd@right
\cd@dim@a=#1\relax
\setbox\cd@cell=\hbox{%
\setbox0=#2%
\dimen7=#4\relax
\dimen8=#3\relax
%\expandafter\message{^^J(\the\cd@top-\the\cd@row,\the\cd@cell-\the\cd@left)
% \the\cd@dim@a, \the\dimen8, pos=\the\column@placing}%
\ifhbox\cd@cell
\unhbox\cd@cell
\advance\cd@dim@a-\lastkern\unkern
\fi
\ifdim\cd@dim@a=\z@\else\kern-\cd@dim@a\fi
\raise\dimen7\box0
\kern-\dimen8
}%
\ifnum\cd@cell=\cd@left\at@least\left@over\cd@dim@a\fi
\else \cd@shouldnt O% \output@cell has overrun the buffer
\fi
}%
%
\def\buffer@to@row{%
\setbox\cd@row=\hbox{%
\cd@cell\cd@left
\cd@donat\cd@left@donat
\cd@dim@b\z@\relax % total width so far
\loop@on@cells
\ifnum\cd@cell<\cd@right
\column@placing\wd\cd@donat\relax
\reoutput@cell
\advance\cd@cell 1
\advance\cd@donat 1
\repeat}%
\at@least\right@over{\wd\cd@row}% greatest width so far
\wd\cd@row\z@ % kill it (we'll deal with positioning at the end)
}%
%
\def\reoutput@cell{%
\ifhbox\cd@cell
\cd@dim@a\column@placing\relax
\advance\cd@dim@a-\cd@dim@b\relax
\ifdim\cd@dim@a=\z@\else\kern\cd@dim@a\fi
\cd@dim@b\column@placing
\advance\cd@dim@b\wd\cd@cell\relax
%\box\cd@cell % commented out 6.4.95 why was it there? R width ok now
\unhbox\cd@cell
\advance\cd@dim@b-\lastkern\unkern
\fi
}%
%
%************************ re-alignment of row ***********************
%
% State of program variables at loop test:
% current vertical list: completed rows of diagram
% \cd@cell still points to cell to right!
% \hbox(\cd@cell-1) current cell, still as packaged by \halign
% \hbox(\cd@left..\cd@cell-2) cells still to be processed
% \hbox(\cd@cell..(\cd@right-1)) completed row so far
% \box\cd@donat vertical donation:
% width is horizontal distance from centre of leftmost column to this one
% \vbox: space donation, depth is amount (height undefined)
% \hbox: pending vericals, height and depths according to their baseline
% \cd@dim@a,0,6 scratch
% \completed@depth = depth of completed diagram so far to current baseline
% \inter@row = distance from current baseline to next above
% \column@placing = dist from centre of first column to centre of this one
% \left@donated = width of left part or of horizontal donation from right
% \row@height = height of this row
% \row@depth = depth of this row
% \hbox\pending@left = horizontal donation:
% void: space donation of \left@donated
% \hbox: left part of single horizontal (not re-set) \wd is of right part
% \vbox: pile (not re-set) ditto
% \hbox\pending@right = right part of single horizontal (or void)
%
\def\reformat@row{%
\setbox\pending@left=\box\voidb@x % horizontal donation is space
\cd@donat=\cd@right@donat % index into buffer of vertical donations
\cd@cell\cd@right % index into buffer of cells to be processed
\cd@donat\cd@left@donat
\advance\cd@donat\cd@cell
\advance\cd@donat-\cd@left % corresponding donation
\advance\cd@donat\m@ne
\column@placing \wd\cd@donat % save
\count@\cd@right % unterminated horizontals on right
\advance\count@\m@ne % extend to the edge of the column as
\left@donated .5\wd\count@ % set by \halign
\advance\left@donated\column@placing
\across@cells\m@ne % no \span'ned columns on right
\far@end@cell\@m
%
\loop@on@cells % of donations buffer
\ifnum \cd@cell>\cd@left
\advance\cd@cell\m@ne
\advance\left@donated-\column@placing
\reformat@cell
\wd\cd@donat\column@placing % restore
\advance\left@donated \column@placing
% add intercolumn to horizontal donation
\advance\cd@donat\m@ne
\column@placing \wd\cd@donat % save
\repeat % loop on cells
%
\left@width\left@over \right@width -\left@width
% zero-width column shifted this much
\complete@horizontal % output remaining unterminated arrow
}%
%
%********************* add to left or right of box **********************
%
%\def\push@queue#1\to#2{% *** push \box#1 onto (left of) queue \hbox#2 ***
%\setbox#2=\hbox{\box#1\unhbox#2}}%
%
%\def\push@stack#1\to#2{% *** push \box#1 onto (right of) stack \hbox#2 ***
%\setbox#2=\hbox{\unhbox#2\box#1}}%
%
% The above was originally implemented so that \box'es could be used
% as stacks and queues. This is, however, probably very time-consuming.
% \def\p@p#1\from#2{% *** pop \box#1 from stack \hbox#2 ***
% \setbox#2=\hbox{%
% \unhbox#2
% \setbox#1=\lastbox
% \vadjust{\box#1}% migrates to enclosing vertical list
% }%
% \setbox#1=\lastbox}% where we pick it up
% Note that this ONLY works if the enclosing list is vertical; otherwise
% no migration occurs at all (ie it doesn't go into a list further out).
%
%
%=======================================================================%
% %
% (13) PARAGRAPH BOMBING %
% %
%=======================================================================%
%
% The paragraph builder works inside any vertical list --- not just the
% current page --- and all we need to do to invoke it is to create a
% horizontal list and terminate it with \endgraf. The horizontal list is
% split into a sequence of \hbox'es delimited by \penalty's and \glue.
% The effect of
% "\noindent\unhbox6\unksip\endgraf"
% is to add
% \glue\parskip [absent if current vertical list is empty]
% \glue\baselineskip [absent if \prevdepth<=-1000pt]
% \hbox(first line)
% [\hbox(\parindent) absent because of \noindent]
% \glue\hfil
% \mathon
% (first part of \hbox6 up to and including
% \penalty-9999 % whatever we used to force a split)
% \glue\rightskip
% [\penalty\clubpenalty absent because all interline penalties=0]
% \glue\baselineskip
% \hbox(sencond line)
% [\penalty\interlinepenalty]
% ...
% \glue\baselineskip
% \hbox(penultimate line)
% (last part of \hbox6, up to \penalty-9993\rightskip)
% [\penalty\widowpenalty absent because all interline penalties=0]
% \glue\baselineskip
% \hbox(last line)
% [\mathoff\glue\hfil lost in line break]
% \null protection
% [\penalty profile code]
% \kern-2\cd@hshift
% \penalty10000
% \glue\parfillskip
% \glue\rightskip
% \null protection
% to the current vertical list, where the number of lines is returned in
% \prevgraf.
%
% Note that \endgraf is defined (TeXbook p351) to be the primitive value of
% \par; LaTeX changes \par quite a lot.
%
% We take advantage of this as a way of splitting a complex \hbox (containing
% \mathon...\mathoff whatsits, which there is no way of stripping) at any
% desired place. For example, we want to divide a horizontal arrow in two
% and stretch the two parts by different amounts. By using peculiar
% parameters we can get this to happen at the desired places and not at the
% usual hyphenation. In particular, we set \linepenalty=9000, so splitting
% can only occur at large negative penalties.
%
% We use particular penalty values as codes:
% -9999: middle of horizontal arrows
% -9998: after \pile (immediately preceded by the \vbox)
% -9997: \HonV
% -9996: \VonH
% -9995: middles of vertical arrows (immed. prec. by two \vbox'es)
% -9994: \HmeetV
% -9993: \end@cell, followed by profiling info
% Hence the number of lines is
% ZERO: empty cell (only \parskip added to vertical list)
% ONE: unused - maybe use for \HonV and \VonH
% TWO: object
% THREE: any of above five cases
% MORE: two or more parallel vertical arrows
%
% The effect of this is to add extra \hbox'es to the vertical list, which
% we then strip off in reverse order. In other words, we use the vertical
% list as a stack (and refer to it as such).
%
% CONVENTION
% Since most of the glue and penalties on the stack are unwanted,
% whenever they are wanted they are removed immediately they come
% to the top of the stack.
%
% bomb to split horizontal and vertical arrows
\newcount\cd@penalty
\def\@bomb{}% no bombs outside diagrams
%
\def\bomb@parameters{%
\mathsurround \z@ % no extra space around maths
\hsize \z@ % zero-width paragraphs,
\rightskip \z@ % \ but allow
plus1fil % | to stick out
minus\maxdimen % / on the right
\parfillskip \z@ %
\linepenalty 9000 % use only one line unless high price paid
\looseness 0 % no extra lines
\hfuzz \maxdimen % don't care how much it sticks out,
\hbadness 10000 % so please don't complain about it!
\clubpenalty 0 % \
\widowpenalty 0 % | set all inter-line penalties to
\displaywidowpenalty 0 % | zero so that they are suppressed
\interlinepenalty 0 % |
\predisplaypenalty 0 % |
\postdisplaypenalty 0 % |
\interdisplaylinepenalty 0 % |
\interfootnotelinepenalty 0 % |
\floatingpenalty 0 % |
\brokenpenalty 0 % /
\everypar {}% % no junk at beginning of paragraph
\leftskip \z@ % or beginning of lines
\parskip \z@ % \parskip is discarded in each case
\parindent \z@ % not used because of \noindent
\pretolerance 10000 % \
\tolerance 10000 % |
\hyphenpenalty 10000 % | hyphenation parameters are
\exhyphenpenalty 10000 % | really irrelevant
\binoppenalty 10000 % |
\relpenalty 10000 % |
\adjdemerits 0 % |
\doublehyphendemerits 0 % |
\finalhyphendemerits 0 % /
\baselineskip \z@ % bug in Luatex? 17.5.2013 and 11.5.2014
\@cd@centre@hlabel@false
%
% Some initial things to ensure \endgraf always generates \parskip\baselineskip
% (even though we always discard them, but we're using the vertical list as
% a stack, so we've got to be regular about things):
% \hbox{}\nointerlineskip at the beginning of the diagram ensures that the
% vertical list is non-empty, so \parskip is generated, but suppresses
% \baselineskip before the top row of the matrix; now we ensure that
% \baselineskip IS generated in our next use.
\prevdepth\z@ % ensures \baselineskip is present - (maybe it shouldn't be)
%
}% (end of \bombparameters)
%
%
\newbox\math@on@box\newbox\math@off@box
\def\math@on{\unhcopy\math@on@box}\def\math@off{\unhcopy\math@off@box}%
%
\def\start@bomb@vlist{\hbox{}\penalty1\nointerlineskip}%
%
%********************* re-alignment of cell ********************
%
% \reformat@cell takes
% \hbox\cd@cell (current cell) or \@VonH
% \hbox\pending@left (donation from right)
% \left@donated (width of donation from right)
% \box\cd@donat (donation from above)
% and returns
% \hbox\pending@left (donation to left)
% \left@donated (width of donation to left)
% \box\cd@donat (donation downwards)
% and accumulates in \hbox\cd@cell:
% completed horizontal arrows,
% completed vertical arrows
% objects
%
% The paragraph builder adds
% 0: \parskip
% 1: \parskip\baselineskip\hbox
% 2: \parskip\baselineskip\hbox\baselineskip\hbox
% 3: etc
% to the current vertical list; \reformat@object & \reformat@complex
% remove all but \parskip. None of this glue or penalty is wanted.
%
% The lines of the paragraph are
% 1: missives
% 2: empty cell: \null\penalty10000\parfillskip\rightskip
% object: \null\hfil\mathon text\penalty-9993\rightskip
% horizontal: \null\hfil\kern(shortfall)\null\xleaders\kern\kern
% \penalty-9999\rightskip
% 3: horizontal: \null\kern\hbox\hfill\hbox\kern\penalty-9993\rightskip
% last: profile information (not used for empty cells):
% \null\kern-2\cd@hshift\penalty10000\parfillskip\rightskip
%
\def\reformat@cell{%
%\showboxdepth 2 \showboxbreadth 999 \tracingonline1 \showbox\cd@cell
\penalty5 % mark \parskip
\noindent
\setbox\object@profile =\null % initialise profile
\left@width\z@\right@width \z@ % widths
%
% use paragraph builder to split the cell
\ifnum \cd@cell<\cd@right
%\showbox\cd@cell
\ht\object@profile \ht\cd@cell
\dp\object@profile \dp\cd@cell % default ht/dp of profile
\unhbox\cd@cell\skip0=\lastskip\unskip
\else \@VonH\skip0=\z@ % if out of range
\fi
\endgraf%\showboxdepth 2 \showboxbreadth 999 \tracingonline1 \showlists
%
%
%\showlists
%\expandafter\message{cell (\the\cd@row,\the\cd@cell) % ascii
% prevgraf=\the\prevgraf\new@line}%
\ifcase\prevgraf % test number of lines as above
\cd@shouldnt Y % 0: empty cell
\or \cd@shouldnt Z % 1: unused (maybe \HonV, \VonH)
\or \reformat@empty % 2: empty cell
\or \reformat@object % 3: object (maybe \HmeetV) with profile
\else \reformat@complex % 4+: many cases
\fi
%
\unskip
\setbox0=\lastbox % all the missives
\unskip\unskip\unpenalty% discard \baselineskip, \parskip and marker 5
%
\noindent\unhbox0% unpack the missives
% remove \null \penalty1000 \parfillskip \rightskip \penalty-9990 \null
\setbox0\lastbox\unpenalty\unskip\unskip\unpenalty\setbox0\lastbox
%\showlists
\loop@on@maps
\cd@penalty\lastpenalty\unpenalty % code no. of missive
\ifnum\cd@penalty>\z@
\setbox\z@\lastbox
\cell@missive
\repeat
%
\endgraf
\unskip\unskip\unpenalty % remove \parskip and marker (5)
%
}%
%
\def\show@prevgraf{%
\cd@num@a\cd@top\advance\cd@num@a-\cd@row
\cd@num@b\cd@cell\advance\cd@num@b-\cd@left\advance\cd@num@b 1
\expandafter\message{prevgraf=\the\prevgraf at (\the\cd@num@a,\the\cd@num@b)}%
}%
%
%
%=======================================================================%
% %
% (14) REFORMATTING OBJECTS AND CROSSES %
% %
%=======================================================================%
%
% Use of registers during the reformatting process
%
% \box \dimen \skip
% 0 scratch scratch scratch
% 1 left \ part of scratch completed depth
% 2 right / current cell scratch interline above
% 3 scratch scratch intercolumn left
% 4 scratch left \ width of horiz \ extra cell
% 5 profile (\ht,\dp) right / profile vert / size needed
% 6 right \ part of pending right \ width of right \ overlap of
% 7 left / horizontal left / donation left / whole diagram
% 8 scratch height\ of horiz height\ of this row
% 9 \hbox{$A^f_f$} depth / rule depth /
%
%
\def\reformat@object{%
\get@profile@info %
\setbox\right@part=\lastbox % fetch box
\setbox\right@part=\hbox{%
\unhbox\right@part % re-set to natural size
\unskip % \rightskip
\unpenalty % -9993
}%
\unskip % discard \baselineskip
%
% make profile - detail if bigger than $A^f_f$
\ifdim\ht\right@part>\ht\default@profile
\setbox\object@profile=\copy\right@part
\else\ifdim\dp\right@part>\dp\default@profile
\setbox\object@profile=\copy\right@part
\else \make@profile\right@part % (13.7.94)
\fi\fi
%
\advance\left@width.5\wd\right@part
\advance\right@width.5\wd\right@part
%
\setbox\right@part=\hbox{\unhbox\right@part\math@off}%
%
% whether to output?
\output@cell\left@width{\box\right@part}\right@width\z@
\complete@vertical
\complete@horizontal
}%
%
% last line of nontrivial paragraph is profile information
% currently just a kern to balance right shift (\cd@hshift)
\def\get@profile@info{%
% pick up width of \span'ned cells (see \reformat@empty) from \dimen0
% use negative value of \across@cells to remember how many (extra) there were
%\expandafter\message{across \the\across@cells\space cells, \the\dimen0^^J}%
\ifnum\across@cells>0
\advance\dimen0-\column@placing
\cd@hshift-.5\dimen0
\across@cells-\across@cells
\else \across@cells0
\cd@hshift\z@
\fi
\setbox\object@profile =\lastbox % the last line, including profile info
%\showbox\object@profile
\setbox\object@profile =\hbox{\unhbox\object@profile % take it apart:
\unskip\unskip\unpenalty % \rightskip\parfillskip\penalty10000
\setbox0=\lastbox % \null protection of glue etc
\global\cd@dim@g\lastkern\unkern% balance
}%
\advance\cd@hshift-.5\cd@dim@g % the amount to shift right
\unskip % remove \baselineskip
\setbox\object@profile =\null % initialise profile
\right@width\cd@hshift
\left@width-\cd@hshift
}%
\def\axis@profile{%
\ht\object@profile\rule@height
\dp\object@profile\rule@depth}%
%
\def\make@profile#1{% (13.7.94)
\setbox\object@profile=\hbox{%
\at@least{\ht\object@profile}{\ht#1}%
\at@least{\dp\object@profile}{\dp#1}%
\at@least{\wd\object@profile}{\wd#1}%
\vrule height\ht\object@profile
depth\dp\object@profile
width\wd\object@profile
}}%
%
%******************** reformat maps ************************************
%
% \reformat@complex deals with arrows, piles and obstructions
% all of which were three-line paragraphs (except multiple verticals).
% The following is removed from the stack (current vertical list):
% \glue\baselineskip
% \box\left@part:= \hbox(first line)
% (penultimate part of cell up to and including
% \penalty-9999 % whatever we used to force a split)
% \glue\rightskip
% \glue\baselineskip
% \box\right@part := \hbox(last line)
% (last part of cell)
% \penalty10000
% \glue\parfillskip
% \glue\rightskip
% by this routine; for multiple vertical arrows, \reformat@vert clears
% the remainder as required by \reformat@cell.
%
%
% \skip0: scratch (local to scope of \hbox)
% \dimen6: scratch
%
\def\reformat@complex{%
\get@profile@info
\axis@profile % (13.7.94)
\setbox\right@part=\lastbox % right(most) part
\unskip % discard \baselineskip
\setbox\left@part=\lastbox % left (or next-to-rightmost) part
\unskip % discard \baselineskip
\setbox\left@part=\hbox{%
\unhbox\left@part % open left part
\unskip % remove \rightskip
\global \cd@num@g\lastpenalty % extract the code
\unpenalty
}% % reset to natural width
\advance\cd@num@g9999
%\tracingonline1 \showboxbreadth999 \showboxdepth1 \showbox\object@profile
\ifcase\cd@num@g % now switch on the code [use \vadjust\penalty instead?]
\reformat@horiz % -9999: single horizontal
\or \reformat@pile % -9998: multiple horizontal
\or \reformat@HonV % -9997: \HonV
\or \reformat@VonH % -9996: \VonH
\or \reformat@vert % -9995: vertical(s)
\or \reformat@HmeetV% -9994: \HmeetV
%\or \reformat@overprint% -9993: idea: overprints (eg pullback symbol)
%\or \reformat@user % -9992: idea: user-defined command
\else \cd@shouldnt 9% unrecognised \penalty splitting cell
\fi
}%
% idea: define the above with a "\new.." construct
% single horizontal arrow \hbox\left@part=left \hbox\right@part =right
% output pending vertical (which has now been obstructed)
% donate both parts
%
%******************** horizontals ************************************
%
\def\reformat@horiz{%
\make@profile\right@part % this is where the labels are (13.7.94)
\@reformat@horiz
\setbox\pending@left=\box\left@part
\setbox\pending@right=\box\right@part
%\showboxdepth999 \showboxbreadth999 \showbox\pending@right
}%
%
\def\reformat@pile{%
%\showbox\left@part\showbox\right@part
\make@profile\left@part % (13.7.94)
\setbox\right@part\hbox{% 15.4.95 test for extra material on right of \pile
\penalty 8 %
\unhbox\right@part\unskip\unpenalty
\ifnum\lastpenalty=8
\else\pile@junk
\fi}%
\@reformat@horiz
\setbox\left@part=\hbox{%
\unhbox\left@part % extract the \vbox from the left part
\unskip % \rightskip
\unpenalty % -9998
\global \setbox\cd@box@g=\lastbox
}% previous item in horiz list is \mathon, so can't really ...
% test if anything remains on the left (test its natural width, anyway).
\ifdim\wd\left@part=\z@\else\pile@junk\fi
\setbox\pending@left=\box\cd@box@g
% save the pile \vbox as the horizontal donation
}%
\def\pile@junk{\cd@refmt@error
{extra material in \string\pile\space cell (lost)}}%ascii
%
\def\@reformat@horiz{% this code is common with \reformat@pile
\complete@vertical
\ifvoid\pending@left\else
\cd@refmt@error{Clashing horizontal arrows}%
\right@width.5\left@donated % setting profile shares the space
\left@width-\right@width % buggers \across and \shift though
\complete@horizontal % output the offending arrow
\right@width\z@ % and our profile is zero width again
\left@width\z@
\fi
\right@donated\left@donated % what its width will be
\advance\right@donated-\right@width
\left@donated-\left@width % new donation - towards the left width
\declared@at@cell\cd@cell
}%
%
%
%
%******************** reformat empty cells ************************************
%
% There are five types of empty cell:
% - empty/white (adjacent &'s)
% - \span: \across, \mutispan, LaTeX version?
% - \HonV
% - \VonH
% - \HmeetV
%
% the absolute value of \across@cells is the number of \span'ned cells to
% the right; positive to show we're still collecting them, negative means
% we've taken account of the width and only want this for error reporting.
% \dimen0 accumulates the width - remember we're only going round a tight
% loop in \reformat@row, with \reformat@cell, ending up in \get@profile@info
%
\def\reformat@empty{%
\setbox0\lastbox\unskip
\cd@hshift\z@ % what \get@profile@info would do
\axis@profile
\ifdim\skip0>\z@
\then % empty/white
\across@cells0 % --- ignore any \across
\else % \across
\ifnum\across@cells<1
\across@cells0 % first one
\dimen0\column@placing
\fi %
\advance\across@cells 1
\fi
}%
%
%\newif\iffred
% the three cross commands
\def\VonH {\cd@cross 46\VonH{.5\intended@breadth}}%
\def\HonV {\cd@cross 57\HonV{.5\intended@breadth}}%
\def\HmeetV{\cd@cross 44\HmeetV{-\MapShortFall}}%
%
% idea: \solder \HjumpV \VjumpH
%
% choose the \penalty, check that we're allowed and read the next token
% #1=new horizontal state after donated arrow,
% #2=last digit of \penalty, #3=name
% #4=effective map breadth
\def\cd@cross#1#2#3#4{%
\check@vert34#1{\string#3}\exec@cross % ensure correct horizontal state
\cd@penalty-999#2 % the penalty value
\dimen0=#4% % initialise strut size (\dimen0,8,9)
\rule@height\dimen0\advance\rule@height\axisheight
\rule@depth\dimen0\advance\rule@depth-\axisheight
%\iffred
%\rule@height\axisheight
%\rule@depth-\rule@height
%\advance\rule@height.5\rounded@breadth
%\advance\rule@depth.5\rounded@breadth
%\fi
%\expandafter\message{ht=\the\rule@height, dp=\the\rule@depth}%
\@ifoptarg\cross@strut\exec@map}% % get optional argument and do it
% \exec@map=\exec@cross (or ignore with error message if outside diagram)
%\exec@map}%
%
% use optional argument to re-calculate strut size
\def\cross@strut#1{%
\setbox0=\hbox{\begin@maths#1\end@maths}%
\dimen0.5\wd0
\rule@height \ht0
\rule@depth \dp0
\exec@map % and do it
}%
% put half the strut on either side of the \penalty
\def\exec@cross{%
\setbox0=\null
\ht0=\rule@height
\dp0=\rule@depth
\wd0=\dimen0
\copy0\penalty\cd@penalty\box0
}%
%
%\def\MapCorner{{%
%\rounded@breadth=-2\MapShortFall
%\set@axis
%\vrule width\rounded@breadth \horizhtdp
%}}%
%
\def\reformat@HonV {\cross@profile\complete@vertical}%
\def\reformat@VonH {\cross@profile\complete@horizontal}%
\def\reformat@HmeetV{\cross@profile\complete@vertical\complete@horizontal}%
%
\def\cross@profile{%
\setbox\right@part=\hbox{\unhbox\right@part}% right strut
\setbox\left@part=\hbox{\unhbox\left@part % left strut
\global \setbox\cd@box@g=\lastbox % this is the real (left) strut (is it?)
}%
\ht\object@profile \ht\cd@box@g % get its real height
\dp\object@profile \dp\cd@box@g % and depth
\advance\left@width \wd\cd@box@g % and left width
\advance\right@width\wd\right@part % right width
}%
%
%=======================================================================%
% %
% (15) LaTeX LINE CHARACTERS %
% %
%=======================================================================%
%
\new@if\ifPositiveGradient\PositiveGradienttrue\PositiveGradientfalse
\PositiveGradienttrue
\new@if\ifClimbing\Climbingtrue\Climbingfalse\Climbingtrue
\newcount\DiagonalChoice\DiagonalChoice\m@ne
%
% LaTeX line & arrow font
\ifx\tenln\nullfont
\then \def\line@char{\no@tenln
\ifPositiveGradient/%ascii slash stands in for LaTeX slopes
\else\begin@maths\backslash\end@maths\fi}%or backslash
\else \def\line@char{\line@font\char\count@}%
\fi
\let\line@font\tenln
%
%
%===========================================================================
% get LaTeX line characters
% for x=\denominator@ y=\numerator@ using \ifPositiveGradient
%
\def\Use@line@char#1{\hbox{#1\line@font
\ifPositiveGradient\else\advance\count@ 64 \fi
\char\count@}}%
%
\def\LaTeX@line@char{\Use@line@char{%
\count@\denominator@\multiply\count@ 8\advance\count@ -9%
\advance\count@\numerator@}}%
%
\def\LaTeX@arrow@char{\Use@line@char{%
\ifcase\DiagonalChoice
\LaTeX@SW
\or\LaTeX@NE
\or\LaTeX@NE
\else\LaTeX@SW
\fi}}%
%
\def\LaTeX@SW{%
\ifnum\denominator@=\z@
\count@'33 % left (-1,0)
\else
\count@\denominator@
\multiply\count@\sixt@@n
\advance\count@ -9%
\advance\count@\numerator@
\advance\count@\numerator@
\fi}%
%
% this might just as well be a case switch!
% 81 tokens versus 115 for \@getrarrow in LaTeX
\def\LaTeX@NE{%
\count@'%
\ifcase\numerator@ 55%
\or\ifcase\denominator@ 66\or 22\or 52\or 61\or 72\fi
\or\ifcase\denominator@ 66\or 25\or 22\or 63\or 52\fi
\or\ifcase\denominator@ 66\or 16\or 36\or 22\or 76\fi
\or\ifcase\denominator@ 66\or 27\or 25\or 67\or 22\fi
\fi\relax}%
%
\def\double@LaTeX#1{\hbox{#1\setbox0=\Use@line@char{#1}%
\ifPositiveGradient\else\raise.3\ht0\fi\copy0
\kern-.7\wd0
\ifPositiveGradient\raise.3\ht0\fi\box0}}%
\def\left@LaTeX@tail#1{\hbox{\setbox0=#1%
\kern-.75\wd0
\vbox to.25\ht0{%
\ifPositiveGradient\else\vss\fi
\box0
\ifPositiveGradient\vss\fi}%
}}%
\def\right@LaTeX@tail#1{\hbox{\setbox0=#1%
\dimen0=\wd0
\vbox to.25\ht0{%
\ifPositiveGradient\vss\fi
\box0
\ifPositiveGradient\else\vss\fi}%
\kern-.75\dimen0
}}%
%
% ****************** LaTeX line-font components *****************
%
% LaTeX diagonal arrow heads
\def@name{+h:>}{\Use@line@char\LaTeX@NE}%
\def@name{-h:>}{\Use@line@char\LaTeX@SW}%
\let@names{+t:<}{-h:>}%
\let@names{-t:<}{+h:>}%
%
% used as tails (different positioning)
\def@name{+t:>}{\left@LaTeX@tail {\Use@line@char\LaTeX@NE}}%
\def@name{-t:>}{\right@LaTeX@tail{\Use@line@char\LaTeX@SW}}%
\let@names{+h:<}{-t:>}%
\let@names{-h:<}{+t:>}%
%
% LaTeX diagonal double arrow heads
\def@name{+h:>>}{\double@LaTeX\LaTeX@NE}%
\def@name{-h:>>}{\double@LaTeX\LaTeX@SW}%
\let@names{+t:<<}{-h:>>}%
\let@names{-t:<<}{+h:>>}%
\let@names{+h:>->}{+h:>>}%
\let@names{-h:>->}{-h:>>}%
\let@names{+t:<-<}{-h:>>}%
\let@names{-t:<-<}{+h:>>}%
%
% used as tails (different positioning - currently too close to object)
\def@name{+t:>>}{\left@LaTeX@tail {\double@LaTeX\LaTeX@NE}}%
\def@name{-t:>>}{\right@LaTeX@tail{\double@LaTeX\LaTeX@SW}}%
\let@names{+h:<<}{-t:>>}%
\let@names{-h:<<}{+t:>>}%
\let@names{+t:>->}{+t:>>}%
\let@names{-t:>->}{-t:>>}%
\let@names{+h:<-<}{-t:>>}%
\let@names{-h:<-<}{+t:>>}%
%
% LaTeX diagonal line segment filler
\def@name{+f:-}{\if@use@TPIC@\null\else\LaTeX@line@char\fi}%
\let@names{-f:-}{+f:-}%
%
% dot filler
\def\dot@filler#1#2{\vbox to#1{\vss\hbox to#2{\hss.\hss}\vss}}%
\def\hfdot{\dot@filler{2\axisheight}{.5em}}%% % .7em until 29.7.98
\def\vfdot{\dot@filler{1ex}\z@}%% % 1.46ex until 29.7.98
\def\LaTeX@dot@filler{\hbox{%
\dimen0=.3\@em\dimen1\dimen0
\ifnum\numerator@>\denominator@\divide@{\dimen1}%
\else\multiply@{\dimen0}\fi
\dot@filler{\dimen0}{\dimen1}}}%
\newarrowfiller{.}\hfdot\hfdot\vfdot\vfdot
\def\dfdot{\LaTeX@dot@filler\@use@TPIC@false}% 12.7.94
\def@name{+f:.}{\dfdot}%
\def@name{-f:.}{\dfdot}%
%
% proposed by Richard Kennaway 11.9.97
%\def\colon@filler#1#2{\vbox to#1{\vss\hbox to#2{\hss=\hss}\vss}}%%
%\def\hfcolon{\colon@filler{2\axisheight}{1.1em}}%%
%\def\vfcolon{\colon@filler{1.46ex}\z@}%%
%\newarrowfiller{:}\hfcolon\hfcolon\vfcolon\vfcolon
% but this needs more thought as it's neither a colon nor a double line
%
%
% ****************** old LaTeX line-font components *****************
%
\def\use@line@char#1{\hbox\bgroup\def\next{#1\egroup}\afterassignment\next%%
\count@='}%
%
% still used for orthogonals arrowheads
\def\lnchar{\use@line@char\line@char}%
%
% the rest is obsolete
% commented out 15.10.2008 (v3.93)
% because Apostolos Sypopoulos <ijdt.editor@gmail.com> said that
% "the command \lat should be renamed \l@t to avoid conflict
% with the name of some unicode math symbol."
% \let\laf\lnchar\let\lah\lnchar
% \def\lad{\use@line@char\xlad}%
%
% \def\xlad{\setbox2=\hbox{\line@char}%
% \setbox0=\hbox to.3\wd2{\hss.\hss}%
% \dimen0=\ht0 \advance\dimen0-\dp0
% \dimen1=.3\ht2 \advance\dimen1-\dimen0 \dp0=.5\dimen1
% \dimen1=.3\ht2 \advance\dimen1\dimen0 \ht0=.5\dimen1
% \raise\dp0\box0}%
%
% \def\lahh{\use@line@char\xlahh}%
% \def\lat{\use@line@char\xlat}%
%
% into tails
% \def\xlat{\setbox0=\hbox{\line@char}%
% \dimen0=\ht0
% \setbox1=\hbox to.25\wd0{%
% \ifcase\DiagonalChoice
% \box0\hss
% \or \hss\box0
% \or \hss\box0
% \or \box0\hss
% \fi}%
% \vbox to.25\dimen0{%
% \ifClimbing\box1\vss\else\vss\box1\fi\kern\z@}%
% }%
% %
% % Can't mangle \mv because it's used in old extra-diagonals.tex
% % double arrowheads
% \def\xlahh{\setbox0=\hbox{\line@char}%
% \ifPositiveGradient
% \then \copy0 \kern-.7\wd0 \mv.3\ht0\box0
% \else \ifClimbing
% \then \copy0 \kern-.7\wd0 \mv.3\ht0\box0
% \else \mv-.3\ht0\copy0 \kern-.7\wd0 \box0
% \fi\fi}%
%
%=======================================================================%
% %
% (16) DIAGONALS %
% %
%=======================================================================%
%
% ******************* \LaTeX@make@line **********************
%
% arithmetic for diagonal repeaters:
% ^ _____a______
% : | ^
% : | |
% : | |b n-1 = floor (e/a)
% : <---c-->+--- | (n-1)c+a = e
% : | | | | b/a = d/c = num/den
% : | <f>+-------v f = a-c
% : | ^
% : | d
% : | |
% v: -----------v
%
% <--------e--------->
%
% the height of the baseline is not specified
%
%
\def\LaTeX@make@line#1{% use \box#1 to make \box#1 with width \dimen#1
\setbox#1=\hbox{%
\dimen5\dimen#1 % required horizontal distance (\dimen5=e)
%\expandafter\message{\string\dimen#1=\the\dimen#1}%
\setbox8=\box#1
\dimen1\wd8 % width (\dimen1=a)
\count@\dimen5 % distance coerced to integer (scaled points)
\divide\count@\dimen1 % no of segments minus one (\cd@num@a=n-1=floor(e/a))
\ifnum \count@=0 %
\box8 % just one
\ifdim\dimen5<.95\dimen1 \cd@warning{diagonal line too short}\fi
\else \dimen3=\dimen5 % otherwise, calculate...
\advance\dimen3-\dimen1 % e-a
\divide\dimen3\count@ % repeat width (\dimen3=c=(e-a)/(n-1))
\dimen4\dimen3
\multiply@{\dimen4}% % repeat height (\dimen4=d)
\ifPositiveGradient\multiply\dimen4\m@ne\fi
\dimen6\dimen1
\advance\dimen6-\dimen3 % backspace (\dimen6=d==a-c)
\loop % on bits
\raise\count@\dimen4\copy8 % a copy of the repeater
\ifnum \count@>0
\kern-\dimen6 % overlap
\advance\count@\m@ne
\repeat
\fi}}%
\def\make@line#1{\if@use@TPIC@\tpic@make@line{#1}\else\LaTeX@make@line{#1}\fi}%
\def\no@make@line#1{}%
%
% *********************** \exec@LaTeX@diagonal **************************
% baseline_____________________________________
% ^ | \MapShortFall ______________|
% : | | |UT |
% : | | |___| UT = upper tip
%\DiagramCellHeight ____| | UF = upper filler
% : | |UL | UF | UL = upper label
% : | |___|_____________| M = middle
% : axis____| | | etc
% v |----------------|---| |
% baseline_____| |LL | |
% | LF |---- |
% | | |
% |___ | |
% |LT | | |
% |___|____________| |\MapShortFall
% | |\MapShortFall | |
% ------------------------------------
% ^\objectheight <\DiagramCellWidth>
% baseline_____v
%
% height and depth is the "obvious": as the arrows, as far as the tips.
% width is zero, so that for one-cell arrow, centered in cell;
% multicell arrows stick out on right, as if centered in that many cells.
%
% assumed height and half-width of endpoints
\newdimen\objectheight \objectheight 1.8ex
\newdimen\objectwidth \objectwidth 1em % 13.7.94
%
% \dimen0 depth of lower tip (from baseline of current cel)
% \dimen1 distance to left tip (from centre of current cell)
% \dimen2 width of left filler
% \dimen3 distance from left tip to left edge of middle
% \dimen4 width of right filler
% \dimen5 height of upper tip (from baseline of current cell)
% \dimen6 total height of arrow
% \dimen7 total width of arrow
% \dimen9 twice amount to lower middle (from baseline of current cell)
%
% ----- check we really have a diagonal -----
%
\def\exec@LaTeX@diagonal{%
% calculate total height and width including shortfall
\dimen6=\y@coord\DiagramCellHeight
\dimen7=\x@coord\DiagramCellWidth
\set@fraction % calculate y=\numerator@ and x=\denominator@
\ifnum\numerator@>0
\ifnum\denominator@>0
\@@LaTeX@diagonal
\else
\aftergroup\diag@is@vert
\fi
\else
\aftergroup\diag@is@horiz
\fi}%
%
\def\diag@is@vert {\cd@error{diagonal map is nearly vertical}\cd@diag@zer}%
\def\diag@is@horiz{\cd@error{diagonal map is nearly horizontal}\cd@diag@zer}%
\new@help\cd@diag@zer{Use an orthogonal map instead}%
%
\def\@@LaTeX@diagonal{%
% use appropriate LaTeX line characters (set boxes 1-5)
\set@map@parts
%
% re-calculate width corresponding to height
\dimen3\dimen7\dimen7\dimen6\divide@{\dimen7}%
\advance\dimen3-\dimen7 % width error (both sides)
%
% ----- compute shortfalls -----
%
\interim@shortfall
\ifnum\numerator@>\denominator@
% steep:
\advance\dimen6-\dimen1\advance\dimen6-\dimen5 % apply shortfalls to height
\divide@{\dimen1}\divide@{\dimen5}% and convert them to widths
\else % shallow
\dimen0\dimen1\advance\dimen0\dimen5\multiply@{\dimen0}% convert to height
\advance\dimen6-\dimen0
\fi
%
\dimen2.5\dimen7\advance\dimen2-\dimen1 % width of left half
\dimen4.5\dimen7\advance\dimen4-\dimen5 % width of right half
%
\ifPositiveGradient
\dimen0\dimen5 % use right margin to calculate top margin
\advance\dimen1-\x@coord\DiagramCellWidth % stick out a lot on the left
\advance\dimen1 \x@offset\DiagramCellWidth % relative to where?
\setbox6=\llap{\unhbox6\kern.1\ht2}%
\setbox7=\rlap{\kern.1\ht2\unhbox7}%
\else
\dimen0\dimen1 % use left margin to calculate top margin
\advance\dimen1-\x@offset\DiagramCellWidth % relative to where?
\setbox7=\llap{\unhbox7\kern.1\ht2}%
\setbox6=\rlap{\kern.1\ht2\unhbox6}%
\fi
%
\setbox6=\vbox{\box6\kern.1\wd2}\setbox7=\vtop{\kern.1\wd2\box7}%
%
\multiply@{\dimen0}% convert top margin from width to depth
\advance\dimen0-\axisheight\advance\dimen0-\y@offset\DiagramCellHeight
\dimen5-\dimen0 % height of upper tip
\advance\dimen0\dimen6 % depth of lower tip
%
\advance\dimen1.5\dimen3 % adjust left margin for width error
%
% middle disables through
\ifdim\wd3>\z@\ifdim\ht3>-\dp3\@cd@through@false\fi\fi
%
\dimen3\dimen2
\dimen7\dimen2\advance\dimen7\dimen4
\ifvoid3
\else
\if@cd@through@
\else
% calculate x coordinate of intersection with top of middle
\dimen8\ht3\advance\dimen8-\axisheight\divide@{\dimen8}%
\at@most{\dimen8}{.5\wd3}% or choose intersection with edge
%
% calculate x coordinate of intersection with bottom of middle
\dimen9\dp3\advance\dimen9\axisheight\divide@{\dimen9}%
\at@most{\dimen9}{.5\wd3}% or choose intersection with edge
%
\ifPositiveGradient
\advance\dimen2-\dimen9\advance\dimen4-\dimen8 % shorten fillers
\else\advance\dimen4-\dimen9\advance\dimen2-\dimen8 % appropriately
\fi\fi
\advance\dimen3-.5\wd3
\fi
\dimen9=\y@coord\DiagramCellHeight\advance\dimen9-2\DiagramCellHeight
%
%
% make the fillers;
% re-use \dimen2 and \dimen4 as amounts to raise them (instead of their widths)
\if@cd@through@
\advance\dimen2\dimen4
\make@line{2}% width \dimen2 using \box2 to make \box2
\dimen2-\dimen0\advance\dimen2\dp2 % amount to raise it
\else
\make@line{2}% width \dimen2 using \box2 to make \box2
\make@line{4}% width \dimen4 using \box4 to make \box4
\ifPositiveGradient
\dimen2-\dimen0\advance\dimen2\dp2 % amount to raise left
\dimen4\dimen5\advance\dimen4-\ht4 % amount to raise right
\else\dimen4-\dimen0\advance\dimen4\dp4 % amount to raise right
\dimen2\dimen5\advance\dimen2-\ht2 % amount to raise left
\fi\fi
%
\setbox0=\hbox to\z@{%
% move to left edge
\kern\dimen1
%
% output the left tip
\ifvoid1
\else
\ifPositiveGradient
\advance\dimen0-\dp1
\lower\dimen0
\else\advance\dimen5-\ht1
\raise\dimen5
\fi\rlap{\unhbox1}%
\fi
%
% left filler
\raise\dimen2\rlap{\unhbox2}%
%
% output the middle
\ifvoid3 \else
\lower.5\dimen9\rlap{\kern\dimen3\unhbox3}%
\fi
%
% labels
\kern.5\dimen7
\lower.5\dimen9\box6
\lower.5\dimen9\box7
\kern.5\dimen7
%
% right filler
\if@cd@through@\else
\raise\dimen4\llap{\unhbox4}%
\fi
%
% right tip
\ifvoid5 \else
\ifPositiveGradient
\advance\dimen5-\ht5
\raise\dimen5
\else\advance\dimen0-\dp5
\lower\dimen0
\fi\llap{\unhbox5}%
\fi
%
\hss}%
\ht0=\axisheight\dp0=-\ht0\box0 }%
%
%\advance\dimen6.25\dimen8 % amount to raise upper label
%\advance\dimen7-.25\dimen8 % amount to raise lower label
%
%
%
%\setbox0=\hbox{\begin@maths\vcenter{%
% \kern.9ex % space above
% \hbox{%
% \kern.4em % space on left
% \count@=0
% \mv-\ht1\box1 % left tip
% \loop % on bits
% \ifnum\count@<\DiagonalLineSegments
% \mv\count@\ht2\copy2 % filler
% \advance\count@1
% \repeat
% \mv\count@\ht2\box5 % right tip
% \kern.4em % space on right
% }%
% \kern.9ex % space below
%}\end@maths}
%\dimen0=.5\wd0 \ht0\z@ \dp0\z@
% %\kern\dimen0
%\mv.5\wd2\hbox to\z@{\hss\box6\kern.5\ht2}% left label
%\kern-\dimen0
%\box0
%\kern-\dimen0
%\mv-.5\wd2\hbox to\z@{\kern.5\ht2\box7\hss}% right label
% %\kern\dimen0
%}
%
% Count clockwise from NW
% \ifPositiveGradient = \ifodd\diagonal@choice
% \ifClimbing = \ifnum\diagonal@choice<2
\def\NorthWest{\PositiveGradientfalse\Climbingtrue \DiagonalChoice0 }%
\def\NorthEast{\PositiveGradienttrue \Climbingtrue \DiagonalChoice1 }%
\def\SouthWest{\PositiveGradienttrue \Climbingfalse\DiagonalChoice3 }%
\def\SouthEast{\PositiveGradientfalse\Climbingfalse\DiagonalChoice2 }%
%
%
%
%=======================================================================%
% %
% (17) STRETCHABLE DIAGONALS %
% %
%=======================================================================%
%
% \missive at any point in the diagram text delivers the text to \cell@missive,
% which is called during \reformat@cell
%
% \hbox{(missive material)}
%
%\def\missive#1(#2,#3){\vadjust{\hbox{#1}\penalty#3\penalty#2\penalty2}}%
%\def\remissive#1(#2,#3)(#4,#5){\vadjust{%
% \hbox{\hbox{#1}\penalty#3\penalty#2}%
% \penalty#5\penalty#4\penalty103}}%
%\def\missivemap#1(#2,#3)(#4,#5){\vadjust{%
% \hbox{\hbox{#1}\penalty#3\penalty#2}%
% \penalty#5\penalty#4\penalty104}}%
\def\exec@missive{\vadjust{%
\cd@num@a\cd@cell
\advance\cd@num@a\ifPositiveGradient\else-\fi\x@offset\relax
\cd@num@b\cd@row\advance\cd@num@b-\y@offset\relax
\hbox{%
\advance\cd@num@a\ifPositiveGradient-\fi\x@coord
\advance\cd@num@b\y@coord
\hbox{%
\box6 % upper label
\kern\crab@
\kern\snake@
\penalty1 % stops upper label being read as missing lower label
\box7 % lower label
\box\z@
}%
\penalty\cd@num@a
\penalty\cd@num@b}%
\penalty\cd@num@a\penalty\cd@num@b\penalty104}}%
%
\def\over@print#1{%
\relax % if case we're the first thing in a cell
%\ifmmode
\vadjust{%
\hbox@maths{#1}%
\penalty\cd@cell
\penalty\cd@row
\penalty\tw@
}%
%\else\cd@warning{mis-placed over-print ignored}% removed 15.4.95
%\fi
}%
%
% handle the missives
% \cd@penalty contains the code number, \box\z@ the missive material
% (note that we are currently in unrestricted horizontal mode,
% inside a paragraph in the main vertical list)
\def\cell@missive{%
%\expandafter\message{missive type \the\cd@penalty\space
% received at (\the\cd@row,\the\cd@cell)\new@line}%
\ifcase \cd@penalty
% 0: unused
\or % 1: was used to mark an ordinal row of the matrix
\or % 2: simple overprint
%\message{overprint}%
\output@cell{.5\wd0}{\box0}{.5\wd0}\z@%
\or % 3: indirected overprint
\unhbox\z@\setbox\z@\lastbox\output@cell{.5\wd0}{\box0}{.5\wd0}\z@
\unpenalty\unpenalty\setbox\z@\lastbox
\or % 4: draw diagonal
\missive@diagonal
\else % 100n+m: collect profiles of n more points and execute case m
\advance\cd@penalty-100
\ifnum\cd@penalty<\z@ \cd@shouldnt B\fi % unknown missive code
\setbox\z@\hbox{%
% save the profile of the current cell
\kern\left@width
\copy\object@profile
\kern\right@width
% and its coordinates
\cd@num@a\cd@top\advance\cd@num@a-\cd@row\penalty\cd@num@a
\cd@num@a\cd@cell\advance\cd@num@a-\cd@left\penalty\cd@num@a
% at the front of the missive material
\unhbox\z@
% removing the coordinates of the next cell to visit
\global\cd@num@g\lastpenalty\unpenalty% its row number
\global\cd@num@h\lastpenalty\unpenalty}% its column number
% send it there
\cd@num@a-\cd@num@g\cd@num@b\cd@num@h
\resend@missive
\fi}%
%
\def\missive@diagonal{%
%\global\@need@PS@lib@true % 12.7.94 deleted 6.10.2001
\unhbox\z@
\setbox\z@\lastbox
%
% get missive data
\cd@num@a\lastpenalty\unpenalty\advance\cd@num@a\cd@left@donat % column no.
\cd@num@b\cd@top\advance\cd@num@b-\lastpenalty\unpenalty % row no.
\dimen1\lastkern\unkern % right width
\setbox 3\lastbox % profile
\dimen0\lastkern\unkern % left width
%
\setbox0=\hbox to\z@{%
%
% get the arrow and the labels
\unhbox0\setbox0\lastbox
\setbox7\lastbox % lower label (\ifPositiveGradient right \else left)
\unpenalty
\snake@\lastkern\unkern
\crab@\lastkern\unkern
\setbox6\lastbox % upper label (\ifPositiveGradient left \else right)
%
% calculate \dimen7=unsigned width of diagonal map 14.7.94
\dimen7\column@placing\advance\dimen7-\wd\cd@num@a
\ifdim\dimen7<\z@
\PositiveGradienttrue
\multiply\dimen7\m@ne
\let\mv\empty
\else\PositiveGradientfalse
\def\mv{\raise\ht1}%
\kern-\dimen7
\fi
%
% calculate \dimen6=height of diagonal map 10.7.94
\ifnum\cd@num@b>\cd@row
\dimen6\completed@depth
\advance\dimen6-\ht\cd@num@b
\else \dimen6\z@
\fi
%
%\expandafter\message{(\the\dimen7,\the\dimen6)}%
% \dimen6=ht=\numerator@ \dimen7=dp=\denominator@ \dimen2=hypotenuse
\stretch@PS@diagonal
\rotate@box@z
%
% get these out of the way of \set@fraction
\setbox1\null\ht1\dimen6\wd1\dimen7
%
% denominator for sine/cosine is hypotenuse
\dimen7\dimen2
%
% cosine \cd@num@a/\cd@num@b
\dimen6\wd1 \set@fraction\cd@num@a\numerator@\cd@num@b\denominator@
%
% sine = \numerator@/\denominator@
\dimen6\ht1 \set@fraction
%
% use \box2 for position of middle
\setbox2\null
\divide\dimen2\tw@
\advance\dimen2\snake@ % snake to right
\multiply@@{\dimen2}\wd2\dimen2 % the width
%
\dimen0.5\dimen7
\advance\dimen0\ifPositiveGradient\else-\fi\snake@ % snake up or down
\multiply@{\dimen0}%
\advance\dimen0-\axisheight % adjustment for maths axis
\ht2\dimen0
%
% crab adjustment (don't adjust for maths axis here)
\dimen0\crab@\multiply@@{\dimen0}\advance\dimen0\ht2\ht2\dimen0
\dimen0\ifPositiveGradient-\fi\crab@\multiply@{\dimen0}%
\advance\dimen0\wd2\wd2\dimen0
%
%
%
% use \box4 for amount by which to shift labels away from shaft
% this should agree with \baselikeskip in \label@horiz
% and the kerning of labels away from vertical arrows
\setbox4\null
\dimen0 .6\@em\multiply@@{\dimen0}\ht4\dimen0
\dimen0 .2\@em\multiply@{\dimen0}\wd4\dimen0
%
% local to this box:
% positive gradient | negative gradient
% \box0 the horizontal arrow to be stretched
% \box1 vector between the centres of the cells which the arrow links
% \box2 position of middle
% \box3 profile
% \box4 amount by which to shift labels away from shaft
% \box6 upper left label | upper right label
% \box7 lower right label | lower left label
% \dimen0
% \dimen1
% \dimen2 hypotenuse
% \dimen3 unsigned width of arrow
% \dimen4 snake correction for length of label
% \dimen5 scratch
% \dimen6 height of arrow
% \dimen7 hypotenuse
%
% upper label
\dimen0\wd2
\ifvoid6\else
\dimen1\ht4
%\iftrue
% \advance\dimen1\axisheight % try locating by maths axis
% \ifdim\dimen1<\dp6\dimen1\dp6\fi % but at least depth
%\fi % instead of base
\advance\dimen1\ht2
\correct@for@width 6+-% \dimen4 = .5\wd6 * \dimen3 / \dimen7
\raise\dimen1\rlap{%
\ifPositiveGradient
\advance\dimen0-\wd6\advance\dimen0-\wd4 % left
\else\advance\dimen0\wd4 %right
\fi
\kern\dimen0\box6}%
\fi
%
% lower label
\dimen0\wd2
\ifvoid7\else
\dimen1\ht4
%\iftrue
% \advance\dimen1\axisheight % try locating by maths axis
% \ifdim\dimen1<\ht7\dimen1\ht7\fi % but at least height
%\else
% \advance\dimen1\ht7 % instead of the top of the label box
%\fi
\advance\dimen1-\ht2
\correct@for@width 7-+%
\lower\dimen1\rlap{%
\ifPositiveGradient
\advance\dimen0\wd4 %right
\else\advance\dimen0-\wd7\advance\dimen0-\wd4 % left
\fi
\kern\dimen0\box7}%
\fi
%
% the arrow
\mv\box0\hss
}%
\ht0\z@\dp0\z@
%\output@cell{left width}{box}{right width}{raise}
\output@cell{\z@}{\box\z@}{\z@}{\axisheight}%
}%
%
\def\correct@for@width#1#2#3{% \dimen4 = .3\wd#1 * \dimen3 / \dimen7
%
% \dimen4 = effective half-width
\dimen4.5\wd#1
%\ifdim\dimen4<.5\@em\dimen4.5\@em\fi % unform correction for small labels
\ifdim\dimen4>.25\dimen7\dimen4=.25\dimen7\fi % cut-off for big ones
\ifdim\dimen4>\@em
\dimen4.4\dimen4 % reduce the correction for biggish ones
\advance\dimen4.6\@em % but make it continuous !
\fi
%
% the projection onto the shaft of the effective half-width
\multiply@@{\dimen4}%
%
% un-correct for the projection onto the shaft of the axis height
\dimen5\axisheight\multiply@{\dimen5}\advance\dimen4-\dimen5
%
% horizontal adjustment: apply *another* cosine factor
\dimen5\dimen4\multiply@@{\dimen5}%
\advance\dimen0\ifPositiveGradient#2\else#3\fi\dimen5
%
% vertical adjustment: apply sine factor
\multiply@{\dimen4}\advance\dimen1\dimen4
}
%
%
%=======================================================================%
% %
% (18) POSTSCRIPT AND TPIC ARROWS %
% %
%=======================================================================%
%
% from dvips.tex: (Rokicki)
% \def\rotninety{\special{ps:currentpoint currentpoint translate 90
% rotate neg exch neg exch translate}}%
% \font\huge=cmbx10 at 14.4truept
% \setbox0=\hbox to0pt{\huge A\hss}%
% \vskip16truept
% \centerline{%
% \copy0
% \special{ps:gsave}%
% \rotninety\copy0
% \rotninety\copy0
% \rotninety\box0
% \special{ps:grestore}}%
% \vskip16truept
% prints something like
% <A
% V>
% except that all four characters are A from cmbx10.
%
% from rotate.tex: (Rokicki again)
% These macros allow you to rotate or flip a \TeX\ box. Very useful for
% sideways tables or upsidedown answers.
%
% To use, create a box containing the information you want to rotate.
% (An hbox or vbox will do.) Now call \@rotr\boxnum to rotate the
% material and create a new box with the appropriate (flipped) dimensions.
% \@rotr rotates right, \@rotl rotates left, \@rotu turns upside down, and
% \@rotf flips. These boxes may contain other rotated boxes.
%
%\newdimen\@rotdimen
%\newbox\@rotbox
%
% idea: circular arcs
% ask Rokicki about portability
% idea; collect PS definitions at top of diagram \vbox
%
%\def\@vspec#1{\special{ps:#1}}% passes #1 verbatim to the output
%\def\@rotstart#1{\@vspec{gsave currentpoint currentpoint translate
% #1 neg exch neg exch translate}}% #1 can be any origin-fixing transformation
%\def\@rotfinish{\@vspec{currentpoint grestore moveto}}% gets back in synch
%
\def\expanded@ps@special#1{\expandafter\verbatim@ps@special{#1}}%
\cd@first@use\using@ps{output is PostScript dependent}%
%
\def\def@ps@turn{%\using@ps
\verbatim@ps@special{%
/bturn {%ascii % x y axisht on PS stack
gsave % save graphics state
currentpoint % push position
%#### 0 4 1 roll translate % fulcrum at axis height
currentpoint translate % move origin there
4 2 roll neg exch atan rotate % rotate baseline
% dvips doesn't know we've changed the coordinate system, so
neg exch neg exch translate % move origin back
} def
/eturn {currentpoint grestore moveto} def}}%ascii
\def\do@eturn{\relax\if@pdf@\pdf@literal{Q}\else\verbatim@ps@special{eturn}\fi}
%
%\def\diagonal@box(#1,#2)#3{%ascii COMPLETELY OBSOLETE - NO PDF VERSION
% \global\@need@PS@lib@true % define PS commands if necessary
% {\dimen0=#1\relax
% \dimen1=#2\relax
% \dimen4=\axisheight
% \raise\dimen4 %#### would prefer PS to do this
% \hbox{\expanded@ps@special{%
% \dim@in@pts{\dimen0}\space % x (could use number of cells instead)
% \dim@in@pts{\dimen1}\space % y
% %#### \dim@in@pts{\dimen4} \space % axis height
% bturn}%
% \Pythagorean@sum %\dimen2:=sqrt((\dimen0)^2+(\dimen1)^2)
% \lower\dimen4 %#### would prefer PS to do this
% \hbox to\dimen2{#3}% % output the text
% \do@eturn}% \verbatim@ps@special{eturn}}%
%}}%
%
% *********** TPIC \special commands *************
%
% see contrib/Vojta/xdvi/tpic.c aston/latex/contrib/eepic/eepic.sty
%
% pn <number> set pen size in thousandths of an inch (ugh!)
% fp flush path
% da <float> dashed line
% dt <float> dotted line
% pa <number> <number> add a point to the current path
% ar <n> <n> <n> <n> <f> <f> draw arc
% ia <n> <n> <n> <n> <f> <f> draw invisible arc
% sp flush spline
% sh shade last box circle or ellipse
% wh whiten ditto
% bk blacken ditto
%
% xdvi doesn't honour the widths of TPIC diagonal lines; dvips does
%
% convert #1 accurately to thousands of an inch in \count@
\def\set@mil#1{\count@#1\relax
\multiply\count@7\advance\count@16577\divide\count@33154 }%
%
\def\expanded@tpic@special#1{\expandafter\special{#1}}
%
%\def\tpic@pen@size{\begingroup\set@mil\intended@breadth
%\expanded@tpic@special{pn \the\count@}\endgroup}%
%
\def\tpic@make@line#1{\setbox#1=\hbox{%
\dimen0\dimen#1\multiply@{\dimen0}\set@mil{\dimen0}% \dimen0=height
\setbox0=\null
\ifPositiveGradient
\count@-\count@\ht0\dimen0
\else\dp0\dimen0
\fi
\box0 % strut
\cd@num@a\count@
\set@mil\intended@breadth\expanded@tpic@special{pn \the\count@}% set pen size
\expanded@tpic@special{pa 0 0}% start path here
\set@mil{\dimen#1}%
\expanded@tpic@special{pa \the\count@\space\the\cd@num@a}% path to here
\expanded@tpic@special{fp}% flush path
\kern\dimen#1}}%
%
%
%=======================================================================%
% %
% (19) TRIGONOMETRY %
% %
%=======================================================================%
% diagonal of A3 paper is 1027pt
% y=\dimen6 and x=\dimen7 non-negative
% \dimen2=+sqrt(y^2+x^2) to within 0.2% (?)
%
\def\Pythagorean@sum{%
\set@fraction
\begingroup
%
% make y=\dimen2=\dimen7 the larger and x=\dimen6 the smaller
\ifdim \dimen7<\dimen6
\dimen2=\dimen6
\dimen6=\dimen7
\dimen7=\dimen2
\count@\numerator@
\numerator@\denominator@
\denominator@\count@
\else
\dimen2=\dimen7
\fi
%
% nothing to do if x=0
\ifdim\dimen6>.01\p@
\@pyth@sum
\global\cd@dim@g\dimen0
\else
\global\cd@dim@g\dimen7
\fi
\endgroup
\dimen2\cd@dim@g
\make@division\num@@{\ifPositiveGradient\else-\fi\dimen6}%
\make@division\mnum@@{\ifPositiveGradient-\fi\dimen6}%
%\make@division\mdenom@@{\ifPositiveGradient-\fi\dimen7}%
\make@division\denom@@{\dimen7}%
}%
%
\def\@pyth@sum{%
\square@fraction% n/d = x^2/y^2
%
\ifdim \dimen7>1.73\dimen6 % 1.73=sqrt(3)=sec(30deg)
%\then % y>>x: use power series in u=x^2/2y^2: z=y'(4+4u-2u^2+2u^3) y'=y/4
\divide\dimen2 4 % x'=\dimen2=y/4
\multiply\denominator@ 2
\else
% y~x: use same series but in u=(x^2-y^2)/4y^2 with y'=y/(sqrt 8)
\dimen2=0.353553\dimen2 % \dimen2=y'=y/(sqrt 8)
\advance\numerator@-\denominator@
\multiply\denominator@ 4
\fi
%
% now have
% x'=\dimen2<341pt
% calculate
% z=x'(4+4u-2u^2+2u^3-(5/2)u^4) in \dimen0 as accumulator
%
\dimen0=4\dimen2 % worst case:
\monomial@ 4% <250pt
\monomial@{-2}% < 20pt
\monomial@ 2% < 3.5pt typically 0.2pt
\monomial@{-2.5}% < 0.66pt drowned by rounding errors
%\monomial@{3.5}% < 0.16pt
%\monomial@{-2.375}% < 0.018pt pixel at 1200dpi is 0.06pt
%\monomial@{2.0675}% < 0.0025pt
}%
%
% \dimen0 is the angle using points for degrees
% \dimen1 the hypotenuse
% y=\dimen6 x=\dimen7 returned
%
\def\polar@to@rect{\begingroup
% reduce \dimen0 to between 0 and 45, and \count@ to number of octants
\count@\dimen0
\dimen2 45pt
\divide\count@\dimen2
\ifdim\dimen0<\z@\advance\count@\m@ne\fi
\ifodd\count@\advance\count@ 1\@cd@a@true\else\@cd@a@false\fi
\advance\dimen0-\count@\dimen2
\if@cd@a@\multiply\dimen0\m@ne\fi
\ifnum\count@<0 \multiply\count@-7 \fi
%
% save hypotenuse (the first term of cosine)
\dimen3\dimen1
\dimen6\dimen0
\dimen7 3754936sp
\ifdim\dimen0<6\p@\def\max@fraction{4000}\fi
\set@fraction % \numerator@/\denominator@ is angle in radians
%
% set first term of sine
\dimen2\dimen3\multiply@{\dimen2}%
%
% calculate multiplier: u=-x^2/6 where x is angle in radians
% not too good for cosines of angles between 1 and 4 degrees.
\square@fraction
\multiply\denominator@-6
%
% compute sin x = x-x^3/6+x^5/120 = x (1+u+(0.3)u^2)
\dimen0\dimen2
\monomial@ 1%
\monomial@{0.3}%
\dimen1\dimen0
%
% compute cos x = 1-x^2/2+x^4/24-x^6/720 = 1+3u+(1.5)u^2+(0.3)u^3
\dimen2\dimen3
\dimen0\dimen3
\monomial@ 3%
\monomial@{1.5}%
\monomial@{0.3}%
%
% swap sin/cos and change sign appropriately
\divide\count@2
\if@cd@a@\multiply\dimen1\m@ne\fi
\ifodd\count@\dimen2\dimen1\dimen1\dimen0\dimen0-\dimen2 \fi
\divide\count@2
\ifodd\count@\multiply\dimen0\m@ne\multiply\dimen1\m@ne\fi
%
% export
\global\cd@dim@g\dimen0\global\cd@dim@h\dimen1\endgroup
\dimen6\cd@dim@g\dimen7\cd@dim@h}%
%
% ****************** continued fraction approximation ********************
%
% set \numerator@/\denominator@ to nearest rational to \dimen6/\dimen7
% with both at most \max@fraction
\def\default@max@fraction{255}\let\max@fraction\default@max@fraction
\def\set@fraction{\begingroup
\ifdim\dimen7<\dimen6
\dimen9\dimen7\dimen7\dimen6\dimen6\dimen9\@cd@a@true
\else
\@cd@a@false
\fi
\dimen2\z@ \dimen3\one@sp % b=0 b'=1 initialisation
\dimen4\one@sp\dimen0\z@ % c=1 c'=0
\dimen8=\max@fraction\one@sp % d tolerance
\do@cont@frac
\global\cd@num@g\dimen\if@cd@a@ 0\else3\fi
\global\cd@num@h\dimen\if@cd@a@ 3\else0\fi
\endgroup
\numerator@\cd@num@g\denominator@\cd@num@h}%
%
\def\do@cont@frac{%
\count@\dimen6
\divide\count@\dimen7 % u := a/a' new quotient
\advance\dimen6-\count@\dimen7 % a -:= ua' reduced data
\dimen9\dimen4
\advance\dimen9\count@\dimen0 % c" := c+uc' trial denominator
%
\ifdim\dimen9>\dimen8 % overflow
\cont@frac@done
\else
\cont@frac@swap % b,b':=b',ub'+b; c,c':=c',c"
\ifdim\dimen6>\z@ % if it's spot on return, else
\dimen9\dimen6 % a,a':=a',a
\dimen6\dimen7
\dimen7\dimen9
\expandafter\expandafter\expandafter
\do@cont@frac % carry on
\fi\fi}% result ends up as b'/c'
%
% When we've gone over the limit, but not twice, there's still a better
% approximation than the previous one, obtained by adjusting the quotient.
%
% Suppose b/c b'/c' and (b"=ub'+b)/(c"=uc'+c) are successive continued
% fraction approximants to r with c'<=d<c". Then any rational number p/q
% between b/c and b'/c' is at least as far away from r as p'/q where p'=vb'+b
% and q=vc'+c. We want v to be an integer such that q<=d. Is this closer
% than b/c (on the other side)? Yes if (p'/q) is less than twice as far from
% b/c as r is, which reduces to (a/a')<2v+(c/c'). This happens if u<2v.
% (It also happens if u=2v and a"c'<a'c, equivalently ac'<a'c", but we ignore
% this case.)
%
% If c'=0 d<c"<=2d then 1/d is the best approximant.
%
\def\cont@frac@done{%
\ifdim\dimen0=\z@ %
\ifdim\dimen9<2\dimen8 % if c'=0 (so b'=1) and d<=c"<2d
\dimen0\dimen8 % choose d/1
\fi
\else
\advance\dimen8-\dimen4
\divide\dimen8\dimen0 % v := (d-c)/c' smaller quotient
\ifdim\count@\one@sp<2\dimen8 % if u<2v there's a better approximation:
\count@\dimen8
\dimen9\dimen4
\advance\dimen9\count@\dimen0 % c" := c+vc' recalculate denominator
\cont@frac@swap % and numerator, and swap
\fi\fi
}%
%
\def\cont@frac@swap{%
\dimen4\dimen0
\dimen0\dimen9
\advance\dimen2\count@\dimen3
\dimen9\dimen2
\dimen2\dimen3
\dimen3\dimen9
%\n\dimen3 \m\dimen0 \expandafter\message{\the\n/\the\m}%
}%
%
% \dimen2 *:= \numerator@/\denominator@
% \dimen0 +:= (#1)*(\dimen2)
\def\monomial@#1{%
\multiply@{\dimen2}%
\advance\dimen0 #1\dimen2
}%
%
\def\multiply@ #1{\divide#1\denominator@\multiply#1\numerator@}%
\def\multiply@@#1{\divide#1\cd@num@b\multiply#1\cd@num@a}%
\def\divide@ #1{\divide#1\numerator@ \multiply#1\denominator@}%
%
\def\square@fraction{%
\dimen6\numerator@ \one@sp\multiply\dimen6\numerator@
\dimen7\denominator@\one@sp\multiply\dimen7\denominator@
\set@fraction}%
%
\def\make@division#1#2{%
\begingroup
\dimen@#2\relax
\loop
\ifdim\dimen2<.4\maxdimen
\multiply\dimen2\tw@
\multiply\dimen@\tw@
\repeat
\divide\dimen2\@cclvi
\divide\dimen@\dimen2\relax
\multiply\dimen@\@cclvi
\expandafter\mk@@div\the\dimen@
\endgroup
%\expandafter\message{make@division=\div@@}%
\let#1\div@@}%
% %% this is a mega-hack for extracting as text the value of a \dimen in points
{\catcode`p=12 \catcode`0=12 \catcode`.=12 \catcode`t=12
\gdef\mk@@div#1pt{\gdef\div@@{#1}}}%
%
%=======================================================================%
% %
% (20) PDFTEX SUPPORT %
% %
%=======================================================================%
%
% See /usr/share/doc/texmf/pdftex/base/example.tex
% or http://www.tug.org/applications/pdftex/
% or ftp://ftp.cstug.cz/pub/tex/local/cstug/thanh/pdftex-testing/latest
%
% \newdimen\d
% \newbox\b
% \def\avoidboxdimen#1{%
% \setbox\b=\hbox{\box#1}%
% \wd\b=0pt
% \ht\b=0pt
% \dp\b=0pt
% \box\b}
%
% % rotation by `t' degrees counterclockwise is specified as
% % `cos(t) sin(t) -sin(t) cos(t) 0 0'.
% \def\rotate@pdf{%
% \vskip\wd0
% \leftline{\hskip\ht0\hskip\dp0%
% \pdf@literal{q 0 1 -1 0 0 0 cm}%
% \avoidboxdimen0%
% \pdf@literal{Q}}}
%
%=======================================================================%
% %
% (21) ERROR RECOVERY %
% %
%=======================================================================%
%
% Would be nice if we could get the error context to contain EXACTLY the
% information we want to show, in particular the inserted text as the next
% text to be input. [Could use \futurelet to show "to be read again"]
\ifx\errorcontextlines\undefined
\then \let\no@error@context\relax
\else \def\no@error@context{\errorcontextlines\m@ne}%
\fi
\ifnum\inputlineno<0
% null input line strings if the info is not available
\let\end@at@line\empty
\let\at@line\empty
\let\first@occur\relax
\let\save@begin@at@line\relax
\let\save@cell@at@line\relax
\let\make@end@at@line\relax
\message{! Why not upgrade to TeX version 3? (available since 1990)}%ascii
\else% input line number messages
\def\at@line{ at line \number\inputlineno}%
\def\first@occur{ - first occurred}%
\def\save@begin@at@line{%
\edef\begin@at@line{\the\inputlineno}%
\global\let\cell@at@line\begin@at@line
}%
\def\begin@at@line{9999}%
% changed \edef to \xdef 15.4.95
\def\save@cell@at@line{%
%\expandafter\message
%{cell (\the\cd@row,\the\cd@cell) at \cell@at@line--\the\inputlineno}%
\xdef\cell@at@line{\the\inputlineno}%
}%
\def\cell@at@line{\begin@at@line}%
\def\make@end@at@line{%
\ifnum\begin@at@line<\inputlineno
\edef\end@at@line{\space at lines \begin@at@line--\the\inputlineno}%
\else\edef\end@at@line{\at@line}%
\fi}%
\fi
\let\end@at@line\empty
%
%
% first pass error (so can stop and give help)
\def\cd@error#1#2{\no@error@context
\errhelp=#2\expandafter\errmessage{\cd@name: #1}}%
%
% second pass error (too late to correct it)
\def\cd@refmt@error#1{\begingroup
\expandafter\message{! \cd@name: #1\end@at@line}%ascii
\ifnum\cd@top>\cd@row
\ifnum\cd@bottom>\cd@row\else
\ifnum\cd@left>\cd@cell\else
\ifnum\cd@right>\cd@cell
% these are ok 'cos we're in a \begingroup...\endgroup
\advance\cd@top-\cd@row
\advance\cd@cell-\cd@left
\advance\cd@cell 1\relax
\expandafter\message{! (error detected at row \the\cd@top, % ascii
column \the\cd@cell, but probably caused elsewhere)}% ascii
\fi\fi\fi\fi
\endgroup}%
%
% warning
\def\cd@warning#1{{%
\expandafter\message{\cd@name\space Warning: #1\at@line}%
}}%
%
\def\cd@obs@msg#1#2{\cd@warning{#1 \string#2 is obsolete\first@occur}}%
\def\cd@obs@dim#1{\cd@obs@msg{Dimension}{#1}%
\glet#1\cd@obs@dimq\cd@obs@dimq}%
\def\cd@obs@dimq{\cd@dim@a=}%
\def\cd@obs@count#1{\cd@obs@msg{Count}{#1}\glet#1\@obs@countq\@obs@countq}%
\def\@obs@countq{\count@=}%
%
\def\HorizontalMapLength{\cd@obs@dim\HorizontalMapLength}%
\def\VerticalMapHeight{\cd@obs@dim\VerticalMapHeight}%
\def\VerticalMapDepth{\cd@obs@dim\VerticalMapDepth}%
\def\VerticalMapExtraHeight{\cd@obs@dim\VerticalMapExtraHeight}%
\def\VerticalMapExtraDepth{\cd@obs@dim\VerticalMapExtraDepth}%
\def\DiagonalLineSegments{\cd@obs@count\DiagonalLineSegments}%
%
%\def\spew#1{%
%\expandafter\message{#1}%
%\message{hbox0: remainder of line}\showbox0
%\message{vbox1: remainder of matrix}\showbox1
%\message{hbox2: donations from below}\showbox2
%\message{hbox3: completed verticals}\showbox3
%\message{hbox4: completed row}\showbox4
%\message{hbox5: donations upwards}\showbox5
%\message{hbox6: scratch}\showbox6
%\message{box7: donation from left}\showbox7
%\message{box8: donation from below}\showbox8
%\message{box9: scratch}\showbox9
%\message{current lists}\showlists
%}%
%
% check whether \font\tenln=line10 is really there
\ifx\tenln\nullfont
\cd@first@use\no@tenln{\LaTeX@name\space diagonal line and arrow font
not available}%
\else
\let\no@tenln\relax
\fi
%
% #1=have, #2=need,
% #6=accumulator, #7=do if OK (\cd@dim@a,\count@ scratch)
%
% #1=h,v,l,r; #2=have; #3=need; #4=message; #5=from row/col; #6=to row/col
\def\more@dim#1#2<#3:#4:#5#6{%
\begingroup
\cd@dim@b#3\relax\advance\cd@dim@b-#2\relax
\ifdim.1em<\cd@dim@b % ignore small amounts
\cd@num@a#5\relax
\cd@num@b#6\relax
\ifnum\cd@num@a<\cd@num@b
\count@\cd@num@b\advance\count@-\cd@num@a
\cd@refmt@error{#4 by \the\cd@dim@b}%
\if#1v%
\let\next\vert@extra
\edef\tmp{\the\cd@num@a--\the\cd@num@b,\the\cd@cell}%
\else % horizontal: correction for \across
\advance\count@\count@
\if#1l\advance\count@-\across@cells
\else\if#1r\advance\count@\across@cells
\fi\fi
\advance\cd@dim@b\cd@dim@b
\let\next\horiz@extra
\edef\tmp{\the\cd@row,\the\cd@num@a--\the\cd@num@b}%
\fi
%\cd@refmt@error
%{#4 by \the\cd@dim@b\space at (\tmp)-(\the\cd@top,\the\cd@left)}%
\divide\cd@dim@b\count@
\ifdim\next<\cd@dim@b\global\next\cd@dim@b\fi
\fi \fi
\endgroup
}%
%
%
%================== erroneous occurences of \enddiagram ================
%
% \diagram\egroup\enddiagram (where \enddiagram may be inserted by \par)
% still causes trouble. same may also apply to \pile
%
% check no of lines since beginning of cell?
\new@if\if@end@diagram@ok@\@end@diagram@ok@true\@end@diagram@ok@false %global
\new@help\see@above{See the message above.}%
\new@help\par@not@allowed{Perhaps you've forgotten to end the diagram
before resuming the text, in\new@line which case some garbage may be added
to the diagram, but we should be ok now.\new@line Alternatively you've
left a blank line in the middle - TeX will now complain\new@line that the
remaining \and@name s are misplaced - so please use comments for layout.}%
\new@help\fated@enddiagram{You have already closed too many brace pairs or
environments; an \end@diagram@name\new@line command was (over)due.}%ascii
\new@help\pair@diagram@end{\diagram@name\space and \end@diagram@name\space
commands must match.}%
%
% (TeXbook p205) any runaway argument ended by \par is discarded
% and replaced by \par alone;
%
% Blank line in the middle of a diagram.
% Ignore (with message) if interactive (\inputlineno=0)
\def\par@enddiagram{%
\ifnum \inputlineno=0
%\then \expandafter\interactive@par@endcd
\else \expandafter\@par@enddiagram
\fi}%
%
\def\@par@enddiagram{%
\end@label % terminate label
\enddiagram@endpile % and \pile if necessary
\crcr % terminate row of matrix
\cd@error{missing \end@diagram@name\space inserted before \par@name -
type "h"}%ascii
\par@not@allowed
\enddiagram % terminate diagram
\make@found@end@diagram\par@name
\par}% % try again to end the paragraph, or whatever we wanted to do
%
% No point - can't seem to suppress the similar (vir)TeX message.
%\def\interactive@par@endcd{\expandafter\message
%{Please type a diagram command or say `\end@diagram@name'}}%
%
\def\make@found@end@diagram#1{%
\edef\enddiagram{\noexpand\found@end@diagram{#1\at@line}}}%
%
\def\found@end@diagram#1{%
\cd@error{\end@diagram@name\space (anticipated by #1) ignored}%ascii
\see@above\let\enddiagram\misplaced@enddiagram}%
%
\def\misplaced@enddiagram{%
\cd@error{misplaced \end@diagram@name\space ignored}\pair@diagram@end}%
%
\def\do@fated@enddiagram{%
\cd@error{missing \end@diagram@name\space inserted.}\fated@enddiagram
\make@found@end@diagram{closing group}}%
%
% Support for LaTeX2e \usepackage options.
% We don't use the official mechanism (\DeclareOption{name}{code}) because
% it deletes the code and does not handle our name=value construct.
% Instead we pick up everything using the LaTeX2e default option mechanism,
% which provides the user's options to us one by one as \CurrentOption.
% This doesn't pick up the \documentclass options.
%
\ifx\DeclareOption\undefined\else\ifx\DeclareOption\@notprerr\else
\DeclareOption*{%ascii
\let\after@opt@arg\relax\let\next@opt@arg\relax
\expandafter\@@getoptarg\CurrentOption,%
}%
%\AtEndOfPackage{%
%\@was@pair@false
%\ProcessOptions\relax
%\if@was@pair@\bad@pair@opt\fi
%}%
\fi\fi
%
%%======================================================================%
%% %
%% (22) AUXILLARY MACROS FOR ADJUSTMENT OF COMPONENTS %
%% %
%%======================================================================%
%% NOTE: The recommended way of defining arrow commands is now
%% \newarrow{Name}{tail}{filler}{middle}{filler}{head}
%% which defines \rName, \lName, \dName and \uName using arrow parts which
%% have themselves previously been defined using the commands
%% \newarrowtail, \newarrowfiller, \newarrowmiddle and \newarrowhead.
%% The components \rhvee etc have been retained for the time being, as an
%% intermediate stage and to continue to support the old \HorizontalMap and
%% \VerticalMap commands, but you should not rely on the continued existence
%% of these macros.
%% The various components usually need some correction
%% - longitudinally, ie to prevent gaps and overprints with the shaft,
%% - transversally, ie to prevent "steps" in the junction with the shaft.
%% The former can be done safely ad hoc, eg with \mkern1mu.
%% The latter are now done with the macros \scriptaxis, \boldscriptaxis,
%% \shifthook and \raisehook, which include pixel corrections.
%% Please note that these and the other auxillary macros which follow are
%% interim. When it becomes clear exactly what kinds of adjustments are
%% needed for characters, this job will be done by a suitable extension
%% to the language of \newarrowhead, etc. If you have any other ideas for
%% transformations of general use please tell me.
%% By all means experiment with other characters for arrowheads, but
%% please, in your own interests, do not rely on macros like \rhvee,
%% send me a copy of your definitions for distribution to other users
%% in this file, and keep track of where your efforts get copied so
%% that they can be replaced with the "official" version when it is
%% incorporated.
%% ***** DONT use macros with mangled names like \Cd@gH. *****
\catcode`\$=3 %% make sure that $ means maths-shift
\def\vboxtoz{\vbox to\z@}%% \z@ is in plain TeX and means 0pt
%\def\ulapm#1{\vboxtoz{\vss\hbox{$#1$}\kern\z@}%
%\def\dlapm#1{\vboxtoz{\kern\z@\hbox{$#1$}\vss\kern\z@}%
%% print #1 in \scriptstyle, adjusting for the maths axis height
\def\scriptaxis#1{\@scriptaxis{$\scriptstyle#1$}}%%
\def\ssaxis#1{\@ssaxis{$\scriptscriptstyle#1$}}%%
\def\@scriptaxis#1{%
\dimen0\axisheight\advance\dimen0-\ss@axisheight%
\raise\dimen0\hbox{#1}}%
\def\@ssaxis#1{%
\dimen0\axisheight\advance\dimen0-\ss@axisheight%
\raise\dimen0\hbox{#1}}%
%% Some of the characters would look better in bold since they're
%% taken from sub/superscript fonts; we use LaTeX's \boldmath to
%% do this, defining this to do nothing if it doesn't exist.
%% With the old LaTeX font selection at other than 10pt you may still
%% get nothing happenning. Also, PK fonts may be missing.
%% If you have problems, DONT use boldhook or boldlittlevee.
\ifx\boldmath\undefined%%
\let\boldscriptaxis\scriptaxis%%
\def\boldscript#1{\hbox{$\scriptstyle#1$}}%%
\def\boldscriptscript#1{\hbox{$\scriptscriptstyle#1$}}%%
\else\def\boldscriptaxis#1{\@scriptaxis{\boldmath$\scriptstyle#1$}}%%
\def\boldscript#1{\hbox{\boldmath$\scriptstyle#1$}}%%
\def\boldscriptscript#1{\hbox{\boldmath$\scriptscriptstyle#1$}}%%
\fi
%% #1= {} or \boldmath; #2= + or -; #3=\subset or \supset
\def\raisehook#1#2#3{\hbox{%
\setbox3=\hbox{#1$\scriptscriptstyle#3$}%% the character to use
\dimen0\ss@axisheight%% \scriptscriptstyle axis height
\dimen1\axisheight\advance\dimen1-\dimen0%% difference in axis heights
\dimen2\ht3\advance\dimen2-\dimen0%% height of char above axis (half spread)
\advance\dimen2-0.021em% \raisehookfudge used in THM 9.4.2 of my book
%\advance\dimen2-.5\rounded@breadth% (dont) need to adjust for rule thickness
\advance\dimen1 #2\dimen2%% shift = axis_difference +/- half_spread
%\expandafter\message{\the\dimen1}%
\raise\dimen1\box3}}%% print the character
%
%\expandafter\message{\new@line\new@line raisehook fudged by \the\raisehookfudge\new@line\new@line}%
%
%% Mark Dawson suggested using the width
% see sym.mf for MetaFont definitions of \cup and \cap (12u wide)
% subtract 2u from its width to remove the MF-encoded margin
% also subtract \rounded@breadth to match up the shaft
% except that 2\rounded@breadth seems to work better (9.7.98)
% ptbook+boldmath+box0 gave a strut, so changed to \box1 (9.7.98)
\def\shifthook#1#2#3{% #1= {} or \boldmath; #2= + or - #3= \cup or \cap
\setbox1=\hbox{#1$\scriptscriptstyle#3$}% the character
\dimen0\wd1\divide\dimen0 12\pixel@round{\dimen0}%% "u"
\dimen1\wd1\advance\dimen1-2\dimen0
%\advance\dimen1-2\intended@breadth
\advance\dimen1-2\rounded@breadth
\pixel@round{\dimen1}%
\kern#2\dimen1\box1}%% print
%% use the extension font (cmex) for double vertical arrows
% and braces
\def\@cmex{\mathchar"03}%%ascii double quote
%% ************* P U L L B A C K S ************
%% These will probably be replaced by something less ad hoc
%% in a future version.
\def\make@pbk#1{\setbox\tw@\hbox to\z@{#1}\ht\tw@\z@\dp\tw@\z@\box\tw@}%
\def\overprint@pbk#1{\overprint{\hbox to\z@{#1}}}%
\def\pbk@sh{\kern0.11em}\def\pbk@osh{\kern0.35em}%
%% This is a hack for my book ``Practical Foundations of Mathematics''
%% and WILL NOT BE SUPPORTED --- DO NOT USE IT!
\def\dblvert{\def\pbk@shsh{\kern .5\PileSpacing}}\def\pbk@shsh{}%
\def\SEpbk{\make@pbk{%
\pbk@sh\pbk@shsh
\vrule depth 2.87ex height -2.75ex width 0.95em
\vrule height -0.66ex depth 2.87ex width 0.05em
\hss
}}
\def\SWpbk{\make@pbk{%
\hss
\vrule height -0.66ex depth 2.87ex width 0.05em
\vrule depth 2.87ex height -2.75ex width 0.95em
\pbk@sh\pbk@shsh
}}
\def\NEpbk{\make@pbk{%
\pbk@sh\pbk@shsh
\vrule depth -3.81ex height 4.00ex width 0.95em
\vrule height 4.00ex depth -1.72ex width 0.05em
\hss
}}
\def\NWpbk{\make@pbk{%
\hss
\vrule height 4.00ex depth -1.72ex width 0.05em
\vrule depth -3.81ex height 4.00ex width 0.95em
\pbk@sh\pbk@shsh
}}
%% Freyd & Scedrov puncture symbol for non-commuting polygon
\def\puncture{{\setbox0\hbox{A}%
\vrule height.53\ht0 depth-.47\ht0 width.35\ht0
\kern .12\ht0
\vrule height\ht0 depth-.65\ht0 width.06\ht0
\kern-.06\ht0
\vrule height.35\ht0 depth0pt width.06\ht0
\kern .12\ht0
\vrule height.53\ht0 depth-.47\ht0 width.35\ht0
}}%
%% 2-cells: (24.11.95)
%% \NEclck puts a clockwise (ie southeast) arrow to the northwest of cell etc
\def\NEclck{\overprint{\raise2.5ex\rlap{ \pbk@shsh$\scriptstyle\searrow$}}}%%
\def\NEanti{\overprint{\raise2.5ex\rlap{ \pbk@shsh$\scriptstyle\nwarrow$}}}%%
\def\NWclck{\overprint{\raise2.5ex\llap{$\scriptstyle\nearrow$ \pbk@shsh}}}%%
\def\NWanti{\overprint{\raise2.5ex\llap{$\scriptstyle\swarrow$ \pbk@shsh}}}%%
\def\SEclck{\overprint{\lower1ex\rlap{ \pbk@shsh$\scriptstyle\swarrow$}}}%%
\def\SEanti{\overprint{\lower1ex\rlap{ \pbk@shsh$\scriptstyle\nearrow$}}}%%
\def\SWclck{\overprint{\lower1ex\llap{$\scriptstyle\nwarrow$ \pbk@shsh}}}%%
\def\SWanti{\overprint{\lower1ex\llap{$\scriptstyle\searrow$ \pbk@shsh}}}
%%======================================================================%
%% %
%% (23) BITS OF ARROWS %
%% %
%%======================================================================%
%% ********** H E A D S ***********
%% \diagramstyle[heads=xxx] defines {>} as {xxx} where xxx
%% has been defined by \newarrowhead{xxx} and \newarrowtail{xxx}
%% vee head
\def\rhvee{\mkern-10mu\greaterthan}%%
\def\lhvee{\lessthan\mkern-10mu}%%
\def\dhvee{\vboxtoz{\vss\hbox{$\vee$}\kern0pt}}%%
\def\uhvee{\vboxtoz{\hbox{$\wedge$}\vss}}%%
\newarrowhead{vee}\rhvee\lhvee\dhvee\uhvee
%% little vee head
\def\dhlvee{\vboxtoz{\vss\hbox{$\scriptstyle\vee$}\kern0pt}}%%
\def\uhlvee{\vboxtoz{\hbox{$\scriptstyle\wedge$}\vss}}%%
\newarrowhead{littlevee}{\mkern1mu\scriptaxis\rhvee}%
{\scriptaxis\lhvee}\dhlvee\uhlvee
\ifx\boldmath\undefined%%
\newarrowhead{boldlittlevee}{\mkern1mu\scriptaxis\rhvee}%
{\scriptaxis\lhvee}\dhlvee\uhlvee
\else%%
\def\dhblvee{\vboxtoz{\vss\boldscript\vee\kern0pt}}%%
\def\uhblvee{\vboxtoz{\boldscript\wedge\vss}}%%
\newarrowhead{boldlittlevee}{\mkern1mu\boldscriptaxis\rhvee}%
{\boldscriptaxis\lhvee}\dhblvee\uhblvee%%
\fi
%% curly vee head (uses AMS symbols fonts)
\def\rhcvee{\mkern-10mu\succ}%%
\def\lhcvee{\prec\mkern-10mu}%%
\def\dhcvee{\vboxtoz{\vss\hbox{$\curlyvee$}\kern0pt}}%%
\def\uhcvee{\vboxtoz{\hbox{$\curlywedge$}\vss}}%%
\newarrowhead{curlyvee}\rhcvee\lhcvee\dhcvee\uhcvee
%% double vee head %% will probably be withdrawn later
\def\rhvvee{\mkern-13mu\gg}%% 24.8.92 changed 10mu to 13mu
\def\lhvvee{\ll\mkern-13mu}%% to make rule go through
\def\dhvvee{\vboxtoz{\vss\hbox{$\vee$}\kern-.6ex\hbox{$\vee$}\kern0pt}}%%
\def\uhvvee{\vboxtoz{\hbox{$\wedge$}\kern-.6ex
\hbox{$\wedge$}\vss}}%%
\newarrowhead{doublevee}\rhvvee\lhvvee\dhvvee\uhvvee
%% open and closed triangles (uses AMS symbols fonts)
\def\triangleup{{\scriptscriptstyle\bigtriangleup}}%%
\def\littletriangledown{{\scriptscriptstyle\triangledown}}%% AMS
\def\rhtriangle{\triangleright\mkern1.2mu}%% 29.1.93
\def\lhtriangle{\triangleleft\mkern.8mu}%%
\def\uhtriangle{\vbox{%
\kern-.2ex % 15.1.93 from -.05ex
\hbox{$\scriptscriptstyle\bigtriangleup$}%
\kern-.25ex}}%%
%% Changed \scriptstyle\triangledown to \scriptscriptstyle\bigtriangledown
%% at the suggestion of Martin Hofmann (25.11.92) to avoid using AMS symbols
%% and also for compatibility with upward arrow.
\def\dhtriangle{\vbox{%
\kern-.28ex % 15.1.93 from -.25
\hbox{$\scriptscriptstyle\bigtriangledown$}%
\kern-.1ex}}%% 15.1.93 from -.25ex
\def\dhblack{\vbox{\kern-.25ex\nointerlineskip
\hbox{$\blacktriangledown$}}}%% AMS
\def\uhblack{\vbox{\kern-.25ex\nointerlineskip
\hbox{$\blacktriangle$}}}%% AMS
\def\dhlblack{\vbox{\kern-.25ex\nointerlineskip
\hbox{$\scriptstyle\blacktriangledown$}}}%% AMS
\def\uhlblack{\vbox{\kern-.25ex\nointerlineskip
\hbox{$\scriptstyle\blacktriangle$}}}%% AMS
\newarrowhead{triangle}\rhtriangle\lhtriangle\dhtriangle\uhtriangle
\newarrowhead{blacktriangle}{\mkern-1mu\blacktriangleright\mkern.4mu}% 29.1.93
{\blacktriangleleft}\dhblack\uhblack
\newarrowhead{littleblack}{\mkern-1mu\scriptaxis\blacktriangleright}%
{\scriptaxis\blacktriangleleft\mkern-2mu}\dhlblack\uhlblack
%% LaTeX arrowheads
\def\rhla{\hbox{\setbox0=\lnchar55\dimen0=\wd0%
\kern-.6\dimen0\ht0\z@ % 15.1.93 from -.5; also smashed height
\raise\axisheight\box0\kern.1\dimen0}}%%
\def\lhla{\hbox{\setbox0=\lnchar33\dimen0=\wd0%
\kern.05\dimen0\ht0\z@ % 15.1.93 from -.1; also smashed height
\raise\axisheight\box0\kern-.5\dimen0}}%%
\def\dhla{\vboxtoz{\vss\rlap{\lnchar77}}}%%
\def\uhla{\vboxtoz{\setbox0=\lnchar66 \wd0\z@\kern-.15\ht0\box0\vss}}%% 1/93
\newarrowhead{LaTeX}\rhla\lhla\dhla\uhla
%% double LaTeX arrowheads %% will probably be withdrawn later
\def\lhlala{\lhla\kern.3em\lhla}%%
\def\rhlala{\rhla\kern.3em\rhla}%%
\def\uhlala{\hbox{\uhla\raise-.6ex\uhla}}%%
\def\dhlala{\hbox{\dhla\lower-.6ex\dhla}}%%
\newarrowhead{doubleLaTeX}\rhlala\lhlala\dhlala\uhlala
%% circles % \rho is a Greek letter!
\def\hhO{\scriptaxis\bigcirc\mkern.4mu}
\def\hho{{\circ}\mkern1.2mu}%
\newarrowhead{o}\hho\hho\circ\circ%%
\newarrowhead{O}\hhO\hhO{\scriptstyle\bigcirc}{\scriptstyle\bigcirc}%%
%% crosses
\def\rhtimes{\mkern-5mu{\times}\mkern-.8mu}%
\def\lhtimes{\mkern-.8mu{\times}\mkern-5mu}%
\def\uhtimes{\setbox0=\hbox{$\times$}\ht0\axisheight\dp0-\ht0\lower\ht0\box0 }%
\def\dhtimes{\setbox0=\hbox{$\times$}\ht0\axisheight\box0 }%
\newarrowhead{X}\rhtimes\lhtimes\dhtimes\uhtimes
\newarrowhead+++++%ascii
%% empty head {} is also available
%% Y from stmaryrd (vertical ones still need large adjustment)
% \Yup and \Ydown swapped 26.2.2007
\newarrowhead{Y}{\mkern-3mu\Yright}{\Yleft\mkern-3mu}\Ydown\Yup
%% ********** H E A D S with S H A F T S ***********
%% little arrow with shaft
\newarrowhead{->}\rightarrow\leftarrow\downarrow\uparrow
%% arrow with double shaft
%%\newarrowhead{=>}\Rightarrow\Leftarrow\Downarrow\Uparrow
\newarrowhead{=>}\Rightarrow\Leftarrow{\@cmex7F}{\@cmex7E}% 16.1.93
%% harpoon with shaft (trailing up/left can be changed to down/right)
% shift verticals to balance! ######## (uses AMS symbols fonts)
\newarrowhead{harpoon}\rightharpoonup\leftharpoonup\downharpoonleft
\upharpoonleft
%% little double-headed arrow with shaft (uses AMS symbols fonts)
\def\twoheaddownarrow{\rlap{$\downarrow$}\raise-.5ex\hbox{$\downarrow$}}%%
\def\twoheaduparrow{\rlap{$\uparrow$}\raise.5ex\hbox{$\uparrow$}}%%
\newarrowhead{->>}\twoheadrightarrow\twoheadleftarrow\twoheaddownarrow
\twoheaduparrow
%% ********** T A I L S ***********
%% vee tail
\def\rtvee{\greaterthan}%%
\def\ltvee{\mkern-1mu{\lessthan}\mkern.4mu}%% \mkern added 15.1.93
%\def\dtvee{\vboxtoz{\vss\hbox{$\vee$}\kern0pt}}%%
%\def\utvee{\vboxtoz{\hbox{$\wedge$}\vss}}%%
\def\dtvee{\vee}%%
\def\utvee{\wedge}%%
\newarrowtail{vee}\greaterthan\ltvee\vee\wedge
%% little vee tail
\newarrowtail{littlevee}{\scriptaxis\greaterthan}%
{\mkern-1mu\scriptaxis\lessthan}%
{\scriptstyle\vee}{\scriptstyle\wedge}%
\ifx\boldmath\undefined
\newarrowtail{boldlittlevee}{\scriptaxis\greaterthan}%
{\mkern-1mu\scriptaxis\lessthan}%
{\scriptstyle\vee}{\scriptstyle\wedge}%
\else
\newarrowtail{boldlittlevee}{\boldscriptaxis\greaterthan}%
{\mkern-1mu\boldscriptaxis\lessthan}%
{\boldscript\vee}{\boldscript\wedge}%
\fi
%% curly vee tail (uses AMS symbols fonts)
\newarrowtail{curlyvee}\succ{\mkern-1mu{\prec}\mkern.4mu}\curlyvee\curlywedge
%% open and closed triangle tails (uses AMS symbols fonts)
\def\rttriangle{\mkern1.2mu\triangleright}%% 29.1.93
\newarrowtail{triangle}\rttriangle\lhtriangle\dhtriangle
\uhtriangle
\newarrowtail{blacktriangle}\blacktriangleright
{\mkern-1mu\blacktriangleleft\mkern.4mu}%
\dhblack\uhblack
\newarrowtail{littleblack}{\scriptaxis\blacktriangleright\mkern-2mu}%
{\mkern-1mu\scriptaxis\blacktriangleleft}\dhlblack\uhlblack
%% LaTeX tails
\def\rtla{\hbox{\setbox0=\lnchar55\dimen0=\wd0%
\kern-.5\dimen0\ht0\z@% 19.1.93 smashed height
\raise\axisheight\box0\kern-.2\dimen0}}%%
\def\ltla{\hbox{\setbox0=\lnchar33\dimen0=\wd0\kern-.15\dimen0\ht0\z@
\raise\axisheight\box0\kern-.5\dimen0}}%%
\def\dtla{\vbox{\setbox0=\rlap{\lnchar77}%
\dimen0=\ht0\kern-.7\dimen0\box0\kern-.1\dimen0}}%% 15.1.93 from -.6
\def\utla{\vbox{\setbox0=\rlap{\lnchar66}%
\dimen0=\ht0\kern-.1\dimen0\box0\kern-.6\dimen0}}%%
\newarrowtail{LaTeX}\rtla\ltla\dtla\utla
%% double vee tail %% will probably be withdrawn later
\def\rtvvee{\gg\mkern-3mu}%%
\def\ltvvee{\mkern-3mu\ll}%%
\def\dtvvee{\vbox{\hbox{$\vee$}\kern-.6ex
\hbox{$\vee$}\vss}}%%
\def\utvvee{\vbox{\vss\hbox{$\wedge$}\kern-.6ex
\hbox{$\wedge$}\kern\z@}}%%
\newarrowtail{doublevee}\rtvvee\ltvvee\dtvvee\utvvee
%% double LaTeX tails %% will probably be withdrawn later
\def\ltlala{\ltla\kern.3em\ltla}%%
\def\rtlala{\rtla\kern.3em\rtla}%%
\def\utlala{\hbox{\utla\raise-.6ex\utla}}%%
\def\dtlala{\hbox{\dtla\lower-.6ex\dtla}}%%
\newarrowtail{doubleLaTeX}\rtlala\ltlala\dtlala\utlala
% single dotted line tail (eh?)
%\def\htdot{\mkern3.15mu\cdot\mkern3.15mu}%%
%\def\vtdot{\vbox to 1.46ex{\vss\hbox{$\cdot$}}}
%% bar (as in \mapsto)
\def\utbar{\vrule height 0.093ex depth0pt width 0.4em}%%
\let\dtbar\utbar%%
\def\rtbar{\mkern1.5mu\vrule height 1.1ex depth.06ex width .04em\mkern1.5mu}%%
\let\ltbar\rtbar%%
\newarrowtail{mapsto}\rtbar\ltbar\dtbar\utbar%%
\newarrowtail{|}\rtbar\ltbar\dtbar\utbar%%ascii vertical bar (|)
%% hooks (as in \into): choice of after/above and before/below
\def\rthooka{\raisehook{}+\subset\mkern-1mu}%%
\def\lthooka{\mkern-1mu\raisehook{}+\supset}%%
\def\rthookb{\raisehook{}-\subset\mkern-2mu}%%
\def\lthookb{\mkern-1mu\raisehook{}-\supset}%%
\def\dthooka{\shifthook{}+\cap}%%
\def\dthookb{\shifthook{}-\cap}%%
\def\uthooka{\shifthook{}+\cup}%%
\def\uthookb{\shifthook{}-\cup}%%
\newarrowtail{hooka}\rthooka\lthooka\dthooka\uthooka
\newarrowtail{hookb}\rthookb\lthookb\dthookb\uthookb
\ifx\boldmath\undefined
\newarrowtail{boldhooka}\rthooka\lthooka\dthooka\uthooka
\newarrowtail{boldhookb}\rthookb\lthookb\dthookb\uthookb
\newarrowtail{boldhook}\rthooka\lthooka\dthookb\uthooka
\else
\def\rtbhooka{\raisehook\boldmath+\subset\mkern-1mu}%%
\def\ltbhooka{\mkern-1mu\raisehook\boldmath+\supset}%%
\def\rtbhookb{\raisehook\boldmath-\subset\mkern-2mu}%%
\def\ltbhookb{\mkern-1mu\raisehook\boldmath-\supset}%%
\def\dtbhooka{\shifthook\boldmath+\cap}%%
\def\dtbhookb{\shifthook\boldmath-\cap}%%
\def\utbhooka{\shifthook\boldmath+\cup}%%
\def\utbhookb{\shifthook\boldmath-\cup}%%
\newarrowtail{boldhooka}\rtbhooka\ltbhooka\dtbhooka\utbhooka
\newarrowtail{boldhookb}\rtbhookb\ltbhookb\dtbhookb\utbhookb
\newarrowtail{boldhook}\rtbhooka\ltbhooka\dtbhooka\utbhooka
\fi
%% square-ended hooks (used for closed subsets in ``lifting and gluing'')
\def\dtsqhooka{\shifthook{}+\sqcap}%%
\def\dtsqhookb{\shifthook{}-\sqcap}%%
\def\ltsqhooka{\mkern-1mu\raisehook{}+\sqsupset}%%
\def\ltsqhookb{\mkern-1mu\raisehook{}-\sqsupset}%%
\def\rtsqhooka{\raisehook{}+\sqsubset\mkern-1mu}%%
\def\rtsqhookb{\raisehook{}-\sqsubset\mkern-2mu}%%
\def\utsqhooka{\shifthook{}+\sqcup}%%
\def\utsqhookb{\shifthook{}-\sqcup}%%
\newarrowtail{sqhook}\rtsqhooka\ltsqhooka\dtsqhooka\utsqhooka
%% the following seem the better choices at 10pt & 300dpi
\newarrowtail{hook}\rthooka\lthookb\dthooka\uthooka
\newarrowtail{C}\rthooka\lthookb\dthooka\uthooka
%% circles
\newarrowtail{o}\hho\hho\circ\circ%%
\newarrowtail{O}\hhO\hhO{\scriptstyle\bigcirc}{\scriptstyle\bigcirc}%%
%% crosses
\newarrowtail{X}\lhtimes\rhtimes\uhtimes\dhtimes
\newarrowtail+++++%ascii
%% empty tail {} is also available
%% Y from stmaryrd (vertical ones still need adjustment)
\newarrowtail{Y}\Yright\Yleft\Ydown\Yup
%% harpoon with shaft (trailing up/left can be changed to down/right)
% shift verticals to balance! ######## (uses AMS symbols fonts)
\newarrowtail{harpoon}\leftharpoondown\rightharpoondown\upharpoonright
\downharpoonright
%% arrow with double shaft
% 12.8.2009 suggested by Bostjan Gabrovsek
%%\newarrowtail{<=}\Leftarrow\Rightarrow\Uparrow\Downarrow
\newarrowtail{<=}\Leftarrow\Rightarrow{\@cmex7E}{\@cmex7F}%
%% ********** F I L L E R S ***********
%% shortening is up to 0.15em=2.7mu horiz and 0.35ex vertically at each end.
%% dot {.}, single rule {-} and empty {} fillers are also available
%% double and triple lines
%%\newarrowfiller{=}==\Vert\Vert%%
\newarrowfiller{=}=={\@cmex77}{\@cmex77}%% 16.1.93
\def\vfthree{\mid\!\!\!\mid\!\!\!\mid}%%ascii
\newarrowfiller{3}\equiv\equiv\vfthree\vfthree
% use the extension font: double vertical="305 or "37F
%% dashed line
\def\vfdashstrut{\vrule width0pt height1.3ex depth0.7ex}%%
\def\vfthedash{\vrule width\intended@breadth height0.6ex depth 0pt}%%
\def\hfthedash{\set@axis\vrule\horizhtdp width 0.26em}%%
\def\hfdash{\mkern5.5mu\hfthedash\mkern5.5mu}%%
\def\vfdash{\vfdashstrut\vfthedash}%%
\newarrowfiller{dash}\hfdash\hfdash\vfdash\vfdash
%% ************* M I D D L E S ************
% corners for bent lines
%\def\dmcornervert{\vrule width\intended@breadth height\intended@breadth}%%
%\def\rdmcorner{\kern.4em\dmcornervert\vrule width .4em \horizhtdp}%%
%\def\ldmcorner{\vrule width .4em \horizhtdp\dmcornervert\kern.4em}%%
%\def\rumcorner{\kern.4em\vrule width .4em \horizhtdp}%%
%\def\lumcorner{\vrule width .4em \horizhtdp\kern.4em}%%
%\def\urmcorner{\mkern-4.2mu}%%
%\let\drmcorner\urmcorner\let\dlmcorner\urmcorner\let\ulmcorner\urmcorner
%% plus
\newarrowmiddle+++++%ascii
%% ************* D I A G O N A L S ************
%% simple arrow heads
%%\def\nwhTO{\nwarrow\mkern-1mu}%%
%%\def\nehTO{\mkern-.1mu\nearrow}%%
%%\def\sehTO{\searrow\mkern-.02mu}%%
%%\def\swhTO{\mkern-.8mu\swarrow}%%
%%======================================================================%
%% %
%% (24) ARROW COMMANDS %
%% %
%%======================================================================%
%% change to \iftrue to get mixed heads
\iffalse%%
\newarrow{To}----{vee}%%
\newarrow{Arr}----{LaTeX}%%
\newarrow{Dotsto}....{vee}%%
\newarrow{Dotsarr}....{LaTeX}%%
\newarrow{Dashto}{}{dash}{}{dash}{vee}%%
\newarrow{Dasharr}{}{dash}{}{dash}{LaTeX}%%
\newarrow{Mapsto}{mapsto}---{vee}%%
\newarrow{Mapsarr}{mapsto}---{LaTeX}%%
\newarrow{IntoA}{hooka}---{vee}%%
\newarrow{IntoB}{hookb}---{vee}%%
\newarrow{Embed}{vee}---{vee}%%
\newarrow{Emarr}{LaTeX}---{LaTeX}%%
\newarrow{Onto}----{doublevee}%%
\newarrow{Dotsonarr}....{doubleLaTeX}%%
\newarrow{Dotsonto}....{doublevee}%%
\newarrow{Dotsonarr}....{doubleLaTeX}%%
\else%%
\newarrow{To}---->%%
\newarrow{Arr}---->%%
\newarrow{Dotsto}....>%%
\newarrow{Dotsarr}....>%%
\newarrow{Dashto}{}{dash}{}{dash}>%%
\newarrow{Dasharr}{}{dash}{}{dash}>%%
\newarrow{Mapsto}{mapsto}--->%%
\newarrow{Mapsarr}{mapsto}--->%%
\newarrow{IntoA}{hooka}--->%%
\newarrow{IntoB}{hookb}--->%%
\newarrow{Embed}>--->%%
\newarrow{Emarr}>--->%%
\newarrow{Onto}----{>>}%%
\newarrow{Dotsonarr}....{>>}%%
\newarrow{Dotsonto}....{>>}%%
\newarrow{Dotsonarr}....{>>}%%
\fi%%
\newarrow{Implies}===={=>}%% minimum cell height 9.5pt
\newarrow{Project}----{triangle}%%
\newarrow{Pto}----{harpoon}%% partial function
\newarrow{Relto}{harpoon}---{harpoon}%% binary relation
\newarrow{Eq}=====%%
\newarrow{Line}-----%%
\newarrow{Dots}.....%%
\newarrow{Dashes}{}{dash}{}{dash}{}%%
%% square hooked arrow (used in my ``gluing and lifting'' paper)
\newarrow{SquareInto}{sqhook}--->
%% braces and parentheses
%% \newarrow gives inappropriate directions, so we change the names
%% the vertical filler is too far to the right; horizontal too high
%% the vertical middles are too low with midvshaft
%% maybe we'll add square brackets and the integral sign one day
\newarrowhead{cmexbra}{\@cmex7B}{\@cmex7C}{\@cmex3B}{\@cmex38}%%
\newarrowtail{cmexbra}{\@cmex7A}{\@cmex7D}{\@cmex39}{\@cmex3A}%%
\newarrowmiddle{cmexbra}{\braceru\bracelu}{\bracerd\braceld}%
{\vcenter{\hbox@maths{\@cmex3D\mkern-2mu}}}%% right
{\vcenter{\hbox@maths{\mkern 2mu\@cmex3C}}}%% left
\newarrow{@brace}{cmexbra}-{cmexbra}-{cmexbra}%% braces
\newarrow{@parenth}{cmexbra}---{cmexbra}%% straight parentheses
\def\rightBrace{\d@brace[thick,cmex]}%%ASCII square brackets []
\def\leftBrace {\u@brace[thick,cmex]}%%ASCII square brackets []
\def\upperBrace{\r@brace[thick,cmex]}%%ASCII square brackets []
\def\lowerBrace{\l@brace[thick,cmex]}%%ASCII square brackets []
\def\rightParenth{\d@parenth[thick,cmex]}%%ASCII square brackets []
\def\leftParenth {\u@parenth[thick,cmex]}%%ASCII square brackets []
\def\upperParenth{\r@parenth[thick,cmex]}%%ASCII square brackets []
\def\lowerParenth{\l@parenth[thick,cmex]}%%ASCII square brackets []
%% synonyms for reverse compatibility
\let\uFrom\uTo%%
\let\lFrom\lTo%%
\let\uDotsfrom\uDotsto%%
\let\lDotsfrom\lDotsto%%
\let\uDashfrom\uDashto%%
\let\lDashfrom\lDashto%%
\let\uImpliedby\uImplies%%
\let\lImpliedby\lImplies%%
\let\uMapsfrom\uMapsto%%
\let\lMapsfrom\lMapsto%%
\let\lOnfrom\lOnto%%
\let\uOnfrom\uOnto%%
\let\lPfrom\lPto%%
\let\uPfrom\uPto%%
\let\uInfromA\uIntoA%%
\let\uInfromB\uIntoB%%
\let\lInfromA\lIntoA%%
\let\lInfromB\lIntoB%%
\let\rInto\rIntoA%%
\let\lInto\lIntoA%%
\let\dInto\dIntoB%%
\let\uInto\uIntoA%%
\let\ruInto\ruIntoA%%
\let\luInto\luIntoA%%
\let\rdInto\rdIntoA%%
\let\ldInto\ldIntoA%%
%%
\let\hEq\rEq%%
\let\vEq\uEq%%
\let\hLine\rLine%%
\let\vLine\uLine%%
\let\hDots\rDots%%
\let\vDots\uDots%%
\let\hDashes\rDashes%%
\let\vDashes\uDashes%%
%%=========================================================================%
%% The following are included for reverse compatibility only.
% \NW plain arrows (like \vector in LaTeX)
% \NWd dotted lines with LaTeX arrowheads
% \NWl lines without arrowheads
% \NWld dotted lines without heads
% \NWe "embed" tails
% \NWo "onto" ie double LaTeX arrowheads (which Henk Barendregt wanted)
% \NWod double heads and dotted lines (ditto)
%%=========================================================================%
\let\NW\luTo\let\NE\ruTo\let\SW\ldTo\let\SE\rdTo
\def\nNW{\luTo(2,3)}\def\nNE{\ruTo(2,3)}%%ascii
\def\sSW{\ldTo(2,3)}\def\sSE{\rdTo(2,3)}%%ascii
\def\wNW{\luTo(3,2)}\def\eNE{\ruTo(3,2)}%%ascii
\def\wSW{\ldTo(3,2)}\def\eSE{\rdTo(3,2)}%%ascii
\def\NNW{\luTo(2,4)}\def\NNE{\ruTo(2,4)}%%ascii
\def\SSW{\ldTo(2,4)}\def\SSE{\rdTo(2,4)}%%ascii
\def\WNW{\luTo(4,2)}\def\ENE{\ruTo(4,2)}%%ascii
\def\WSW{\ldTo(4,2)}\def\ESE{\rdTo(4,2)}%%ascii
\def\NNNW{\luTo(2,6)}\def\NNNE{\ruTo(2,6)}%%ascii
\def\SSSW{\ldTo(2,6)}\def\SSSE{\rdTo(2,6)}%%ascii
\def\WWNW{\luTo(6,2)}\def\EENE{\ruTo(6,2)}%%ascii
\def\WWSW{\ldTo(6,2)}\def\EESE{\rdTo(6,2)}%%ascii
\let\NWd\luDotsto\let\NEd\ruDotsto\let\SWd\ldDotsto\let\SEd\rdDotsto
\def\nNWd{\luDotsto(2,3)}\def\nNEd{\ruDotsto(2,3)}%%ascii
\def\sSWd{\ldDotsto(2,3)}\def\sSEd{\rdDotsto(2,3)}%%ascii
\def\wNWd{\luDotsto(3,2)}\def\eNEd{\ruDotsto(3,2)}%%ascii
\def\wSWd{\ldDotsto(3,2)}\def\eSEd{\rdDotsto(3,2)}%%ascii
\def\NNWd{\luDotsto(2,4)}\def\NNEd{\ruDotsto(2,4)}%%ascii
\def\SSWd{\ldDotsto(2,4)}\def\SSEd{\rdDotsto(2,4)}%%ascii
\def\WNWd{\luDotsto(4,2)}\def\ENEd{\ruDotsto(4,2)}%%ascii
\def\WSWd{\ldDotsto(4,2)}\def\ESEd{\rdDotsto(4,2)}%%ascii
\def\NNNWd{\luDotsto(2,6)}\def\NNNEd{\ruDotsto(2,6)}%%ascii
\def\SSSWd{\ldDotsto(2,6)}\def\SSSEd{\rdDotsto(2,6)}%%ascii
\def\WWNWd{\luDotsto(6,2)}\def\EENEd{\ruDotsto(6,2)}%%ascii
\def\WWSWd{\ldDotsto(6,2)}\def\EESEd{\rdDotsto(6,2)}%%ascii
\let\NWl\luLine\let\NEl\ruLine\let\SWl\ldLine\let\SEl\rdLine
\def\nNWl{\luLine(2,3)}\def\nNEl{\ruLine(2,3)}%%ascii
\def\sSWl{\ldLine(2,3)}\def\sSEl{\rdLine(2,3)}%%ascii
\def\wNWl{\luLine(3,2)}\def\eNEl{\ruLine(3,2)}%%ascii
\def\wSWl{\ldLine(3,2)}\def\eSEl{\rdLine(3,2)}%%ascii
\def\NNWl{\luLine(2,4)}\def\NNEl{\ruLine(2,4)}%%ascii
\def\SSWl{\ldLine(2,4)}\def\SSEl{\rdLine(2,4)}%%ascii
\def\WNWl{\luLine(4,2)}\def\ENEl{\ruLine(4,2)}%%ascii
\def\WSWl{\ldLine(4,2)}\def\ESEl{\rdLine(4,2)}%%ascii
\def\NNNWl{\luLine(2,6)}\def\NNNEl{\ruLine(2,6)}%%ascii
\def\SSSWl{\ldLine(2,6)}\def\SSSEl{\rdLine(2,6)}%%ascii
\def\WWNWl{\luLine(6,2)}\def\EENEl{\ruLine(6,2)}%%ascii
\def\WWSWl{\ldLine(6,2)}\def\EESEl{\rdLine(6,2)}%%ascii
\let\NWld\luDots\let\NEld\ruDots\let\SWld\ldDots\let\SEld\rdDots
\def\nNWld{\luDots(2,3)}\def\nNEld{\ruDots(2,3)}%%ascii
\def\sSWld{\ldDots(2,3)}\def\sSEld{\rdDots(2,3)}%%ascii
\def\wNWld{\luDots(3,2)}\def\eNEld{\ruDots(3,2)}%%ascii
\def\wSWld{\ldDots(3,2)}\def\eSEld{\rdDots(3,2)}%%ascii
\def\NNWld{\luDots(2,4)}\def\NNEld{\ruDots(2,4)}%%ascii
\def\SSWld{\ldDots(2,4)}\def\SSEld{\rdDots(2,4)}%%ascii
\def\WNWld{\luDots(4,2)}\def\ENEld{\ruDots(4,2)}%%ascii
\def\WSWld{\ldDots(4,2)}\def\ESEld{\rdDots(4,2)}%%ascii
\def\NNNWld{\luDots(2,6)}\def\NNNEld{\ruDots(2,6)}%%ascii
\def\SSSWld{\ldDots(2,6)}\def\SSSEld{\rdDots(2,6)}%%ascii
\def\WWNWld{\luDots(6,2)}\def\EENEld{\ruDots(6,2)}%%ascii
\def\WWSWld{\ldDots(6,2)}\def\EESEld{\rdDots(6,2)}%%ascii
\let\NWe\luEmbed\let\NEe\ruEmbed\let\SWe\ldEmbed\let\SEe\rdEmbed
\def\nNWe{\luEmbed(2,3)}\def\nNEe{\ruEmbed(2,3)}%%ascii
\def\sSWe{\ldEmbed(2,3)}\def\sSEe{\rdEmbed(2,3)}%%ascii
\def\wNWe{\luEmbed(3,2)}\def\eNEe{\ruEmbed(3,2)}%%ascii
\def\wSWe{\ldEmbed(3,2)}\def\eSEe{\rdEmbed(3,2)}%%ascii
\def\NNWe{\luEmbed(2,4)}\def\NNEe{\ruEmbed(2,4)}%%ascii
\def\SSWe{\ldEmbed(2,4)}\def\SSEe{\rdEmbed(2,4)}%%ascii
\def\WNWe{\luEmbed(4,2)}\def\ENEe{\ruEmbed(4,2)}%%ascii
\def\WSWe{\ldEmbed(4,2)}\def\ESEe{\rdEmbed(4,2)}%%ascii
\def\NNNWe{\luEmbed(2,6)}\def\NNNEe{\ruEmbed(2,6)}%%ascii
\def\SSSWe{\ldEmbed(2,6)}\def\SSSEe{\rdEmbed(2,6)}%%ascii
\def\WWNWe{\luEmbed(6,2)}\def\EENEe{\ruEmbed(6,2)}%%ascii
\def\WWSWe{\ldEmbed(6,2)}\def\EESEe{\rdEmbed(6,2)}%%ascii
\let\NWo\luOnto\let\NEo\ruOnto\let\SWo\ldOnto\let\SEo\rdOnto
\def\nNWo{\luOnto(2,3)}\def\nNEo{\ruOnto(2,3)}%%ascii
\def\sSWo{\ldOnto(2,3)}\def\sSEo{\rdOnto(2,3)}%%ascii
\def\wNWo{\luOnto(3,2)}\def\eNEo{\ruOnto(3,2)}%%ascii
\def\wSWo{\ldOnto(3,2)}\def\eSEo{\rdOnto(3,2)}%%ascii
\def\NNWo{\luOnto(2,4)}\def\NNEo{\ruOnto(2,4)}%%ascii
\def\SSWo{\ldOnto(2,4)}\def\SSEo{\rdOnto(2,4)}%%ascii
\def\WNWo{\luOnto(4,2)}\def\ENEo{\ruOnto(4,2)}%%ascii
\def\WSWo{\ldOnto(4,2)}\def\ESEo{\rdOnto(4,2)}%%ascii
\def\NNNWo{\luOnto(2,6)}\def\NNNEo{\ruOnto(2,6)}%%ascii
\def\SSSWo{\ldOnto(2,6)}\def\SSSEo{\rdOnto(2,6)}%%ascii
\def\WWNWo{\luOnto(6,2)}\def\EENEo{\ruOnto(6,2)}%%ascii
\def\WWSWo{\ldOnto(6,2)}\def\EESEo{\rdOnto(6,2)}%%ascii
\let\NWod\luDotsonto\let\NEod\ruDotsonto\let\SWod\ldDotsonto
\let\SEod\rdDotsonto
\def\nNWod{\luDotsonto(2,3)}\def\nNEod{\ruDotsonto(2,3)}%%ascii
\def\sSWod{\ldDotsonto(2,3)}\def\sSEod{\rdDotsonto(2,3)}%%ascii
\def\wNWod{\luDotsonto(3,2)}\def\eNEod{\ruDotsonto(3,2)}%%ascii
\def\wSWod{\ldDotsonto(3,2)}\def\eSEod{\rdDotsonto(3,2)}%%ascii
\def\NNWod{\luDotsonto(2,4)}\def\NNEod{\ruDotsonto(2,4)}%%ascii
\def\SSWod{\ldDotsonto(2,4)}\def\SSEod{\rdDotsonto(2,4)}%%ascii
\def\WNWod{\luDotsonto(4,2)}\def\ENEod{\ruDotsonto(4,2)}%%ascii
\def\WSWod{\ldDotsonto(4,2)}\def\ESEod{\rdDotsonto(4,2)}%%ascii
\def\NNNWod{\luDotsonto(2,6)}\def\NNNEod{\ruDotsonto(2,6)}%%ascii
\def\SSSWod{\ldDotsonto(2,6)}\def\SSSEod{\rdDotsonto(2,6)}%%ascii
\def\WWNWod{\luDotsonto(6,2)}\def\EENEod{\ruDotsonto(6,2)}%%ascii
\def\WWSWod{\ldDotsonto(6,2)}\def\EESEod{\rdDotsonto(6,2)}%%ascii
%%======================================================================%
%% %
%% (25) MISCELLANEOUS %
%% %
%%======================================================================%
\def\labelstyle{%%
\ifincommdiag%%
\textstyle%%
\else%%
\scriptstyle%%
\fi}%%
\let\objectstyle\displaystyle
\newdiagramgrid{pentagon}%
{0.618034,0.618034,1,1,1,1,0.618034,0.618034}%
{1.17557,1.17557,1.902113,1.902113}
\newdiagramgrid{perspective}%
{0.75,0.75,1.1,1.1,0.9,0.9,0.95,0.95,0.75,0.75}%
{0.75,0.75,1.1,1.1,0.9,0.9}%
\diagramstyle[%%ascii open square bracket
dpi=300,%% office laserwriters are usually 300 dots per inch
vmiddle,nobalance,%% vertical and horizontal positioning
loose,%% allow rows and columns to stretch
thin,%% line10 arrows; default rule thickness (TeXbook p447)
pilespacing=10pt,%% parallel vertical separation (horizontals: half this)
shortfall=4pt,%% distance between arrowheads and their targets
%% The following are defaulted on entry to the diagram itself.
%% l>=2em minimum length of horizontal arrow shafts in text
%% l>=1em ditto in diagrams
%% size=3em cell size
%% heads=LaTeX arrowheads
]%%ascii close square bracket
%% process options to LaTeX2e's \usepackage[options]{diagrams}
%\tracingmacros1 \tracingcommands1 \tracingonline1
\ifx\ProcessOptions\undefined\else
\@was@pair@false\ProcessOptions\relax\if@was@pair@\bad@pair@opt\fi
\fi
%%============================== THE END ====================================
\if@cd@use@PS@
\if@pdf@
\message{| running in pdf mode -- diagonal arrows will work automatically |}%
\else
\message{| >>>>>>>> POSTSCRIPT MODE (DVIPS) IS NOW THE DEFAULT <<<<<<<<<<<<|}%
\message{|(DVI mode has not been supported since 1992 and produces inferior|}%
\message{|results which are completely unsuitable for publication. However,|}%
\message{|if you really still need it, you can still get it by loading the |}%
\message{|package using ``\string
\usepackage[UglyObsolete]{diagrams}'' instead. ) |}%
\fi\else
\message{| >>>>>>>> USING UGLY OBSOLETE DVI CODE - PLEASE STOP <<<<<<<<<<<<|}%
\message{|(DVI mode has not been supported since 1992 and produces inferior|}%
\message{|results which are completely unsuitable for publication - Please |}%
\message{|use the PostScript or PDF mode instead, for much better results.)|}%
\fi
\cdrestoreat %% restore old category code for @ etc
\message{===================================================================}%
%% This is the end of Paul Taylor's commutative diagrams package.