\message{==================================================================}% \message{}% %% %% %% This code runs the LaTeX \ProvidesPackage command iff it is defined. %% included at the request of Michael Downes 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 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 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 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 %% 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 % \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 % \def\checklist#1\expand\thenexttoken#2\endlist{% % \def\rest{##2}% % \ifx\rest\empty % \then % \else % \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 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 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 (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. \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 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 % : | +-------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 % % 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 set pen size in thousandths of an inch (ugh!) % fp flush path % da dashed line % dt dotted line % pa add a point to the current path % ar draw arc % ia 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\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.