1 \ProvidesPackage{graphs}[2000/12/19]
4 %_________________________________________________________________%%
5 % Draw graphs only if this is set to TRUE:
6 %_________________________________________________________________%%
11 \DeclareOption{draft}{\drawgraphsfalse}
15 \typeout{LaTeX2e package `graphs', version 1.53}
16 \typeout{Frank Drewes, University of Bremen, 19.12.2000}
20 % \input the low-level commands that produce PostScript \special's.
24 % \input the local configuration.
29 %_________________________________________________________________%%
30 % Initial value of \unitlength:
32 \newdimen\g@oldunitlength
36 %_________________________________________________________________%%
37 % Global settings and macros to change them (all lengths are numbers
38 % interpreted as multiples of \unitlength, except for the ones in
41 % - \graphlinewidth define the width of lines (relevant
42 % for nodes and edges)
43 % - \graphlinedash define the dash style of lines; the argument
44 % is a sequence of natural numbers delimited by
45 % blanks (relevant for nodes and edges). Is
46 % taken as input to the postscript setdash
48 % - \graphnodesize define the size (= diameter) of nodes
49 % - \graphnodecolour define the interior shading of nodes (a
50 % number between 0 (= black) and 1 (= white))
52 % \fillednodesfalse determine whether the interior of nodes shall be
54 % - \graphlinecolour define the `colour' of edges; similar to
56 % - \grapharrowlength define the length from tip to basis of a
57 % directed edge's arrow head
58 % - \grapharrowwidth define the width of the basis of a
59 % directed edge's arrow head (in multiples of
61 % - \grapharrowtype define the type of the arrow heads (argument
63 % - \autodistance define the factor that defines the distance
64 % of automatically placed text boxes from the
65 % centre of a node (1 means "placed on the
67 % - \enlargeboxes define the length that is added to
68 % text boxes (in x and y direction) in order
69 % to determine the size of the necessary
70 % white area underlying it.
72 % \opaquetextfalse determine whether text boxes shall be considered
73 % opaque or transparent (In the latter case
74 % \enlargeboxes doesn't have a (visible)
75 % effect.) Its initial value is true except
76 % for \autonodetext, which always has it set
77 % to false if it's not changed explicitely
78 % through the optional parameter.
80 % \filledareasfalse determine whether areas shall be filled or not
82 % - \graphfillcolour define the fill colour of areas (if filled
85 %_________________________________________________________________%%
87 \def\g@defrel#1*#2{\edef#1{#1\ps@s #2 0 ge {#2 mul} if}}
88 \def\g@defplus#1+#2{\edef#1{
91 {1 exch sub #2 div 1 exch sub}
94 \def\g@defcolplus#1+#2{\edef#1{
99 {1 exch sub #2 div 1 exch sub}
100 {#2 0 ge {#2 mul} if}
105 \def\g@defabs#1#2#3{\def#1{#3}\def#2{}}
106 \def\g@defcolabs#1#2{%
107 \@ifnextchar({\g@defcolabsrgb{#1}{#2}}{\g@defcolabsbw{#1}{#2}}%
109 \def\g@defcolabsbw#1#2#3{\def#1{#3\ps@s #3\ps@s #3}\def#2{}}
110 \def\g@defcolabsrgb#1#2(#3,#4,#5){\def#1{#3\ps@s #4\ps@s #5}\def#2{}}
112 \def\graphlinewidth{%
113 \@ifnextchar*{\g@defrel{\g@lwidthmod}}%
114 {\g@defabs{\g@lwidth}{\g@lwidthmod}}}
117 \def\graphlinedash#1{\def\g@ldash{[ #1 ]}}
120 \def\graphnodesize#1{\def\g@nsize{#1}}
123 \def\graphnodecolour{%
124 \@ifnextchar+{\g@defcolplus{\g@ncolourmod}}%
125 {\g@defcolabs{\g@ncolour}{\g@ncolourmod}}}
128 \newif\iffillednodes\fillednodestrue
130 \def\graphlinecolour{%
131 \@ifnextchar+{\g@defcolplus{\g@lcolourmod}}%
132 {\g@defcolabs{\g@lcolour}{\g@lcolourmod}}}
135 \def\grapharrowlength{%
136 \@ifnextchar*{\g@defrel{\g@alengthmod}}%
137 {\g@defabs{\g@alength}{\g@alengthmod}}}
138 \grapharrowlength{.3}
140 \def\grapharrowwidth{%
141 \@ifnextchar*{\g@defrel{\g@awidthmod}}%
142 {\g@defabs{\g@awidth}{\g@awidthmod}}}
145 \def\grapharrowtype#1{\def\g@atype{#1}}
148 \def\autodistance#1{\def\g@autodistance{#1}}
151 \def\enlargeboxes#1{\def\g@eboxes{#1}}
154 \newif\ifopaquetext\opaquetexttrue
156 \newif\iffilledareas\filledareastrue
158 \def\graphfillcolour{%
159 \@ifnextchar+{\g@defcolplus{\g@fcolourmod}}%
160 {\g@defcolabs{\g@fcolour}{\g@fcolourmod}}}
164 %_________________________________________________________________%%
165 % Issue a warning if a command name defined in graphs.sty already has
167 %_________________________________________________________________%%
172 \typeout{Warning: command name `#1' already used;
173 redefined in graphs.sty!}
179 %_________________________________________________________________%%
180 % This is the environment in which the macros above can be used.
184 % As for the LaTeX picture environment, i.e., it starts with
185 % \begin{graph}(x,y)(dx,dy) (where the second pair is optional) and
186 % ends with \end{graph}.
190 % The graph enviroment is imlemented on the basis of the picture
191 % environment. As a result, all commands allowed in pictures may be
192 % used (in addition to the graph commands). The picture commands'
193 % effects will always take place first, so subsequent AS WELL AS
194 % PRECEEDING graph commands will overlay the ordinary LaTeX
195 % picture. (This is one reason why a command like \freetext is NOT
196 % useless: its effect takes place after nodes and edges have been
198 %_________________________________________________________________%%
200 \g@test{graph}\g@test{framegraph}
201 \def\framegraph(#1){\@ifnextchar({\g@graph f(#1)}{\g@graph f(#1)(0,0)}}
202 \def\graph(#1){\@ifnextchar({\g@graph n(#1)}{\g@graph n(#1)(0,0)}}
203 \def\g@graph#1(#2)(#3){%
204 \begin{picture}(#2)(#3)%
206 \put(#3){\framebox(#2){}}%
209 \put(#3){\framebox(#2){graph}}%
211 \def\g@nodeinfo{}\def\g@specialeffects{}\def\g@nodes{}\def\g@texts{}%
216 \g@nodeinfo\g@specialeffects\g@edges\g@nodes\g@texts%
220 \def\endframegraph{\endgraph}
223 %_________________________________________________________________%%
225 %_________________________________________________________________%%
228 \def\g@rectangletype{1}
231 %_________________________________________________________________%%
232 % Definition of square nodes:
236 % Nodename (a character sequence like abc)
237 % Position (x,y) = a pair of numbers
238 %_________________________________________________________________%%
241 \def\squarenode#1(#2,#3){
242 \@ifnextchar[{\g@squarenode{#1}(#2,#3)}{\g@squarenode{#1}(#2,#3)[]}
245 \def\g@squarenode#1(#2,#3)[#4]{
246 \g@extendlist\g@nodeinfo{\g@node{#1}{\g@rectangletype}(#2,#3)[#4]}
247 \g@extendlist\g@nodes{\g@drawsquarenode{#1}(#2,#3)[#4]}
250 % The actual drawing routine:
252 \def\g@drawsquarenode#1(#2,#3)[#4]{%
253 \edef\g@size{\g@thenodesize{#1}}%
255 \put(#2,#3){\expandafter\ps@rectangle\g@size}%
260 %_________________________________________________________________%%
261 % Definition of round nodes:
265 % Nodename (a character sequence like abc)
266 % Position (x,y) = a pair of numbers
267 %_________________________________________________________________%%
270 \def\roundnode#1(#2,#3){
271 \@ifnextchar[{\g@roundnode{#1}(#2,#3)}{\g@roundnode{#1}(#2,#3)[]}
274 \def\g@roundnode#1(#2,#3)[#4]{
275 \g@extendlist\g@nodeinfo{\g@node{#1}{\g@circletype}(#2,#3)[#4]}
276 \g@extendlist\g@nodes{\g@drawroundnode{#1}(#2,#3)[#4]}
279 % The actual drawing routine:
281 \def\g@drawroundnode#1(#2,#3)[#4]{%
282 \edef\g@size{\g@thenodesize{#1}}%
284 \put(#2,#3){\expandafter\ps@circle\g@size}%
289 %_________________________________________________________________%%
290 % Definition of rectangular nodes:
294 % Nodename (a character sequence like abc)
295 % Size [width,height] (in multiples of \unitlength)
296 % Position (x,y) = a pair of numbers
297 %_________________________________________________________________%%
300 \def\rectnode#1[#2,#3](#4,#5){
301 \@ifnextchar[{\g@rectnode{#1}[#2,#3](#4,#5)}%
302 {\g@rectnode{#1}[#2,#3](#4,#5)[]}
305 \def\g@rectnode#1[#2,#3](#4,#5)[#6]{
306 \g@extendlist\g@nodeinfo{\g@noderect{#1}[#2,#3](#4,#5)}
307 \g@extendlist\g@nodes{\g@drawrectnode{#1}[#6]}
310 % The actual drawing routine:
312 \def\g@drawrectnode#1[#2]{%
313 \edef\g@size{\g@thenodesize{#1}}%
314 \edef\g@coords{\g@nodecoords{#1}}%
316 \expandafter\put\g@coords{\expandafter\ps@rectangle\g@size}%
321 %_________________________________________________________________%%
322 % Definition of text nodes (rectangular nodes whose dimension is
323 % determined by the given text):
327 % Nodename (a character sequence like abc)
328 % Position (x,y) = a pair of numbers
329 % Text (=anything that may occur as a \put argument in a picture
330 % environment, i.e., even lines, vectors, and so on.)
331 %_________________________________________________________________%%
334 \def\textnode#1(#2,#3)#4{
335 \@ifnextchar[{\g@textnode{#1}(#2,#3){#4}}%
336 {\g@textnode{#1}(#2,#3){#4}[]}
339 \def\g@textnode#1(#2,#3)#4[#5]{
340 \autonodetext{#1}{#4}[#5]
341 \g@extendlist\g@nodeinfo{\g@nodebytext{#1}(#2,#3){#4}[#5]}
342 \g@extendlist\g@nodes{\g@drawrectnode{#1}%
343 [\graphnodecolour{1}#5]}
347 %_________________________________________________________________%%
348 % Definition of an edge:
352 % The two incident nodes
353 %_________________________________________________________________%%
357 \@ifnextchar[{\g@edge{#1}{#2}}{\g@edge{#1}{#2}[]}
361 \g@extendlist\g@edges{\g@drawedge{#1}{#2}[#3]}
364 % The actual drawing routine:
366 \def\g@drawedge#1#2[#3]{%
367 \g@testname{#1}\g@testname{#2}%
368 \g@differentpositions{#1}{#2}{\edge{#1}{#2}}%
369 \edef\g@firstcoords{\g@nodecoords{#1}}%
370 \edef\g@secondcoords{\g@nodecoords{#2}}%
371 \g@defcoorddiff{\g@diffcoords}{\g@firstcoords}{\g@secondcoords}%
373 \expandafter\put\g@firstcoords{\expandafter\ps@line\g@diffcoords}%
378 %_________________________________________________________________%%
379 % Definition of a directed edge:
381 % Arguments (same as for \edge):
383 % The two incident nodes (order indicates direction of the arrow)
384 %_________________________________________________________________%%
388 \@ifnextchar[{\g@diredge{#1}{#2}}{\g@diredge{#1}{#2}[]}
391 \def\g@diredge#1#2[#3]{
392 \g@extendlist\g@edges{\g@drawdiredge{#1}{#2}[#3]}
395 % The actual drawing routine:
397 \def\g@drawdiredge#1#2[#3]{%
398 \g@testname{#1}\g@testname{#2}%
399 \g@differentpositions{#1}{#2}{\diredge{#1}{#2}}%
400 \edef\g@firstcoords{\g@nodecoords{#1}}%
401 \edef\g@secondcoords{\g@nodecoords{#2}}%
402 \g@defcoorddiff{\g@diffcoords}{\g@firstcoords}{\g@secondcoords}%
404 % Choose the right drawing procedure, according to the node's type:
406 \edef\g@type{\g@nodetype{#2}}%
407 \ifnum\g@circletype=\g@type%
408 \let\g@draw=\ps@arrowoncircle%
410 \let\g@draw=\ps@arrowonrectangle%
411 \ifnum\g@rectangletype=\g@type%
414 \typeout{Error in \string\g@drawdiredge: unrecognized node type}%
420 \edef\g@diffcoordsandsize{\g@diffcoords\g@thenodesize{#2}}%
422 \expandafter\put\g@firstcoords{\expandafter\g@draw\g@diffcoordsandsize}%
427 %_________________________________________________________________%%
428 % Definition of a `bow' (a curved edge):
432 % The two incident nodes
433 % The displacement factor of the midpoint relative to the distance.
434 % of both nodes. A positive number means the bow extends
435 % to the left (if one looks in the direction of the edge).
436 %_________________________________________________________________%%
440 \@ifnextchar[{\g@bow{#1}{#2}{#3}}{\g@bow{#1}{#2}{#3}[]}
443 \def\g@bow#1#2#3[#4]{
444 \g@extendlist\g@edges{\g@drawbow{#1}{#2}{#3}[#4]}
447 % The actual drawing routine:
449 \def\g@drawbow#1#2#3[#4]{%
450 \g@testname{#1}\g@testname{#2}%
451 \g@differentpositions{#1}{#2}{\bow{#1}{#2}...}%
452 \edef\g@firstcoords{\g@nodecoords{#1}}%
453 \edef\g@secondcoords{\g@nodecoords{#2}}%
454 \expandafter\g@bowcombine\g@secondcoords{#3}%
457 \put(0,0){\expandafter\ps@path\g@combineresult}%
461 % Macro used above to combine coordinates of nodes and displacement:
462 \def\g@bowcombine(#1,#2)#3{
463 \edef\g@combineresult{\g@firstcoords{(#1,#2,#3)}}
467 %_________________________________________________________________%%
468 % Definition of a `directed bow' (a curved arrow):
470 % Arguments (same as for \bow):
472 % The two incident nodes
473 % The displacement factor of the midpoint relative to the distance.
474 % of both nodes. A positive number means the bow extends
475 % to the left (if one looks in the direction of the edge).
476 %_________________________________________________________________%%
480 \@ifnextchar[{\g@dirbow{#1}{#2}{#3}}{\g@dirbow{#1}{#2}{#3}[]}
483 \def\g@dirbow#1#2#3[#4]{
484 \g@extendlist\g@edges{\g@drawdirbow{#1}{#2}{#3}[#4]}
487 % The actual drawing routine:
489 \def\g@drawdirbow#1#2#3[#4]{
490 \g@testname{#1}\g@testname{#2}%
491 \g@differentpositions{#1}{#2}{\dirbow{#1}{#2}...}%
492 \edef\g@firstcoords{\g@nodecoords{#1}}%
493 \edef\g@secondcoordsandsize{\g@nodecoords{#2}\g@thenodesize{#2}}%
494 \expandafter\g@dirbowcombine\g@secondcoordsandsize{#3}%
496 % Choose the right drawing procedure, according to the node's type:
498 \edef\g@type{\g@nodetype{#2}}%
499 \ifnum\g@circletype=\g@type%
500 \let\g@draw=\ps@dirbowoncircle%
502 \let\g@draw=\ps@dirbowonrectangle%
503 \ifnum\g@rectangletype=\g@type%
506 \typeout{Error in \string\g@drawdirbow: unrecognized node type}%
514 \put(0,0){\expandafter\g@draw\g@combineresult}%
518 % Macro used above to combine coordinates of nodes and displacement:
519 \def\g@dirbowcombine(#1,#2)[#3]#4{
520 \edef\g@combineresult{\g@firstcoords(#1,#2,#4)[#3]}
524 %_________________________________________________________________%%
525 % Definition of a loop. There're two ways to provide this macro
526 % with the necessary arguments. Here's the
531 % Node that carries the loop
532 % Two relative coordinates (x1,y1) (x2,y2) indicating the lines from
533 % the incident node to (x1,y1) and (x2,y2) that form the loop
534 % together with a curve connecting (x1,y1) and (x2,y2).
535 %_________________________________________________________________%%
539 \@ifnextchar({\g@loopedgeA{#1}}{\g@loopedgeB{#1}}
542 \def\g@loopedgeA#1(#2,#3)(#4,#5){
543 \@ifnextchar[{\g@loopedgeAa{#1}(#2,#3)(#4,#5)}%
544 {\g@loopedgeAa{#1}(#2,#3)(#4,#5)[]}
547 \def\g@loopedgeAa#1(#2,#3)(#4,#5)[#6]{
548 \g@extendlist\g@edges{\g@drawloopedgeA{#1}(#2,#3)(#4,#5)[#6]}
551 % The actual drawing routine:
553 \def\g@drawloopedgeA#1(#2,#3)(#4,#5)[#6]{%
555 \edef\g@coords{\g@nodecoords{#1}}%
557 \expandafter\put\g@coords{%%
558 \ps@loopA(#2,#3)(#4,#5)}%
563 %_________________________________________________________________%%
564 % Definition of a loop - the second form:
568 % Node that carries the loop
569 % Angle the two lines defining the loop build
570 % Coordinates (x,y) that give the axis along which the loop is
571 % to be drawn and its length (ie, the length of the two lines
572 % defining the loop).
573 %_________________________________________________________________%%
575 \def\g@loopedgeB#1#2(#3,#4){
576 \@ifnextchar[{\g@loopedgeBa{#1}{#2}(#3,#4)}%
577 {\g@loopedgeBa{#1}{#2}(#3,#4)[]}
580 \def\g@loopedgeBa#1#2(#3,#4)[#5]{
581 \g@extendlist\g@edges{\g@drawloopedgeB{#1}{#2}(#3,#4)[#5]}
584 % The actual drawing routine:
586 \def\g@drawloopedgeB#1#2(#3,#4)[#5]{%
588 \edef\g@coords{\g@nodecoords{#1}}%
590 \expandafter\put\g@coords{%%
591 \ps@loopB{#2}(#3,#4)}%
596 %_________________________________________________________________%%
597 % Definition of a directed loop. There're two ways to provide
598 % this macro with the necessary arguments. Here's the first:
602 % Node that carries the loop
603 % Two relative coordinates (x1,y1) (x2,y2) indicating the lines from
604 % the incident node to (x1,y1) and (x2,y2) that form the loop
605 % together with a curve connecting (x1,y1) and (x2,y2).
606 %_________________________________________________________________%%
610 \@ifnextchar({\g@dirloopedgeA{#1}}{\g@dirloopedgeB{#1}}
613 \def\g@dirloopedgeA#1(#2,#3)(#4,#5){
614 \@ifnextchar[{\g@dirloopedgeAa{#1}(#2,#3)(#4,#5)}%
615 {\g@dirloopedgeAa{#1}(#2,#3)(#4,#5)[]}
618 \def\g@dirloopedgeAa#1(#2,#3)(#4,#5)[#6]{
619 \g@extendlist\g@edges{\g@drawdirloopedgeA{#1}(#2,#3)(#4,#5)[#6]}
622 % The actual drawing routine:
624 \def\g@drawdirloopedgeA#1(#2,#3)(#4,#5)[#6]{%
626 \edef\g@coords{\g@nodecoords{#1}}%
628 % Choose the drawing procedure for the arrow according
629 % to the node's type:
631 \edef\g@type{\g@nodetype{#1}}%
632 \ifnum\g@circletype=\g@type%
633 \let\g@draw=\ps@looparrowoncircleA%
635 \let\g@draw=\ps@looparrowonrectangleA%
636 \ifnum\g@rectangletype=\g@type%
639 \typeout{Error in \string\g@drawdirloopedge: unrecognized node type}%%
642 \edef\g@args{(#2,#3)(#4,#5)\g@thenodesize{#1}}%
647 \expandafter\put\g@coords{\expandafter\g@draw\g@args}%
652 %_________________________________________________________________%%
653 % Definition of a directed loop - the second form:
657 % Node that carries the loop
658 % Angle the two lines defining the loop build
659 % Coordinates (x,y) that give the axis along which the loop is
660 % to be drawn and its length (ie, the length of the two lines
661 % defining the loop).
662 %_________________________________________________________________%%
664 \def\g@dirloopedgeB#1#2(#3,#4){
665 \@ifnextchar[{\g@dirloopedgeBa{#1}{#2}(#3,#4)}%
666 {\g@dirloopedgeBa{#1}{#2}(#3,#4)[]}
669 \def\g@dirloopedgeBa#1#2(#3,#4)[#5]{
670 \g@extendlist\g@edges{\g@drawdirloopedgeB{#1}{#2}(#3,#4)[#5]}
673 % The actual drawing routine:
675 \def\g@drawdirloopedgeB#1#2(#3,#4)[#5]{%
677 \edef\g@coords{\g@nodecoords{#1}}%
679 % Choose the drawing procedure for the arrow according
680 % to the node's type:
682 \edef\g@type{\g@nodetype{#1}}%
683 \ifnum\g@circletype=\g@type%
684 \let\g@draw=\ps@looparrowoncircleB%
686 \let\g@draw=\ps@looparrowonrectangleB%
687 \ifnum\g@rectangletype=\g@type%
690 \typeout{Error in \string\g@drawdirloopedge: unrecognized node type}%%
693 \edef\g@args{{#2}(#3,#4)\g@thenodesize{#1}}%
698 \expandafter\put\g@coords{\expandafter\g@draw\g@args}%
703 %_________________________________________________________________%%
704 % Automatic positioning of a node's text
705 % (This one sets \opaquetextfalse if it's not enforced by the optional
711 % Optional (surrounded by []): n, s, e, w, ne, nw, se, sw (for north,
712 % south, east, west, ...) indicating the position of the text
713 % with respect to the node. If omitted, the text is centered
715 % Text (=anything that may occur as a \put argument in a picture
716 % environment, i.e., even lines, vectors, and so on.)
717 %_________________________________________________________________%%
719 \g@test{autonodetext}
721 \@ifnextchar[{\g@autonodetext{#1}}{\g@autonodetext{#1}[]}
724 \def\g@autonodetext#1[#2]#3{
725 \@ifnextchar[{\g@autonodetextopt{#1}{#3}[#2]}%
726 {\g@autonodetextopt{#1}{#3}[#2][]}
729 \def\g@rootofahalf{.70710678}% square root of 0.5
731 \def\g@autonodetextopt#1#2[#3][#4]{
732 \def\g@doit##1##2##3;{
733 \def\g@xdisplace{0}\def\g@ydisplace{0}\def\g@torb{,0]}\def\g@lorr{[0}
734 \def\g@xdisplacec{0}\def\g@ydisplacec{0}
736 \if##1s\def\g@ydisplace{-1}\def\g@torb{,-1]}\else
737 \if##1n\def\g@ydisplace{1}\def\g@torb{,1]}\else
738 \if##1e\def\g@xdisplace{1}\def\g@lorr{[1}\else
739 \if##1w\def\g@xdisplace{-1}\def\g@lorr{[-1}\fi\fi\fi\fi
740 \edef\g@xdisplacec{\g@xdisplace}\edef\g@ydisplacec{\g@ydisplace}
742 \if##1s\def\g@ydisplace{-1}\def\g@torb{,-1]}
743 \def\g@ydisplacec{-\g@rootofahalf}\else
744 \if##1n\def\g@ydisplace{1}\def\g@torb{,1]}
745 \def\g@ydisplacec{\g@rootofahalf}\else
746 \if##1e\def\g@xdisplace{1}\def\g@lorr{[1}
747 \def\g@xdisplacec{\g@rootofahalf}\else
748 \if##1w\def\g@xdisplace{-1}\def\g@lorr{[-1}
749 \def\g@xdisplacec{-\g@rootofahalf}\fi\fi\fi\fi
750 \if##2e\def\g@xdisplace{1}\def\g@lorr{[1}
751 \def\g@xdisplacec{\g@rootofahalf}\else
752 \if##2w\def\g@xdisplace{-1}\def\g@lorr{[-1}
753 \def\g@xdisplacec{-\g@rootofahalf}
757 {(\g@xdisplacec,\g@ydisplacec)}{\g@lorr\g@torb}{%
758 (\g@xdisplace,\g@ydisplace)}%
760 \expandafter\g@extendtextsauto\g@values{#1}{#2}[#4]}
764 \def\g@extendtextsauto#1#2#3#4#5[#6]{
765 \g@extendlist\g@texts{\g@putautotext{#1}{#2}{#3}{#4}{#5}[#6]}
768 % The actual drawing routine:
770 \def\g@putautotext#1#2#3#4#5[#6]{%
772 \edef\g@coords{\g@nodecoords{#4}}%
773 \edef\g@type{\g@nodetype{#4}}%
774 \edef\g@size{\g@thenodesize{#4}}%
775 \ifnum\g@circletype=\g@type%
776 \def\g@draw{\g@xyput#1}%
777 \expandafter\g@getcirclexy\g@size%
779 \def\g@draw{\g@xyput#3}%
780 \expandafter\g@getrectanglexy\g@size%
781 \ifnum\g@rectangletype=\g@type%
784 \typeout{Error in \string\putautotext: unrecognized node type}%
787 \expandafter\put\g@coords{%
790 \g@xunitlength=\g@autodistance\g@xunitlength\divide\g@xunitlength by 2%
791 \g@yunitlength=\g@autodistance\g@yunitlength\divide\g@yunitlength by 2%
793 \g@draw{\expandafter\g@makeautotext\g@thetextsize%
794 #2{\expandafter\ps@deletebox\g@thetextsize}}%
796 \g@draw{\expandafter\g@makeautotext\g@thetextsize%
797 #2{\makebox(0,0){#5}}}%
801 \def\g@getcirclexy[#1]{
802 \g@xunitlength=#1\unitlength\relax
803 \g@yunitlength=\g@xunitlength\relax
806 \def\g@getrectanglexy[#1,#2]{
807 \g@xunitlength=#1\unitlength\relax
808 \g@yunitlength=#2\unitlength\relax
813 \def\g@makeautotext(#1,#2)[#3,#4]#5{%
814 \g@oldunitlength=\unitlength%
815 \g@xpos=#1\divide\g@xpos by 2\multiply\g@xpos by #3\relax%
816 \g@ypos=#2\divide\g@ypos by 2\multiply\g@ypos by #4\relax%
818 \edef\g@positions{(\number\g@xpos,\number\g@ypos)}%
819 \expandafter\put\g@positions{\unitlength=\g@oldunitlength{#5}}%
823 %_________________________________________________________________%%
824 % Definition of a node's text:
829 % Relative coordinates of the text (optional).
830 % Text is centered horizontally and vertically at this position.
831 % (Use a \makebox(0,0)[...]{Text} construction to disable the
832 % centering if necessary.)
833 % Omitting the optinal argument means the same as (0,0).
834 % Text (=anything that may occur as a \put argument in a picture
835 % environment, i.e., even lines, vectors, and so on.)
836 %_________________________________________________________________%%
840 \@ifnextchar({\g@nodetext{#1}}{\g@nodetext{#1}(0,0)}
842 \def\g@nodetext#1(#2,#3)#4{
843 \@ifnextchar[{\g@nodetextb{#1}(#2,#3){#4}}%
844 {\g@nodetextb{#1}(#2,#3){#4}[]}
847 \def\g@nodetextb#1(#2,#3)#4[#5]{
848 \g@extendlist\g@texts{\g@putnodetext{#1}(#2,#3){#4}[#5]}
851 % The actual drawing routine:
853 \def\g@putnodetext#1(#2,#3)#4[#5]{%
855 \edef\g@coords{\g@nodecoords{#1}}%
856 \expandafter\put\g@coords{%
860 \put(#2,#3){\expandafter\ps@deletebox\g@thetextsize}%
862 \put(#2,#3){\makebox(0,0){#4}}%
867 %_________________________________________________________________%%
868 % Definition of an edge's text (for straight edges only):
872 % Both nodes incident with the edge in question
873 % Text (=anything that may occur as a \put argument in a picture
874 % environment, i.e., even lines, vectors, and so on.)
875 %_________________________________________________________________%%
879 \@ifnextchar[{\g@edgetext{#1}{#2}{#3}}%
880 {\g@edgetext{#1}{#2}{#3}[]}
883 \def\g@edgetext#1#2#3[#4]{
884 \g@extendlist\g@texts{\g@putedgetext{#1}{#2}{#3}[#4]}
887 % The actual drawing routine:
889 \def\g@putedgetext#1#2#3[#4]{%
890 \g@testname{#1}\g@testname{#2}%
891 \g@differentpositions{#1}{#2}{\edgetext{#1}{#2}...}%
892 \edef\g@firstcoords{\g@nodecoords{#1}}%
893 \edef\g@secondcoords{\g@nodecoords{#2}}%
897 \g@oldunitlength=\unitlength%
898 \divide\unitlength by 2%
899 \expandafter\put\g@firstcoords{%
901 \expandafter\put\g@secondcoords{%
902 \expandafter\ps@deletebox\g@thetextsize%
905 \expandafter\put\g@secondcoords{%
906 \unitlength=\g@oldunitlength%
914 %_________________________________________________________________%%
915 % Definition of a bow's text:
919 % Both nodes and displacement factor defining the bow in question
920 % Text (=anything that may occur as a \put argument in a picture
921 % environment, i.e., even lines, vectors, and so on.)
922 %_________________________________________________________________%%
925 \def\bowtext#1#2#3#4{
926 \@ifnextchar[{\g@bowtext{#1}{#2}{#3}{#4}}%
927 {\g@bowtext{#1}{#2}{#3}{#4}[]}
930 \def\g@bowtext#1#2#3#4[#5]{
931 \g@extendlist\g@texts{\g@putbowtext{#1}{#2}{#3}{#4}[#5]}
934 % The actual drawing routine:
939 \def\g@putbowtext#1#2#3#4[#5]{%
940 \g@testname{#1}\g@testname{#2}%
941 \g@differentpositions{#1}{#2}{\bowtext{#1}{#2}...}%
942 \def\g@doit(##1,##2)(##3,##4){%
945 \g@oldunitlength=\unitlength%
946 \unitlength=.5\unitlength%
948 % Compute the difference of coordinates:
950 \g@x=##3\g@oldunitlength\g@aux=##1\g@oldunitlength%
951 \advance\g@x by -\g@aux\g@x=#3\g@x%
952 \g@y=##4\g@oldunitlength\g@aux=##2\g@oldunitlength%
953 \advance\g@y by -\g@aux\g@y=#3\g@y%
955 \edef\g@thirdcoords{(\number\g@y,\number\g@x)}%
960 \expandafter\put\g@thirdcoords{%
961 \expandafter\ps@deletebox\g@thetextsize%
967 \expandafter\put\g@thirdcoords{%
968 \unitlength=\g@oldunitlength%
974 \edef\g@firstcoords{\g@nodecoords{#1}}%
975 \edef\g@secondcoords{\g@nodecoords{#2}}%
977 % Expand both arguments before executing \g@doit:
979 \expandafter\expandafter\expandafter%
980 \g@doit\expandafter\g@firstcoords\g@secondcoords%
984 %_________________________________________________________________%%
985 % Definition of free text:
989 % Absolute coordinates of the text. (Text is centered horizontally
990 % and vertically at this position. Use a
991 % \makebox(0,0)[...]{Text} construction to disable the
992 % centering if necessary.)
993 % Text (=anything that may occur as a \put argument in a picture
994 % environment, i.e., even lines, vectors, and so on.)
995 %_________________________________________________________________%%
998 \def\freetext(#1,#2)#3{
999 \@ifnextchar[{\g@freetext(#1,#2){#3}}%
1000 {\g@freetext(#1,#2){#3}[]}
1003 \def\g@freetext(#1,#2)#3[#4]{
1004 \g@extendlist\g@texts{\g@putfreetext(#1,#2){#3}[#4]}
1007 % The actual drawing routine:
1009 \def\g@putfreetext(#1,#2)#3[#4]{%
1013 \put(#1,#2){\expandafter\ps@deletebox\g@thetextsize}%
1015 \put(#1,#2){\makebox(0,0){#3}}%
1020 %_________________________________________________________________%%
1021 % Definition of a (perhaps filled) area:
1025 % Absolute coordinates of the starting point
1026 % Sequence of pairs (x_i,y_i) or triples (x_i,y_i,d_i) where the
1027 % (x_i,y_i) are absolute coordinates of the next segment's
1028 % end point and d_i is the displacement factor of the midpoint
1029 % relative to the length of the segment. A positive number
1030 % means the segment extends to the left.
1031 %_________________________________________________________________%%
1035 \@ifnextchar[{\g@area(#1,#2){#3}}%
1036 {\g@area(#1,#2){#3}[]}
1039 \def\g@area(#1,#2)#3[#4]{
1040 \g@extendlist\g@specialeffects{\g@putarea(#1,#2){#3}[#4]}
1043 % The actual drawing routine:
1045 \def\g@putarea(#1,#2)#3[#4]{%
1047 \put(0,0){\ps@path(#1,#2){#3}}%
1051 % For reasons of compatibility with older versions:
1052 \g@test{filledarea}\def\filledarea{\area}
1055 %_________________________________________________________________%%
1056 % Definition of a (perhaps filled) Bezier curve:
1060 % Normal distance of control points from points of the curve,
1061 % in multiples of the segment length.
1062 % Sequence of triples (x_i,y_i,alpha_i), and and optional
1063 % [factora_i,factorb_i]) after each of the triples:
1064 % (x_i,y_i) is a point on the curve, alpha_i is the angle
1065 % between the x-axis and the line through (x_i,y_i) and the
1066 % next control point (the previous control point lies opposite),
1067 % and factora_i (factorb_i) is overwrites the first argument
1068 % for the two control points between two points.
1069 %_________________________________________________________________%%
1073 \@ifnextchar[{\g@curve{#1}{#2}}%
1074 {\g@curve{#1}{#2}[]}
1077 \def\g@curve#1#2[#3]{
1078 \g@extendlist\g@specialeffects{\g@putcurve{#1}{#2}[#3]}
1081 % The actual drawing routine:
1083 \def\g@putcurve#1#2[#3]{%
1085 \put(0,0){\ps@curve{#1}{#2}}%
1090 %_________________________________________________________________%%
1091 % Definition of a (perhaps filled) Bezier ``bubble'':
1095 % Normal distance (in multiples of unitlength) of control points
1096 % in multiples of segment length.
1097 % Sequence of points (x_i,y_i).
1098 %_________________________________________________________________%%
1102 \@ifnextchar[{\g@bubble{#1}{#2}}%
1103 {\g@bubble{#1}{#2}[]}
1106 \def\g@bubble#1#2[#3]{
1107 \g@extendlist\g@specialeffects{\g@putbubble{#1}{#2}[#3]}
1110 % The actual drawing routine:
1112 \def\g@putbubble#1#2[#3]{%
1114 \put(0,0){\ps@bubble{#1}{#2}}%
1122 %_________________________________________________________________%%
1123 %_________________________________________________________________%%
1124 %_________________________________________________________________%%
1125 % The rest consists of auxiliary macros used above:
1126 %_________________________________________________________________%%
1127 %_________________________________________________________________%%
1128 %_________________________________________________________________%%
1132 %_________________________________________________________________%%
1133 % Globally extend a list by another item.
1135 % Replaces the definition of the macro #1 by the expansion of #1
1136 % immediately followed by #2.
1137 %_________________________________________________________________%%
1139 \def\g@extendlist#1#2{
1140 \expandafter\def\expandafter#1\expandafter{#1#2}
1144 %_________________________________________________________________%%
1145 % Give the different attributes of a node.
1146 %_________________________________________________________________%%
1148 \def\g@nodecoords#1{%
1149 \csname g@xy@#1\endcsname%
1152 \csname g@type@#1\endcsname%
1154 \def\g@thenodesize#1{%
1155 \csname g@size@#1\endcsname%
1158 \@ifundefined{g@name@#1}{%
1160 \typeout{! Graph package error: node #1 undefined!}%
1167 %_________________________________________________________________%%
1168 % Give the difference between coordinate pairs the second and
1169 % third argument expand to and define the first as the result.
1170 %_________________________________________________________________%%
1172 \def\g@defcoorddiff#1#2#3{
1173 \edef#1{% Expand both arguments before expanding \g@coorddiff:
1174 \expandafter\expandafter\expandafter\g@coorddiff\expandafter#2#3}
1177 \def\g@coorddiff(#1,#2)(#3,#4){(#3 #1 sub, #4 #2 sub)
1181 %_________________________________________________________________%%
1182 % Find out the size of a box and add \g@eboxes.
1183 %_________________________________________________________________%%
1185 \newdimen\g@heightplusdepth
1189 \g@heightplusdepth=\ht0
1190 \advance\g@heightplusdepth by\dp0
1191 \advance\g@heightplusdepth by\g@eboxes\unitlength
1193 \advance\g@width by\g@eboxes\unitlength
1194 \edef\g@thetextsize{%
1195 (\number\g@width,\number\g@heightplusdepth)%
1200 %_________________________________________________________________%%
1201 % Save the information about a node in appropriate macros
1202 % (one macro to treat round and square nodes, one for
1203 % rectangular nodes, and one for text nodes):
1204 %_________________________________________________________________%%
1206 \def\g@node#1#2(#3,#4)[#5]{
1207 \g@nodedef{g@name@#1}{}
1210 \xdef\g@auxnodesize{\g@nsize}
1212 \g@nodedef{g@xy@#1}{(#3,#4)}
1213 \g@nodedef{g@type@#1}{#2}
1214 \ifx\g@rectangletype#2
1215 \g@nodedef{g@size@#1}{[\g@auxnodesize,\g@auxnodesize]}
1217 \g@nodedef{g@size@#1}{[\g@auxnodesize]}
1221 \def\g@noderect#1[#2,#3](#4,#5){
1222 \g@nodedef{g@name@#1}{}
1223 \g@nodedef{g@xy@#1}{(#4,#5)}
1224 \g@nodedef{g@type@#1}{\g@rectangletype}
1225 \g@nodedef{g@size@#1}{[#2,#3]}
1228 \def\g@nodebytext#1(#2,#3)#4[#5]{
1229 \g@nodedef{g@name@#1}{}
1230 \g@nodedef{g@xy@#1}{(#2,#3)}
1231 \g@nodedef{g@type@#1}{\g@rectangletype}
1234 \expandafter\g@findsize\g@thetextsize
1236 \g@nodedef{g@size@#1}{\g@auxtextsize}
1239 \def\g@nodedef#1#2{\expandafter\edef\csname #1\endcsname{#2}}
1243 %_________________________________________________________________%%
1244 % Compare the coordinates of nodes and give an error message if they
1245 % coincide. (Used to prevent the definition of edges of length 0.)
1246 %_________________________________________________________________%%
1249 \def\g@differentpositions#1#2#3{%
1250 \edef\g@firstname{#1}%
1251 \edef\g@secondname{#2}%
1252 \ifx\g@firstname\g@secondname%
1254 \typeout{! Graph package error: Node #1 used twice
1259 \edef\g@firstposition{\g@nodecoords{#1}}%
1260 \edef\g@secondposition{\g@nodecoords{#2}}%
1261 \ifx\g@firstposition\g@secondposition%
1263 \typeout{! Graph package error: Coordinates of nodes
1265 \typeout{\string#3 coincide.}%
1274 %_________________________________________________________________%%
1275 % Nasty procedure to compute the necessary size of the node. We need
1276 % something that computes
1277 % textdimension / \unitlength + 2 * \g@lwidth
1278 % with high precision. So we can't simply use the \divide macro of
1279 % TeX (yielding an integer value), but must explicitely construct a
1280 % number showing some (I chose three) digits after the period.
1281 % (I don't know whether there's a more elegant way of doing this.
1282 % Sorry to anybody who might be bothered.)
1283 %_________________________________________________________________%%
1292 \def\g@findsize(#1,#2){
1294 \g@helpB=\g@lwidth\unitlength\multiply\g@helpB by 2\relax
1295 \advance\g@xsizeA by \g@helpB\relax
1297 \divide\g@xsizeA by\unitlength\relax
1298 \g@help=\unitlength\multiply\g@help by -\g@xsizeA\relax
1299 \advance\g@xsizeB by \g@help\relax
1300 \g@help=\unitlength\advance\g@help by 999\divide\g@help by 1000
1301 \multiply\g@help by 1000
1302 \advance\g@xsizeB by \g@help\relax
1303 \divide\g@help by 1000
1304 \divide\g@xsizeB by \g@help
1307 \advance\g@ysizeA by \g@helpB\relax
1309 \divide\g@ysizeA by\unitlength\relax
1310 \g@help=\unitlength\multiply\g@help by -\g@ysizeA\relax
1311 \advance\g@ysizeB by \g@help\relax
1312 \g@help=\unitlength\advance\g@help by 999\divide\g@help by 1000
1313 \multiply\g@help by 1000
1314 \advance\g@ysizeB by \g@help\relax
1315 \divide\g@help by 1000
1316 \divide\g@ysizeB by \g@help
1317 \xdef\g@auxtextsize{%
1318 [\expandafter\g@mkpoint\number\g@xsizeB;{\number\g@xsizeA},%
1319 \expandafter\g@mkpoint\number\g@ysizeB;{\number\g@ysizeA}]}
1322 \def\g@mkpoint#1#2;#3{
1327 %_________________________________________________________________%%
1328 % \put with separated x- and y-\unitlengths
1329 % (modified definition from LaTeX):
1330 %_________________________________________________________________%%
1332 \newdimen\g@xunitlength\g@xunitlength=\unitlength
1333 \newdimen\g@yunitlength\g@yunitlength=\unitlength
1334 \long\def\g@xyput(#1,#2)#3{\@killglue\raise#2\g@yunitlength\hbox to\z@{\kern
1335 #1\g@xunitlength #3\hss}\ignorespaces}