diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/diagmac2 |
Initial commit
Diffstat (limited to 'macros/latex/contrib/diagmac2')
-rw-r--r-- | macros/latex/contrib/diagmac2/README | 39 | ||||
-rw-r--r-- | macros/latex/contrib/diagmac2/diagmac2.sty | 1059 | ||||
-rw-r--r-- | macros/latex/contrib/diagmac2/doc/diagmac2.pdf | bin | 0 -> 167195 bytes | |||
-rw-r--r-- | macros/latex/contrib/diagmac2/doc/diagmac2.tex | 1241 | ||||
-rw-r--r-- | macros/latex/contrib/diagmac2/doc/diagmactest.pdf | bin | 0 -> 67158 bytes | |||
-rw-r--r-- | macros/latex/contrib/diagmac2/doc/diagmactest.tex | 403 |
6 files changed, 2742 insertions, 0 deletions
diff --git a/macros/latex/contrib/diagmac2/README b/macros/latex/contrib/diagmac2/README new file mode 100644 index 0000000000..72936fe159 --- /dev/null +++ b/macros/latex/contrib/diagmac2/README @@ -0,0 +1,39 @@ +This is the README for diagmac2, Version 2.1 (May 2009) + +John Reynolds's diagram macros (available from +http://www.cs.cmu.edu/~jcr/ and at CTAN in macros/latex/contrib/misc) +have been in use since 1987, particularly for commutative diagrams. +Although originally written for use with latex209, they do work with +more recent formats such as latex2e and pdflatex, but the diagmac macros +are based on the original picture environment in LaTeX and inherit its +limitations on line slopes and circle diameters. + +diagmac2.sty is a modification of the macros to allow use of the pict2e +package (available at CTAN in macros/latex/contrib) so that there are +effectively no restrictions on line slopes or circle diameters. Starting +in Version 2.1, some extensions have been added. Also, the User's Manual +has been \TeXified (diagmac2.tex) and expanded, including several +examples. The test file (diagmactest.tex) is as originally released by +Reynolds (but modified to load diagmac2.sty). + +At Reynolds's ftp site, there is the following disclaimer: + + These macros are in the public domain, and have not changed in many + years. Acknowledgement of their usage is not necessary. However, + neither I nor CMU accept any responsibility for the consequences of + errors in these macros or their documentation. This is more than the + usual disclaimer; TeX is a beastly language for programming anything + complex, and I am not an expert in its use, so that there are probably + errors lurking in the macros. + +In fact, after more than 20 years of intensive use by dozens of +enthusiastic users, it seems that not a single error has been +discovered. + +The licence for diagmac2.sty and diagmac2.tex is LPPL. + +Bob Tennent +School of Computing +Queen's University +Kingston, Canada K7L 3N6 +rdt@cs.queensu.ca diff --git a/macros/latex/contrib/diagmac2/diagmac2.sty b/macros/latex/contrib/diagmac2/diagmac2.sty new file mode 100644 index 0000000000..5826312c1b --- /dev/null +++ b/macros/latex/contrib/diagmac2/diagmac2.sty @@ -0,0 +1,1059 @@ +%% This is file 'diagmac2.sty' +%% +%% Copyright (C) 1997 J. C. Reynolds, john.reynolds@cs.cmu.edu +%% 2004-09 R. D. Tennent, rdt@cs.queensu.ca +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". + +%MACROS FOR DIAGRAMS - J. C. Reynolds - December 1987 + +% Modified to use pict2e.sty by Bob Tennent +% Changes indicated thusly: %%%pict2e + +% Changelog: +% +% Version 2.1 May 2009 +% +% Two extensions added: \drawedgebar and \ctec +% User Manual TeXified and expanded +% +% Version 2.0 February 2004 +% +% Modified to use pict2e.sty +% Changes indicated thusly: %%%pict2e + +\ProvidesPackage{diagmac2}[2009/05/09 v2.1 LaTeX style for (category-theory) diagrams] + +\AtBeginDocument{\RequirePackage{pict2e}} %%%pict2e +\def\slopemax{1000} %%%pict2e slope factor maximum + +%This file contains general-purpose macros for drawing diagrams in LATEX, +%followed by additional macros especially for category-theory diagrams. +%A user's manual is given in the file diagmac2.tex, and a test program is %%%pict2e +%given in the file diagmactest.tex. + +%GENERAL-PURPOSE MACROS + +%The following control symbols may need to be redefined by the user. +\def\diagramunit{1pt}%Redefine only in main program or at the beginning +% of \diagram or \ctdiagram. +\def\centerheight{3pt} +\def\edgeheaddisp{4pt} +\def\circleheaddisp{2pt} +\def\diameterlist{1pt,2pt,3pt,4pt,5pt,6pt,7pt,8pt,9pt,10pt,11pt,% +12pt,13pt,14pt,15pt,16pt,20pt,24pt,28pt,32pt,36pt,40pt,} %%%pict2e: not used +%Redefine if circle fonts are different. + +%The following registers store the representation of diagram and/or +%expression programs: +\newdimen\texpr\newdimen\bexpr\newdimen\lexpr\newdimen\rexpr%current rectangle +\newdimen\xcenter\newdimen\ycenter%center point +\newcount\xslope\newcount\yslope%slope of current edge +\newdimen\xstart\newdimen\ystart%start point of current edge +\newdimen\xend\newdimen\yend%end point of current edge +\newdimen\dcircle%diameter of current circle +\newdimen\xcircle\newdimen\ycircle%center of current circle +\newcount\zzisedge%1 if current edge is defined, 0 otherwise +\newcount\zziscircle%1 if current circle is defined, 0 otherwise +\newbox\zzdiagbox%printable material in state +\newdimen\zztotlwidth\newdimen\zztotrwidth%horizontal extent of box material +\newdimen\zztotheight\newdimen\zztotdepth%vertical extent of box material + +%The following registers are assigned globally to communicate information +%across group boundaries: +\newdimen\zzglobaltotlwidth\newdimen\zzglobaltotrwidth +\newdimen\zzglobaltotheight\newdimen\zzglobaltotdepth +\newdimen\zzglobalxcenter\newdimen\zzglobalycenter +\newcount\zzglobalcnA + +%The following registers are used locally for various purposes: +\newdimen\zzdmA\newdimen\zzdmB\newdimen\zzdmC\newdimen\zzdmD\newdimen\zzdmE +\newdimen\zzdmF\newdimen\zzdmG\newdimen\zzdmH\newdimen\zzdmI +\newcount\zzcnA\newcount\zzcnB\newcount\zzcnC +\newcount\zzcnD\newcount\zzcnE\newcount\zzcnF +\newcount\zzcnG\newcount\zzcnH\newcount\zzcnI + +%Hidden macros and other defined control symbols: +% generally used macros: \zzsetupbox\zznoshadow\zzissue\zzrecordwidth +% \zzrecordheight\zzmultdiagramunit\zzmakepicture\zzsqroot\zzdistance +% \zzreduceterms +% error-checking macros: \zzisnegside\zzcheckedge\zzcheckslope\zzcheckslopea +% \zzcheckcircle\zzcheckbool\zzcheckposdimen\zzchecknonnegnum +% used by \vertex: \zzconsvertexlist\zzconsvertexlista\zzconsvertexlistb +% used by \rect: \zzprocrect +% used by \hexagon: \zzprochexagon +% used by \octagon and \rorect: \zzprococtagon +% used by \diamond: \zzprocdiamond +% used by \rorect: \zzprocrorecta\zzsearchdiameterlist\zzsearchdiameterlista +% \zzsearchdiameterlistb +% used by \outline: \zzoutlinepoly\zzoutlinepolya\zzoutlinepolyb +% \zzoutlinepolyc +% used by \outline with \rorect: \zzoutlinerorect +% used by \setedge: \zzsearchvertexlist\zzsearchvertexlista +% \zzsearchvertexlistb +% used by \shadeedge: \zzcastpoly\zzcastpolya\zzcastpolyb +% \zzcastpolyc\zzcastpolye\zzcastpolyf\zzcastpolyg +% used by \drawdashedge, \drawdotedge, and \drawsolidedge: \zzdrawedge +% used by \drawedgehead: \zzdrawedgeheada +% used by all abutment macros: \zzslidehoriz\zzslidevert\zzclosestpoly +% \zzclosestpolya\zzclosestpolyb\zzclosestpolyc\zzclosestpolyd +% used by edge abutment macros: \zzabut +% used by circle abutment macros: \zzabutcircle\zzabutcirclea\zzrotate +% used by \shadeedge and all abutment macros: \zzcastpolyd +% used by \drawcircle: \zzdrawcirclea +% multiply defined control symbols: \zzvertexlist\zzshadow\zzglobalshadow +% \zztesta\zztestb\zzvertexitem\zzprocpoly\zzprocrorect\zznext +% \zzstartshadow\zzendshadow\zzlocalshadow + +%\diagram creates a box, initializes \zztotlwidth, \zztotrwidth, and +%\zzvertexlist, sets \zzisedge to 0, executes #1, which must be a diagram +%program, and then issues the resulting box, surrounded by kerns so that +%there are no horizontal overhangs. + +\def\diagram#1{{\setbox\zzdiagbox=\hbox{$\mathsurround=0pt +\zztotlwidth=0pt\zztotrwidth=0pt\def\zzvertexlist{\end}\zzisedge=0\relax +#1\relax\kern\zztotrwidth\global\zzglobaltotlwidth=\zztotlwidth $} +\kern-\zzglobaltotlwidth\box\zzdiagbox}} + +%\zzsetupbox sets \zzdiagbox to the expression #1 modified by the program #2. +%It also sets \zzglobalxcenter and \zzglobalycenter to the coordinates of +%the center relative to the reference point, \zzglobaltotlwidth to the +%negative of the left overhang width of the expression, and \zzglobalshadow +%to the shadow established by the program, relative to the reference point. +%Before executing #2, it initializes \texpr, \bexpr, \lexpr, \rexpr, +%\xcenter, and \ycenter appropriately, and sets \zziscircle to 0. + +\def\zzsetupbox#1#2{\setbox\zzdiagbox=\hbox{$\mathsurround=0pt +\setbox\zzdiagbox=\hbox{$\mathsurround=0pt{{#1}}$} +\texpr=\ht\zzdiagbox\bexpr=-\dp\zzdiagbox\rexpr=\wd\zzdiagbox\lexpr=0pt +\xcenter=\rexpr\divide\xcenter by 2\ycenter=\centerheight +\zztotlwidth=0pt\zztotrwidth=\rexpr\def\zzshadow{\zznoshadow0pt,0pt:;} +\zziscircle=0 +\box\zzdiagbox\kern-\rexpr +#2\relax +\global\zzglobalxcenter=\xcenter\global\zzglobalycenter=\ycenter +\global\zzglobaltotlwidth=\zztotlwidth\kern\zztotrwidth +\global\let\zzglobalshadow=\zzshadow +$}} + +%\zznoshadow is a dummy shadowing routine that gives an error when executed. + +\def\zznoshadow#1,#2:;{\errmessage{ATTEMPT TO OUTLINE OR ABUT AN EXPRESSION +WITH NO SHADOW}} + +%\leftghost (\rightghost) sets \xcenter to \lexpr plus (\rexpr minus) +%half of the width of its argument. + +\def\leftghost#1{\setbox\zzdiagbox=\hbox{$\mathsurround=0pt{{#1}}$} +\xcenter=\wd\zzdiagbox\divide\xcenter by 2\advance\xcenter by \lexpr} + +\def\rightghost#1{\setbox\zzdiagbox=\hbox{$\mathsurround=0pt{{#1}}$} +\xcenter=\wd\zzdiagbox\divide\xcenter by -2\advance\xcenter by \rexpr} + +%\zzissue should be executed after \zzsetupbox. It issues the contents of +%\zzdiagbox with its center placed at \zzdmA, \zzdmB (which are modified), +%and adjusts \zztotlwidth and \zztotrwidth appropriately. + +\def\zzissue{\advance\zzdmA by -\zzglobalxcenter +\advance\zzdmB by -\zzglobalycenter +\zzdmC=\zzdmA\advance\zzdmC by \wd\zzdiagbox +\zzdmD=\zzdmA\advance\zzdmD by \zzglobaltotlwidth +\zzrecordwidth\zzdmD\zzdmC +\kern\zzdmA\raise\zzdmB\box\zzdiagbox\kern-\zzdmC} + +%\zzrecordwidth adjusts \zztotlwidth to be the minimum of its previous value +%and #1, and adjusts \zztotrwidth to be the maximum of its previous value +%and #2. + +\def\zzrecordwidth#1#2{\relax\ifdim#1<\zztotlwidth\relax\zztotlwidth=#1\fi +\ifdim\zztotrwidth<#2\relax\zztotrwidth=#2\fi} + +%\zzrecordheight adjusts \zztotheight to be the maximum of its previous value +%and #1, and adjusts \zztotdepth to be the minimum of its previous value +%and #2. + +\def\zzrecordheight#1#2{\relax\ifdim\zztotheight<#1\relax\zztotheight=#1\fi +\ifdim#2<\zztotdepth\relax\zztotdepth=#2\fi} + +%\placed executes \zzsetupbox{#3}{#4} and issues the contents of the resulting +%\zzdiagbox with its center placed at #1, #2 (which must be dimensions). +%\place is similar except that #1, #2 must be integer multiples of +%\diagramunit. + +\def\placed#1#2#3#4{\zzsetupbox{#3}{#4}\zzdmA=#1\zzdmB=#2\zzissue} + +\def\place#1,#2:#3#4{\zzsetupbox{#3}{#4}\zzmultdiagramunit\zzdmA{#1} +\zzmultdiagramunit\zzdmB{#2}\zzissue} + +%\zzmultdiagramunit sets #1 to #2 times \diagramunit. + +\def\zzmultdiagramunit#1#2{#1=\diagramunit\multiply#1 by #2\relax} + +%\vertex#1,#2:#3#4 executes \zzsetupbox{#3}{#4}, issues the contents of the +%resulting \zzdiagbox with its center placed at #1, #2 times \diagramunit, +%adjusts \zztotlwidth and \zztotrwidth appropriately, and adds \zzglobalshadow +%to the beginning of \zzvertexlist (unless \zzglobalshadow is a call of +%\zznoshadow) after readjusting the shadow to be relative +%to the coordinates of the enclosing box. + +\def\vertex#1,#2:#3#4{\place{#1},{#2}:{#3}{#4}\zzcnA=#1\zzcnB=#2\relax +\expandafter\zzconsvertexlist\zzglobalshadow} + +\def\zzconsvertexlist#1#2,#3:#4;{\def\zztesta{#1}\def\zztestb{\zznoshadow} +\ifx\zztesta\zztestb\else +\advance\zzdmA by #2\advance\zzdmB by #3\relax +\edef\zzvertexitem{\the\zzcnA,\the\zzcnB:\noexpand #1\the\zzdmA,\the\zzdmB:#4;} +\expandafter\zzconsvertexlista\zzvertexlist\fi} + +\def\zzconsvertexlista{\expandafter\zzconsvertexlistb\zzvertexitem} + +\def\zzconsvertexlistb#1\end{\def\zzvertexlist{#1\end}} + +%\rect, \hexagon, \octagon, and \diamond (and, roughly speaking, \rorect) +%are polygon descriptors. A polygon descriptor defines \zzshadow to have +% the form \somecontrolsymbol #1,#2:#3; such that executing +%\zzshadow causes a call \zzprocpoly{#1}{#2}{<edgelist>}, where <edgelist> +%depends only upon the parameter #3. Here #1, #2 are the +%coordinates of a vertex of a convex polygon, and <edgelist> is a list of +%triples describing the edges of the polygon in clockwise order. If an +%edge is x = xs.t + x0, y = ys.t + y0 for 0 < t < tend (with the start at +%t = 0 and the end at t = tend when the edge is traversed in clockwise +%order) the the trip describing the edge is {xs}{ys}{tend}, where xs and +%ys are numbers (the brackets may be omitted for single-digit numbers) +%and tend is a dimension. xs and ys must have a least common divisor of one. + +\def\rect{\zzdmC=\rexpr\advance\zzdmC by -\lexpr +\zzdmD=\texpr\advance\zzdmD by -\bexpr +\zzisnegside{\zzdmC}{RECT}\zzisnegside{\zzdmD}{RECT} +\edef\zzshadow{\noexpand\zzprocrect +\the\lexpr,\the\texpr:\the\zzdmC,\the\zzdmD;}} + +\def\zzprocrect#1,#2:#3,#4;{\zzprocpoly +{#1}{#2}{10{#3}0{-1}{#4}{-1}0{#3}01{#4}}} + +\def\zzisnegside#1#2{\relax\ifdim#1<0pt\errmessage +{#2 WITH NEGATIVE SIDE}\fi} + +\def\hexagon{\zzdmC=\rexpr\advance\zzdmC by -\lexpr +\zzdmD=\texpr\advance\zzdmD by -\bexpr\divide\zzdmD by 4 +\zzisnegside{\zzdmC}{HEXAGON}\zzisnegside{\zzdmD}{HEXAGON} +\edef\zzshadow{\noexpand\zzprochexagon +\the\lexpr,\the\texpr:\the\zzdmC,\the\zzdmD;}} + +\def\zzprochexagon#1,#2:#3,#4;{\zzprocpoly{#1}{#2} +{10{#3}1{-2}{#4}{-1}{-2}{#4}{-1}0{#3}{-1}2{#4}12{#4}}} + +\def\octagon#1{\zzdmC=#1\zzdmD=\zzdmC\multiply\zzdmD by -2\zzdmE=\zzdmD +\advance\zzdmD by \rexpr\advance\zzdmD by -\lexpr +\advance\zzdmE by \texpr\advance\zzdmE by -\bexpr +\zzdmF=\lexpr\advance\zzdmF by \zzdmC +\zzisnegside{\zzdmC}{OCTAGON}\zzisnegside{\zzdmD}{OCTAGON} +\zzisnegside{\zzdmE}{OCTAGON} +\edef\zzshadow{\noexpand\zzprococtagon +\the\zzdmF,\the\texpr:\the\zzdmC,\the\zzdmD,\the\zzdmE;}} + +\def\zzprococtagon#1,#2:#3,#4,#5;{\zzprocpoly{#1}{#2} +{10{#4}1{-1}{#3}0{-1}{#5}{-1}{-1}{#3}{-1}0{#4}{-1}1{#3}01{#5}11{#3}}} + +\def\diamond{\zzdmC=\texpr\advance\zzdmC by -\bexpr +\advance\zzdmC by \rexpr\advance\zzdmC by -\lexpr\divide\zzdmC by 2 +\zzdmD=\lexpr\advance\zzdmD by \rexpr\divide\zzdmD by 2 +\zzdmE=\texpr\advance\zzdmE by \bexpr\divide\zzdmE by 2\advance\zzdmE by \zzdmC +\zzisnegside{\zzdmC}{DIAMOND} +\edef\zzshadow{\noexpand\zzprocdiamond +\the\zzdmD,\the\zzdmE:\the\zzdmC;}} + +\def\zzprocdiamond#1,#2:#3;{\zzprocpoly{#1}{#2} +{1{-1}{#3}{-1}{-1}{#3}{-1}1{#3}11{#3}}} + +\def\rorect#1#2#3{\zzcheckposdimen{#1}{FIRST}{RORECT} +\zzcheckbool{#2}{SECOND}{RORECT}\zzcheckbool{#3}{THIRD}{RORECT} +\zzdmD=\rexpr\advance\zzdmD by -\lexpr\zzdmE=\texpr\advance\zzdmE by -\bexpr +\zzdmC=#1\relax +\ifnum#2=1\relax\ifdim\zzdmD>\zzdmC\relax\zzdmC=\zzdmD\fi\fi +\ifnum#3=1\relax\ifdim\zzdmE>\zzdmC\relax\zzdmC=\zzdmE\fi\fi +%\expandafter\zzsearchdiameterlist\diameterlist\end\zzdmC=\zzdmF\relax %%%pict2e +\ifdim\zzdmC>\zzdmD\relax\zzdmD=\zzdmC\fi +\ifdim\zzdmC>\zzdmE\relax\zzdmE=\zzdmC\fi +\zzdmF=\lexpr\advance\zzdmF by \rexpr\divide\zzdmF by 2 +\zzdmG=\bexpr\advance\zzdmG by \texpr\divide\zzdmG by 2 +\edef\zzshadow{\noexpand\zzprocrorect +\the\zzdmF,\the\zzdmG:\the\zzdmC,\the\zzdmD,\the\zzdmE;}} + +\def\zzsearchdiameterlist#1{\def\zztesta{#1}\def\zztestb{\end} +\ifx\zztesta\zztestb\let\zznext=\zzsearchdiameterlista +\else\let\zznext=\zzsearchdiameterlistb\fi\zznext #1} + +\def\zzsearchdiameterlista#1\end{} + +\def\zzsearchdiameterlistb#1,{\zzdmF=#1\relax +\ifdim\zzdmF<\zzdmC\relax\let\zznext=\zzsearchdiameterlist +\else\let\zznext=\zzsearchdiameterlista\fi\zznext} + +%\outline uses \zzoutlinepoly and \zzoutlinerorect to issue an outline of +%the shadow. + +\def\outline{\def\zzprocpoly{\zzoutlinepoly} +\def\zzprocrorect{\zzoutlinerorect}\zzshadow} + +%\zzmakepicture encapsulates all usage of the LATEX picture facility. + +\def\zzmakepicture#1{{\setlength{\unitlength}{1sp}\begin{picture}(0,0) +#1\relax +\global\zzglobaltotlwidth=\zztotlwidth\global\zzglobaltotrwidth=\zztotrwidth +\global\zzglobaltotheight=\zztotheight\global\zzglobaltotdepth=\zztotdepth +\end{picture}\vrule height\zzglobaltotheight depth-\zzglobaltotdepth width0pt} +\zztotlwidth=\zzglobaltotlwidth\zztotrwidth=\zzglobaltotrwidth} + +\def\zzoutlinepoly#1#2#3{\zzmakepicture{\zzdmA=#1\zzdmB=#2\relax +\zztotheight=\zzdmB\zztotdepth=\zzdmB\zzoutlinepolya #3\end}} + +\def\zzoutlinepolya#1{\def\zztesta{#1}\def\zztestb{\end} +\ifx\zztesta\zztestb\let\zznext=\zzoutlinepolyb +\else\let\zznext=\zzoutlinepolyc\fi\zznext {#1}} + +\def\zzoutlinepolyb#1{} + +\def\zzoutlinepolyc#1#2#3{\zzrecordwidth\zzdmA\zzdmA\zzrecordheight\zzdmB\zzdmB +\zzdmE=#3\multiply\zzdmE by #1\zzdmF=#3\multiply\zzdmF by #2\relax +\zzcnA=\zzdmA\zzcnB=\zzdmB\relax +\ifnum #1=0\relax\zzcnC=\zzdmF\else\zzcnC=\zzdmE\fi +\ifnum\zzcnC<0\relax\zzcnC=-\zzcnC\fi +\put(\zzcnA,\zzcnB){\line(#1,#2){\zzcnC}} +\advance\zzdmA by \zzdmE\advance\zzdmB by \zzdmF +\zzoutlinepolya} + +\def\zzoutlinerorect#1,#2:#3,#4,#5;{\zzmakepicture{ +\zzdmA=#1\zzdmB=#2\zzdmC=#3\zzdmD=#4\zzdmE=#5 +\zzcnA=\zzdmA\zzcnB=\zzdmB\zzcnC=\zzdmC\zzcnD=\zzdmD\zzcnE=\zzdmE +\ifnum\zzcnD=\zzcnC\relax\put(\zzcnA,\zzcnB){\oval(\zzcnD,\zzcnE)} +\else\ifnum\zzcnE=\zzcnC\relax\put(\zzcnA,\zzcnB){\oval(\zzcnD,\zzcnE)} +\else\advance\zzcnE by -\zzcnC +\zzcnF=\zzcnE\divide\zzcnF by 2\advance\zzcnF by \zzcnB +\put(\zzcnA,\zzcnF){\oval(\zzcnD,\zzcnC)[t]} +\advance\zzcnF by -\zzcnE +\put(\zzcnA,\zzcnF){\oval(\zzcnD,\zzcnC)[b]} +\zzcnC=\zzcnD\divide\zzcnC by 2\advance\zzcnA by \zzcnC +\put(\zzcnA,\zzcnF){\line(0,1){\zzcnE}} +\advance\zzcnA by -\zzcnD +\put(\zzcnA,\zzcnF){\line(0,1){\zzcnE}}\fi\fi +\zztotheight=\zzdmE\divide\zztotheight by 2\advance\zztotheight by \zzdmB +\zztotdepth=\zztotheight\advance\zztotdepth by -\zzdmE +\zzdmC=\zzdmD\divide\zzdmC by -2\advance\zzdmC by \zzdmA +\advance\zzdmD by \zzdmC\zzrecordwidth\zzdmC\zzdmD}} + +%\border, \borderto, and \symmetrize adjust the current rectangle. + +\def\border#1#2{\advance\texpr by #2\advance\bexpr by -#2 +\advance\lexpr by -#1\advance\rexpr by #1} + +\def\borderto#1#2{\zzdmA=\rexpr\advance\zzdmA by -\lexpr\relax +\ifdim#1>\zzdmA\relax\advance\zzdmA by -#1\divide\zzdmA by 2 +\advance\rexpr by -\zzdmA\advance\lexpr by \zzdmA\fi +\zzdmA=\texpr\advance\zzdmA by -\bexpr\relax +\ifdim#2>\zzdmA\relax\advance\zzdmA by -#2\divide\zzdmA by 2 +\advance\texpr by -\zzdmA\advance\bexpr by \zzdmA\fi} + +\def\symmetrize{\zzdmA=\texpr\advance\zzdmA by -\ycenter +\zzdmB=\ycenter\advance\zzdmB by -\bexpr\relax +\ifdim\zzdmA<\zzdmB\relax\zzdmA=\zzdmB\fi +\texpr=\ycenter\advance\texpr by \zzdmA +\bexpr=\ycenter\advance\bexpr by -\zzdmA} + +%\setedge#1,#2,#3,#4: accepts four numbers (giving dimensions as multiples of +%\diagramunit). It sets \xstart, \ystart, \xend, \yend to #1, #2, #3, +%#4, each multiplied by \diagramunit, and \xslope, \yslope to numbers +% giving the slope of the line from \xstart, \ystart to \xend, \yend, +%reduced to have a least common divisor. It uses \zzsearchvertexlist to set +%\zzstartshadow (\zzendshadow) to the \zzshadow stored on \zzvertexlist with +%coordinates #1, #2 (#3, #4). It sets \zzisedge to 1. + +\def\setedge#1,#2,#3,#4:{\zzcnA=#1\zzcnB=#2 +\zzmultdiagramunit\xstart\zzcnA\zzmultdiagramunit\ystart\zzcnB +\expandafter\zzsearchvertexlist\zzvertexlist +\let\zzstartshadow=\zzshadow +\zzcnA=#3\zzcnB=#4 +\zzmultdiagramunit\xend\zzcnA\zzmultdiagramunit\yend\zzcnB +\expandafter\zzsearchvertexlist\zzvertexlist +\let\zzendshadow=\zzshadow +\xslope=#3\advance\xslope by -#1\relax +\yslope=#4\advance\yslope by -#2\relax +\zzreduceterms\xslope\yslope{START AND END OF EDGE ARE BOTH THE SAME} +\xslope=\zzcnC\yslope=\zzcnD\zzisedge=1} + +%\zzreduceterms sets \zzcnC and \zzcnD to the results of dividing the numbers +% #1 and #2 by their greatest common divisor. The error message #3 is given +%if #1 and #2 are both zero. + +\def\zzreduceterms#1#2#3{{ +\ifnum#1<0\relax\zzcnA=-#1\else\zzcnA=#1\fi +\ifnum#2<0\relax\zzcnB=-#2\else\zzcnB=#2\fi +\loop\ifnum\zzcnB>0\relax +\zzcnC=\zzcnA\divide\zzcnC by \zzcnB\multiply\zzcnC by -\zzcnB +\advance\zzcnC by \zzcnA\zzcnA=\zzcnB\zzcnB=\zzcnC +\repeat\relax +\ifnum\zzcnA=0\errmessage{#3}\fi +\global\zzglobalcnA=\zzcnA} +\zzcnC=#1\divide\zzcnC by \zzglobalcnA\zzcnD=#2\divide\zzcnD by \zzglobalcnA} + +%\zzsearchvertexlist\zzvertexlist searches \zzvertexlist for an entry of the +%form #1,#2:#3; for which #1 = \zzcnA and #2 = \zzcnB. If such an entry is +%found, \zzshadow is defined to be #3;. Otherwise, \zzshadow is defined to be +%\zzdmE=\zzdmA\zzdmF=\zzdmB. + +\def\zzsearchvertexlist#1{\def\zztesta{#1}\def\zztestb{\end} +\ifx\zztesta\zztestb\def\zzshadow{\zzdmE=\zzdmA\zzdmF=\zzdmB} +\let\zznext=\zzsearchvertexlista +\else\let\zznext=\zzsearchvertexlistb\fi\zznext #1} + +\def\zzsearchvertexlista#1\end{} + +\def\zzsearchvertexlistb#1,#2:#3;{\relax +\ifnum\zzcnA=#1\relax\ifnum\zzcnB=#2\relax +\def\zzshadow{#3;}\let\zznext=\zzsearchvertexlista +\else\let\zznext=\zzsearchvertexlist\fi +\else\let\zznext=\zzsearchvertexlist\fi\zznext} + +%\shadeedge shades the start and end of the current edge, changing \xstart, +%\ystart, \xend, \yend. + +\def\shadeedge{\zzcheckedge{SHADE} +\def\zzprocpoly{\zzcastpoly}\def\zzprocrorect{\zzprocrorecta} +\zzdmA=\xstart\zzdmB=\ystart\zzcnA=\xslope\zzcnB=\yslope +\zzstartshadow\xstart=\zzdmE\ystart=\zzdmF +\zzdmA=\xend\zzdmB=\yend\zzcnA=-\xslope\zzcnB=-\yslope +\zzendshadow\xend=\zzdmE\yend=\zzdmF} + +\def\zzcheckedge#1{\relax\ifnum\zzisedge=0\relax\errmessage +{ATTEMPT TO #1 NONEXISTENT EDGE}\fi} + +%\zzprocrorecta is used as the definition of \zzprocrorect within \shadeedge +%and \zzabut. It causes a rounded rectangle to be treated as the +%circumscribed octagon for purposes of shadowing or abutment. + +\def\zzprocrorecta#1,#2:#3,#4,#5;{\zzdmC=#3 +\multiply\zzdmC by 53\divide\zzdmC by 181 +\zzdmD=\zzdmC\multiply\zzdmD by -2\zzdmE=\zzdmD +\advance\zzdmD by #4\advance\zzdmE by #5 +\zzdmF=#4\divide\zzdmF by -2\advance\zzdmF by #1\advance\zzdmF by \zzdmC +\zzdmG=#5\divide\zzdmG by 2\advance\zzdmG by #2 +\edef\zzlocalshadow{\noexpand\zzprococtagon +\the\zzdmF,\the\zzdmG:\the\zzdmC,\the\zzdmD,\the\zzdmE;} +\zzlocalshadow} + +%\zzcastpoly computes the outgoing intersection of a directed line, +%x = xs.t+x0, y = ys.t+y0 with a convex polygon. It is called +%by defining \zzprocpoly to be \zzcastpoly, setting \zzdmA, \zzdmB, \zzcnA, +%\zzcnB to x0, y0, xs, ys, and executing \zzshadow, which must have been +%defined by a polygon descriptor. The result is left in \zzdmE, \zzdmF. +%If the directed line does not intersect the polygon, the result is the +%point on the line that is closest to the polygon. + +\def\zzcastpoly#1#2#3{\zzdmC=#1\zzdmD=#2\zzcnC=0 +\zzcastpolya #3\end} + +\def\zzcastpolya#1{\def\zztesta{#1}\def\zztestb{\end} +\ifx\zztesta\zztestb\let\zznext=\zzcastpolyg +\else\let\zznext=\zzcastpolyc\fi\zznext {#1}} + +\def\zzcastpolyb#1\end{\zzcnC=\zzcnA\multiply\zzcnC by \zzcnA +\zzcnD=\zzcnB\multiply\zzcnD by \zzcnB\advance\zzcnC by \zzcnD +\zzdmE=\zzdmC\advance\zzdmE by -\zzdmA\multiply\zzdmE by \zzcnA +\zzdmF=\zzdmD\advance\zzdmF by -\zzdmB\multiply\zzdmF by \zzcnB +\advance\zzdmE by \zzdmF\divide\zzdmE by \zzcnC\zzdmF=\zzdmE +\multiply\zzdmE by \zzcnA\advance\zzdmE by \zzdmA +\multiply\zzdmF by \zzcnB\advance\zzdmF by \zzdmB} + + +\def\zzcastpolyc#1#2#3{\zzcnD=\zzcnB\multiply\zzcnD by #1\relax +\zzcnE=\zzcnA\multiply\zzcnE by #2\relax\advance\zzcnD by -\zzcnE\relax +\ifnum\zzcnD>0\relax +\ifnum\zzcnC=2\zzcastpolyd{#1}{#2}{#3}\let\zznext=\zzcastpolya\else +\zzdmE=\zzdmA\advance\zzdmE by -\zzdmC\multiply\zzdmE by \zzcnB +\zzdmF=\zzdmB\advance\zzdmF by -\zzdmD\multiply\zzdmF by \zzcnA +\advance\zzdmE by -\zzdmF\divide\zzdmE by \zzcnD\relax +\ifdim\zzdmE>#3\relax\zzcnC=3\zzcastpolyd{#1}{#2}{#3}\let\zznext=\zzcastpolya +\else\ifnum\zzcnC=3\zzcastpolyf{#1}{#2}\let\zznext=\zzcastpolye\else +\ifdim\zzdmE<0pt\relax +\ifnum\zzcnC=1\let\zznext=\zzcastpolyb\else +\zzcnC=2\zzcastpolyd{#1}{#2}{#3}\let\zznext=\zzcastpolya\fi +\else\zzcastpolyf{#1}{#2}\let\zznext=\zzcastpolye\fi\fi\fi\fi +\else\ifnum\zzcnC=3\let\zznext=\zzcastpolyb +\else\zzcnC=1\zzcastpolyd{#1}{#2}{#3}\let\zznext=\zzcastpolya\fi\fi +\zznext} + +\def\zzcastpolyd#1#2#3{ +\zzdmE=#3\multiply\zzdmE by #1\advance\zzdmC by \zzdmE +\zzdmE=#3\multiply\zzdmE by #2\advance\zzdmD by \zzdmE} + +\def\zzcastpolye#1\end{} + +\def\zzcastpolyf#1#2{\zzdmF=\zzdmE +\multiply\zzdmE by #1\relax\advance\zzdmE by \zzdmC +\multiply\zzdmF by #2\relax\advance\zzdmF by \zzdmD} + +\def\zzcastpolyg#1{\zzcastpolyb\end} + +%\shiftedge changes \xstart, \ystart, \xend, \yend so as to displace +%the edge from \xstart, \ystart to \xend, \yend by a vector of length +%#1 (a dimension) that is rotated 90 degrees counterclockwise from the edge. + +\def\shiftedge#1{\zzcheckedge{SHIFT} +\zzdistance\xslope\yslope +\zzdmA=#1\multiply\zzdmA by 100\divide\zzdmA by \zzglobalcnA\zzdmB=\zzdmA +\multiply\zzdmA by -\yslope\multiply\zzdmB by \xslope +\advance\xstart by \zzdmA \advance\xend by \zzdmA +\advance\ystart by \zzdmB \advance\yend by \zzdmB} + +%\zzsqroot#1 accepts an integer and sets \zzglobalcnA to the integer part +%of its square root. It works for numbers up to at least 1,000,000,000. + +\def\zzsqroot#1{{\zzcnA=#1 +%x is \zzcnA, y is \zzcnB, n is \zzcnC, z is \zzcnD +\zzcnC=0\zzcnD=1 +\loop\zzcnE=\zzcnA\divide\zzcnE by \zzcnD\advance\zzcnE by 1 +\relax\ifnum\zzcnD<\zzcnE\relax +\advance \zzcnC by 1\multiply\zzcnD by 2 +\repeat +\zzcnB=0 +\loop\ifnum\zzcnC>0\relax +\advance\zzcnC by -1\divide\zzcnD by 2 +\zzcnE=\zzcnB\advance\zzcnE by \zzcnD\multiply\zzcnE by \zzcnE\relax +\ifnum\zzcnA<\zzcnE\relax\else\advance\zzcnB by \zzcnD\fi +\repeat +\global\zzglobalcnA=\zzcnB}} + +%\zzdistance#1#2 accepts two integers and sets \zzglobalcnA to 100 times +%the square root of the sum of their squares. + +\def\zzdistance#1#2{{\zzcnA=#1\multiply\zzcnA by \zzcnA +\zzcnB=#2\multiply\zzcnB by \zzcnB +\advance\zzcnA by \zzcnB\multiply\zzcnA by 10000 +\zzsqroot\zzcnA}} + +%\drawdashedge, \drawdotedge, or \drawsolidedge draws a dashed, dotted, or +%solid line along the current edge. + +\def\drawdashedge#1#2#3#4{\zzcnA=1\zzdmA=#1\zzdmB=#2 +\zzcheckposdimen\zzdmA{FIRST}{DRAWDASHEDGE} +\zzcheckposdimen\zzdmB{SECOND}{DRAWDASHEDGE} +\zzchecknonnegnum{#3}{THIRD}{DRAWDASHEDGE} +\zzchecknonnegnum{#4}{FOURTH}{DRAWDASHEDGE} +\zzcnI=#3\relax\advance\zzcnI by #4\relax +\ifnum\zzcnI>0\else\errmessage +{SUM OF THIRD AND FOURTH PARAMETERS OF DRAWDASHEDGE MUST BE POSITIVE}\fi +\advance\zzdmB by \zzdmA +\zzdrawedge{\advance\zzcnC by -\zzcnD +\zzcnG=\zzcnC\divide\zzcnG by \zzcnE\relax +\ifnum\zzcnG>0\relax +\zzcnH=\zzcnG\multiply\zzcnH by \zzcnE\advance\zzcnC by -\zzcnH +\zzcnH=\zzcnI\multiply\zzcnH by \zzcnG +\advance\zzcnH by #3\divide\zzcnC by \zzcnH +\zzcnH=#3\multiply\zzcnH by \zzcnC\advance\zzcnD by \zzcnH +\multiply\zzcnC by \zzcnI\advance\zzcnE by \zzcnC +\else\advance\zzcnD by \zzcnC\fi} +{\line(\xslope,\yslope){\zzcnD}}} + +\def\zzcheckposdimen#1#2#3{\relax\ifdim#1>0pt\else\errmessage{ +#2 PARAMETER OF #3 MUST BE POSITIVE}\fi} + +\def\zzchecknonnegnum#1#2#3{\relax\ifnum#1<0\relax\errmessage{ +#2 PARAMETER OF #3 MUST BE NONNEGATIVE}\fi} + +\def\drawdotedge#1#2{\zzcnA=0\zzdmA=0pt\zzdmB=#1 +\zzcheckposdimen\zzdmB{}{DRAWDOTEDGE}\zzcheckbool{#2}{SECOND}{DRAWDOTEDGE} +\zzdrawedge{\zzcnG=\zzcnC\divide\zzcnG by \zzcnE\relax +\ifnum\zzcnG<1\relax\zzcnG=1\fi\zzcnE=\zzcnC\divide\zzcnE by \zzcnG\relax +\ifnum#2=0\relax\advance\zzcnG by -1\fi} +{\kern-1.39pt\raise-.76pt\hbox{.}}} + +\def\drawsolidedge{\zzcnA=1\zzdmA=0pt\zzdmB=0pt +\zzdrawedge{\zzcnG=0\zzcnD=\zzcnC} +{\line(\xslope,\yslope){\zzcnD}}} + +\def\zzdrawedge#1#2{\zzcheckedge{DRAW}\relax +\ifnum\zzcnA=1\relax\zzcheckslope\xslope\yslope\slopemax{SOLID OR DASHED EDGE}\fi%%%pict2e +\zzcnA=\xstart\zzcnB=\ystart\zzcnD=\zzdmA\zzcnE=\zzdmB\relax +\ifnum\xslope=0\relax\zzcnC=\yend\advance\zzcnC by -\zzcnB\zzcnF=\yslope +\else\zzcnC=\xend\advance\zzcnC by -\zzcnA\zzcnF=\xslope +\zzdistance\xslope\yslope\relax +\ifnum\xslope<0\relax\global\zzglobalcnA=-\zzglobalcnA\fi +\multiply\zzcnD by 100\divide\zzcnD by \zzglobalcnA\multiply\zzcnD by \xslope +\multiply\zzcnE by 100\divide\zzcnE by \zzglobalcnA\multiply\zzcnE by \xslope +\fi +\ifnum\zzcnF<0\relax\zzcnC=-\zzcnC\fi +\ifnum\zzcnC>0\relax #1\relax +\ifnum\zzcnF<0\relax\zzcnE=-\zzcnE\fi\zzcnF=\zzcnE\relax +\ifnum\xslope=0\relax\zzcnE=0 +\else\multiply\zzcnF by \yslope\divide\zzcnF by \xslope\fi +\zzmakepicture{\loop\put(\zzcnA,\zzcnB){#2} +\ifnum\zzcnG>0\relax\advance\zzcnG by -1 +\advance\zzcnA by \zzcnE\advance\zzcnB by \zzcnF\repeat +\zzrecordwidth\xstart\xstart\zzrecordwidth\xend\xend +\zztotheight=\ystart\zztotdepth=\ystart\zzrecordheight\yend\yend}\fi} + +%\drawedgehead draws an arrowhead along the current edge. + +\def\drawedgehead#1#2#3{\zzcheckbool{#2}{SECOND}{DRAWEDGEHEAD} +\zzcheckbool{#3}{THIRD}{DRAWEDGEHEAD}\zzcnB=#3 +\relax\ifnum#2=1\relax\zzcnA=#1\relax +\zzdrawedgeheada\xstart\ystart\xend\yend\xslope\yslope +\else\zzcnA=100\advance\zzcnA by -#1\relax +\zzdrawedgeheada\xend\yend\xstart\ystart{-\xslope}{-\yslope}\fi} + +%\zzcheckbool gives an error message unless its first argument is 1 or 0. + +\def\zzcheckbool#1#2#3{ +\ifnum#1<0\errmessage{#2 PARAMETER OF #3 MUST BE 1 OR 0}\fi +\ifnum#1>1\errmessage{#2 PARAMETER OF #3 MUST BE 1 OR 0}\fi} + +\def\zzdrawedgeheada#1#2#3#4#5#6{\zzcheckedge{DRAW ARROWHEAD FOR} +\zzcheckslope{#5}{#6}\slopemax{ARROWHEAD}%%%pict2e +\zzdmA=#3\advance\zzdmA by -#1 +\divide\zzdmA by 10\multiply\zzdmA by \zzcnA\divide\zzdmA by 10 +\zzdmB=#4\advance\zzdmB by -#2 +\divide\zzdmB by 10\multiply\zzdmB by \zzcnA\divide\zzdmB by 10 +\relax\ifnum\zzcnB=1\relax +\zzdistance{#5}{#6}\zzdmC=\edgeheaddisp +\multiply\zzdmC by 100\divide\zzdmC by \zzglobalcnA\zzdmD=\zzdmC +\multiply\zzdmC by #5\multiply\zzdmD by #6 +\advance\zzdmA by \zzdmC\advance\zzdmB by \zzdmD\fi +\advance\zzdmA by #1\zzcnA=\zzdmA\advance\zzdmB by #2\zzcnB=\zzdmB +\zzmakepicture{\put(\zzcnA,\zzcnB){\vector(#5,#6){0}} +\zzrecordwidth\zzdmA\zzdmA\zztotheight=\zzdmB\zztotdepth=\zzdmB}} + +%\zzcheckslope gives an errormessage if the absolute value of #1 or #2 +%is greater than #3. + +\def\zzcheckslope#1#2#3#4{\relax +\ifnum#1>#3\zzcheckslopea{#1}{#2}{#4}\fi +\ifnum#1<-#3\zzcheckslopea{#1}{#2}{#4}\fi +\ifnum#2>#3\zzcheckslopea{#1}{#2}{#4}\fi +\ifnum#2<-#3\zzcheckslopea{#1}{#2}{#4}\fi} + +\def\zzcheckslopea#1#2#3{\errmessage{\the#1,\the#2 IS ILLEGAL SLOPE FOR #3}} + +%The following macros each call \zzsetupbox{#2}{#3} and then issue the +%resulting expression so that its shadow touches the edge x = \xslope.t +%+\xstart, y = \yslope.t+\ystart. \abutX places the expression to the X +%of the edge. For \abutleft and \abutright, #1 gives the y-coordinate +%of the expression as an integer multiple of \diagramunit. For \abutbelow +%and \abutabove, #1 gives the x-coordinate similarly. The macros \abutXd +%are similar, except that #1 should be a dimension. + +\def\abutleft#1:#2#3{\zzabut{#1}{#2}{#3}{-\yslope}{\zzslidehoriz}{1}} +\def\abutright#1:#2#3{\zzabut{#1}{#2}{#3}{\yslope}{\zzslidehoriz}{1}} +\def\abutbelow#1:#2#3{\zzabut{#1}{#2}{#3}{\xslope}{\zzslidevert}{1}} +\def\abutabove#1:#2#3{\zzabut{#1}{#2}{#3}{-\xslope}{\zzslidevert}{1}} + +\def\abutleftd#1#2#3{\zzabut{#1}{#2}{#3}{-\yslope}{\zzslidehoriz}{0}} +\def\abutrightd#1#2#3{\zzabut{#1}{#2}{#3}{\yslope}{\zzslidehoriz}{0}} +\def\abutbelowd#1#2#3{\zzabut{#1}{#2}{#3}{\xslope}{\zzslidevert}{0}} +\def\abutaboved#1#2#3{\zzabut{#1}{#2}{#3}{-\xslope}{\zzslidevert}{0}} + +\def\zzabut#1#2#3#4#5#6{\zzcheckedge{ABUT TO} +\zzsetupbox{#2}{#3}\zzcnA=\xslope\zzcnB=\yslope +\relax\ifnum#4<0\relax\zzcnA=-\zzcnA\zzcnB=-\zzcnB\fi +\def\zzprocpoly{\zzclosestpoly}\def\zzprocrorect{\zzprocrorecta} +\zzglobalshadow +\advance\zzdmC by -\zzglobalxcenter\advance\zzdmD by -\zzglobalycenter +\relax\ifnum#6=1\relax\zzmultdiagramunit\zzdmA{#1}\else\zzdmA=#1\fi +\zzdmB=\zzdmA#5\relax\zzissue} + +\def\zzslidehoriz{\relax\ifnum\yslope=0\errmessage +{ABUTLEFT OR ABUTRIGHT ATTEMPTED FOR HORIZONTAL EDGE}\fi +\advance\zzdmA by \zzdmD\advance\zzdmA by -\ystart +\multiply\zzdmA by \xslope\divide\zzdmA by \yslope +\advance\zzdmA by \xstart\advance\zzdmA by -\zzdmC} + +\def\zzslidevert{\relax\ifnum\xslope=0\errmessage +{ABUTBELOW OR ABUTABOVE ATTEMPTED FOR VERTICAL EDGE}\fi +\advance\zzdmB by \zzdmC\advance\zzdmB by -\xstart +\multiply\zzdmB by \yslope\divide\zzdmB by \xslope +\advance\zzdmB by \ystart\advance\zzdmB by -\zzdmD} + +%\zzclosestpoly finds the vertex of a convex polygon that is closest to a +%directed line, x = xs.t+x0, y = ys.t+y0, assuming that the directed line +%is to the left (right) of the polygon if ys is positive (negative) +%and above (below) the polygon if xs is positive (negative). +%It is called by defining \zzprocpoly to be \zzclosestpoly, setting \zzcnA, +%\zzcnB to xs, ys, and executing \zzglobalshadow, which must have been +%defined by a polygon descriptor. The output is left in \zzdmC, \zzdmD. + +\def\zzclosestpoly#1#2#3{\zzdmC=#1\zzdmD=#2\zzcnC=0\zzclosestpolya #3\end} + +\def\zzclosestpolya#1{\def\zztesta{#1}\def\zztestb{\end} +\ifx\zztesta\zztestb\let\zznext=\zzclosestpolyb +\else\let\zznext=\zzclosestpolyc\fi\zznext {#1}} + +\def\zzclosestpolyb#1{} + +\def\zzclosestpolyc#1#2#3{\zzcnD=\zzcnB\multiply\zzcnD by #1\relax +\zzcnE=\zzcnA\multiply\zzcnE by #2\relax\advance\zzcnD by -\zzcnE\relax +\ifnum\zzcnD>0\relax +\ifnum\zzcnC=1\let\zznext=\zzclosestpolyd +\else\zzcnC=0\zzcastpolyd{#1}{#2}{#3}\let\zznext=\zzclosestpolya\fi +\else\zzcnC=1\zzcastpolyd{#1}{#2}{#3}\let\zznext=\zzclosestpolya\fi +\zznext} + +\def\zzclosestpolyd#1\end{} + +%\setcircle initializes \dcircle, \xcircle, and \ycircle to its first +%three parameters, and sets \zziscircle to 1. + +\def\setcircle#1#2#3{\dcircle=#1\xcircle=#2\ycircle=#3\zziscircle=1} + +%\shiftcircle#1#2 displaces \xcircle, \ycircle by #1, #2. + +\def\shiftcircle#1#2{\zzcheckcircle{SHIFT} +\advance\xcircle by #1\advance\ycircle by #2} + +\def\zzcheckcircle#1{\relax\ifnum\zziscircle=0\errmessage +{ATTEMPT TO #1 NONEXISTENT CIRCLE}\fi} + +%\drawcircle draws quadrants of the current circle. + +\def\drawcircle#1#2#3#4{\zzcheckcircle{DRAW}\zzdmA=\dcircle\divide\zzdmA by 2 +\zzmakepicture{\zzcnA=\dcircle\zzcnB=\xcircle\zzcnC=\ycircle +\zztotheight=\ycircle\zztotdepth=\ycircle +\zzrecordwidth\xcircle\xcircle\relax +\zzdrawcirclea{#1}{tr}{\zzdmA}{\zzdmA}\zzdrawcirclea{#2}{br}{\zzdmA}{-\zzdmA} +\zzdrawcirclea{#3}{bl}{-\zzdmA}{-\zzdmA} +\zzdrawcirclea{#4}{tl}{-\zzdmA}{\zzdmA}}} + +\def\zzdrawcirclea#1#2#3#4{\zzcheckbool{#1}{}{DRAWCIRCLE}\ifnum#1=1\relax +\put(\zzcnB,\zzcnC){\oval(\zzcnA,\zzcnA)[#2]} +\zzdmB=\xcircle\advance\zzdmB by #3\zzrecordwidth\zzdmB\zzdmB +\zzdmB=\ycircle\advance\zzdmB by #4\zzrecordheight\zzdmB\zzdmB\fi} + +%\drawcirclehead issues an arrowhead placed on the current circle. + +\def\drawcirclehead#1#2#3{\zzcheckcircle{DRAW ARROWHEAD FOR} +\zzreduceterms{#1}{#2}{0,0 ARE ILLEGAL PARAMETERS FOR DRAWCIRCLEHEAD} +\zzdistance{\zzcnC}{\zzcnD}\zzcheckbool{#3}{THIRD}{DRAWCIRCLEHEAD} +\ifnum#3=1\relax\zzcnA=\zzcnD\zzcnB=-\zzcnC\else\zzcnA=-\zzcnD\zzcnB=\zzcnC\fi +\zzdmA=\dcircle\multiply\zzdmA by 50\divide\zzdmA by \zzglobalcnA +\zzdmB=\circleheaddisp\multiply\zzdmB by 100\divide\zzdmB by \zzglobalcnA +\zzdmE=\zzdmA\multiply\zzdmE by \zzcnC\zzdmC=\xcircle\advance\zzdmC by \zzdmE +\zzdmE=\zzdmB\multiply\zzdmE by \zzcnA\advance\zzdmC by \zzdmE +\zzdmE=\zzdmA\multiply\zzdmE by \zzcnD\zzdmD=\ycircle\advance\zzdmD by \zzdmE +\zzdmE=\zzdmB\multiply\zzdmE by \zzcnB\advance\zzdmD by \zzdmE +\zzcnC=\zzdmC\zzcnD=\zzdmD\zzcheckslope\zzcnA\zzcnB\slopemax{ARROWHEAD}%%%pict2e +\zzmakepicture{\put(\zzcnC,\zzcnD){\vector(\zzcnA,\zzcnB){0}} +\zzrecordwidth\zzdmC\zzdmC\zztotheight=\zzdmD\zztotdepth=\zzdmD}} + +%The next four macros cause an expression to be abutted to the current +%circle. + +\def\abutcircleleft#1#2#3{\zzabutcircle{#1}{#2}{#3}{} +\zzslidehoriz{\relax\ifdim\zzdmA>\zzdmH\relax\zzdmH=\zzdmA\fi}} + +\def\abutcircleright#1#2#3{\zzabutcircle{#1}{#2}{#3}{\zzrotate\zzrotate} +\zzslidehoriz{\relax\ifdim\zzdmA<\zzdmH\relax\zzdmH=\zzdmA\fi}} + +\def\abutcirclebelow#1#2#3{\zzabutcircle{#1}{#2}{#3}{\zzrotate} +\zzslidevert{\relax\ifdim\zzdmB>\zzdmI\relax\zzdmI=\zzdmB\fi}} + +\def\abutcircleabove#1#2#3{\zzabutcircle +{#1}{#2}{#3}{\zzrotate\zzrotate\zzrotate} +\zzslidevert{\relax\ifdim\zzdmB<\zzdmI\relax\zzdmI=\zzdmB\fi}} + +\def\zzabutcircle#1#2#3#4#5#6{\zzcheckcircle{ABUT TO} +\zzsetupbox{#2}{#3}\def\zzprocpoly{\zzclosestpoly} +\def\zzprocrorect{\zzprocrorecta} +\zzdmF=\dcircle\divide\zzdmF by 2 +\zzdmG=\dcircle\multiply\zzdmG by 100\divide\zzdmG by 283 +\xstart=-\zzdmF\ystart=0pt\xslope=0\yslope=-1 +\zzabutcirclea{#1}{#4}{#5}\zzdmH=\zzdmA\zzdmI=\zzdmB +\xstart=-\zzdmG\ystart=\zzdmG\xslope=-1\yslope=-1 +\zzabutcirclea{#1}{#4}{#5}#6\relax +\xstart=-\zzdmG\ystart=-\zzdmG\xslope=1\yslope=-1 +\zzabutcirclea{#1}{#4}{#5}#6\relax +\zzdmA=\zzdmH\advance\zzdmA by \xcircle +\zzdmB=\zzdmI\advance\zzdmB by \ycircle +\zzissue} + +\def\zzabutcirclea#1#2#3{#2\relax +\zzcnA=\xslope\zzcnB=\yslope +\zzglobalshadow +\advance\zzdmC by -\zzglobalxcenter\advance\zzdmD by -\zzglobalycenter +\zzdmA=#1\zzdmB=\zzdmA #3\relax} + +\def\zzrotate{\zzdmE=\xstart\xstart=-\ystart\ystart=\zzdmE +\zzcnC=\xslope\xslope=-\yslope\yslope=\zzcnC} + +%MACROS FOR CATEGORY-THEORY DIAGRAMS + +%The following control symbols may be redefined by the user: +\def\ctvertexstyle{\displaystyle} +\def\ctabutstyle{\textstyle} +\def\ctvertexborderlr{3pt} +\def\ctvertexbordertb{4pt} +\def\ctloopdiameter{20pt} +\def\ctabutcircledisp{5pt} +\def\ctabutborderlr{2pt} +\def\ctabutbordertb{2pt} +\def\ctabutborderinset{3pt} +\def\ctabutborderinsetdouble{6pt}%Must be twice \ctabutborderinset +\def\ctdoubleedgedisp{2pt} + +%The following registers are used locally: +\newdimen\zzdmX\newdimen\zzdmY + +%Hidden macros and other defined control symbols: +% used by \ctdiagram: \diagram\ctsolid\cthead +% used by \ctv and \ctvg: \vertex\border\rect +% used by \ctgl: \leftghost +% used by \ctgr: \rightghost +% used by \ctlptl, \ctlptlcc, \ctlptr, \ctlptrcc, \ctlpbr, \ctlpbrcc, +% \ctlpbl, \ctlpblcc: \zzctlp\border\setcircle\shiftcircle\drawcircle +% \drawcirclehead\abutcircleleft\abutcircleright\zzctabutprog +% \octagon +% used by \cten, \ctet, \cteb, \ctel, \cter, \ctetg, \ctebg, \ctelg, \cterg, +% \ctetb, \ctelr, \ctetbg, \ctelrg: \setedge\zzctxmean\zzctymean +% \zzmultdiagramunit\zzcte\zzctee\shadeedge\abutaboved\abutbelowd +% \abutleftd\abutrightd\zzctabutprog\border\octagon\shiftedge +% \drawsolidedge\zzctdrawdashedge\drawdashedge\zzctdrawdotedge +% \drawdotedge\zzctdrawedgehead\drawedgehead\zzctnodrawedgehead +% multiply defined control symbols: \zzctdrawedge\zzctdrawhead +% \zzctxmeanadj\zzctymeanadj + +%\ctdiagram is similar to \diagram, except that it executes \ctsolid and +%\cthead before the expression program #1. + +\def\ctdiagram#1{\diagram{\ctsolid\cthead\ctoutermid #1}} + +%\ctvg is similar to \vertex except that the expression #3 is printed in +%\ctvertexstyle mode, and the expression program #4 is followed by a +%standard program that borders the current rectangle by \ctvertexborderlr +%on the sides and \ctvertexbordertb on the top and bottom, and then +%creates a rectangular shadow. \ctv is similar to \ctvg except that the +%expression program is empty (except for the standard program). + +\def\ctvg#1,#2:#3#4{\vertex #1,#2:{\ctvertexstyle #3}{#4\relax +\border\ctvertexborderlr\ctvertexbordertb\rect}} + +\def\ctv#1,#2:#3{\ctvg #1,#2:{#3}{}} + +%\ctgl and \ctgr are similar to \leftghost and \rightghost except that +%the expression #1 is printed in \ctvertexstyle. + +\def\ctgl#1{\leftghost{\ctvertexstyle #1}} + +\def\ctgr#1{\rightghost{\ctvertexstyle #1}} + +%The following eight macros print a three-quarter-circle loop of diameter +%\ctloopdiameter at one of the corners of an expanded current rectangle, +%with an arrowhead at one end of the loop. + +\def\ctlptl#1{\zzctlp{\lexpr\texpr}{{0pt}\circleheaddisp}{1011}{101} +{\abutcircleleft\ctabutcircledisp}{#1}} + +\def\ctlptlcc#1{\zzctlp{\lexpr\texpr}{{-\circleheaddisp}{0pt}}{1011}{0{-1}0} +{\abutcircleleft\ctabutcircledisp}{#1}} + +\def\ctlptr#1{\zzctlp{\rexpr\texpr}{\circleheaddisp{0pt}}{1101}{0{-1}1} +{\abutcircleright\ctabutcircledisp}{#1}} + +\def\ctlptrcc#1{\zzctlp{\rexpr\texpr}{{0pt}\circleheaddisp}{1101}{{-1}00} +{\abutcircleright\ctabutcircledisp}{#1}} + +\def\ctlpbr#1{\zzctlp{\rexpr\bexpr}{{0pt}{-\circleheaddisp}}{1110}{{-1}01} +{\abutcircleright{-\ctabutcircledisp}}{#1}} + +\def\ctlpbrcc#1{\zzctlp{\rexpr\bexpr}{\circleheaddisp{0pt}}{1110}{010} +{\abutcircleright{-\ctabutcircledisp}}{#1}} + +\def\ctlpbl#1{\zzctlp{\lexpr\bexpr}{{-\circleheaddisp}{0pt}}{0111}{011} +{\abutcircleleft{-\ctabutcircledisp}}{#1}} + +\def\ctlpblcc#1{\zzctlp{\lexpr\bexpr}{{0pt}{-\circleheaddisp}}{0111}{100} +{\abutcircleleft{-\ctabutcircledisp}}{#1}} + +\def\zzctlp#1#2#3#4#5#6{\border\ctvertexborderlr\ctvertexbordertb +\setcircle\ctloopdiameter #1 +\border{-\ctvertexborderlr}{-\ctvertexbordertb} +\shiftcircle #2\drawcircle #3\drawcirclehead #4 +#5{\ctabutstyle #6}\zzctabutprog} + +\def\zzctabutprog{\border\ctabutborderlr\ctabutbordertb +\borderto{\ctabutborderinsetdouble}{\ctabutborderinsetdouble} +\octagon\ctabutborderinset} + +%\cten#1,#2,#3,#4: draws a shaded edge from #1,#2 to #3,#4, possibly with +%an arrowhead at its end. + +\def\cten#1:{\setedge#1:\shadeedge\zzctdrawedge\zzctdrawhead1} + +%The following four macros draw a shaded edge, possibly with an arrowhead +%at the end, and abut an expression to the edge at its midpoint. + +\def\ctet#1:#2{\setedge#1:\zzctxmean\zzcte\abutaboved{#2}\zzctxmeanadj} + +\def\cteb#1:#2{\setedge#1:\zzctxmean\zzcte\abutbelowd{#2}\zzctxmeanadj} + +\def\ctel#1:#2{\setedge#1:\zzctymean\zzcte\abutleftd{#2}\zzctymeanadj} + +\def\cter#1:#2{\setedge#1:\zzctymean\zzcte\abutrightd{#2}\zzctymeanadj} + +\def\zzctxmean{\zzdmX=\xstart\advance\zzdmX by \xend\divide\zzdmX by 2} + +\def\zzctymean{\zzdmX=\ystart\advance\zzdmX by \yend\divide\zzdmX by 2} + +\def\zzcte#1#2#3{\shadeedge #3\zzctdrawedge\zzctdrawhead1 +#1\zzdmX{\ctabutstyle #2}\zzctabutprog} + +%The next four macros behave similarly to those above, but abut an +%expression to a specified point on the edge. + +\def\ctetg#1;#2:#3{\setedge#1:\zzmultdiagramunit\zzdmX{#2}\zzcte +\abutaboved{#3}\relax} + +\def\ctebg#1;#2:#3{\setedge#1:\zzmultdiagramunit\zzdmX{#2}\zzcte +\abutbelowd{#3}\relax} + +\def\ctelg#1;#2:#3{\setedge#1:\zzmultdiagramunit\zzdmX{#2}\zzcte +\abutleftd{#3}\relax} + +\def\cterg#1;#2:#3{\setedge#1:\zzmultdiagramunit\zzdmX{#2}\zzcte +\abutrightd{#3}\relax} + +%\ctetb (\ctelr) draws a pair of shaded edges, with two expressions +%abutted to the top and bottom (left and right) of the midpoint. +%\ctetbg and \ctelrg are similar, but abut to a specified point on the edge. + +\def\ctetb#1:#2#3#4#5{\zzcheckbool{#2}{FIFTH}{CTETB} +\zzcheckbool{#3}{SIXTH}{CTETB} +\setedge#1:\zzctxmean\zzctee\xslope\abutaboved\abutbelowd +{#2}{#3}{#4}{#5}\zzctxmeanadj} + +\def\ctelr#1:#2#3#4#5{\zzcheckbool{#2}{FIFTH}{CTELR} +\zzcheckbool{#3}{SIXTH}{CTELR} +\setedge#1:\zzctymean\zzctee\yslope\abutleftd\abutrightd +{#2}{#3}{#4}{#5}\zzctymeanadj} + +\def\ctetbg#1;#2,#3:#4#5#6#7{\zzcheckbool{#4}{SEVENTH}{CTETBG} +\zzcheckbool{#5}{EIGHTH}{CTETBG}\setedge#1:\zzmultdiagramunit\zzdmX{#2} +\zzctee\xslope +\abutaboved{\zzmultdiagramunit\zzdmX{#3}\abutbelowd}{#4}{#5}{#6}{#7}\relax} + +\def\ctelrg#1;#2,#3:#4#5#6#7{\zzcheckbool{#4}{SEVENTH}{CTELRG} +\zzcheckbool{#5}{EIGHTH}{CTELRG}\setedge#1:\zzmultdiagramunit\zzdmX{#2} +\zzctee\yslope +\abutleftd{\zzmultdiagramunit\zzdmX{#3}\abutrightd}{#4}{#5}{#6}{#7}\relax} + +\def\zzctee#1#2#3#4#5#6#7#8{ +\ifnum#1>0\relax\zzdmY=\ctdoubleedgedisp\else\zzdmY=-\ctdoubleedgedisp\fi +\shiftedge\zzdmY\shadeedge #8\zzctdrawedge\zzctdrawhead{#4} +#2\zzdmX{\ctabutstyle #6}\zzctabutprog +\multiply\zzdmY by -2\relax +\shiftedge\zzdmY\shadeedge #8\zzctdrawedge\zzctdrawhead{#5} +#3\zzdmX{\ctabutstyle #7}\zzctabutprog} + +%\ctinnermid defines \zzctxmeanadj and \zzctymeanadj so that \ctet, \cteb, +%\ctel, \cter, \ctetb, and \ctelr recompute the midpoint of the current +%edge after shading. \ctoutermid defines these control symbols so that +%these routines do not recompute the midpoint. + +\def\ctinnermid{\def\zzctxmeanadj{\zzctxmean}\def\zzctymeanadj{\zzctymean}} + +\def\ctoutermid{\def\zzctxmeanadj{\relax}\def\zzctymeanadj{\relax}} + +%\zzctdrawdashedge draws a dashed edge. + +\def\zzctdrawdashedge{\relax +\ifnum\xslope=0\relax\drawdashedge{7pt}{7pt}11 +\else\ifnum\yslope=0\relax\drawdashedge{7pt}{7pt}11 +\else\drawdashedge{15pt}{7pt}01\fi\fi} + +%\zzctdrawdotedge draws a dotted edge. + +\def\zzctdrawdotedge{\drawdotedge{8pt}1} + +%\ctsolid (\ctdash,\ctdot) defines \zzctdrawedge to be \drawsolidedge +%(\zzctdrawdashedge,\zzctdrawdotedge), so that edges will be solid +%(dashed, dotted). + +\def\ctsolid{\def\zzctdrawedge{\drawsolidedge}} + +\def\ctdash{\def\zzctdrawedge{\zzctdrawdashedge}} + +\def\ctdot{\def\zzctdrawedge{\zzctdrawdotedge}} + +%\zzctdrawedgehead places a forward-pointing arrowhead at the end of an edge +%if #1=1 or a backward-pointing arrowhead at the beginning if #1=0. +%\zzctnodrawedgehead is called in the same way but does nothing. + +\def\zzctdrawedgehead#1{\relax\ifnum#1=1\relax +\drawedgehead{100}10\else\drawedgehead{0}00\fi} + +\def\zzctnodrawedgehead#1{} + +%\cthead (\ctnohead) defines \zzctdrawhead to be \zzctdrawedgehead +%(\zzctnodrawedgehead), so that edges will (will not) have arrowheads. + +\def\cthead{\def\zzctdrawhead{\zzctdrawedgehead}} + +\def\ctnohead{\def\zzctdrawhead{\zzctnodrawedgehead}} + + +% Extensions by Bob Tennent (May 2009): +% +%\drawedgebar draws a bar across the end of the current edge. +% +\def\drawedgebar{\zzdrawedgebara\xend\yend\xstart\ystart{-\xslope}{-\yslope}} +\def\zzdrawedgebara#1#2#3#4#5#6{\zzcheckedge{DRAW ARROWBAR FOR} +\zzcheckslope{#5}{#6}4{ARROWBAR} +\zzdmA=#3\advance\zzdmA by -#1 +\divide\zzdmA by 10\multiply\zzdmA by 100\divide\zzdmA by 10 +\zzdmB=#4\advance\zzdmB by -#2 +\divide\zzdmB by 10\multiply\zzdmB by 100\divide\zzdmB by 10 +\zzdistance{#5}{#6}\zzdmC=0pt +\multiply\zzdmC by 100\divide\zzdmC by \zzglobalcnA\zzdmD=\zzdmC +\multiply\zzdmC by #5\multiply\zzdmD by #6 +\advance\zzdmA by \zzdmC\advance\zzdmB by \zzdmD +\advance\zzdmA by #1\zzcnA=\zzdmA\advance\zzdmB by #2\zzcnB=\zzdmB +\zzmakepicture{\put(\zzcnA,\zzcnB){\line(#6,-#5){140000}} +\zzrecordwidth\zzdmA\zzdmA\zztotheight=\zzdmB\zztotdepth=\zzdmB} +\zzmakepicture{\put(\zzcnA,\zzcnB){\line(-#6,#5){140000}} +\zzrecordwidth\zzdmA\zzdmA\zztotheight=\zzdmB\zztotdepth=\zzdmB} +} + +% \ctec draws a bezier-curve edge from (#1,#2) to (#3,#4) using (#5,#6) as a +% control point; the balanced math text #7 is centered at the control point +% +\def\ctec#1,#2,#3,#4,#5,#6:#7{ +\ctv #5,#6:{#7} +% get and save \xstart,\ystart after shadowing +\setedge#1,#2,#5,#6: +\def\zzprocpoly{\zzcastpoly}\def\zzprocrorect{\zzprocrorecta} +\zzdmA=\xstart\zzdmB=\ystart\zzcnA=\xslope\zzcnB=\yslope +\zzstartshadow\xstart=\zzdmE\ystart=\zzdmF +\zzdmH=\xstart\zzdmI=\ystart +% get \xend, \yend and shadow +\setedge#5,#6,#3,#4: +\def\zzprocpoly{\zzcastpoly}\def\zzprocrorect{\zzprocrorecta} +\zzdmA=\xend\zzdmB=\yend\zzcnA=-\xslope\zzcnB=-\yslope +\zzendshadow\xend=\zzdmE\yend=\zzdmF +% draw head +\zzctdrawhead1 +% restore saved \xstart, \ystart +\xstart=\zzdmH\ystart=\zzdmI +% compute control-point parameters +\zzcnA=#5\zzcnB=#6 +\zzmultdiagramunit\zzdmH\zzcnA\zzmultdiagramunit\zzdmI\zzcnB +\zzcnA=\xstart\zzcnB=\ystart\zzcnC=\xend\zzcnD=\yend\zzcnE=\zzdmH\zzcnF=\zzdmI +% draw bezier curve +\zzmakepicture{\qbezier(\zzcnA,\zzcnB)(\zzcnE,\zzcnF)(\zzcnC,\zzcnD) +\zzrecordwidth\xstart\xstart\zzrecordwidth\xend\xend +\zztotheight=\ystart\zztotdepth=\ystart\zzrecordheight\yend\yend}} + + diff --git a/macros/latex/contrib/diagmac2/doc/diagmac2.pdf b/macros/latex/contrib/diagmac2/doc/diagmac2.pdf Binary files differnew file mode 100644 index 0000000000..a9c041255e --- /dev/null +++ b/macros/latex/contrib/diagmac2/doc/diagmac2.pdf diff --git a/macros/latex/contrib/diagmac2/doc/diagmac2.tex b/macros/latex/contrib/diagmac2/doc/diagmac2.tex new file mode 100644 index 0000000000..42d4e439fc --- /dev/null +++ b/macros/latex/contrib/diagmac2/doc/diagmac2.tex @@ -0,0 +1,1241 @@ +\documentclass[11pt]{article} +\title{User's Manual for Diagram Macros} +\date{December, 1987\\[2ex] Revised for \texttt{diagmac2.sty}\\by Bob Tennent\\ Version 2.1 May, 2009} +\author{J. C. Reynolds} +\usepackage{fullpage} +\usepackage{url} +\usepackage{diagmac2} +\RequirePackage{amssymb} +\RequirePackage{fancyvrb} +\DefineVerbatimEnvironment{myverb}{Verbatim}{baselinestretch=0.95} +\DefineVerbatimEnvironment{smallverb}{Verbatim}{fontsize=\footnotesize,baselinestretch=0.95} +\RequirePackage{doc} +\MakeShortVerb{\"} % "..." is equivalent to \verb"..." +\PassOptionsToPackage{urlcolor=black,linkcolor=blue,colorlinks}{hyperref} +\RequirePackage{hyperref} +\newcommand{\myurl}[1]{\textcolor{blue}{\underline{\textcolor{black}{\url{#1}}}}} + + +\begin{document} +\sloppy +\maketitle +\thispagestyle{empty} +\tableofcontents + +\section{Introduction} +\begin{list}{}{\setlength{\leftmargin}{0.6in}} +\item +\footnotesize +\begin{flushright} + These macros are in the public domain, and have not changed in many + years. Acknowledgement of their usage is not necessary. However, + neither I nor CMU accept any responsibility for the consequences of + errors in these macros or their documentation. This is more than the + usual disclaimer; \TeX\ is a beastly language for programming anything + complex, and I am not an expert in its use, so that there are probably + errors lurking in the macros. +\\ [1ex] +John Reynolds\footnote{\myurl{ftp://ftp.cs.cmu.edu/user/jcr/README}} +\end{flushright} +\end{list} + + + +\enlargethispage*{4ex} +\par\noindent +The file \texttt{diagmac2.sty} contains \TeX\ macros for producing various kinds +of diagrams. It consists of two parts: a collection of general macros +for producing a wide variety of diagrams, and a second collection of +macros (which call upon the first) that are specifically oriented to +category-theory diagrams. + +\texttt{diagmac2.sty} is fully compatible with Reynolds's original \texttt{diagmac}, but +takes advantage of the \texttt{pict2e} implementation of the \texttt{picture} environment +to allow arbitrary slopes for edges and diameters for circles. In +this manual, the sections of the original manual that refered to the +limitations have been deleted. Sections~\ref{extensions} and \ref{examples} are new +in Version~2.1. + +The \LaTeX\ declarations "\thinlines" and "\thicklines" or the "pict2e" declaration +"\linethickness" may be used to vary +the thickness of lines, arrowheads, and circles. + +\cleardoublepage +\section{Programs and States} + +Certain parameters to these macros are ``programs.'' A program is a +\TeX\ text that does not directly produce any output but causes state changes +by calling macros. For example, in \LaTeX, the text read in picture mode, +i.e. the text between "\begin{picture}" and "\end{picture}" commands, is a +program that causes state changes by calling the macro "\put". (Internally, +such macros cause state changes by assigning to hidden registers and +redefining hidden control symbols. As a consequence, a program cannot +call state-changing macros within a group.) + +The diagram-producing macros use two kinds of program, called diagram +programs and expression programs. The state manipulated by a diagram +program, called a diagram state, is a plane containing symbols, lines, +and circles. Locations on this plane are specified by an $x,y$-coordinate +system, in which $x$ specifies horizontal distance, with increasing values +to the right, and $y$ specifies vertical distance, with increasing values +upwards. The diagram state also contains a ``vertex list,'' which is a +list of points (i.e. $x,y$-coordinate pairs) paired with polygonal regions +called ``shadows.'' + +The diagram state may also contain a ``current edge,'' which is a +(perhaps invisible) directed line segment. When the current edge is defined, +it is determined by four dimension registers: +\begin{itemize} + +\item "\xstart": the $x$-coordinate of the start point +\item "\ystart": the $y$-coordinate of the start point +\item "\xend": the $x$-coordinate of the end point +\item "\yend": the $y$-coordinate of the end point, +\end{itemize} +and two number registers: +\begin{itemize} +\item "\xslope": the $x$-component of the slope +\item "\yslope": the $y$-component of the slope +\end{itemize} +giving the slope of the edge, reduced to lowest terms. A diagram program may +refer to any of these quantities, and may also alter the dimension registers +explicitly (as well as by calling diagram macros), providing this alteration +preserves the slope of the edge. + +The state manipulated by an expression program, called an expression state, +is also a plane, containing an expression and other symbols, etc., +upon which is imposed an $x,y$-coordinate system. This state contains an +invisible ``current rectangle,'' determined by the four dimension registers: +\begin{itemize} +\item "\lexpr": the $x$-coordinate of the left side +\item "\rexpr": the $x$-coordinate of the right side +\item "\texpr": the $y$-coordinate of the top +\item "\bexpr": the $y$-coordinate of the bottom, +\end{itemize} +and a ``center point,'' determined by the two dimension registers: +\begin{itemize} +\item "\xcenter": the $x$-coordinate of the center point +\item "\ycenter": the $y$-coordinate of the center point. +\end{itemize} +An expression program may refer to or alter these six dimension registers +explicitly (as well as by calling various macros). + +The expression state may also contain a (perhaps invisible) polygon called +the ``current shadow,'' and a (perhaps invisible) circle called the +``current circle.'' When the current circle is defined, it is determined +by three dimension registers: +\begin{itemize} +\item "\dcircle": the diameter +\item "\xcircle": the $x$-coordinate of the center +\item "\ycircle": the $y$-coordinate of the center. +\end{itemize} +An expression program may refer to or alter these three dimension registers +explicitly (as well as by calling various macros). + +The qualification ``perhaps invisible'' is meant to indicate that the +position, shape, and size of edges, shadows, and circles are established +by one group of macros (e.g. "\setedge", "\rect", "\octagon", "\setcircle"), but +that these entities are actually drawn, i.e. made to appear on the plane +of the diagram or expression state, by another group of macros (e.g. +"\drawsolidedge", "\outline", "\drawcircle"). + +In calls of the diagram macros, a coordinate is sometimes specified by a +dimension, but often it is specified by a number (i.e. integer) that gives +the coordinate as a multiple of the dimension that is the meaning of the +control symbol "\diagramunit". This control symbol is defined to be 1pt, +but the user may redefine it to be some other dimension, either in his main +program or at the beginning of a diagram program. + +In addition to the control symbols discussed in this description, this +collection of macros defines a large number of control symbols that are +normally no concern of the user. To avoid the accidental redefinition +of these symbols by the user, they are all given names beginning with "\zz". + +\cleardoublepage +\section{The General Macros for Diagrams} + +We now describe the general macros for drawing diagrams. The main level +macro is +\begin{myverb} + \diagram{<diagram program>} +\end{myverb} +It executes the diagram program that is its only parameter, and then issues +the final state produced by this program as a horizontal box whose height, +width, and depth are just enough to enclose all of the symbols and lines +in this state, plus the origin (0,0) of the coordinate system. The height +(depth) will be the distance from the horizontal line $y=0$ to the highest +(lowest) extent of any symbol or line. + +Within a diagram program, one can call the following macros: +\begin{myverb} + \vertex<number:x-coord>,<number:y-coord>: + {<balanced mathematical text>}{<expression program>} +\end{myverb} +"\vertex" sets the <balanced mathematical text> in math mode, with text style, +and creates an expression state containing the resulting expression, with +the current rectangle just enclosing the expression. The center point is +placed midway between the left and right sides of the current rectangle, +at a height above the baseline of the expression given by the control +symbol "\centerheight", which is defined to be 3pt. (The effect is to place +the center point on the axis of the expression. However, the user may need +to change the definition of "\centerheight" if he is using unusual fonts or +script style.) The reference point of the expression will lie at the +origin of the coordinate system. + +Next, "\vertex" executes the "<expression program>" to modify the expression +state. Then the material in the expression state is placed in the +current diagram state, at a position so that the center point lies at +the point "<number:x-coord>,<number:y-coord>". Finally, if the expression +state contains a current shadow, the point "<number:x-coord>,<number:y-coord>" +is paired with the shadow and placed on the vertex list. +\begin{myverb} + \place<number:x-coord>,<number:y-coord>: + {<balanced mathematical text>}{<expression program>} + + \placed{<dimen:x-coord>}{<dimen:y-coord>} + {<balanced mathematical text>}{<expression program>} +\end{myverb} +"\place" behaves the same way as "\vertex", except that nothing is placed on the +vertex list. "\placed" behaves the same way as "\place", except that the +coordinates at which the center point is placed are expressed by dimensions +rather than numbers. +\begin{myverb} + \setedge<number:x-start-coord>,<number:y-start-coord>, + <number:x-end-coord>,<number:y-end-coord>: +\end{myverb} +"\setedge" makes the current edge a directed line segment from the point +``start'' given by its first two parameters to the point ``end'' given +by its last two parameters. This line segment is invisible (until it +is drawn by one of the macros discussed below). + +"\setedge" also examines the vertex list to obtain any shadows that have been +associated with the start or end points by prior executions of "\vertex". +\begin{myverb} + \shiftedge{<dimen:length>} +\end{myverb} +"\shiftedge" displaces the current edge by a vector whose length is determined +by the "<dimen:length>" parameter, and whose direction is obtained by rotating +the current edge 90 degrees counterclockwise. +\begin{myverb} + \shadeedge +\end{myverb} +"\shadeedge" changes the extent of the current edge, without displacing +or rotating it, to exclude the portions of the edge lying within shadows +associated with its start and end points. If the execution of "\setedge" that +established the current edge found a shadow associated with the start point, +then "\shadedge" will shorten (or conceivably lengthen) the current edge +so that its start point lies on the boundary of the shadow. (If this is +not possible, the start point will be adjusted to be as close as possible +to the shadow.) The end point is adjusted similarly. +\begin{myverb} + \drawsolidedge +\end{myverb} +"\drawsolidedge" draws the current edge as a solid line. +\begin{myverb} + \drawdashedge{<dimen:length>}{<dimen:length>}{<number>}{<number>} +\end{myverb} +"\drawdashedge" draws the current edge as a dashed line. The dashed line +will always begin and end with a dash. The number of dashes will be as +large as possible subject to the constraint that, if one or more blanks +occur, the dashes will be at least as long as the first parameter and +the blanks will be at least as long as the second parameter. If one or +more blanks occur, the excess length of the dashes and of the blanks +will be proportional to the third and fourth parameters respectively. +The first two parameters must be positive dimensions, and the last two +parameters must be nonnegative numbers whose sum is positive. +\begin{myverb} + \drawdotedge{<dimen:length>}{<1 or 0>} +\end{myverb} +"\drawdotedge" draws the current edge as a dotted line. The number of dots +will be the largest number such that the distance between dots is at least +as large as the first parameter, which must be a positive dimension. +A dot will always appear at the start point, and will appear at the end +point if the second parameter is 1. If the second parameter is 0 then +the final dot will be omitted. +\begin{myverb} + \drawedgehead{<number:0 to 100>}{<1 or 0>}{<1 or 0>} +\end{myverb} +"\drawedgehead" draws an arrowhead on the current edge at a distance from +the start point of $p$ times the length of the edge, where $p$ is the first +parameter divided by 100. The arrowhead will point to the end point if +the second parameter is 1, or to the start point if the second parameter +is 0. If the third parameter is 1, the arrowhead will be advanced towards +its tip by the value of the control symbol "\edgeheaddisp", which is defined +to be 4pt, but may be redefined by the user. +\begin{myverb} + \abutleft<number:y-coord>: + {<balanced mathematical text>}{<expression program>} + + \abutright<number:y-coord>: + {<balanced mathematical text>}{<expression program>} + + \abutbelow<number:x-coord>: + {<balanced mathematical text>}{<expression program>} + + \abutabove<number:x-coord>: + {<balanced mathematical text>}{<expression program>} +\end{myverb} +Each of these macros uses the "<balanced mathematical text>" to initialize +an expression state (in the same way as "\vertex") and then executes +the "<expression program>", which must establish a shadow. The material in +the expression state is then placed in the diagram state, at a location +such that the shadow touches the current edge (or its extension as an +infinite line), and lies to the left (or to the right, below, or above, +as determined by the macro name). For "\abutleft" and "\abutright", which +must not be used when the current edge is horizontal, the first parameter +gives the $y$-coordinate of the point at which the center point is to be +located. For "\abutbelow" and "\abutabove", which must not be used when the +current edge is vertical, the first parameter gives the $x$-coordinate. +\begin{myverb} + \abutleftd{<dimen:y-coord>} + {<balanced mathematical text>}{<expression program>} + + \abutrightd{<dimen:y-coord>} + {<balanced mathematical text>}{<expression program>} + + \abutbelowd{<dimen:x-coord>} + {<balanced mathematical text>}{<expression program>} + + \abutaboved{<dimen:x-coord>} + {<balanced mathematical text>}{<expression program>} +\end{myverb} +Each of these macros behaves the same way as its cousin, described above, +except that the first parameter is a dimension instead of a number. + +Within an expression program, one can call the following macros: +\begin{myverb} + \leftghost{<balanced mathematical text>} + + \rightghost{<balanced mathematical text>} +\end{myverb} +These macros change "\xcenter" (the $x$-coordinate of the center point). +The "<balanced mathematical text>" is set in an hbox, using math mode, +text style, which is ignored except for its width. "\leftghost" sets +"\xcenter" to the left of the current rectangle plus half the width of +the hbox. "\rightghost" sets "\xcenter" to the right of the current rectangle +minus half the width of the hbox. The effect is to place the ``ghost +expression'' (invisibly) within the current rectangle at the left or +right side, and to move the center point horizontally to the midpoint of +the ghost expression. +\begin{myverb} + \border{<dimen:x-length>}{<dimen:y-length>} + + \borderto{<dimen:x-length>}{<dimen:y-length>} + + \symmetrize +\end{myverb} +These macros enlarge the current rectangle. "\border" moves the left and +right sides outwards by its first parameter, and raises the top and lowers +the bottom by its second parameter. (If either parameter is negative, +the rectangle will contract.) "\borderto" enlarges the current rectangle +so that its width is at least the first parameter and its height (including +depth) is at least the second parameter. (Equal amounts will be added at +the left and right, and at the top and bottom.) "\symmetrize" raises the top +or lowers the bottom so that they are equally distant from the center point. +\begin{myverb} + \place<number:x-coord>,<number:y-coord>: + {<balanced mathematical text>}{<expression program>} + + \placed{<dimen:x-coord>}{<dimen:y-coord>} + {<balanced mathematical text>}{<expression program>} +\end{myverb} +These macros can be called from expression programs as well as diagram +programs. They have no effect on the current rectangle or center point. +\begin{myverb} + \rect +\end{myverb} +"\rect" defines the current shadow to be the current rectangle. +\begin{myverb} + \hexagon +\end{myverb} +"\hexagon" defines the current shadow to be a hexagon with two horizontal +sides identical with the top and bottom of the current rectangle, and +four sides of slope (+ or - 1), (+ or - 2). +\begin{myverb} + \octagon{<dimen:length>} +\end{myverb} +"\octagon" defines the current shadow to be an octagon inscribed in the +current rectangle. The horizontal sides and vertical sides are shorter than +those of the current rectangle by twice the parameter, and the remaining +sides have slope (+ or - 1), (+ or - 1). +\begin{myverb} + \diamond +\end{myverb} +"\diamond" defines the current shadow to be a square, just large enough to +enclose the current rectangle, whose sides have slope (+ or - 1), (+ or - 1). +\begin{myverb} + \rorect{<dimen:diameter>}{<1 or 0>}{<1 or 0>} +\end{myverb} +"\rorect defines" the current shadow to be a rectangle with rounded (i.e. +quarter-circle) corners. The diameter of the corners is determined as +follows. +\begin{enumerate} + \item \label{one} Take the maximum of: +\begin{enumerate} + \item the first parameter; + \item if the second parameter is 1, then the width of the current + rectangle, else 0; + \item if the third parameter is 1, then the height of the current + rectangle, else 0. +\end{enumerate} + + \item Take the diameter of the smallest printable circle larger or equal + to (\ref{one}), or if no such printable circle exists, take the diameter + of the largest printable circle. +\end{enumerate} +The shadow is then the smallest rounded rectangle with corners of this +diameter such that the corresponding true (unrounded) rectangle encloses +the current rectangle. + +The effect (if there is a sufficiently large printable circle) is to produce: +\begin{verse} +\begin{tabular}{lcc} + & if the 2nd parameter is & and the 3rd parameter is\\ +\hline + a rounded rectangle & 0& 0 \\ + a vertical oblong & 1& 0 \\ + a horizontal oblong & 0& 1 \\ + a circle & 1& 1 + +\end{tabular} +\end{verse} +If the shadow is drawn (using "\outline", as described below) its shape will +be the rounded rectangle just described. However, if the shadow is used +to shade an edge or to abut an expression to an edge or circle, then a +slight fudge occurs: the shadow is taken to be the smallest octagon +(with the same shape as that produced by "\octagon") enclosing the specified +rounded rectangle. +\begin{myverb} + \outline +\end{myverb} +"\outline" draws the current shadow. +\begin{myverb} + \setcircle{<dimen:diameter>}{<dimen:x-coord>}{<dimen:y-coord>} +\end{myverb} +"\setcircle" defines the current circle to have a diameter given by the first +parameter and a center defined by the second and third parameter. +\begin{myverb} + \shiftcircle{<dimen:x-length>}{<dimen:y-length>} +\end{myverb} +"\shiftcircle" displaces the current circle by the vector described by its +parameters. +\begin{myverb} + \drawcircle<1 or 0:upper right quadrant><1 or 0:lower right quadrant> + <1 or 0:lower left quadrant><1 or 0:upper left quadrant> +\end{myverb} +"\drawcircle" draws the current circle. More precisely, it draws those +quadrants of the current circle for which the corresponding parameter is 1. +\begin{myverb} + \drawcirclehead{<number:x-slope>}{<number:y-slope>}{<1 or 0>} +\end{myverb} +"\drawcirclehead" draws an arrowhead on the current circle, at the +intersection with a directed line segment starting at the center with a +slope determined by the first two parameters. If the third parameter +is 1 (0) the arrowhead will point in a clockwise (counterclockwise) +direction. The arrowhead will be advanced towards its tip by the distance +"\circleheaddisp". This control symbol is defined to be 2pt, but may be +redefined by the user. +\begin{myverb} + \abutcircleleft{<dimen:y-length>} + {<balanced mathematical text>}{<expression program>} + + \abutcircleright{<dimen:y-length>} + {<balanced mathematical text>}{<expression program>} + + \abutcirclebelow{<dimen:x-length>} + {<balanced mathematical text>}{<expression program>} + + \abutcircleabove{<dimen:x-length>} + {<balanced mathematical text>}{<expression program>} +\end{myverb} +Each of these macros uses the "<balanced mathematical text>" to initialize +an expression state (in the same way as "\vertex") and then executes the +"<expression program>", which must establish a shadow. The material in the +final expression state produced by this program is then placed in the +expression state of the expression program containing the call of +"\abutcircle..." , at a location such that shadow touches the current circle +on the outside of this circle. For "\abutcircleleft" and "\abutcircleright" +the first parameter gives the $y$-coordinate of the point at which the center +is to be located. For "\abutcirclebelow" and "\abutcircleabove" the first +parameter gives the $x$-coordinate. + +Actually, the abutment is approximate. For "\abutcircleabove", the shadow +is abutted against three tangents to the current circle, that touch at the +top of the circle and at the two points 45 degrees to the left and right +of the top, and is then given the lowest of the three positions obtained +by these abutments. The other three macros behave similarly. + +\paragraph{An Example} + +Consider the simple example in Figure~\ref{example1}. +This call of "\diagram" contains a diagram program in which the four calls +of "\vertex" place the expressions $A$, $B$, $A'$, and $B'$ at the four corners of +a 100pt by 150pt rectangle. Then come four groups of five calls that +draw edges along the sides of this rectangle and abut expressions to +the middles of these edges. + +In each group, "\setedge" determines the position of the edge, +"\shadeedge" +adjusts the end points to exclude the shadows of the expressions that +have been placed at these points by "\vertex", +"\drawsolidedge" draws the +edge as a solid line, and +"\drawedgehead" places an arrowhead at the end +of the edge. Then "\abut..." places an expression above, below, to the +left, or to the right of the midpoint of the edge, so that its shadow +touches the edge. + +In the calls of "\vertex", + "{\border{3pt}{4pt}\rect}" +is an expression program +that enlarges the current rectangle by 3pt at the left and right and by 4pt +at the top and bottom, and then establishes this expanded rectangle as the +shadow. In the calls of "\abut...", + "{\border{2pt}{2pt}\octagon{3pt}}" +is an +expression program that enlarges the current rectangle by 2pt on each side +and then defines the shadow to be an octagon inscribed in this expanded +rectangle, with slanted edges of length 4.24pt. + +\begin{figure}[t] +\begin{smallverb} + \[ + \diagram{ + \vertex 0,100:{A}{\border{3pt}{4pt}\rect} + \vertex 150,100:{B}{\border{3pt}{4pt}\rect} + \vertex 0,0:{A'}{\border{3pt}{4pt}\rect} + \vertex 150,0:{B'}{\border{3pt}{4pt}\rect} + + \setedge 0,100,150,100: + \shadeedge + \drawsolidedge + \drawedgehead{100}10 + \abutabove 75:{\textstyle c}{\border{2pt}{2pt}\octagon{3pt}} + + \setedge 0,0,150,0: + \shadeedge + \drawsolidedge + \drawedgehead{100}10 + \abutbelow 75:{\textstyle c'}{\border{2pt}{2pt}\octagon{3pt}} + + \setedge 0,100,0,0: + \shadeedge + \drawsolidedge + \drawedgehead{100}10 + \abutleft 50:{\textstyle a}{\border{2pt}{2pt}\octagon{3pt}} + + \setedge 150,100,150,0: + \shadeedge + \drawsolidedge + \drawedgehead{100}10 + \abutright 50:{\textstyle b}{\border{2pt}{2pt}\octagon{3pt}} + } + \] +\end{smallverb} +\caption{A Simple Example} +\label{example1} +\end{figure} +The result is as follows: +\[ +\diagram{ +\vertex 0,100:{A}{\border{3pt}{4pt}\rect} +\vertex 150,100:{B}{\border{3pt}{4pt}\rect} +\vertex 0,0:{A'}{\border{3pt}{4pt}\rect} +\vertex 150,0:{B'}{\border{3pt}{4pt}\rect} +\setedge 0,100,150,100: +\shadeedge +\drawsolidedge +\drawedgehead{100}10 +\abutabove 75:{\textstyle c}{\border{2pt}{2pt}\octagon{3pt}} +\setedge 0,0,150,0: +\shadeedge +\drawsolidedge +\drawedgehead{100}10 +\abutbelow 75:{\textstyle c'}{\border{2pt}{2pt}\octagon{3pt}} +\setedge 0,100,0,0: +\shadeedge +\drawsolidedge +\drawedgehead{100}10 +\abutleft 50:{\textstyle a}{\border{2pt}{2pt}\octagon{3pt}} +\setedge 150,100,150,0: +\shadeedge +\drawsolidedge +\drawedgehead{100}10 +\abutright 50:{\textstyle b}{\border{2pt}{2pt}\octagon{3pt}} +} +\] + +\cleardoublepage +\section{The Macros for Category-Theory Diagrams} + +Now we describe the additional macros oriented towards category-theory +diagrams. The main level program is +\begin{myverb} + \ctdiagram{<diagram program>} +\end{myverb} +"\ctdiagram" is similar to "\diagram", except that it executes "\ctsolid", +"\cthead", and "\ctoutermid" (described below) before the "<diagram program>", +so that the category-theory macros for drawing edges will draw solid edges +with arrowheads and will calculate midpoints of edges before shading or +displacement. + +Within a diagram program, one can call the following macros (in addition +to the general macros described previously): +\begin{myverb} + \ctvg<number:x-coord>,<number:y-coord>: + {<balanced mathematical text>}{<expression program>} + + \ctv<number:x-coord>,<number:y-coord>:{<balanced mathematical text>} +\end{myverb} +"\ctvg" is similar to "\vertex", except that: +\begin{enumerate} + \item The "<balanced mathematical text>" is set in "\ctvertexstyle". + The control symbol "\ctvertexstyle" is defined to be "\displaystyle", + but may be redefined by the user. + + \item The execution of the "<expression program>" is followed by a + ``standard expression program'' that enlarges the current rectangle + by "\ctvertexborderlr" on the left and right and by "\ctvertexbordertb" + on the top and bottom, and then creates a rectangular shadow of the + same size. The control symbols "\ctvertexborderlr" and "\ctvertexbordertb" + are defined to be 3pt and 4pt respectively, but may be redefined + by the user. +\end{enumerate} +"\ctv" is similar to "\ctvg" except that only the standard expression program +is executed. +\begin{myverb} + \ctsolid + + \ctdash + + \ctdot +\end{myverb} +These macros cause subsequent executions of the edge-drawing macros described +below to draw solid, dashed, or dotted edges respectively. Horizontal and +vertical dashed edges are drawn by "\drawdashedge{7pt}{7pt}11", but other +dashed edges are drawn by "\drawdashedge{15pt}{7pt}01". Dotted edges are +drawn by "\drawdotedge{8pt}1". (These conventions can be altered by redefining +the macros "\zzctdrawdashedge" and "\zzctdrawdotedge".) +\begin{myverb} + \cthead + + \ctnohead +\end{myverb} +"\cthead" ("\ctnohead") causes subsequent executions of the edge-drawing macros +described below to draw (not to draw) arrowheads. +\begin{myverb} + \cten<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>: +\end{myverb} +"\cten" draws an edge from $x$-start to $x$-end, after shading the start and end +points with any shadows associated with these points on the vertex list. +The edge will be solid, dashed, or dotted depending upon whether "\ctsolid", +"\ctdash", or "\ctdot" was called last. An arrowhead will or will not be placed +at the end point depending upon whether "\cthead" or "\ctnohead" was called last. +\begin{myverb} + \ctetg<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>;<number:x-coord>:{<balanced mathematical text>} + + \ctebg<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>;<number:x-coord>:{<balanced mathematical text>} + + \ctelg<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>;<number:y-coord>:{<balanced mathematical text>} + + \cterg<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>;<number:y-coord>:{<balanced mathematical text>} +\end{myverb} +Each of these macros draws an edge in the same way as "\cten", and then abuts +the "<balanced mathematical text>" to the +\begin{verse} +\begin{tabular}{lll} + top & for & "\ctetg" \\ + bottom & for & "\ctebg" \\ + left & for & "\ctelg" \\ + right & for & "\cterg" \\ +\end{tabular} +\end{verse} +of the edge, with its center placed at the $x$-coordinate (for "\ctetg" or +"\ctebg") or $y$-coordinate (for "\ctelg" or "\cterg") specified by the fifth +parameter. The abutted expression is set in "\ctabutstyle", with an octagonal +shadow (of the shape produced by "\octagon"). This octagon will be inscribed +in a rectangle obtained by bordering the expression by "\ctabutborderlr" +on the left and right, and by "\ctabutbordertb" on the top and bottom; +the length of the slanted sides of the octagon will be "\ctabutborderinset" +times the square root of 2. + +The relevant control symbols are defined to be: +\begin{verse} +\begin{tabular}{lc} + + "\ctabutstyle" & "\textstyle" \\ + "\ctabutborderlr" & 2pt \\ + "\ctabutbordertb" & 2pt \\ + "\ctabutborderinset" & 3pt \\ +\end{tabular} +\end{verse} +These symbols may be redefined by the user, but "\ctabutborderinsetdouble" +must also be redefined so that its value is twice "\ctabutborderinset". + +"\ctetg" and "\ctebg" should not be used to draw a vertical edge; "\ctelg" and +"\cterg" should not be used to draw a horizontal edge. +\begin{myverb} + \ctetbg<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>;<number:x-coord>,<number:x-coord>: + {<1 or 0>}{<1 or 0>} + {<balanced mathematical text>}{<balanced mathematical text>} +\end{myverb} +"\ctetbg" draws a pair of edges in the same manner as "\cten" and then abuts +the first "<balanced mathematical text>" above the pair, in the same manner +as "\ctetg", with its center placed at the $x$-coordinate specified by the +fifth parameter, and abuts the second "<balanced mathematical text>" below +the pair, in the same manner as "\ctebg", with its center placed at the +$x$-coordinate specified by the sixth parameter. If the seventh parameter +is 1 (and "\cthead" has been called most recently), the arrowhead on the upper +edge will occur at the end point; otherwise it will occur (pointing +backwards) at the start point. The eighth parameter controls the arrowhead +on the lower edge similarly. The distance between the edges will be twice +the control symbol "\ctdoubleedgedisp", which is defined to be 2pt, but may +be redefined by the user. + +"\ctetbg" should not be used to draw a vertical edge. +\begin{myverb} + \ctelrg<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>;<number:y-coord>,<number:y-coord>: + {<1 or 0>}{<1 or 0>} + {<balanced mathematical text>}{<balanced mathematical text>} +\end{myverb} +"\ctelrg" draws a pair of edges in the same manner as "\cten" and then abuts +the first "<balanced mathematical text>" to the left, in the same manner +as "\ctetg", with its center placed at the $y$-coordinate specified by the +fifth parameter, and abuts the second "<balanced mathematical text>" to +the right, in the same manner as "\ctebg", with its center placed at the +$y$-coordinate specified by the sixth parameter. If the seventh parameter +is 1 (and "\cthead" has been called most recently), the arrowhead on the left +edge will occur at the end point; otherwise it will occur (pointing +backwards) at the start point. The eighth parameter controls the arrowhead +on the right edge similarly. The distance between the edges will be twice +the control symbol "\ctdoubleedgedisp", which is defined to be 2pt, but may +be redefined by the user. + +"\ctelrg" should not be used to draw a horizontal edge. +\begin{myverb} + \ctet<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>:{<balanced mathematical text>} + + \cteb<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>:{<balanced mathematical text>} + + \ctel<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>:{<balanced mathematical text>} + + \cter<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>:{<balanced mathematical text>} + + \ctetb<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>:{<1 or 0>}{<1 or 0>} + {<balanced mathematical text>}{<balanced mathematical text>} + + \ctelr<number:x-start-coord>,<number:y-start-coord>,<number:x-end-coord>, + <number:y-end-coord>:{<1 or 0>}{<1 or 0>} + {<balanced mathematical text>}{<balanced mathematical text>} +\end{myverb} +These macros behave similarly to their cousins described above, except that +the fifth parameter (and also the sixth parameter in the case of "\ctetb" and +"\ctelr") is omitted. In its place, these macros use the $x$- or $y$-coordinate +of the midpoint between the start and end points of the edge. If "\ctoutermid" +(described below) has been called most recently, then the midpoint will +be calculated from the start and end coordinates given as parameters to the +macros. If "\ctinnermid" (described below) has been called most recently, +then the midpoint will be computed after displacement and shading, so that +it will be the midpoint of the actual line segment that is printed. +(In the case of "\ctetb" and "\ctelr", this midpoint will be calculated +separately for the two edges that are printed.) +\begin{myverb} + \ctoutermid + + \ctinnermid +\end{myverb} +These macros control the calculation of edge midpoints as described above. + +Within a expression program, one can call the following macros (in addition +to the general macros described previously): +\begin{myverb} + \ctgl{<balanced mathematical text>} + + \ctgr{<balanced mathematical text>} +\end{myverb} +These macros are similar to "\leftghost" and "\rightghost" except that the +"<balanced mathematical text>" is set in "\ctvertexstyle". +\begin{myverb} + \ctlptl{<balanced mathematical text>} + + \ctlptr{<balanced mathematical text>} + + \ctlpbr{<balanced mathematical text>} + + \ctlpbl{<balanced mathematical text>} +\end{myverb} +These macros print a loop (three quarters of a circle) of diameter +"\ctloopdiameter" on the exterior of the current rectangle, with its center +at the +\begin{verse} +\begin{tabular}{lll} + + top left & for & "\ctlptl" \\ + top right & for & "\ctlptr" \\ + bottom right & for & "\ctlpbr" \\ + bottom left & for & "\ctlpbl" +\end{tabular} +\end{verse} +corner of the current rectangle, and with a clockwise arrowhead at the +clockwise end of the loop. Then the "<balanced mathematical text>" is +abutted to the +\begin{verse} +\begin{tabular}{lll} + + left & for & "\ctlptl" \\ + right & for & "\ctlptr" \\ + right & for & "\ctlpbr" \\ + left & for & "\ctlpbl" +\end{tabular} +\end{verse} +of the loop, with its center +\begin{verse} +\begin{tabular}{lll} + + above & for & "\ctlptl" \\ + above & for & "\ctlptr" \\ + below & for & "\ctlpbr" \\ + below & for & "\ctlpbl" +\end{tabular} +\end{verse} +the center of the loop by the distance \ctabutcircledisp. + +The control symbols "\ctloopdiameter" and "\ctabutcircledisp" are defined to be +20pt and 5pt respectively, but may be redefined by the user. + +The current rectangle is expanded by "\ctvertexborderlr" at the left and right +and by "\ctvertexbordertb" at the top and bottom before the loop center +is determined, and is contracted to its original size afterwards. Thus +the loop center will lie at a corner of the shadow that will be produced +by the ``standard expression program'' executed by "\ctvg". (Actually, the +loop center is displaced by "\circleheaddisp", so that the tip of the +arrowhead will just touch the shadow.) The arrowhead is always printed, +regardless of the use of "\cthead" and "\ctnohead". + +The "<balanced mathematical text>" is set in "\ctabutstyle", and is given an +octagonal shadow in the same manner as by "\ctetg". The abutment to the loop +is similar to that performed by "\abutcircleleft" or "\abutcircleright". +\begin{myverb} + \ctlptlcc{<balanced mathematical text>} + + \ctlptrcc{<balanced mathematical text>} + + \ctlpbrcc{<balanced mathematical text>} + + \ctlpblcc{<balanced mathematical text>} +\end{myverb} +These macros are similar to their cousins described above, except that a +counterclockwise arrowhead is placed at the counterclockwise end of the loop. + +\paragraph{An Example} + +The following program produces the same display as the previous +example. +\begin{myverb} + \[ + \ctdiagram{ + \ctv 0,100:{A} + \ctv 150,100:{B} + \ctv 0,0:{A'} + \ctv 150,0:{B'} + \ctet 0,100,150,100:{c} + \cteb 0,0,150,0:{c'} + \ctel 0,100,0,0:{a} + \cter 150,100,150,0:{b} + } + \] +\end{myverb} +Less trivial examples of the usage of these macros are found in Section~\ref{examples} and +in "diagmactest.tex". + +\cleardoublepage +\section{Extensions} +\label{extensions} + +This section describes two macros that have been +added to "diagmac2.sty" +by Bob Tennent (and are not in Reynolds's original "diagmac"). + +\begin{myverb} + \drawedgebar +\end{myverb} +"\drawedgebar" draws a bar across the end of the current edge. +\begin{myverb} + \ctec<number:x-start-coord>,<number:y-start-coord>, + <number:x-end-coord>,<number:y-end-coord>, + <number:x-ctrl-coord>,<number:y-ctrl-coord>:{<balanced mathematical text>} +\end{myverb} +"\ctec" draws a bezier-curve edge from the start point to the end point, using the +third point as a control point. The "<balanced mathematical text>" is centered at +the control point. + +\section{Examples} +\label{examples} + +\begin{minipage}[t]{2.9in} + \[ +\ctdiagram{ + \def\diagramunit{0.8pt} + \ctinnermid + \ctv 0,100:{a} + \ctv 150,100:{f(a)} + \ctv 0,0:{g(a)} + \ctv 150,0:{f(g(a))=g(f(a))} + \ctet 0,100,150,100:{f} + \drawedgebar + \cteb 0,0,150,0:{f} + \drawedgebar + \ctel 0,100,0,0:{g} + \drawedgebar + \cter 150,100,150,0:{g} + \drawedgebar +} +\] +\end{minipage} +\qquad +\begin{minipage}[t]{3.0in} +\begin{smallverb} +\[ +\ctdiagram{ + \def\diagramunit{0.8pt} + \ctinnermid + \ctv 0,100:{a} + \ctv 150,100:{f(a)} + \ctv 0,0:{g(a)} + \ctv 150,0:{f(g(a))=g(f(a))} + \ctet 0,100,150,100:{f} + \drawedgebar + \cteb 0,0,150,0:{f} + \drawedgebar + \ctel 0,100,0,0:{g} + \drawedgebar + \cter 150,100,150,0:{g} + \drawedgebar +} +\] +\end{smallverb} +\end{minipage} +\\[4ex] + +\begin{minipage}[t]{3.1in} +\[ +\ctdiagram{ +\def\diagramunit{1.1pt} +\ctv 0,0: {I\otimes v} +\ctv 0,60: {(I\otimes I)\otimes v} +\ctv -80,60: {I\otimes (I\otimes v)} +\ctv 80,60: {I\otimes (I\otimes v)} +\ctelg -80,60,0,0;25:{I\otimes\lambda_v\!} +\cterg 80,60,0,0;25:{\,\lambda{_I\otimes v}} +\ctec -80,60,80,60,0,80:{\mathsf{id}} +\cteb -80,60,0,60:{\alpha^{-1}} +\cteb 0,60,80,60:{\alpha^{-1}} +\ctv 0,36:{\rho_I\otimes v = + \lambda_I\otimes v} +\ctnohead +\cten 0,60,0,36: +\cthead +\cten 0,36,0,0: +} +\] +\end{minipage} +\qquad +\begin{minipage}[t]{3.0in} +\begin{smallverb} +\[ +\ctdiagram{ + \ctv 0,0: {I\otimes v} + \ctv 0,60: {(I\otimes I)\otimes v} + \ctv -80,60: {I\otimes (I\otimes v)} + \ctv 80,60: {I\otimes (I\otimes v)} + \ctelg -80,60,0,0;25:{I\otimes\lambda_v\!} + \cterg 80,60,0,0;25:{\,\lambda{_I\otimes v}} + \ctec -80,60,80,60,0,80:{\mathsf{id}} + \cteb -80,60,0,60:{\alpha^{-1}} + \cteb 0,60,80,60:{\alpha^{-1}} + \ctv 0,36:{\rho_I\otimes v = + \lambda_I\otimes v} + \ctnohead + \cten 0,60,0,36: + \cthead + \cten 0,36,0,0: +} +\] +\end{smallverb} +\end{minipage} + +\clearpage + +\begin{minipage}[t]{3.0in} +\[ +\ctdiagram{ +\ctv -60,0:{V} +\ctv 60,0:{E} +\ctv 0,0: {I} +\cten 0,0,60,0: +\ctnohead +\cten -60,0,0,0: +\ctet -50,20,50,20:{\delta_0} +\setcircle{20pt}{\xstart}{\ystart} +\shiftcircle{0pt}{-10pt} +\drawcircle0001 +\drawcirclehead{-1}{0}{0} +\setcircle{20pt}{\xend}{\yend} +\shiftcircle{0pt}{-10pt} +\drawcircle1000 +\cteb -50,-18,50,-18:{\delta_1} +\setcircle{20pt}{\xstart}{\ystart} +\shiftcircle{0pt}{10pt} +\drawcircle0010 +\drawcirclehead{-1}{0}{1} +\setcircle{20pt}{\xend}{\yend} +\shiftcircle{0pt}{10pt} +\drawcircle0100 +} +\] +\end{minipage} +\qquad +\begin{minipage}[t]{3.0in} +\begin{smallverb} +\[ +\ctdiagram{ + \ctv -60,0:{V} + \ctv 60,0:{E} + \ctv 0,0: {I} + \cten 0,0,60,0: + \ctnohead + \cten -60,0,0,0: + \ctet -50,20,50,20:{\delta_0} + \setcircle{20pt}{\xstart}{\ystart} + \shiftcircle{0pt}{-10pt} + \drawcircle0001 + \drawcirclehead{-1}{0}{0} + \setcircle{20pt}{\xend}{\yend} + \shiftcircle{0pt}{-10pt} + \drawcircle1000 + \cteb -50,-18,50,-18:{\delta_1} + \setcircle{20pt}{\xstart}{\ystart} + \shiftcircle{0pt}{10pt} + \drawcircle0010 + \drawcirclehead{-1}{0}{1} + \setcircle{20pt}{\xend}{\yend} + \shiftcircle{0pt}{10pt} + \drawcircle0100 +} +\] +\end{smallverb} +\end{minipage} +\\[4ex] + +\begin{minipage}[t]{3.0in} +\[ +\ctdiagram{ +\ctv 0,0:{\widetilde{B}} +\ctv 60,0:{B} +\ctv 0,60:{E_b} +\ctv 60,60:{E} +\ctinnermid +\cteb 0,0,60,0:{b} +\cter 0,60,0,0:{q_b} +\cteb 0,60,60,60:{\overline{b}} +\cter 60,60,60,0:{q} +\ctv -40,100: {\widetilde{E}} +\ctec -40,100,0,0,-40,50:{\tilde{q}} +\ctec -40,100,60,60,10,100:{p} +\def\ctvertexborderlr{1pt} +\def\ctvertexbordertb{1pt} +\ctv -20,80:{\hat{p}} +\ctnohead\ctdot +\def\zzctdrawdotedge{\drawdotedge{2.5pt}1} +\cten -40,100,-20,80: +\cthead +\def\zzctdrawdotedge{\drawdotedge{2.5pt}0} +\cten -20,80,-6,66: +\ctv 5,55:{\mbox{\Large$\lrcorner$}} +} +\] +\end{minipage} +\qquad +\begin{minipage}[t]{3.0in} +\begin{smallverb} +\[ +\ctdiagram{ + \ctv 0,0:{\widetilde{B}} + \ctv 60,0:{B} + \ctv 0,60:{E_b} + \ctv 60,60:{E} + \ctinnermid + \cteb 0,0,60,0:{b} + \cter 0,60,0,0:{q_b} + \cteb 0,60,60,60:{\overline{b}} + \cter 60,60,60,0:{q} + \ctv -40,100: {\widetilde{E}} + \ctec -40,100,0,0,-40,50:{\tilde{q}} + \ctec -40,100,60,60,10,100:{p} + \def\ctvertexborderlr{1pt} + \def\ctvertexbordertb{1pt} + \ctv -20,80:{\hat{p}} + \ctnohead\ctdot + \def\zzctdrawdotedge{\drawdotedge{2.5pt}1} + \cten -40,100,-20,80: + \cthead + \def\zzctdrawdotedge{\drawdotedge{2.5pt}0} + \cten -20,80,-6,66: + \ctv 5,55:{\mbox{\Large$\lrcorner$}} +} +\] +\end{smallverb} +\end{minipage} + +\clearpage +\vspace*{-4ex} +\[ +\ctdiagram{ +\ctinnermid +\ctv 0,0: {(I\otimes I) \otimes(v\otimes w)} +\ctv 0,60: {I\otimes \bigl(I\otimes(v\otimes w)\bigr)} +\ctv 0,120: {I\otimes \bigl((I\otimes v)\otimes w\bigr)} +\ctv 80,180: {I\otimes\bigl((v\otimes I)\otimes w\bigr)} +\ctv 200,0: {I\otimes (v\otimes w)} +\ctv 200,180:{I\otimes \bigl(v\otimes(I\otimes w)\bigr)} +\ctv 280,0:{v\otimes w} +\ctv 280,60:{(I\otimes v)\otimes w} +\ctv 280,120: { (I\otimes v)\otimes(I\otimes w)} +\ctel 0,0,0,60:{\alpha^{-1}} +\ctel 0,60,0,120:{I\otimes \alpha^{-1}} +\ctet 0,0,200,0:{\rho_I\otimes(v\otimes v)} +\ctet 200,0,280,0:{\lambda_{v\otimes w}} +\ctelg 0,120,80,180;155:{I\otimes\sigma_{I,v}\otimes w} +\ctet 80,180,200,180:{I\otimes \alpha^{-1}} +\cterg 200,180,280,120;155:{\alpha^{-1}} +\cter 280,120,280,60:{(I\otimes v)\otimes \lambda_w} +\cter 280,60,280,0: {\lambda_v\otimes w} +\ctv 240,30:{\alpha^{-1}} +\ctnohead +\cten 200,0,240,30: +\cthead +\cten 240,30,280,60: +\ctv 100,30:{I\otimes\lambda_{v\otimes w}} +\ctnohead +\cten 0,60,100,30: +\cthead +\cten 100,30,200,0: +\ctv 100,60:{I\otimes(\lambda_v\otimes w)} +\ctnohead +\cten 0,120,100,60: +\cthead +\cten 100,60,200,0: +\ctv 120,120:{I\otimes (\rho_v\otimes w)} +\ctnohead +\cten 80,180,120,120: +\cthead +\cten 120,120,200,0: +\ctv 200,90:{I\otimes (v\otimes \lambda_w)} +\ctnohead +\cten 200,180,200,90: +\cthead +\cten 200,90,200,0: +} +\] +\\ +\begin{smallverb} + \[ + \ctdiagram{\ctinnermid + \ctv 0,0: {(I\otimes I) \otimes(v\otimes w)} + \ctv 0,60: {I\otimes \bigl(I\otimes(v\otimes w)\bigr)} + \ctv 0,120: {I\otimes \bigl((I\otimes v)\otimes w\bigr)} + \ctv 80,180: {I\otimes\bigl((v\otimes I)\otimes w\bigr)} + \ctv 200,0: {I\otimes (v\otimes w)} + \ctv 200,180:{I\otimes \bigl(v\otimes(I\otimes w)\bigr)} + \ctv 280,0:{v\otimes w} + \ctv 280,60:{(I\otimes v)\otimes w} + \ctv 280,120: { (I\otimes v)\otimes(I\otimes w)} + \ctel 0,0,0,60:{\alpha^{-1}} + \ctel 0,60,0,120:{I\otimes \alpha^{-1}} + \ctet 0,0,200,0:{\rho_I\otimes(v\otimes v)} + \ctet 200,0,280,0:{\lambda_{v\otimes w}} + \ctelg 0,120,80,180;155:{I\otimes\sigma_{I,v}\otimes w} + \ctet 80,180,200,180:{I\otimes \alpha^{-1}} + \cterg 200,180,280,120;155:{\alpha^{-1}} + \cter 280,120,280,60:{(I\otimes v)\otimes \lambda_w} + \cter 280,60,280,0: {\lambda_v\otimes w} + \ctv 240,30:{\alpha^{-1}} + \ctnohead\cten 200,0,240,30: + \cthead\cten 240,30,280,60: + \ctv 100,30:{I\otimes\lambda_{v\otimes w}} + \ctnohead\cten 0,60,100,30: + \cthead\cten 100,30,200,0: + \ctv 100,60:{I\otimes(\lambda_v\otimes w)} + \ctnohead\cten 0,120,100,60: + \cthead \cten 100,60,200,0: + \ctv 120,120:{I\otimes (\rho_v\otimes w)} + \ctnohead\cten 80,180,120,120: + \cthead\cten 120,120,200,0: + \ctv 200,90:{I\otimes (v\otimes \lambda_w)} + \ctnohead\cten 200,180,200,90: + \cthead\cten 200,90,200,0: + } + \] +\end{smallverb} + +\clearpage + +\newcommand{\op}{\mathsf{op}} +\newcommand{\vnat}{\Downarrow\mskip-\medmuskip} +\[ +\ctdiagram{ +\ctinnermid +\ctv 0,0:{W^\op\times W^\op} +\ctv 180,0:{S\times S} +\ctv 0,60:{RW^\op} +\ctv 180,60:{RS} +\ctel 0,60,0,0:{\mathit{rw}^\op} +\cter 180,60,180,0:{\mathit{rs}} +\def\ctdoubleedgedisp{6.5pt} +\ctetb 0,60,180,60:11{\widetilde{F}}{\widetilde{G}} +\ctv 98,60:{\vnat\widetilde{\eta}} +\ctetb 0,0,180,0:11{F_0\times F_1}{G_0\times G_1} +\ctv 112,0:{\vnat\eta_0\times\eta_1} +} +\] +\\[4ex] + +\begin{smallverb} + \newcommand{\op}{\mathsf{op}} + \newcommand{\vnat}{\Downarrow\mskip-\medmuskip} + \[ + \ctdiagram{ + \ctinnermid + \ctv 0,0:{W^\op\times W^\op} + \ctv 180,0:{S\times S} + \ctv 0,60:{RW^\op} + \ctv 180,60:{RS} + \ctel 0,60,0,0:{\mathit{rw}^\op} + \cter 180,60,180,0:{\mathit{rs}} + \def\ctdoubleedgedisp{6.5pt} + \ctetb 0,60,180,60:11{\widetilde{F}}{\widetilde{G}} + \ctv 98,60:{\vnat\widetilde{\eta}} + \ctetb 0,0,180,0:11{F_0\times F_1}{G_0\times G_1} + \ctv 112,0:{\vnat\eta_0\times\eta_1} + } + \] +\end{smallverb} + + +See also the examples in Reynolds's "diagmactest". + + + +\end{document} diff --git a/macros/latex/contrib/diagmac2/doc/diagmactest.pdf b/macros/latex/contrib/diagmac2/doc/diagmactest.pdf Binary files differnew file mode 100644 index 0000000000..ec4f0136fa --- /dev/null +++ b/macros/latex/contrib/diagmac2/doc/diagmactest.pdf diff --git a/macros/latex/contrib/diagmac2/doc/diagmactest.tex b/macros/latex/contrib/diagmac2/doc/diagmactest.tex new file mode 100644 index 0000000000..a4ee5e99f4 --- /dev/null +++ b/macros/latex/contrib/diagmac2/doc/diagmactest.tex @@ -0,0 +1,403 @@ +%TESTS OF DIAGRAM MACROS - J. C. Reynolds - December 1987 + +%This is an input file for LATEX that inputs the macros in diagmac.tex +%and tests them. A user's manual for these macros is in diagmac.doc + +\documentclass[12pt]{article} +\input diagmac +\oddsidemargin=0in +\evensidemargin=0in +\textwidth=6.5in +\begin{document} + +\thispagestyle{empty} + +\begin{centering} +{\large\bf TESTS OF DIAGRAM MACROS} \\[14 pt] +\today \\[21 pt] +\end{centering} + + +%These are the two examples given in the user's manual. + +$$\diagram{ +\vertex 0,100:{A}{\border{3pt}{4pt}\rect} +\vertex 150,100:{B}{\border{3pt}{4pt}\rect} +\vertex 0,0:{A'}{\border{3pt}{4pt}\rect} +\vertex 150,0:{B'}{\border{3pt}{4pt}\rect} +\setedge 0,100,150,100: +\shadeedge +\drawsolidedge +\drawedgehead{100}10 +\abutabove 75:{\textstyle c}{\border{2pt}{2pt}\octagon{3pt}} +\setedge 0,0,150,0: +\shadeedge +\drawsolidedge +\drawedgehead{100}10 +\abutbelow 75:{\textstyle c'}{\border{2pt}{2pt}\octagon{3pt}} +\setedge 0,100,0,0: +\shadeedge +\drawsolidedge +\drawedgehead{100}10 +\abutleft 50:{\textstyle a}{\border{2pt}{2pt}\octagon{3pt}} +\setedge 150,100,150,0: +\shadeedge +\drawsolidedge +\drawedgehead{100}10 +\abutright 50:{\textstyle b}{\border{2pt}{2pt}\octagon{3pt}} +}$$ + +$$\ctdiagram{ +\ctv 0,100:{A} +\ctv 150,100:{B} +\ctv 0,0:{A'} +\ctv 150,0:{B'} +\ctet 0,100,150,100:{c} +\cteb 0,0,150,0:{c'} +\ctel 0,100,0,0:{a} +\cter 150,100,150,0:{b} +}$$ + +\newpage + +%This gives a thorough workout to the general macros for diagrams. +%The result looks like an eye-chart for Martians. + +$$\diagram{ +\vertex -150,0:{X+Y}{\border{4pt}{3pt}\rorect{2pt}01\outline} +\vertex 0,-50:Y{\border{10pt}{10pt}\hexagon\outline} +\vertex 150,0:\sum{\border{10pt}{10pt}\octagon{10pt}\outline + \border{5pt}{5pt}\octagon{12pt}\thicklines\outline\thinlines} +\vertex -100,150:\alpha{\border{4pt}{3pt}\diamond\outline} +\vertex 100,150:\sum{\border{10pt}{10pt}\rorect{20pt}00\outline + \border{5pt}{5pt}\rorect{24pt}00\thicklines\outline\thinlines} +\vertex 0,200:{X^2+Y^2}{\border{4pt}{3pt}\rect\outline} +\place -150,-150:{X+Y^{Z^2}} + {\leftghost X\symmetrize\borderto{0pt}{0pt}\border{4pt}{3pt}\rect\outline + \setcircle{16pt}{\xcenter}{\bexpr}\drawcircle0110 + \drawcirclehead{0}{-1}1 + \abutcirclebelow{-10pt}\alpha{\border{2pt}{2pt}\rect\outline} + \abutcirclebelow{10pt}\alpha{\border{2pt}{2pt}\rect\outline}} +\placed{150pt}{-150pt}{X+Y} + {\rightghost Y\symmetrize\borderto{0pt}{26pt}\border{4pt}{0pt}\rect\outline + \placed{\lexpr}{\ycenter}{\vrule height3.2pt depth-2.8pt width10pt}{} + \place 0,-3:{\vrule height3.2pt depth-2.8pt width10pt}{\xcenter=\lexpr} + \setcircle{16pt}{\rexpr}{\texpr}\shiftcircle{8pt}{8pt}\drawcircle1101 + \drawcirclehead{0}{-1}1\drawcirclehead{-1}00 + \abutcircleabove{0pt}\alpha{\border{2pt}{2pt}\rect\outline}} +\vertex 0,-150:{}{\setcircle{40pt}{\xcenter}{\ycenter}\drawcircle1111 + \drawcirclehead231\drawcirclehead{-2}30 + \drawcirclehead6{-9}0\drawcirclehead{-4}{-6}1 + \abutcircleleft{0pt}\alpha{\border{2pt}{2pt}\rect\outline} + \abutcircleright{20pt}\alpha{\border{2pt}{2pt}\rect\outline} + \abutcircleright{0pt}\alpha{\border{2pt}{2pt}\rect\outline} + \abutcircleright{-20pt}\alpha{\border{2pt}{2pt}\rect\outline}} +\setedge 0,200,-100,150:\shadeedge\drawsolidedge\drawedgehead{100}10 + \abutleft 185:{\alpha+\beta}{\border{2pt}{2pt}\rorect{5pt}01\outline} +\setedge 0,200,100,150:\shadeedge\drawsolidedge\drawedgehead{100}10 + \abutright 185:{\alpha+\beta}{\border{2pt}{2pt}\rorect{5pt}01\outline} +\setedge -150,0,0,-50:\shadeedge\drawdashedge{11pt}{10pt}01\drawedgehead{80}01 + \abutleftd{-25pt}{\alpha\beta} + {\border{2pt}{2pt}\borderto{25pt}{0pt}\rect\outline} +\setedge -150,0,150,0:\drawedgehead{50}01\shadeedge\drawsolidedge + \abutabove -10:\rho{\border{2pt}{2pt}\diamond\outline} +\setedge -150,0,-100,150:\shadeedge\drawsolidedge\drawedgehead{100}10 + \abutleft 75:\rho{\border{10pt}{10pt}\octagon{10pt}\outline} +\setedge -150,0,100,150:\shadeedge\drawdotedge{7pt}1 + \abutaboved{-100pt}\rho{\border{10pt}{10pt}\hexagon\outline} +\setedge 0,-50,150,0:\shadeedge\drawsolidedge\drawedgehead{20}11 + \abutrightd{-25pt}\rho{\border{2pt}{2pt}\borderto{25pt}{0pt}\rect\outline} +\setedge 0,-50,-100,150:\shadeedge\drawsolidedge +\setedge 0,-50,100,150:\shadeedge\drawsolidedge +\setedge 150,0,-100,150:\shadeedge\drawsolidedge + \abutbelowd{100pt}\rho{\border{10pt}{10pt}\hexagon\outline} +\setedge 150,0,100,150:\shadeedge\drawdashedge{40pt}{40pt}11\drawedgehead000 + \abutleft 75:\rho{\border{10pt}{10pt}\hexagon\outline} + \shiftedge{-10pt}\shadeedge\drawdashedge{30pt}{30pt}10\drawedgehead000 + \shiftedge{-10pt}\shadeedge\drawdashedge{11pt}{5pt}01\drawedgehead000 + \shiftedge{-10pt}\shadeedge\drawdotedge{8pt}0\drawedgehead{100}10 + \abutright 75:\rho{\border{5pt}{5pt}\rorect{5pt}11\outline} +\setedge -100,150,100,150:\drawedgehead{50}11\shadeedge\drawsolidedge + \abutbelow 0:\rho{\border{2pt}{2pt}\rect\outline} +\setedge 0,-50,-150,-150:\thicklines\drawedgehead{50}01\thinlines + \shadeedge\drawdashedge{13pt}{3pt}01\drawedgehead{50}11 + \abutbelow -50:{X \atop Y}{\border{2pt}{2pt}\rorect{5pt}10\outline} +\setedge 0,-50,0,-150:\thicklines\shadeedge\drawsolidedge\thinlines +\setedge 0,-50,150,-150:\shadeedge\drawsolidedge + \abutabove 75:{X \atop Y}{\border{2pt}{2pt}\rorect{5pt}10\outline} +\setedge -175,-50,-175,-100:\drawdashedge{10pt}{31pt}11 +\setedge -165,-100,-165,-50:\drawdashedge{15pt}{15pt}01 +\setedge -155,-50,-155,-100:\drawdashedge{5pt}{5pt}11 +\setedge -145,-100,-145,-50:\drawdotedge{26pt}1 +\setedge -135,-50,-135,-100:\drawdotedge{25pt}1 +\setedge -125,-100,-125,-50:\drawdotedge{5pt}1 +\setedge 125,-50,175,-50:\drawdashedge{10pt}{31pt}11 +\setedge 175,-60,125,-60:\drawdashedge{15pt}{15pt}01 +\setedge 125,-70,175,-70:\drawdashedge{5pt}{5pt}11 +\setedge 175,-80,125,-80:\drawdotedge{26pt}1 +\setedge 125,-90,175,-90:\drawdotedge{25pt}1 +\setedge 175,-100,125,-100:\drawdotedge{5pt}1 +}$$ + +\newpage + +%These three diagrams test the macros for category-theory diagrams. + +$$\ctdiagram{ +\ctvg0,0:{Y'}{\ctlpbl{I_{Y'}}} +\ctvg150,0:{Z=Z_0}{\ctgl{Z}\ctlpbr{I_Z}} +\ctvg0,100:{X_0=X}{\ctgr{X}\ctlptl{I_X}} +\ctvg150,100:{Y}{\ctlptr{I_Y}} +\ctet0,100,150,100:\alpha +\cteb0,0,150,0:{\beta'} +\ctel0,100,0,0:{\alpha'} +\cter150,100,150,0:\beta +\ctetb0,100,150,0:11{\alpha;\beta}{\alpha';\beta'} +}$$ + +$$\ctdiagram{\ctdash +\ctvg0,0:{Y'}{\ctlpblcc{I_{Y'}}} +\ctvg150,0:{Z=Z_0}{\ctgl{Z}\ctlpbrcc{I_Z}} +\ctvg0,100:{X_0=X}{\ctgr{X}\ctlptlcc{I_X}} +\ctvg150,100:{Y}{\ctlptrcc{I_Y}} +\ctet0,100,150,100:\alpha +\ctnohead\cteb0,0,150,0:{\beta'}\cthead +\ctel0,100,0,0:{\alpha'} +\cter150,100,150,0:\beta +\ctelr0,100,150,0:11{\alpha';\beta'}{\alpha;\beta} +}$$ + +$$\ctdiagram{ +\ctv0,0:{Y'} +\ctvg150,0:{Z=Z_0}{\ctgl{Z}} +\ctvg0,100:{X_0=X}{\ctgr{X}} +\ctv150,100:Y +\ctetg0,100,150,100;50:\alpha +\ctebg0,0,150,0;50:{\beta'} +\ctelg0,100,0,0;30:{\alpha'} +\cterg150,100,150,0;30:\beta +\ctetbg0,100,150,0;50,100:10{\rho}{\rho'} +\ctelrg0,0,150,100;70,30:01{\theta}{\theta'} +}$$ + +\newpage + +%The next two diagrams are further tests of the macros for drawing +%double edges. + +$$\ctdiagram{ +\ctv0,0:X +\ctv-100,100:Y\ctv-100,0:Y\ctv-100,-100:Y +\ctv100,100:Z\ctv100,0:Z\ctv100,-100:Z +\ctetb0,0,-100,100:10\alpha\beta +\ctdash\ctetb0,0,-100,0:00\alpha\beta\ctsolid +\ctetb0,0,-100,-100:01\alpha\beta +\ctetb0,0,100,100:10\alpha\beta +\ctdash\ctetb0,0,100,0:11\alpha\beta\ctsolid +\ctetb0,0,100,-100:01\alpha\beta +}$$ + +$$\ctdiagram{ +\ctv0,0:X +\ctv-100,100:Y\ctv0,100:Y\ctv100,100:Y +\ctv-100,-100:Z\ctv0,-100:Z\ctv100,-100:Z +\ctelr0,0,-100,100:10\alpha\beta +\ctelr0,0,0,100:00\alpha\beta +\ctelr0,0,100,100:01\alpha\beta +\ctelr0,0,-100,-100:10\alpha\beta +\ctelr0,0,0,-100:11\alpha\beta +\ctelr0,0,100,-100:01\alpha\beta +}$$ + +\newpage + +%These two diagrams test the usage of \ctinnermid and \ctoutermid. + +$$\ctdiagram{\ctv 0,0:{ +{\displaystyle\sum_{i=0}^{100}x_i\cdot y_i}\over +{\displaystyle\sqrt{\biggl(\sum_{i=0}^{100}x_i^2\biggr) ++\biggl(\sum_{i=0}^{100}y_i^2\biggr)}}} +\ctv0,150:A\ctv150,150:B\ctv150,0:C\ctv150,-150:D +\ctv0,-150:E\ctv-150,-150:F\ctv-150,0:G\ctv-150,150:H +\cter0,0,0,150:A\ctinnermid\cter0,0,0,150:a\ctoutermid +\cter150,150,0,0:B\ctinnermid\cter150,150,0,0:b\ctoutermid +\cteb0,0,150,0:C\ctinnermid\cteb0,0,150,0:c\ctoutermid +\cteb150,-150,0,0:D\ctinnermid\cteb150,-150,0,0:d\ctoutermid +\ctel0,0,0,-150:E\ctinnermid\ctel0,0,0,-150:e\ctoutermid +\ctel-150,-150,0,0:F\ctinnermid\ctel-150,-150,0,0:f\ctoutermid +\ctet0,0,-150,0:G\ctinnermid\ctet0,0,-150,0:g\ctoutermid +\ctet-150,150,0,0:H\ctinnermid\ctet-150,150,0,0:h +}$$ + +$$\ctdiagram{\ctv 0,0:{ +{\displaystyle\sum_{i=0}^{100}x_i\cdot y_i}\over +{\displaystyle\sqrt{\biggl(\sum_{i=0}^{100}x_i^2\biggr) ++\biggl(\sum_{i=0}^{100}y_i^2\biggr)}}} +\ctv-150,150:A\ctv0,150:C\ctv150,150:E\ctv150,0:G +\ctelr0,0,-150,150:11AB\ctinnermid +\ctelr0,0,-150,150:11ab\ctoutermid +\ctelr0,150,0,0:11CD\ctinnermid +\ctelr0,150,0,0:11cd\ctoutermid +\ctetb0,0,150,150:11EF\ctinnermid +\ctetb0,0,150,150:11ef\ctoutermid +\ctetb150,0,0,0:11GH\ctinnermid +\ctetb150,0,0,0:11gh +}$$ + +\newpage + +%This is a ``real'' diagram, relating directed complete relations to +%Scott's inverse limit construction. It is sufficiently crowded +%that it has been necessary to place some of the abutted expressions +%carefully to avoid ambiguity. + +$$\ctdiagram{ +\ctvg0,0:{D_0}{\border{2pt}{0pt}} +\ctv72,0:{D_1} +\ctv144,0:{D_2} +\ctv216,0:{\quad\cdots} +\ctvg288,144:{D_\infty}{\advance\ycenter by 5pt\border{50pt}{10pt}} +\ctv234,36:{\cdots} +\ctetbg0,0,72,0;48,48:10{\phi_0}{\psi_0} +\ctetbg72,0,144,0;114,114:10{\phi_1}{\psi_1} +\ctetb144,0,216,0:10{\phi_2}{\psi_2} +\ctelrg0,0,288,144;42,30:10{\Phi_0}{\Psi_0} +\ctelrg72,0,288,144;42,30:10{\Phi_1}{\Psi_1} +\ctelrg144,0,288,144;42,30:10{\Phi_2}{\Psi_2} +\ctvg0,-72:{D'_0}{\border{2pt}{0pt}} +\ctv72,-72:{D'_1} +\ctv144,-72:{D'_2} +\ctv216,-72:{\quad\cdots} +\ctvg288,-216:{D'_\infty}{\advance\ycenter by -5pt\border{50pt}{10pt}} +\ctv234,-108:{\cdots} +\ctetbg0,-72,72,-72;48,48:10{\phi'_0}{\psi'_0} +\ctetbg72,-72,144,-72;114,114:10{\phi'_1}{\psi'_1} +\ctetb144,-72,216,-72:10{\phi'_2}{\psi'_2} +\ctelrg0,-72,288,-216;-114,-102:10{\Phi'_0}{\Psi'_0} +\ctelrg72,-72,288,-216;-114,-102:10{\Phi'_1}{\Psi'_1} +\ctelrg144,-72,288,-216;-114,-102:10{\Phi'_2}{\Psi'_2} +\cter0,0,0,-72:{\alpha_0} +\cter72,0,72,-72:{\alpha_1} +\cter144,0,144,-72:{\alpha_2} +\ctv216,-36:{\cdots} +\ctdash +\cter288,144,288,-216:{\alpha_\infty} +}$$ + +\newpage + +%This shows how a macro can be defined and then used to give two different +%views of the same diagram. + +\def\testcube#1#2#3#4#5#6#7#8{ +$$\ctdiagram{ +\ctv#1,#3:{A_1} +\ctv#2,#3:{B_1} +\ctv#1,#4:{A_2} +\ctv#2,#4:{B_2} +\ctv#5,#7:{A'_1} +\ctv#6,#7:{B'_1} +\ctv#5,#8:{A'_2} +\ctv#6,#8:{B'_2} +\ctet#1,#3,#2,#3:{\gamma_1} +\ctet#1,#4,#2,#4:{\gamma_2} +\cter#1,#3,#1,#4:{\alpha} +\cter#2,#3,#2,#4:{\beta} +\ctet#5,#7,#6,#7:{\gamma'_1} +\ctet#5,#8,#6,#8:{\gamma'_2} +\cter#5,#7,#5,#8:{\alpha'} +\cter#6,#7,#6,#8:{\beta'} +\cter#1,#3,#5,#7:{a_1} +\cter#2,#3,#6,#7:{b_1} +\cter#1,#4,#5,#8:{a_2} +\cter#2,#4,#6,#8:{b_2} +}$$} + +\testcube{0}{200}{200}{0}{50}{150}{150}{50} + +\testcube{0}{150}{150}{0}{100}{250}{200}{50} + +\newpage + +%An example of a partial ordering with a limit point. + +$${\def\diagramunit{0.25in} +\ctdiagram{\ctnohead +\ctv0,0:{\geq 0} +\ctv2,2:{\geq 1} +\ctv4,4:{\geq 2} +\ctv7,7:\infty +\ctv-2,2:{=0} +\ctv0,4:{=1} +\ctv2,6:{=2} +\cten0,0,2,2: +\cten2,2,4,4: +\cten0,0,-2,2: +\cten2,2,0,4: +\cten4,4,2,6: +\ctdot +\cten4,4,7,7: +}}$$ + +%An example of a binary tree, produced by user macros. + +\newcount\cnx\newcount\cny\newcount\cnxx\newcount\cnyy + +\def\treea#1{\cnxx=\cnx\cnyy=\cny +\ctv\cnx,\cny:{\scriptstyle #1} +\advance\cnx by -1\advance\cny by 4 +\ctdot +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by 2 +\cten\cnxx,\cnyy,\cnx,\cny: +\ctsolid +\cnx=\cnxx\cny=\cnyy} + +\def\treeb#1{\ctv\cnx,\cny:{\scriptstyle #1} +\advance\cnx by -2\advance\cny by 4 +\treea{#10} +\cnxx=\cnx\advance\cnxx by 2\cnyy=\cny\advance\cnyy by -4 +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by 4 +\treea{#11} +\cnxx=\cnx\advance\cnxx by -2\cnyy=\cny\advance\cnyy by -4 +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by -2\advance\cny by -4} + +\def\treec#1{\ctv\cnx,\cny:{\scriptstyle #1} +\advance\cnx by -4\advance\cny by 4 +\treeb{#10} +\cnxx=\cnx\advance\cnxx by 4\cnyy=\cny\advance\cnyy by -4 +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by 8 +\treeb{#11} +\cnxx=\cnx\advance\cnxx by -4\cnyy=\cny\advance\cnyy by -4 +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by -4\advance\cny by -4} + +\def\treed#1{\ctv\cnx,\cny:{\scriptstyle #1} +\advance\cnx by -8\advance\cny by 4 +\treec{#10} +\cnxx=\cnx\advance\cnxx by 8\cnyy=\cny\advance\cnyy by -4 +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by 16 +\treec{#11} +\cnxx=\cnx\advance\cnxx by -8\cnyy=\cny\advance\cnyy by -4 +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by -8\advance\cny by -4} + +\def\tree{\ctv\cnx,\cny:\bot\def\centerheight{2pt} +\advance\cnx by -16\advance\cny by 4 +\treed{0} +\cnxx=\cnx\advance\cnxx by 16\cnyy=\cny\advance\cnyy by -4 +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by 32 +\treed{1} +\cnxx=\cnx\advance\cnxx by -16\cnyy=\cny\advance\cnyy by -4 +\cten\cnxx,\cnyy,\cnx,\cny: +\advance\cnx by -16\advance\cny by -4} + +$${\def\diagramunit{7.5pt} +\ctdiagram{\ctnohead\cnx=0\cny=0\tree}}$$ + +\end{document} |