\ProvidesPackage{graphs}[2003/11/16]
%
%
%_________________________________________________________________%%
% Draw graphs only if this is set to TRUE:
%_________________________________________________________________%%
%
\newif\ifdrawgraphs
\drawgraphstrue

\DeclareOption{draft}{\drawgraphsfalse}
\ProcessOptions

\typeout{}
\typeout{LaTeX2e package `graphs', version 1.53}
\typeout{Frank Drewes, Umea University, 16/11 2003}
\typeout{}

%
% \input the low-level commands that produce PostScript \special's.
%
\input{graphs_ps}
%
% \input the local configuration.
%
\input{graphs_config}
%
%
%_________________________________________________________________%%
% Initial value of \unitlength:
%
\newdimen\g@oldunitlength
\unitlength=1cm
%
%
%_________________________________________________________________%%
% Global settings and macros to change them (all lengths are numbers
% interpreted as multiples of \unitlength, except for the ones in
% \graphlinedash):
%
% - \graphlinewidth	define the width of lines (relevant
%			for nodes and edges)
% - \graphlinedash	define the dash style of lines; the argument
%			is a sequence of natural numbers delimited by
%			blanks (relevant for nodes and edges). Is
%			taken as input to the postscript setdash
%			command.
% - \graphnodesize	define the size (= diameter) of nodes
% - \graphnodecolour	define the interior shading of nodes (a
%			number between 0 (= black) and 1 (= white))
% - \fillednodestrue
%   \fillednodesfalse	determine whether the interior of nodes shall be
%                       filled or not
% - \graphlinecolour	define the `colour' of edges; similar to
%			\graphnodecolour
% - \grapharrowlength	define the length from tip to basis of a
%			directed edge's arrow head
% - \grapharrowwidth	define the width of the basis of a
%			directed edge's arrow head (in multiples of
%			\grapharrowlength)
% - \grapharrowtype	define the type of the arrow heads (argument
%			should be 1 or 2)
% - \autodistance	define the factor that defines the distance
%			of automatically placed text boxes from the
%			centre of a node (1 means "placed on the
%			edge").
% - \enlargeboxes	define the length that is added to
%			text boxes (in x and y direction) in order
%			to determine the size of the necessary
%			white area underlying it.
% - \opaquetexttrue
%   \opaquetextfalse	determine whether text boxes shall be considered
%			opaque or transparent (In the latter case
%			\enlargeboxes doesn't have a (visible)
%			effect.) Its initial value is true except
%			for \autonodetext, which always has it set
%			to false if it's not changed explicitely
%			through the optional parameter. 
% - \filledareastrue
%   \filledareasfalse	determine whether areas shall be filled or not
%
% - \graphfillcolour	define the fill colour of areas (if filled
%			at all).
%			
%_________________________________________________________________%%
%
\def\g@defrel#1*#2{\edef#1{#1\ps@s #2 0 ge {#2 mul} if}}
\def\g@defplus#1+#2{\edef#1{
	#1\ps@s
	#2 1 gt
	{1 exch sub #2 div 1 exch sub}
	{#2 0 ge {#2 mul} if}
	ifelse}}
\def\g@defcolplus#1+#2{\edef#1{
	#1
	3 {
	    3 1 roll
	    #2 1 gt
	    {1 exch sub #2 div 1 exch sub}
	    {#2 0 ge {#2 mul} if}
	    ifelse
	  }
	repeat
}}
\def\g@defabs#1#2#3{\def#1{#3}\def#2{}}
\def\g@defcolabs#1#2{%
	\@ifnextchar({\g@defcolabsrgb{#1}{#2}}{\g@defcolabsbw{#1}{#2}}%
}
\def\g@defcolabsbw#1#2#3{\def#1{#3\ps@s #3\ps@s #3}\def#2{}}
\def\g@defcolabsrgb#1#2(#3,#4,#5){\def#1{#3\ps@s #4\ps@s #5}\def#2{}}
%
\def\graphlinewidth{%
	\@ifnextchar*{\g@defrel{\g@lwidthmod}}%
			{\g@defabs{\g@lwidth}{\g@lwidthmod}}}
\graphlinewidth{.02}
%
\def\graphlinedash#1{\def\g@ldash{[ #1 ]}}
\graphlinedash{}
%
\def\graphnodesize#1{\def\g@nsize{#1}}
\graphnodesize{.2}
%
\def\graphnodecolour{%
	\@ifnextchar+{\g@defcolplus{\g@ncolourmod}}%
			{\g@defcolabs{\g@ncolour}{\g@ncolourmod}}}
\graphnodecolour{0}
%
\newif\iffillednodes\fillednodestrue
%
\def\graphlinecolour{%
	\@ifnextchar+{\g@defcolplus{\g@lcolourmod}}%
			{\g@defcolabs{\g@lcolour}{\g@lcolourmod}}}
\graphlinecolour{0}
%
\def\grapharrowlength{%
	\@ifnextchar*{\g@defrel{\g@alengthmod}}%
			{\g@defabs{\g@alength}{\g@alengthmod}}}
\grapharrowlength{.3}
%
\def\grapharrowwidth{%
	\@ifnextchar*{\g@defrel{\g@awidthmod}}%
			{\g@defabs{\g@awidth}{\g@awidthmod}}}
\grapharrowwidth{.5}
%
\def\grapharrowtype#1{\def\g@atype{#1}}
\grapharrowtype{1}
%
\def\autodistance#1{\def\g@autodistance{#1}}
\autodistance{1.3}
%
\def\enlargeboxes#1{\def\g@eboxes{#1}}
\enlargeboxes{.1}
%
\newif\ifopaquetext\opaquetexttrue
%
\newif\iffilledareas\filledareastrue
%
\def\graphfillcolour{%
	\@ifnextchar+{\g@defcolplus{\g@fcolourmod}}%
			{\g@defcolabs{\g@fcolour}{\g@fcolourmod}}}
\graphfillcolour{.5}
%
%
%_________________________________________________________________%%
% Issue a warning if a command name defined in graphs.sty already has
% a meaning.
%_________________________________________________________________%%
%
\def\g@test#1{
	\@ifundefined{#1}{}{
	  \typeout{}
	  \typeout{Warning: command name `#1' already used;
	  	redefined in graphs.sty!}
	  \typeout{}
	}
}
%
%
%_________________________________________________________________%%
% This is the environment in which the macros above can be used.
%
% Arguments:
%
% As for the LaTeX picture environment, i.e., it starts with
% \begin{graph}(x,y)(dx,dy) (where the second pair is optional) and
% ends with \end{graph}.
%
% Remark:
%
% The graph enviroment is imlemented on the basis of the picture
% environment. As a result, all commands allowed in pictures may be
% used (in addition to the graph commands). The picture commands'
% effects will always take place first, so subsequent AS WELL AS
% PRECEEDING graph commands will overlay the ordinary LaTeX
% picture. (This is one reason why a command like \freetext is NOT
% useless: its effect takes place after nodes and edges have been
% drawn.)
%_________________________________________________________________%%
%
\g@test{graph}\g@test{framegraph}
\def\framegraph(#1){\@ifnextchar({\g@graph f(#1)}{\g@graph f(#1)(0,0)}}
\def\graph(#1){\@ifnextchar({\g@graph n(#1)}{\g@graph n(#1)(0,0)}}
\def\g@graph#1(#2)(#3){%
	\begin{picture}(#2)(#3)%
	\if #1f%
  	  \put(#3){\framebox(#2){}}%
  	\fi%
	\ifdrawgraphs\else%
  	  \put(#3){\framebox(#2){graph}}%
  	\fi%
  	\def\g@nodeinfo{}\def\g@specialeffects{}\def\g@nodes{}\def\g@texts{}%
  	\def\g@edges{}%
}
\def\endgraph{%
	\ifdrawgraphs
	  \g@nodeinfo\g@specialeffects\g@edges\g@nodes\g@texts%
	\fi%
	\end{picture}%
}
\def\endframegraph{\endgraph}
%
%
%_________________________________________________________________%%
% Types of nodes
%_________________________________________________________________%%
%
\def\g@circletype{0}
\def\g@rectangletype{1}
%
%
%_________________________________________________________________%%
% Definition of square nodes:
%
% Arguments:
%
% Nodename (a character sequence like abc)
% Position (x,y) = a pair of numbers
%_________________________________________________________________%%
%
\g@test{squarenode}
\def\squarenode#1(#2,#3){
	\@ifnextchar[{\g@squarenode{#1}(#2,#3)}{\g@squarenode{#1}(#2,#3)[]}
}
%
\def\g@squarenode#1(#2,#3)[#4]{
	\g@extendlist\g@nodeinfo{\g@node{#1}{\g@rectangletype}(#2,#3)[#4]}
	\g@extendlist\g@nodes{\g@drawsquarenode{#1}(#2,#3)[#4]}
}
%
% The actual drawing routine:
%
\def\g@drawsquarenode#1(#2,#3)[#4]{%
	\edef\g@size{\g@thenodesize{#1}}%
	{#4%
	\put(#2,#3){\expandafter\ps@rectangle\g@size}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of round nodes:
%
% Arguments:
%
% Nodename (a character sequence like abc)
% Position (x,y) = a pair of numbers
%_________________________________________________________________%%
%
\g@test{roundnode}
\def\roundnode#1(#2,#3){
	\@ifnextchar[{\g@roundnode{#1}(#2,#3)}{\g@roundnode{#1}(#2,#3)[]}
}
%
\def\g@roundnode#1(#2,#3)[#4]{
	\g@extendlist\g@nodeinfo{\g@node{#1}{\g@circletype}(#2,#3)[#4]}
	\g@extendlist\g@nodes{\g@drawroundnode{#1}(#2,#3)[#4]}
}
%
% The actual drawing routine:
%
\def\g@drawroundnode#1(#2,#3)[#4]{%
	\edef\g@size{\g@thenodesize{#1}}%
	{#4%%
	\put(#2,#3){\expandafter\ps@circle\g@size}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of rectangular nodes:
%
% Arguments:
%
% Nodename (a character sequence like abc)
% Size [width,height] (in multiples of \unitlength)
% Position (x,y) = a pair of numbers
%_________________________________________________________________%%
%
\g@test{rectnode}
\def\rectnode#1[#2,#3](#4,#5){
	\@ifnextchar[{\g@rectnode{#1}[#2,#3](#4,#5)}%
		{\g@rectnode{#1}[#2,#3](#4,#5)[]}
}
%
\def\g@rectnode#1[#2,#3](#4,#5)[#6]{
	\g@extendlist\g@nodeinfo{\g@noderect{#1}[#2,#3](#4,#5)}
	\g@extendlist\g@nodes{\g@drawrectnode{#1}[#6]}
}
%
% The actual drawing routine:
%
\def\g@drawrectnode#1[#2]{%
	\edef\g@size{\g@thenodesize{#1}}%
	\edef\g@coords{\g@nodecoords{#1}}%
	{#2%
	\expandafter\put\g@coords{\expandafter\ps@rectangle\g@size}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of text nodes (rectangular nodes whose dimension is
% determined by the given text):
%
% Arguments:
%
% Nodename (a character sequence like abc)
% Position (x,y) = a pair of numbers
% Text (=anything that may occur as a \put argument in a picture
%	environment, i.e., even lines, vectors, and so on.)
%_________________________________________________________________%%
%
\g@test{textnode}
\def\textnode#1(#2,#3)#4{
	\@ifnextchar[{\g@textnode{#1}(#2,#3){#4}}%
		{\g@textnode{#1}(#2,#3){#4}[]}
}
%
\def\g@textnode#1(#2,#3)#4[#5]{
	\autonodetext{#1}{#4}[#5]
	\g@extendlist\g@nodeinfo{\g@nodebytext{#1}(#2,#3){#4}[#5]}
	\g@extendlist\g@nodes{\g@drawrectnode{#1}%
					[\graphnodecolour{1}#5]}
}
%
%
%_________________________________________________________________%%
% Definition of an edge:
%
% Arguments:
%
% The two incident nodes
%_________________________________________________________________%%
%
\g@test{edge}
\def\edge#1#2{
	\@ifnextchar[{\g@edge{#1}{#2}}{\g@edge{#1}{#2}[]}
}
%
\def\g@edge#1#2[#3]{
	\g@extendlist\g@edges{\g@drawedge{#1}{#2}[#3]}
}
%
% The actual drawing routine:
%
\def\g@drawedge#1#2[#3]{%
	\g@testname{#1}\g@testname{#2}%
	\g@differentpositions{#1}{#2}{\edge{#1}{#2}}%
	\edef\g@firstcoords{\g@nodecoords{#1}}%
	\edef\g@secondcoords{\g@nodecoords{#2}}%
	\g@defcoorddiff{\g@diffcoords}{\g@firstcoords}{\g@secondcoords}%
	{#3%
	\expandafter\put\g@firstcoords{\expandafter\ps@line\g@diffcoords}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of a directed edge:
%
% Arguments (same as for \edge):
%
% The two incident nodes (order indicates direction of the arrow)
%_________________________________________________________________%%
%
\g@test{diredge}
\def\diredge#1#2{
	\@ifnextchar[{\g@diredge{#1}{#2}}{\g@diredge{#1}{#2}[]}
}
%
\def\g@diredge#1#2[#3]{
	\g@extendlist\g@edges{\g@drawdiredge{#1}{#2}[#3]}
}
%
% The actual drawing routine:
%
\def\g@drawdiredge#1#2[#3]{%
	\g@testname{#1}\g@testname{#2}%
	\g@differentpositions{#1}{#2}{\diredge{#1}{#2}}%
	\edef\g@firstcoords{\g@nodecoords{#1}}%
	\edef\g@secondcoords{\g@nodecoords{#2}}%
	\g@defcoorddiff{\g@diffcoords}{\g@firstcoords}{\g@secondcoords}%
	%
	% Choose the right drawing procedure, according to the node's type:
	%
	\edef\g@type{\g@nodetype{#2}}%
	\ifnum\g@circletype=\g@type%
	  \let\g@draw=\ps@arrowoncircle%
	\else%
	  \let\g@draw=\ps@arrowonrectangle%
	  \ifnum\g@rectangletype=\g@type%
	  \else%
	    \typeout{}%
	    \typeout{Error in \string\g@drawdiredge: unrecognized node type}%
	  \fi%
	\fi%
	%
	% and draw it:
	%
	\edef\g@diffcoordsandsize{\g@diffcoords\g@thenodesize{#2}}%
	{#3%
	\expandafter\put\g@firstcoords{\expandafter\g@draw\g@diffcoordsandsize}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of a `bow' (a curved edge):
%
% Arguments:
%
% The two incident nodes
% The displacement factor of the midpoint relative to the distance.
%	of both nodes. A positive number means the bow extends 
%	to the left (if one looks in the direction of the edge).
%_________________________________________________________________%%
%
\g@test{bow}
\def\bow#1#2#3{
	\@ifnextchar[{\g@bow{#1}{#2}{#3}}{\g@bow{#1}{#2}{#3}[]}
}
%
\def\g@bow#1#2#3[#4]{
	\g@extendlist\g@edges{\g@drawbow{#1}{#2}{#3}[#4]}
}
%
% The actual drawing routine:
%
\def\g@drawbow#1#2#3[#4]{%
	\g@testname{#1}\g@testname{#2}%
	\g@differentpositions{#1}{#2}{\bow{#1}{#2}...}%
	\edef\g@firstcoords{\g@nodecoords{#1}}%
	\edef\g@secondcoords{\g@nodecoords{#2}}%
	\expandafter\g@bowcombine\g@secondcoords{#3}%
	{#4%
	\filledareasfalse%
	\put(0,0){\expandafter\ps@path\g@combineresult}%
	}%
}
%
% Macro used above to combine coordinates of nodes and displacement:
\def\g@bowcombine(#1,#2)#3{
	\edef\g@combineresult{\g@firstcoords{(#1,#2,#3)}}
}
%
%
%_________________________________________________________________%%
% Definition of a `directed bow' (a curved arrow):
%
% Arguments (same as for \bow):
%
% The two incident nodes
% The displacement factor of the midpoint relative to the distance.
%	of both nodes. A positive number means the bow extends 
%	to the left (if one looks in the direction of the edge).
%_________________________________________________________________%%
%
\g@test{dirbow}
\def\dirbow#1#2#3{
	\@ifnextchar[{\g@dirbow{#1}{#2}{#3}}{\g@dirbow{#1}{#2}{#3}[]}
}
%
\def\g@dirbow#1#2#3[#4]{
	\g@extendlist\g@edges{\g@drawdirbow{#1}{#2}{#3}[#4]}
}
%
% The actual drawing routine:
%
\def\g@drawdirbow#1#2#3[#4]{
	\g@testname{#1}\g@testname{#2}%
	\g@differentpositions{#1}{#2}{\dirbow{#1}{#2}...}%
	\edef\g@firstcoords{\g@nodecoords{#1}}%
	\edef\g@secondcoordsandsize{\g@nodecoords{#2}\g@thenodesize{#2}}%
	\expandafter\g@dirbowcombine\g@secondcoordsandsize{#3}%
	%
	% Choose the right drawing procedure, according to the node's type:
	%
	\edef\g@type{\g@nodetype{#2}}%
	\ifnum\g@circletype=\g@type%
	  \let\g@draw=\ps@dirbowoncircle%
	\else%
	  \let\g@draw=\ps@dirbowonrectangle%
	  \ifnum\g@rectangletype=\g@type%
	  \else%
	    \typeout{}%
	    \typeout{Error in \string\g@drawdirbow: unrecognized node type}%
	  \fi%
	\fi%
	%
	% and draw it:
	%
	{#4%
	\filledareasfalse%
	\put(0,0){\expandafter\g@draw\g@combineresult}%
	}%
}
%
% Macro used above to combine coordinates of nodes and displacement:
\def\g@dirbowcombine(#1,#2)[#3]#4{
	\edef\g@combineresult{\g@firstcoords(#1,#2,#4)[#3]}
}
%
%
%_________________________________________________________________%%
% Definition of a loop. There're two ways to provide this macro
% with the necessary arguments. Here's the
% first:
%
% Arguments:
%
% Node that carries the loop
% Two relative coordinates (x1,y1) (x2,y2) indicating the lines from
%	the incident node to (x1,y1) and (x2,y2) that form the loop
%	together with a curve connecting (x1,y1) and (x2,y2).
%_________________________________________________________________%%
%
\g@test{loopedge}
\def\loopedge#1{
	\@ifnextchar({\g@loopedgeA{#1}}{\g@loopedgeB{#1}}
}
%
\def\g@loopedgeA#1(#2,#3)(#4,#5){
	\@ifnextchar[{\g@loopedgeAa{#1}(#2,#3)(#4,#5)}%
			{\g@loopedgeAa{#1}(#2,#3)(#4,#5)[]}
}
%
\def\g@loopedgeAa#1(#2,#3)(#4,#5)[#6]{
	\g@extendlist\g@edges{\g@drawloopedgeA{#1}(#2,#3)(#4,#5)[#6]}
}
%
% The actual drawing routine:
%
\def\g@drawloopedgeA#1(#2,#3)(#4,#5)[#6]{%
	\g@testname{#1}%
	\edef\g@coords{\g@nodecoords{#1}}%
	{#6%
	\expandafter\put\g@coords{%%
	  \ps@loopA(#2,#3)(#4,#5)}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of a loop - the second form:
%
% Arguments:
%
% Node that carries the loop
% Angle the two lines defining the loop build
% Coordinates (x,y) that give the axis along which the loop is
% to be drawn and its length (ie, the length of the two lines 
% defining the loop).
%_________________________________________________________________%%
%
\def\g@loopedgeB#1#2(#3,#4){
	\@ifnextchar[{\g@loopedgeBa{#1}{#2}(#3,#4)}%
			{\g@loopedgeBa{#1}{#2}(#3,#4)[]}
}
%
\def\g@loopedgeBa#1#2(#3,#4)[#5]{
	\g@extendlist\g@edges{\g@drawloopedgeB{#1}{#2}(#3,#4)[#5]}
}
%
% The actual drawing routine:
%
\def\g@drawloopedgeB#1#2(#3,#4)[#5]{%
	\g@testname{#1}%
	\edef\g@coords{\g@nodecoords{#1}}%
	{#5%
	\expandafter\put\g@coords{%%
	  \ps@loopB{#2}(#3,#4)}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of a directed loop. There're two ways to provide
% this macro with the necessary arguments. Here's the first:
%
% Arguments:
%
% Node that carries the loop
% Two relative coordinates (x1,y1) (x2,y2) indicating the lines from
%	the incident node to (x1,y1) and (x2,y2) that form the loop
%	together with a curve connecting (x1,y1) and (x2,y2).
%_________________________________________________________________%%
%
\g@test{dirloopedge}
\def\dirloopedge#1{
	\@ifnextchar({\g@dirloopedgeA{#1}}{\g@dirloopedgeB{#1}}
}
%
\def\g@dirloopedgeA#1(#2,#3)(#4,#5){
	\@ifnextchar[{\g@dirloopedgeAa{#1}(#2,#3)(#4,#5)}%
			{\g@dirloopedgeAa{#1}(#2,#3)(#4,#5)[]}
}
%
\def\g@dirloopedgeAa#1(#2,#3)(#4,#5)[#6]{
	\g@extendlist\g@edges{\g@drawdirloopedgeA{#1}(#2,#3)(#4,#5)[#6]}
}
%
% The actual drawing routine:
%
\def\g@drawdirloopedgeA#1(#2,#3)(#4,#5)[#6]{%
	\g@testname{#1}%
	\edef\g@coords{\g@nodecoords{#1}}%
	%
	% Choose the drawing procedure for the arrow according
	% to the node's type:
	%
	\edef\g@type{\g@nodetype{#1}}%
	\ifnum\g@circletype=\g@type%
	  \let\g@draw=\ps@looparrowoncircleA%
	\else%
	  \let\g@draw=\ps@looparrowonrectangleA%
	  \ifnum\g@rectangletype=\g@type%
	  \else%
	    \typeout{}%
	    \typeout{Error in \string\g@drawdirloopedge: unrecognized node type}%%
	  \fi%
	\fi%
	\edef\g@args{(#2,#3)(#4,#5)\g@thenodesize{#1}}%
	%
	% and draw it:
	%
	{#6%
	\expandafter\put\g@coords{\expandafter\g@draw\g@args}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of a directed loop - the second form:
%
% Arguments:
%
% Node that carries the loop
% Angle the two lines defining the loop build
% Coordinates (x,y) that give the axis along which the loop is
% to be drawn and its length (ie, the length of the two lines 
% defining the loop).
%_________________________________________________________________%%
%
\def\g@dirloopedgeB#1#2(#3,#4){
	\@ifnextchar[{\g@dirloopedgeBa{#1}{#2}(#3,#4)}%
			{\g@dirloopedgeBa{#1}{#2}(#3,#4)[]}
}
%
\def\g@dirloopedgeBa#1#2(#3,#4)[#5]{
	\g@extendlist\g@edges{\g@drawdirloopedgeB{#1}{#2}(#3,#4)[#5]}
}
%
% The actual drawing routine:
%
\def\g@drawdirloopedgeB#1#2(#3,#4)[#5]{%
	\g@testname{#1}%
	\edef\g@coords{\g@nodecoords{#1}}%
	%
	% Choose the drawing procedure for the arrow according
	% to the node's type:
	%
	\edef\g@type{\g@nodetype{#1}}%
	\ifnum\g@circletype=\g@type%
	  \let\g@draw=\ps@looparrowoncircleB%
	\else%
	  \let\g@draw=\ps@looparrowonrectangleB%
	  \ifnum\g@rectangletype=\g@type%
	  \else%
	    \typeout{}%
	    \typeout{Error in \string\g@drawdirloopedge: unrecognized node type}%%
	  \fi%
	\fi%
	\edef\g@args{{#2}(#3,#4)\g@thenodesize{#1}}%
	%
	% and draw it:
	%
	{#5%
	\expandafter\put\g@coords{\expandafter\g@draw\g@args}%
	}%
}
%
%
%_________________________________________________________________%%
% Automatic positioning of a node's text
% (This one sets \opaquetextfalse if it's not enforced by the optional
% parameter!):
%
% Arguments:
%
% Node
% Optional (surrounded by []): n, s, e, w, ne, nw, se, sw (for north,
%	south, east, west, ...) indicating the position of the text
%	with respect to the node. If omitted, the text is centered
%	inside the node.
% Text (=anything that may occur as a \put argument in a picture
%	environment, i.e., even lines, vectors, and so on.)
%_________________________________________________________________%%
%
\g@test{autonodetext}
\def\autonodetext#1{
  \@ifnextchar[{\g@autonodetext{#1}}{\g@autonodetext{#1}[]}
}
%
\def\g@autonodetext#1[#2]#3{
  \@ifnextchar[{\g@autonodetextopt{#1}{#3}[#2]}%
  	{\g@autonodetextopt{#1}{#3}[#2][]}
}
%
\def\g@rootofahalf{.70710678}% square root of 0.5
%
\def\g@autonodetextopt#1#2[#3][#4]{
  \def\g@doit##1##2##3;{
    \def\g@xdisplace{0}\def\g@ydisplace{0}\def\g@torb{,0]}\def\g@lorr{[0}
    \def\g@xdisplacec{0}\def\g@ydisplacec{0}
    \if##2.
      \if##1s\def\g@ydisplace{-1}\def\g@torb{,-1]}\else
      \if##1n\def\g@ydisplace{1}\def\g@torb{,1]}\else
      \if##1e\def\g@xdisplace{1}\def\g@lorr{[1}\else
      \if##1w\def\g@xdisplace{-1}\def\g@lorr{[-1}\fi\fi\fi\fi
      \edef\g@xdisplacec{\g@xdisplace}\edef\g@ydisplacec{\g@ydisplace}
    \else
      \if##1s\def\g@ydisplace{-1}\def\g@torb{,-1]}
      	\def\g@ydisplacec{-\g@rootofahalf}\else
      \if##1n\def\g@ydisplace{1}\def\g@torb{,1]}
      	\def\g@ydisplacec{\g@rootofahalf}\else
      \if##1e\def\g@xdisplace{1}\def\g@lorr{[1}
      	\def\g@xdisplacec{\g@rootofahalf}\else
      \if##1w\def\g@xdisplace{-1}\def\g@lorr{[-1}
      	\def\g@xdisplacec{-\g@rootofahalf}\fi\fi\fi\fi
      \if##2e\def\g@xdisplace{1}\def\g@lorr{[1}
      	\def\g@xdisplacec{\g@rootofahalf}\else
      \if##2w\def\g@xdisplace{-1}\def\g@lorr{[-1}
      	\def\g@xdisplacec{-\g@rootofahalf}
      \fi\fi
    \fi
    \edef\g@values{%
      {(\g@xdisplacec,\g@ydisplacec)}{\g@lorr\g@torb}{%
        (\g@xdisplace,\g@ydisplace)}%
    }
    \expandafter\g@extendtextsauto\g@values{#1}{#2}[#4]}
  \g@doit#3...;}
%
%
\def\g@extendtextsauto#1#2#3#4#5[#6]{
	\g@extendlist\g@texts{\g@putautotext{#1}{#2}{#3}{#4}{#5}[#6]}
}
%
% The actual drawing routine:
%
\def\g@putautotext#1#2#3#4#5[#6]{%
	\g@testname{#4}%
	\edef\g@coords{\g@nodecoords{#4}}%
	\edef\g@type{\g@nodetype{#4}}%
	\edef\g@size{\g@thenodesize{#4}}%
	\ifnum\g@circletype=\g@type%
	  \def\g@draw{\g@xyput#1}%
	  \expandafter\g@getcirclexy\g@size%
	\else%
	  \def\g@draw{\g@xyput#3}%
	  \expandafter\g@getrectanglexy\g@size%
	  \ifnum\g@rectangletype=\g@type%
	  \else%
	    \typeout{}%
	    \typeout{Error in \string\putautotext: unrecognized node type}%
	  \fi%
	\fi%
	\expandafter\put\g@coords{%
	  \opaquetextfalse #6%
	  \g@textsize{#5}%
	  \g@xunitlength=\g@autodistance\g@xunitlength\divide\g@xunitlength by 2%
	  \g@yunitlength=\g@autodistance\g@yunitlength\divide\g@yunitlength by 2%
	  \ifopaquetext%
	    \g@draw{\expandafter\g@makeautotext\g@thetextsize%
	  	#2{\expandafter\ps@deletebox\g@thetextsize}}%
	  \fi%
	  \g@draw{\expandafter\g@makeautotext\g@thetextsize%
	  	#2{\makebox(0,0){#5}}}%
	}%
}%
%
\def\g@getcirclexy[#1]{
	\g@xunitlength=#1\unitlength\relax
	\g@yunitlength=\g@xunitlength\relax
}
%
\def\g@getrectanglexy[#1,#2]{
	\g@xunitlength=#1\unitlength\relax
	\g@yunitlength=#2\unitlength\relax
}
%
\newcount\g@xpos
\newcount\g@ypos
\def\g@makeautotext(#1,#2)[#3,#4]#5{%
	\g@oldunitlength=\unitlength%
	\g@xpos=#1\divide\g@xpos by 2\multiply\g@xpos by #3\relax%
	\g@ypos=#2\divide\g@ypos by 2\multiply\g@ypos by #4\relax%
	\unitlength=1sp%
	\edef\g@positions{(\number\g@xpos,\number\g@ypos)}%
	\expandafter\put\g@positions{\unitlength=\g@oldunitlength{#5}}%
}%
%
%
%_________________________________________________________________%%
% Definition of a node's text:
%
% Arguments:
%
% Node
% Relative coordinates of the text (optional).
%	Text is centered horizontally and vertically at this position.
%	(Use a \makebox(0,0)[...]{Text} construction to disable the
%	centering if necessary.)
%	Omitting the optinal argument means the same as (0,0).
% Text (=anything that may occur as a \put argument in a picture
%	environment, i.e., even lines, vectors, and so on.)
%_________________________________________________________________%%
%
\g@test{nodetext}
\def\nodetext#1{
	\@ifnextchar({\g@nodetext{#1}}{\g@nodetext{#1}(0,0)}
}
\def\g@nodetext#1(#2,#3)#4{
	\@ifnextchar[{\g@nodetextb{#1}(#2,#3){#4}}%
			{\g@nodetextb{#1}(#2,#3){#4}[]}
}
%
\def\g@nodetextb#1(#2,#3)#4[#5]{
	\g@extendlist\g@texts{\g@putnodetext{#1}(#2,#3){#4}[#5]}
}
%
% The actual drawing routine:
%
\def\g@putnodetext#1(#2,#3)#4[#5]{%
	\g@testname{#1}%
	\edef\g@coords{\g@nodecoords{#1}}%
	\expandafter\put\g@coords{%
	  #5%
	  \ifopaquetext%
	    \g@textsize{#4}%
	    \put(#2,#3){\expandafter\ps@deletebox\g@thetextsize}%
	  \fi%
	  \put(#2,#3){\makebox(0,0){#4}}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of an edge's text (for straight edges only):
%
% Arguments:
%
% Both nodes incident with the edge in question
% Text (=anything that may occur as a \put argument in a picture
%	environment, i.e., even lines, vectors, and so on.)
%_________________________________________________________________%%
%
\g@test{edgetext}
\def\edgetext#1#2#3{
	\@ifnextchar[{\g@edgetext{#1}{#2}{#3}}%
			{\g@edgetext{#1}{#2}{#3}[]}
}
%
\def\g@edgetext#1#2#3[#4]{
	\g@extendlist\g@texts{\g@putedgetext{#1}{#2}{#3}[#4]}
}
%
% The actual drawing routine:
%
\def\g@putedgetext#1#2#3[#4]{%
	\g@testname{#1}\g@testname{#2}%
	\g@differentpositions{#1}{#2}{\edgetext{#1}{#2}...}%
	\edef\g@firstcoords{\g@nodecoords{#1}}%
	\edef\g@secondcoords{\g@nodecoords{#2}}%
	{%
	  #4%
	  \g@textsize{#3}%
	  \g@oldunitlength=\unitlength%
	  \divide\unitlength by 2%
	  \expandafter\put\g@firstcoords{%
	    \ifopaquetext%
	      \expandafter\put\g@secondcoords{%
	        \expandafter\ps@deletebox\g@thetextsize%
	      }%
	    \fi%
	    \expandafter\put\g@secondcoords{%
	      \unitlength=\g@oldunitlength%
	      \makebox(0,0){#3}%
	    }%
	  }%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of a bow's text:
%
% Arguments:
%
% Both nodes and displacement factor defining the bow in question
% Text (=anything that may occur as a \put argument in a picture
%	environment, i.e., even lines, vectors, and so on.)
%_________________________________________________________________%%
%
\g@test{bowtext}
\def\bowtext#1#2#3#4{
	\@ifnextchar[{\g@bowtext{#1}{#2}{#3}{#4}}%
			{\g@bowtext{#1}{#2}{#3}{#4}[]}
}
%
\def\g@bowtext#1#2#3#4[#5]{
	\g@extendlist\g@texts{\g@putbowtext{#1}{#2}{#3}{#4}[#5]}
}
%
% The actual drawing routine:
%
\newdimen\g@x
\newdimen\g@y
\newdimen\g@aux
\def\g@putbowtext#1#2#3#4[#5]{%
	\g@testname{#1}\g@testname{#2}%
	\g@differentpositions{#1}{#2}{\bowtext{#1}{#2}...}%
	\def\g@doit(##1,##2)(##3,##4){%
	  {#5%
	  \g@textsize{#4}%
	  \g@oldunitlength=\unitlength%
	  \unitlength=.5\unitlength%
	  %
	  % Compute the difference of coordinates:
	  %
	  \g@x=##3\g@oldunitlength\g@aux=##1\g@oldunitlength%
	  \advance\g@x by -\g@aux\g@x=#3\g@x%
	  \g@y=##4\g@oldunitlength\g@aux=##2\g@oldunitlength%
	  \advance\g@y by -\g@aux\g@y=#3\g@y%
	  \g@y=-\g@y%
	  \edef\g@thirdcoords{(\number\g@y,\number\g@x)}%
	  \put(##1,##2){%
	    \ifopaquetext%
	      \put(##3,##4){%
	        \unitlength=1sp%
	        \expandafter\put\g@thirdcoords{%
	          \expandafter\ps@deletebox\g@thetextsize%
	        }%
	      }%
	    \fi%
	    \put(##3,##4){%
	      \unitlength=1sp%
	      \expandafter\put\g@thirdcoords{%
	        \unitlength=\g@oldunitlength%
	        \makebox(0,0){#4}%
	      }%
	    }%
	  }}%
	}%
	\edef\g@firstcoords{\g@nodecoords{#1}}%
	\edef\g@secondcoords{\g@nodecoords{#2}}%
	%
	% Expand both arguments before executing \g@doit:
	%
	\expandafter\expandafter\expandafter%
		\g@doit\expandafter\g@firstcoords\g@secondcoords%
}
%
%
%_________________________________________________________________%%
% Definition of free text:
%
% Arguments:
%
% Absolute coordinates of the text. (Text is centered horizontally
%	and vertically at this position. Use a
%	\makebox(0,0)[...]{Text} construction to disable the
%	centering if necessary.)
% Text (=anything that may occur as a \put argument in a picture
%	environment, i.e., even lines, vectors, and so on.)
%_________________________________________________________________%%
%
\g@test{freetext}
\def\freetext(#1,#2)#3{
	\@ifnextchar[{\g@freetext(#1,#2){#3}}%
			{\g@freetext(#1,#2){#3}[]}
}
%
\def\g@freetext(#1,#2)#3[#4]{
	\g@extendlist\g@texts{\g@putfreetext(#1,#2){#3}[#4]}
}
%
% The actual drawing routine:
%
\def\g@putfreetext(#1,#2)#3[#4]{%
	{#4%
	\ifopaquetext%
	  \g@textsize{#3}%
	  \put(#1,#2){\expandafter\ps@deletebox\g@thetextsize}%
	\fi%
	\put(#1,#2){\makebox(0,0){#3}}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of a (perhaps filled) area:
%
% Arguments:
%
% Absolute coordinates of the starting point
% Sequence of pairs (x_i,y_i) or triples (x_i,y_i,d_i) where the
% 	(x_i,y_i) are absolute coordinates of the next segment's
%	end point and d_i is the displacement factor of the midpoint
%	relative to the length of the segment. A positive number
%	means the segment extends to the left.
%_________________________________________________________________%%
%
\g@test{area}
\def\area(#1,#2)#3{
	\@ifnextchar[{\g@area(#1,#2){#3}}%
			{\g@area(#1,#2){#3}[]}
}
%
\def\g@area(#1,#2)#3[#4]{
	\g@extendlist\g@specialeffects{\g@putarea(#1,#2){#3}[#4]}
}
%
% The actual drawing routine:
%
\def\g@putarea(#1,#2)#3[#4]{%
	{#4%
	\put(0,0){\ps@path(#1,#2){#3}}%
	}%
}
%
% For reasons of compatibility with older versions:
\g@test{filledarea}\def\filledarea{\area}
%
%
%_________________________________________________________________%%
% Definition of a (perhaps filled) Bezier curve:
%
% Arguments:
%
% Normal distance of control points from points of the curve,
%	in multiples of the segment length.
% Sequence of triples (x_i,y_i,alpha_i), and and optional
%	[factora_i,factorb_i]) after each of the triples:
%	(x_i,y_i) is a point on the curve, alpha_i is the angle
%	between the x-axis and the line through (x_i,y_i) and the
%	next control point (the previous control point lies opposite),
%	and factora_i (factorb_i) is overwrites the first argument
%	for the two control points between two points.
%_________________________________________________________________%%
%
\g@test{curve}
\def\curve#1#2{
	\@ifnextchar[{\g@curve{#1}{#2}}%
			{\g@curve{#1}{#2}[]}
}
%
\def\g@curve#1#2[#3]{
	\g@extendlist\g@specialeffects{\g@putcurve{#1}{#2}[#3]}
}
%
% The actual drawing routine:
%
\def\g@putcurve#1#2[#3]{%
	{#3%
	\put(0,0){\ps@curve{#1}{#2}}%
	}%
}
%
%
%_________________________________________________________________%%
% Definition of a (perhaps filled) Bezier ``bubble'':
%
% Arguments:
%
% Normal distance (in multiples of unitlength) of control points
%	in multiples of segment length.
% Sequence of points (x_i,y_i).
%_________________________________________________________________%%
%
\g@test{bubble}
\def\bubble#1#2{
	\@ifnextchar[{\g@bubble{#1}{#2}}%
			{\g@bubble{#1}{#2}[]}
}
%
\def\g@bubble#1#2[#3]{
	\g@extendlist\g@specialeffects{\g@putbubble{#1}{#2}[#3]}
}
%
% The actual drawing routine:
%
\def\g@putbubble#1#2[#3]{%
	{#3%
	\put(0,0){\ps@bubble{#1}{#2}}%
	}%
}
%
%
%
%
%
%_________________________________________________________________%%
%_________________________________________________________________%%
%_________________________________________________________________%%
% The rest consists of auxiliary macros used above:
%_________________________________________________________________%%
%_________________________________________________________________%%
%_________________________________________________________________%%
%
%
%
%_________________________________________________________________%%
% Globally extend a list by another item.
%
% Replaces the definition of the macro #1 by the expansion of #1
% immediately followed by #2.
%_________________________________________________________________%%
%
\def\g@extendlist#1#2{
	\expandafter\def\expandafter#1\expandafter{#1#2}
}
%
%
%_________________________________________________________________%%
% Give the different attributes of a node.
%_________________________________________________________________%%
%
\def\g@nodecoords#1{%
	\csname g@xy@#1\endcsname%
}
\def\g@nodetype#1{%
	\csname g@type@#1\endcsname%
}
\def\g@thenodesize#1{%
	\csname g@size@#1\endcsname%
}
\def\g@testname#1{%
	\@ifundefined{g@name@#1}{%
		\typeout{}%
		\typeout{! Graph package error: node #1 undefined!}%
		\typeout{}%
		\errmessage{}%
	}{}%
}
%
%
%_________________________________________________________________%%
% Give the difference between coordinate pairs the second and
% third argument expand to and define the first as the result.
%_________________________________________________________________%%
%
\def\g@defcoorddiff#1#2#3{
	\edef#1{% Expand both arguments before expanding \g@coorddiff:
	\expandafter\expandafter\expandafter\g@coorddiff\expandafter#2#3}
}
%
\def\g@coorddiff(#1,#2)(#3,#4){(#3 #1 sub, #4 #2 sub)
}
%
%
%_________________________________________________________________%%
% Find out the size of a box and add \g@eboxes.
%_________________________________________________________________%%
%
\newdimen\g@heightplusdepth
\newdimen\g@width
\def\g@textsize#1{
	\setbox0=\hbox{#1}
	\g@heightplusdepth=\ht0
	\advance\g@heightplusdepth by\dp0
	\advance\g@heightplusdepth by\g@eboxes\unitlength
	\g@width=\wd0
	\advance\g@width by\g@eboxes\unitlength
	\edef\g@thetextsize{%
	  (\number\g@width,\number\g@heightplusdepth)%
	}
}
%
%
%_________________________________________________________________%%
% Save the information about a node in appropriate macros
% (one macro to treat round and square nodes, one for
% rectangular nodes, and one for text nodes):
%_________________________________________________________________%%
%
\def\g@node#1#2(#3,#4)[#5]{
	\g@nodedef{g@name@#1}{}
	{
	  #5
	  \xdef\g@auxnodesize{\g@nsize}
	}
	\g@nodedef{g@xy@#1}{(#3,#4)}
	\g@nodedef{g@type@#1}{#2}
	\ifx\g@rectangletype#2
	  \g@nodedef{g@size@#1}{[\g@auxnodesize,\g@auxnodesize]}
	\else
	  \g@nodedef{g@size@#1}{[\g@auxnodesize]}
	\fi
}
%
\def\g@noderect#1[#2,#3](#4,#5){
	\g@nodedef{g@name@#1}{}
	\g@nodedef{g@xy@#1}{(#4,#5)}
	\g@nodedef{g@type@#1}{\g@rectangletype}
	\g@nodedef{g@size@#1}{[#2,#3]}
}
%
\def\g@nodebytext#1(#2,#3)#4[#5]{
	\g@nodedef{g@name@#1}{}
	\g@nodedef{g@xy@#1}{(#2,#3)}
	\g@nodedef{g@type@#1}{\g@rectangletype}
	{#5
	  \g@textsize{#4}
	  \expandafter\g@findsize\g@thetextsize
	}
	\g@nodedef{g@size@#1}{\g@auxtextsize}
}
%
\def\g@nodedef#1#2{\expandafter\edef\csname #1\endcsname{#2}}
%
%
%
%_________________________________________________________________%%
% Compare the coordinates of nodes and give an error message if they
% coincide. (Used to prevent the definition of edges of length 0.)
%_________________________________________________________________%%
%
%
\def\g@differentpositions#1#2#3{%
	\edef\g@firstname{#1}%
	\edef\g@secondname{#2}%
	\ifx\g@firstname\g@secondname%
	  \typeout{}%
	  \typeout{! Graph package error: Node #1 used twice
	  in \string#3.}%
	  \typeout{}%
	  \errmessage{}
	\else
	  \edef\g@firstposition{\g@nodecoords{#1}}%
	  \edef\g@secondposition{\g@nodecoords{#2}}%
	  \ifx\g@firstposition\g@secondposition%
	    \typeout{}%
	    \typeout{! Graph package error: Coordinates of nodes
	    #1 and #2 in}%
	    \typeout{\string#3 coincide.}%
	    \typeout{}%
	    \errmessage{}	    
	  \fi%
	\fi%
}
%
%
%
%_________________________________________________________________%%
% Nasty procedure to compute the necessary size of the node. We need
% something that computes
%            textdimension / \unitlength + 2 * \g@lwidth
% with high precision. So we can't simply use the \divide macro of
% TeX (yielding an integer value), but must explicitely construct a
% number showing some (I chose three) digits after the period.
% (I don't know whether there's a more elegant way of doing this.
% Sorry to anybody who might be bothered.)
%_________________________________________________________________%%
%
%
\newcount\g@xsizeA
\newcount\g@xsizeB
\newcount\g@ysizeA
\newcount\g@ysizeB
\newcount\g@help
\newdimen\g@helpB
\def\g@findsize(#1,#2){
	\g@xsizeA=#1\relax
	\g@helpB=\g@lwidth\unitlength\multiply\g@helpB by 2\relax
	\advance\g@xsizeA by \g@helpB\relax
	\g@xsizeB=\g@xsizeA
	\divide\g@xsizeA by\unitlength\relax
	\g@help=\unitlength\multiply\g@help by -\g@xsizeA\relax
	\advance\g@xsizeB by \g@help\relax
	\g@help=\unitlength\advance\g@help by 999\divide\g@help by 1000
							\multiply\g@help by 1000
	\advance\g@xsizeB by \g@help\relax
	\divide\g@help by 1000
	\divide\g@xsizeB by \g@help
	%
	\g@ysizeA=#2\relax
	\advance\g@ysizeA by \g@helpB\relax
	\g@ysizeB=\g@ysizeA
	\divide\g@ysizeA by\unitlength\relax
	\g@help=\unitlength\multiply\g@help by -\g@ysizeA\relax
	\advance\g@ysizeB by \g@help\relax
	\g@help=\unitlength\advance\g@help by 999\divide\g@help by 1000
							\multiply\g@help by 1000
	\advance\g@ysizeB by \g@help\relax
	\divide\g@help by 1000
	\divide\g@ysizeB by \g@help
	\xdef\g@auxtextsize{%
	  [\expandafter\g@mkpoint\number\g@xsizeB;{\number\g@xsizeA},%
	   \expandafter\g@mkpoint\number\g@ysizeB;{\number\g@ysizeA}]}
}
%
\def\g@mkpoint#1#2;#3{
	#3.#2
}
%
%
%_________________________________________________________________%%
% \put with separated x- and y-\unitlengths
% (modified definition from LaTeX):
%_________________________________________________________________%%
%
\newdimen\g@xunitlength\g@xunitlength=\unitlength
\newdimen\g@yunitlength\g@yunitlength=\unitlength
\long\def\g@xyput(#1,#2)#3{\@killglue\raise#2\g@yunitlength\hbox to\z@{\kern
#1\g@xunitlength #3\hss}\ignorespaces}
