summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-12-19 17:54:30 +0000
committerKarl Berry <karl@freefriends.org>2006-12-19 17:54:30 +0000
commit9352e2fa3eb4f66dc8cc30533bf5658a99fdac7e (patch)
tree6ee28078c9262b39a0441ecb3e932d40144b3b72
parent23b2789419e9e22d552147033a4f7f8ff569f649 (diff)
new pstricks package uml (1dec06)
git-svn-id: svn://tug.org/texlive/trunk@2817 c570f23f-e606-0410-a88d-b1316a301751
-rwxr-xr-xBuild/tools/tpm-ctan-check2
-rw-r--r--Master/texmf-dist/doc/latex/uml/Changes2
-rw-r--r--Master/texmf-dist/doc/latex/uml/README27
-rw-r--r--Master/texmf-dist/doc/latex/uml/example.tex197
-rw-r--r--Master/texmf-dist/doc/latex/uml/uml.pdfbin0 -> 612123 bytes
-rw-r--r--Master/texmf-dist/source/latex/uml/Makefile49
-rw-r--r--Master/texmf-dist/source/latex/uml/uml.dtx5398
-rw-r--r--Master/texmf-dist/source/latex/uml/uml.ins17
-rw-r--r--Master/texmf-dist/tex/latex/uml/uml.sty935
-rw-r--r--Master/texmf-dist/tpm/uml.tpm33
-rw-r--r--Master/texmf/lists/uml11
-rw-r--r--Master/texmf/tpm/collection-pstricks.tpm1
12 files changed, 6671 insertions, 1 deletions
diff --git a/Build/tools/tpm-ctan-check b/Build/tools/tpm-ctan-check
index f2d465fda38..9a9fcdbcc0b 100755
--- a/Build/tools/tpm-ctan-check
+++ b/Build/tools/tpm-ctan-check
@@ -103,7 +103,7 @@ my @WorkingTPM = qw(
tocloft todo tokenizer toolbox tools totpages tracking
trajan trfsigns trsym tugboat twoup Type1fonts typedref
typogrid
- ucthesis uhrzeit uiucthesis umich-thesis umlaute underlin
+ ucthesis uhrzeit uiucthesis umich-thesis uml umlaute underlin
undertilde units unitsdef upquote ushort
vancouver variations varindex vector velthuis verse versions
vhistory visualfaq vmargin volumes vpe
diff --git a/Master/texmf-dist/doc/latex/uml/Changes b/Master/texmf-dist/doc/latex/uml/Changes
new file mode 100644
index 00000000000..ea4b8f5e906
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/uml/Changes
@@ -0,0 +1,2 @@
+uml.dtx --------
+0.10 2006-11-23 first CTAN version (hv)
diff --git a/Master/texmf-dist/doc/latex/uml/README b/Master/texmf-dist/doc/latex/uml/README
new file mode 100644
index 00000000000..6189689dc78
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/uml/README
@@ -0,0 +1,27 @@
+uml.sty is a package for writing UML (Unified Modelling Language)
+diagrams in LaTeX. Currently, it implements a subset
+of class diagrams, and some extra constructs as well.
+The example on the right hand demonstrates the
+Schema constructs.
+
+Run the Makefile or alternative:
+
+latex uml.ins
+latex uml.dtx
+makeindex -s gind.ist uml
+makeindex -s gglo.ist -o uml.gls uml.glo
+latex uml.dtx
+dvips uml.dvi
+ps2pdf uml.ps
+
+
+This version of uml uses the extended version of the keyval
+package. So be sure that you
+- have installed xkeyval with the special pst-xkey.tex
+ (CTAN: tex-archive/macros/latex/contrib/xkeyval/)
+- do not load another package after uml, which loads
+ the old keyval.sty or pst-key.tex
+
+
+--
+Herbert Voss 2006-11-23
diff --git a/Master/texmf-dist/doc/latex/uml/example.tex b/Master/texmf-dist/doc/latex/uml/example.tex
new file mode 100644
index 00000000000..daa07da3ba8
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/uml/example.tex
@@ -0,0 +1,197 @@
+%%
+%% This is file `example.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% uml.dtx (with options: `example')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from example.tex.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file uml.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+\def\filedate{2006/11/28}
+\def\docdate{2006/11/28}
+\def\fileversion{0.10}
+\def\basename{uml}
+%% Package 'uml' to use with LaTeX2e and PSTricks
+%% Copyright 2006 by Ellef Fange Gjelstad.
+%% http://www.ifi.uio.no/~ellefg/uml.sty/
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN archives
+%% in directory macros/latex/base/lppl.txt.
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+
+
+
+\newcommand\umlADTExample{%
+ \umlDiagram[box=,sizeX=15cm, sizeY=16cm,ref=ADTdiagram,
+ grayness=0.92]{}% End of diagram
+ \umlSchema[pos=\umlTopRight{ADTdiagram}, posDelta={-.5,-.5},
+ refpoint=tr]{ADT}{% Attributes
+ \umlAttribute[visibility,type=String]{name}}{}{}{}{}
+ \umlSchema[pos=\umlTopLeft{ADTdiagram}, posDelta={.5,-1},
+ refpoint=lt, abstract,
+ ref=ADTexample]{ADT-example}{%
+ \umlAttribute[visibility=-,
+ type=\emph{\umlColorsArgument\umlColorsAdjust type},default=null]{%
+ firstNode}
+ }{%Methods
+ }{%Arguments
+ \umlArgument[type=Metaclass]{type}
+ }{%Constraints
+ }{%Structure
+ \umlDiagram[box=,innerBorder=2mm,outerBorder]{%
+ \umlClass[pos={.5,.5}, ref=adtNode,box=]{Node}{%
+ \umlAttribute[visibility,
+ type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ data}}{}%
+ \umlAssociation[angleA=20, angleB=-20,
+ arm=1em, arm=1em]{adtNode}{adtNode}%
+ }\cr% End of Diagram
+ }% End of ADT-example
+ \umlInstance{ADTexample}{ADT}%
+ \umlSchema[pos=\umlRight{ADTexample}, posDelta={3,-1},
+ refpoint=tl, ]{Graph}{% Attributes
+ }{% Methods
+ \umlMethod[visibility,]{%
+ insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility,
+ type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ dijkstra}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, type=boolean]{%
+ insertEdge}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, ]{%
+ delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ }{% Arguments
+ }{% Constraints
+ }{% Structure
+ \umlDiagram[box=,innerBorder=2mm, outerBorder,
+ sizeX=11em,sizeY=3.5em,ref=GraphDiagram]{%
+ \begin{umlColors}{\umlColorsSub}
+ \umlClass[pos=\umlBottomLeft{GraphDiagram},
+ posDelta={1,1}, ref=graphNode]{Node}{}{}%
+ \umlAssociation[angleA=20, angleB=-20, armA=1em, armB=1em
+ ]{graphNode}{graphNode}%
+ \end{umlColors}
+ \umlLabelA[height=0mm,offset=1ex]{graphNodegraphNode}{*}%
+ \umlLabelB[height=0mm,offset=1ex,refpoint=t
+ ]{graphNodegraphNode}{*}%
+ \umlSymbol[fraction=.5]{graphNodegraphNode}{\pnode{gngn}}
+ \umlClass[pos=gngn, posDelta={2,0},
+ ref=graphEdge, refpoint=l]{Edge}{%
+ \umlAttribute[type=real]{cost}}{}%
+ \umlAssociationClass[]{graphEdge}{gngn}%
+ }\cr% End of diagram
+ }% End of Graph
+ \umlSubclass{Graph}{ADTexample}
+ \umlSchema[posX=\umlLeft{ADTexample}, posDelta={3em,-1em},
+ posY=\umlBottom{Graph},
+ refpoint=tl, ref=searchTree]{Search Tree}{% Attributes
+ }{% Methods
+ \umlMethod[visibility,]{%
+ insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility,
+ type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, type=boolean]{%
+ search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, ]{%
+ delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ }{% Arguments
+ \umlArgument[type=Integer, initialValue=2]{arity}
+ \umlArgument[type={${\umlColorsArgument\umlColorsAdjust type}
+ \times {\umlColorsArgument\umlColorsAdjust type}\rightarrow$
+ boolean}, default=>]{sort}
+ }{% Constraints
+ }{% Structure
+ \umlDiagram[box=, sizeX=14em, sizeY=4em,
+ innerBorder=2mm, outerBorder]{%
+ \begin{umlColors}{\umlColorsSub}
+ \umlClass[pos={.5, .5}, ref=treeNode]{Node}{}{}%
+ \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
+ ]{treeNode}{treeNode}%
+ \end{umlColors}
+ \umlLabelA[height=1mm, offset=4mm,refpoint=l
+ ]{treeNodetreeNode}{%
+ \emph{\umlColorsArgument\umlColorsAdjust arity}}%
+ \umlLabelB[refpoint=tl,height=-1mm, offset=4mm,
+ ]{treeNodetreeNode}{1}%
+ }\cr% End of diagram
+ }%
+ \umlSubclass{searchTree}{ADTexample}%
+ \umlSchema[pos=\umlBottomLeft{searchTree},posDelta={0,-1},
+ refpoint=lt]{List}{%Attributes
+ }{% Methods
+ }{% Arguments
+ }{% Constraints
+ }{% Structure
+ \umlDiagram[box=, sizeX=6em, sizeY=4em,
+ innerBorder=2mm, outerBorder]{%
+ \begin{umlColors}{\umlColorsSub}
+ \umlClass[pos={.5, .5}, ref=listNode]{Node}{}{}%
+ \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
+ ]{listNode}{listNode}%
+ \end{umlColors}
+ \umlLabelA[height=1mm, offset=5mm, refpoint=l
+ ]{listNodelistNode}{1}%
+ \umlLabelB[refpoint=tl, height=-1mm,offset=5mm
+ ]{listNodelistNode}{1}%
+ }\cr% End of diagram
+ }% End of Schema List
+ \umlPlaceNode[leftside, top, down=1em]{List}{Listtl}
+ \umlPlaceNode[leftside,right=2em,bottom]{ADTexample}{ADTexamplebl}
+ \umlSubclass[armA=1.4142em, armAngleA=135]{Listtl}{ADTexamplebl}%
+ \umlSchema[pos=\umlTopRight{List},posDelta={1em,-2em},
+ refpoint=tl]{Queue}{% Attributes
+ }{\umlMethod[visibility]{%
+ enqueue}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ dequeue}{}}{%Arguments
+ }{%Constraints
+ \umlCompartmentline{First come, first served.}
+ }{% Structure
+ }% End of Queue
+ \umlPlaceNode[rightside, top, down=1em]{List}{Listtr}
+ \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Queue}{Listtr}%
+ \umlSchema[pos=\umlTopRight{Queue},posDelta={\umlNodeSep,0em},
+ refpoint=tl]{Stack}{%Attributes
+ }{% Methods
+ \umlMethod[visibility]{
+ push}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ pop}{}
+ }{% Arguments
+ }{% Constraints
+ \umlCompartmentline{S:Stack = S.push(x).pop()}
+ }{% Structure
+ }% End of Stack
+ \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Stack}{Listtr}%
+}
+\endinput
+%%
+%% End of file `example.tex'.
diff --git a/Master/texmf-dist/doc/latex/uml/uml.pdf b/Master/texmf-dist/doc/latex/uml/uml.pdf
new file mode 100644
index 00000000000..4b5ad0e7107
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/uml/uml.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/uml/Makefile b/Master/texmf-dist/source/latex/uml/Makefile
new file mode 100644
index 00000000000..23f4505fc0a
--- /dev/null
+++ b/Master/texmf-dist/source/latex/uml/Makefile
@@ -0,0 +1,49 @@
+
+# `Makefile' for `pst-uml.pdf', hv, 2006/08/21
+
+.SUFFIXES : .tex .ltx .dvi .ps .pdf .eps
+
+MAIN = uml
+
+LATEX = latex
+
+ARCHNAME = $(MAIN)-$(shell date +%y%m%d)
+
+ARCHFILES = $(MAIN).dtx $(MAIN).ins Makefile
+
+all : $(MAIN).sty doc clean
+
+$(MAIN).sty : $(MAIN).dtx
+%.sty : %.dtx
+ latex $(basename $<).ins
+
+doc: $(MAIN).pdf
+
+$(MAIN).pdf : $(MAIN).ps
+ GS_OPTIONS=-dAutoRotatePages=/None ps2pdf $<
+
+$(MAIN).ps : $(MAIN).dvi
+ dvips $<
+
+$(MAIN).dvi : $(MAIN).dtx
+ $(LATEX) $<
+ $(LATEX) $<
+ if ! test -f $(basename $<).glo ; then touch $(basename $<).glo; fi
+ if ! test -f $(basename $<).idx ; then touch $(basename $<).idx; fi
+ makeindex -s gglo.ist -t $(basename $<).glg -o $(basename $<).gls \
+ $(basename $<).glo
+ makeindex -s gind.ist -t $(basename $<).ilg -o $(basename $<).ind \
+ $(basename $<).idx
+ $(LATEX) $<
+
+clean :
+ $(RM) $(addprefix $(MAIN), .log .aux .glg .glo .gls .ilg .idx .ind .tmp .toc .out .tex )
+ $(RM) $(addprefix $(MAIN), .dvi .ps )
+
+veryclean : clean
+ $(RM) $(MAIN).pdf
+
+arch :
+ zip $(ARCHNAME).zip $(ARCHFILES)
+
+# EOF
diff --git a/Master/texmf-dist/source/latex/uml/uml.dtx b/Master/texmf-dist/source/latex/uml/uml.dtx
new file mode 100644
index 00000000000..06f0ee909ba
--- /dev/null
+++ b/Master/texmf-dist/source/latex/uml/uml.dtx
@@ -0,0 +1,5398 @@
+\def\filedate{2006/11/28}
+\def\docdate{2006/11/28}
+\def\fileversion{0.10}
+\def\basename{uml}
+%
+% \iffalse meta-comment
+%
+%% Package 'uml' to use with LaTeX2e and PSTricks
+%% Copyright 2006 by Ellef Fange Gjelstad.
+%% http://www.ifi.uio.no/~ellefg/uml.sty/
+%
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN archives
+%% in directory macros/latex/base/lppl.txt.
+%
+% \fi
+%
+% \changes{v0.10}{2006/11/28}{First CTAN release (hv)}
+%
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+%
+% \GetFileInfo{showexpl.dtx}
+%
+% \DoNotIndex{\newcommand,\renewcommand,\newenvironment,\renewenvironment}
+% \DoNotIndex{\usepackage,\documentclass,\nofiles,\bibliogaphy}
+% \DoNotIndex{\tiny,\tableofcontens}
+% \DoNotIndex{\newif,\newcounter,\linewidth,\listfiles}
+% \DoNotIndex{\providecommand,\def,\edef,\let,\gdef,\xdef,\global,\newtoks}
+% \DoNotIndex{\RequirePackage,\DeclareOption,\ProcessOptions,\ExecuteOptions}
+% \DoNotIndex{\@nameuse,\value,\input,\InputIfFileExists}
+% \DoNotIndex{\@ifdefinable,\@ifundefined,\@percentchar}
+% \DoNotIndex{\AtBeginDocument,\AtEndOfPackage,\PassOptionsToPackage}
+% \DoNotIndex{\CurrentOption,\jobname}
+% \DoNotIndex{\PackageError,\PackageWarning,\PackageWarningNoLine,\PackageInfo}
+% \DoNotIndex{\MessageBreak,\typeout}
+% \DoNotIndex{\z@,\z@skip,\p@,\@ne,\tw@,\thr@@,\@iv,\two@fourteen,\strip@pt}
+% \DoNotIndex{\the,\if,\else,\or,\fi,\ifnum,\ifdim,\ifcase,\ifodd}
+% \DoNotIndex{\advance,\multiply,\divide,\ht,\dp,\wd,\catcode}
+% \DoNotIndex{\@tfor,\do,\bgroup,\egroup,\ifx,\iftrue,\iffalse}
+% \DoNotIndex{\csname,\endcsname,\begingroup,\endgroup}
+% \DoNotIndex{\expandafter,\afterassignment,\noexpand}
+% \DoNotIndex{\@tempdima,\@tempdimb,\@tempdimc,\@tempcnta,\@tempcntb}
+% \DoNotIndex{\@halfwidth,\@wholewidth,\unitlength}
+% \DoNotIndex{\@clnwd,\@clnht,\@ovdx,\@ovdy,\@ovro,\@ovri,\@ovxx,\@ovyy}
+% \DoNotIndex{\@xarg,\@xdim,\@yarg,\@ydim,\@linelen,\@dashdim,\dimen@}
+% \DoNotIndex{\reserved@a,\relax,\protect,\long,\space}
+% \DoNotIndex{\if@tempswa,\@tempswatrue,\@tempswafalse,\@tempa}
+% \DoNotIndex{\@tempboxa,\@tempboxb,\show}
+% \DoNotIndex{\@empty,\%,\typeout,\vspace,\vskip,\the,\hbox,\par}
+% \DoNotIndex{\minipage,\endminipage,\trivlist,\endtrivlist}
+% \DoNotIndex{\parbox,\setbox,\setlength,\hfill,\item,\number}
+% \DoNotIndex{\x}
+% \DoNotIndex{\SX@put@a,\SX@put@b,\SX@put@l,\SX@put@r,\SX@put@o,\SX@put@i}
+%
+% ^^A\DoNotIndex{\usepackage,\documentclass,\tableofcontens,\printindex}
+%
+% \RecordChanges
+%
+%\iffalse
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[T1]{fontenc}
+\usepackage[dvips,lmargin=4cm]{geometry}
+\usepackage{latexsym}
+\usepackage[scaled]{luximono}
+\usepackage{uml,lscape,varioref,listings}
+\RequirePackage{xcolor}
+\SpecialCoor
+\RequirePackage[linktocpage,colorlinks]{hyperref}
+\definecolor{hellgelb}{rgb}{1,1,0.85}
+\definecolor{colKeys}{rgb}{0,0,1}
+\definecolor{colIdentifier}{rgb}{0,0,0}
+\definecolor{colComments}{rgb}{1,0,0}
+\definecolor{colString}{rgb}{0,0.5,0}
+\lstset{%
+ gobble=1,
+ frame=single,%
+ language=TeX,%
+ basicstyle=\small\ttfamily,%
+ identifierstyle=\small\ttfamily,%
+ keywordstyle=\bfseries,%
+ stringstyle=\itshape\color{colComments},%
+ commentstyle=\itshape\color{colComments},%
+ columns=fixed,
+ tabsize=4,%
+ frame=single,%
+ extendedchars=true,%
+ showspaces=false,%
+ showstringspaces=false,%
+ numbers=left,%
+ numberstyle=\tiny\ttfamily,%
+ numbersep=1em,%
+ breaklines=true,%
+ breakindent=10pt,%
+ backgroundcolor=\color{hellgelb},%
+ breakautoindent=true,%
+ xleftmargin=1em
+}
+\parindent0pt
+\input example
+\begin{document}
+ \DocInput{uml.dtx}
+\end{document}
+%</driver>
+%\fi
+%
+% \MakeShortVerb{"}
+% \DeleteShortVerb{\|}
+% \makeatletter
+% \def\Codelabel#1{\@bsphack
+% \protected@write\@auxout{}{\string\newlabel{#1}{{\number\the
+% \c@CodelineNo}{\thepage}}}\@esphack}
+% \newcounter{tmpcount}
+% \def\Coderef#1#2{\setcounter{tmpcount}{0}\@ifundefined{r@#1}\relax
+% {\setcounter{tmpcount}{\ref{#1}}}\relax
+% \addtocounter{tmpcount}{#2}\arabic{tmpcount}}
+% \makeatother
+
+% \title{\texttt{uml.sty}, a package for writing UML diagrams in \LaTeX}
+% \author{Ellef Fange Gjelstad}
+% \maketitle
+%
+% \tableofcontents
+%
+%
+% \section{Syntax for all the commands}\label{sec:useSyntax}\label{sec:use}
+%
+% Most of the commands in "uml.sty" have the syntax
+% "\uml"\meta{Construct}"["\meta{Named options}"]"\meta{Arguments}.
+% \begin{description}
+% \item[\meta{Construct}] can be "Diagram", "Class", "Method" or other
+% things.
+% \item[\meta{Named options}] is a comma-separated list of
+% \meta{key}"="\meta{value} pairs. This is implemented by
+% "keyval.sty". The entire "["\meta{Named options}"]" part is
+% optional.\index{keyval.sty}\index{named options}
+%
+% In this documentation, the "=" often is replaced with a
+% "-". This is due to an error in the index generation process, which
+% does not accept.
+%
+% \item[\meta{Arguments}] a number of arguments, typically enclosed in
+% brackets ("{}"). Typical arguments are a name and some interior of
+% a box.
+% \end{description}
+%
+%
+% \subsection{Lengths}
+%
+% \index{lengths}Legal \emph{lengths} are all PSTricks lengths,
+% including \TeX{} lengths. In
+% PSTricks lengths, the unit is optional; if no unit is present, the
+% current PSTricks "unit" is used.
+%
+%
+% \subsection{Angles}
+% \label{sec:angles}
+%
+% \index{angles}
+% \index{rotations}
+% We distinguish between \emph{angles} and \emph{rotations}. An angle
+% should be a number giving the angle in degrees, by default. You can
+% also change the units used for angles with the PSTricks
+% "\degrees[num]" command.
+%
+% A rotation also expresses a direction, but can have different syntax
+% forms:
+% \begin{description}
+% \item[An angle] i.e.\ a number
+% \item[An angle preceded by an asterisk] This means the angle is to be
+% interpreted absolute (relative to the page) and not to the underling
+% text direction. This is useful when getting a relation label right
+% up, not in the direction of the relation
+% \item[A letter] One of\\
+% \begin{tabular}{lcr|lcr}
+% \emph{letter} & \emph{Short for} & \emph{Equiv. to} &
+% \emph{letter} & \emph{Short for} & \emph{Equiv. to} \\\hline
+% U & Up & 0 & N & North & *0 \\
+% L & Left & 90 & W & West & *90\\
+% D & Down & 180 & S & South & *180\\
+% R & Right & 270 & E & East & *270\\\hline
+% \end{tabular}
+% \item[When rotating along lines] e.g.\ relations, you can precede an
+% angle or one of "ULDR" with a colon. This is to orientate the text
+% relative to the line. This is useful when getting a relation along
+% the relation, not right up.
+% \end{description}
+%
+%
+% \subsection{Node names}\label{sec:useNodeNames}
+%
+% \index{node names}
+% A \emph{node name} is a name of a location on the page. Such a name
+% must contain only letters and numbers, and must begin with a letter.
+% Also, the node names should be unique (at least, to the page).
+%
+% Node names are typically placed by means of the "reference" named
+% option, but could be placed using any PSTricks node command.
+%
+%
+% \subsection{Reference points}
+% \label{sec:useReference}
+%
+% \index{reference points}A \emph{reference point} is the point in a box
+% which is to be placed. E.g., if the reference point is "tl", meaning
+% top left, the top left corner is placed relative to whatever.
+%
+% A reference point can be any of "l" (left), "r" (right), "t" (top),
+% "b" (bottom) or "B" (baseline) or reasonable combinations of
+% them.
+%
+% \subsection{Colors}
+% \label{sec:useColorsPrimitive}
+%
+% \index{colors}This is as in PSTricks. E.g., you can say
+% "\red Red" gives \fbox{{\red Red}} and use the color "red" as
+% linecolor or fillcolor.
+%
+% See also section \vref{sec:useColors}.
+%
+% \subsection{Line styles}
+% \label{sec:useLinestyles}
+%
+% \index{line styles}As in PSTricks, e.g., solid, dashed, dotted or none.
+%
+% \section{uml.sty options}\label{sec:useOptions}
+%
+% \subsection{debug}\label{sec:useOptionsDefault}
+% \subsection{index}\label{sec:useOptionsIndex}
+%
+% By default, every named uml.sty construct (e.g., each Class and
+% Attribute) makes an entry in the index of the form
+% \meta{name}!\meta{type}. This feature can be turned off with the
+% option "noindex" or on with "index". The feature can also be turned
+% on with "\umlIndexOn"\DescribeMacro\umlIndexOn{} and off with
+% "\umlIndexOff"\DescribeMacro\umlIndexOff{}.
+%
+% Tip: It is possible to change the index entry format by changing
+% "\umlIndex". "\umlIndex" should take two arguments: The name and the
+% type. E.g., "\renewcommand\umlIndex[2]{\index{#1 (#2)}}".
+%
+% \section{Object-oriented approach}\label{sec:useApproach}
+%
+% \index{object oriented LaTeX}When making an uml package for \LaTeX{},
+% it seems natural to do the programming object-oriented. While
+% \LaTeX{} has no direct support for object-oriented programming, it can
+% be simulated using command calls and keyval.sty.
+%
+% {\tiny
+% \umlSchema[box=,posDelta={0,-.5em},refpoint=t,
+% abstract=,
+% comment={Drawable}]{%
+% Drawable}{%
+% \umlAttribute[type=color]{import}%
+% \umlAttribute[type=String,propertyString={quasi-static}]{type}%
+% }{}{%%
+% \umlArgument{[named options]}%%
+% \umlArgument{Contents}}{}{}
+% }
+%
+% \newlength\saveHeight
+% \setlength\saveHeight\umlSymbolHeightDefault
+% \setlength\umlSymbolHeightDefault{1ex}
+% \newlength\saveWidth
+% \setlength\saveWidth\umlSymbolWidthDefault
+% \setlength\umlSymbolWidthDefault{.5ex}
+%
+% \newcommand\pagesReference[1]{
+% Pages~\pageref{sec:use#1} and \pageref{sec:imp#1}}
+% \begin{figure}[htbp]
+% \begin{center}
+% \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
+% sizeY=9.5cm,innerBorder=2mm,ref=approachDiagram ]{
+% }{}% End of diagram
+% \end{center}
+% \begin{tiny}
+% \setlength{\umlNodeSep}{1.5em}
+% \umlSchema[pos=\umlTop{approachDiagram},posDelta={0,-.5em},refpoint=t,
+% abstract=,
+% comment=\pagesReference{Drawable}]{
+% Drawable}{
+% \umlAttribute[type=color]{import}
+% \umlAttribute[type=String,propertyString={quasi-static}]{type}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Contents}}{}{}
+% \umlSchema[pos=\umlBottomSep{Drawable},refpoint=t,
+% abstract=,
+% comment=\pagesReference{Element}]{
+% Element}{
+% \umlAttribute{reference}
+% \umlAttribute{stereotype}
+% \umlAttribute{subof}
+% \umlAttribute[type=bool]{abstract}
+% \umlAttribute{importedFrom}
+% \umlAttribute{comment}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Contents}}{}{}
+% \umlSubclass{Element}{Drawable}
+% \umlSchema[pos=\umlBottomSep{Element},refpoint=t,comment=\pagesReference{Box}]{
+% Box}{
+% \umlAttribute[type=position]{pos[XY ]}
+% \umlAttribute[type=position]{posDelta[XY ]}
+% \umlAttribute{refpoint}
+% \umlAttribute[default=true]{box}
+% \umlAttribute[type=length]{size[XY]}
+% \umlAttribute[type=real 0--1]{grayness}
+% \umlAttribute[type=colorName, default=umlFillColor]{%
+% fillcolorCommand}
+% \umlAttribute[type=length]{border}
+% \umlAttribute[default=solid]{borderLine}
+% \umlAttribute[type=length]{outerBorder}
+% \umlAttribute[type=length]{innerBorder}
+% }{}{}{}{}
+% \umlSubclass{Box}{Element}
+% \umlSchema[pos=\umlTopRight{Box},refpoint=tl,comment=\pagesReference{Diagram},
+% posDelta={2em,-4em}]{
+% Diagram}{
+% \umlAttribute[colorset=\umlColorsSub,
+% default={\umlColorsDefault\umlColorsAdjust always true}]{%
+% box}
+% }{}{}{Size given\\contents placed\\~~according to size\\}{}
+% \umlSubclass{Diagram}{Box}
+% \umlSchema[pos=\umlTopLeft{Box},refpoint=tr,comment=\pagesReference{Stretchbox},
+% posDelta={-2em,-4em}]{
+% Stretchbox}{
+% \umlAttribute{name}
+% \umlAttribute[visibility=-]{graphicalName}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Name}
+% \umlArgument{Contents}}{
+% Size according to contents\\}{}
+% \umlSubclass{Stretchbox}{Box}
+% \umlSchema[pos=\umlBottomRight{Stretchbox},posDelta={0em,-2em},refpoint=tr,
+% comment=\pagesReference{Package}]{
+% Package}{
+% }{}{}{}{}
+% \umlSubclass{Package}{Stretchbox}
+% \caption{Main commands in uml.sty. This and the following class
+% diagrams work as a short-form documentation of uml.sty.}
+% \label{fig:useApproach}
+% \label{fig:approachStart}
+% \end{tiny}
+% \end{figure}
+%
+% Each box in figure \ref{fig:useApproach}--\ref{fig:approachEnd}
+% corresponds to one \LaTeX{} command (e.g., "\umlDrawable" and
+% "\umlElement"). Each attribute correspond to one \LaTeX{} variable
+% (e.g., "\umlReference") and often one named option (e.g., "reference=").
+%
+% The arguments of the commands are shown in the fourth compartment.
+% Characteristics of each command are shown in the sixth.
+%
+% \begin{figure}[thbp]
+% \begin{center}
+% \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
+% sizeY=10cm,innerBorder=2mm,ref=approachClassifierDiagram ]{
+% }{}% End of diagram
+% \end{center}
+% \begin{tiny}
+% \setlength{\umlNodeSep}{1.5em}
+% \umlSchema[pos=\umlTopLeft{approachClassifierDiagram},
+% posDelta={3cm,-.5em},refpoint=tl,
+% abstract=,import=,importedFrom=main]{
+% Drawable}{
+% \umlAttribute[type=color]{import}
+% \umlAttribute[type=String,propertyString={quasi-static}]{type}
+% \umlAttribute[type=String]{name}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Contents}}{}{}
+% \umlSchema[pos=\umlTopRight{Drawable},refpoint=tl,
+% posDelta={\umlNodeSep,0},abstract=,
+% import=,importedFrom=main]{
+% Element}{
+% \umlAttribute{reference}
+% \umlAttribute{stereotype}
+% \umlAttribute{subof}
+% \umlAttribute[type=bool]{abstract}
+% \umlAttribute{importedFrom}
+% \umlAttribute{comment}
+% }{}{}{}{}
+% \umlPlaceNode[rightside,top=-4em]{Drawable}{DrawableRight}
+% \umlPlaceNode[leftside,top=-4em]{Element}{ElementLeft}
+% \umlSubclass[import=]{ElementLeft}{DrawableRight}
+% \umlSchema[pos=\umlTopRight{Element},refpoint=tl,
+% import=,importedFrom=main,
+% posDelta={\umlNodeSep,0}]{
+% Box}{
+% \umlAttribute{pos}
+% \umlAttribute{posDelta}
+% \umlAttribute{refpoint}
+% \umlAttribute{box}
+% \umlAttribute{size}
+% \umlAttribute{grayness}
+% \umlAttribute{border}
+% \umlAttribute{innerBorder}
+% \umlAttribute{borderLine}
+% }{}{}{}{}
+% \umlPlaceNode[rightside,top=-4em]{Element}{ElementRight}
+% \umlPlaceNode[leftside,top=-4em]{Box}{BoxLeft}
+% \umlSubclass[import=]{BoxLeft}{ElementRight}
+% \umlSchema[pos=\umlTopRight{Box},refpoint=lt,
+% import=,importedFrom=main,
+% posDelta={\umlNodeSep,0}]{
+% Stretchbox}{
+% \umlAttribute{name}
+% \umlAttribute[visibility=-]{graphicalName}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Name}
+% \umlArgument{Contents}}{
+% Size according to contents\\}{}
+% \umlPlaceNode[rightside,top=-4em]{Box}{BoxRight}
+% \umlPlaceNode[leftside,top=-4em]{Stretchbox}{StretchboxLeft}
+% \umlSubclass[import=]{StretchboxLeft}{BoxRight}
+% \umlSchema[pos=\umlBottom{Stretchbox},refpoint=t,
+% posDelta={0,-7em},comment=\pagesReference{Classifier}]{
+% Classifier}{
+% \umlAttribute[type=boolean, default=false]{Object}
+% }{}{}{}{}
+% \umlSubclass{Classifier}{Stretchbox}
+% \umlSchema[pos=\umlTopLeft{Classifier},posDelta={-3em,0},refpoint=tr,
+% comment=\pagesReference{Compartment}]{
+% Compartment}{
+% \umlAttribute[type=boolean]{suppress}
+% \umlAttribute[type=boolean]{showName}}{}{
+% \umlArgument{[named options]}
+% \umlArgument{Contents}}{}{}
+% \umlSubclass[angleB=270,armB=4em,armAngleB=270
+% ]{Compartment}{Drawable}
+%  \umlLabelA{CompartmentDrawable}{<<conceptual>>}
+% \umlAggregation{Compartment}{Classifier}
+% \umlLabelA[offset=1ex]{CompartmentClassifier}{*}
+% \umlLabelB[offset=1ex]{CompartmentClassifier}{1}
+% \umlSchema[pos=\umlTopLeft{Compartment},posDelta={-3em,0},refpoint=tr,
+% comment=\pagesReference{Compartmentline}]{
+% Compartmentline}{
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Contents}
+% }{}{}
+% \umlSubclass[ref=CompartmentlineDrawable,
+% angleB=270, armB=4em, armAngleB=270]{
+% Compartmentline}{Drawable}
+% \umlAggregation[ref=cline]{Compartmentline}{Compartment}
+% \umlLabelA[offset=1ex]{cline}{*}
+% \umlLabelB[offset=1ex]{cline}{1}
+%
+% \umlSchema[pos=\umlBottomSep{Compartmentline}, refpoint=t,
+% comment=\pagesReference{Feature}]{
+% Feature}{
+% \umlAttribute{visibility}
+% \umlAttribute{type}
+% \umlAttribute{propertyString}
+% \umlAttribute{initialValue}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Name}
+% }{}{}
+% \umlSubclass{Feature}{Compartmentline}
+%
+% \umlSchema[pos=\umlBottomSep{Feature},refpoint=t,
+% comment=\pagesReference{Attribute}]{
+% Attribute}{
+% \umlAttribute{multiplicity}
+% \umlAttribute{ordering}
+% \umlAttribute{/multiplicityOrdering}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Name}
+% }{}{}
+% \umlSubclass{Attribute}{Feature}
+%
+% \umlSchema[pos=\umlTopLeft{Attribute},refpoint=tr,
+% posDelta={-\umlNodeSep,0},
+% comment=\pagesReference{Method}]{
+% Method}{
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Name}
+% \umlArgument{Arguments}
+% }{}{}
+% \umlSubclass{Method}{Feature}
+% \umlSchema[pos=\umlTopRight{Attribute},refpoint=tl,
+% posDelta={\umlNodeSep,0},
+% comment=\pagesReference{Argument}]{
+% Argument}{
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Name}
+% }{}{}
+% \umlSubclass{Argument}{Feature}
+% \umlSchema[pos=\umlBottomSep{Classifier},
+% posDelta={-.5em,-4em},refpoint=tr,
+% comment=\pagesReference{Class}]{
+% Class}{
+% }{}{
+% \umlArgument{[named Options]}
+% \umlArgument{Name}
+% \umlArgument{Attributes}
+% \umlArgument{Methods}}{}{}{}
+% \umlSubclass{Class}{Classifier}
+% \umlSchema[pos=\umlTopRight{Class},
+% posDeltaX={1em,0},refpoint=tl,
+% comment=\pagesReference{Schema}]{
+% Schema}{
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Name}
+% \umlArgument{Attributes}
+% \umlArgument{Methods}
+% \umlArgument{Arguments}
+% \umlArgument{Constraints}
+% \umlArgument{Structure}
+% }{}{}
+% \umlSubclass{Schema}{Classifier}
+% \caption{Classifier commands}
+% \label{fig:useApproachClassifiers}
+% \end{tiny}
+% \end{figure}
+%
+%
+% \index{subclass!in LaTeX}The subclass relation (e.g., between Box and
+% Element) is implemented this way:
+% \begin{description}
+% \item[Command call] The subclass-commando calls the
+% superclass-commando. E.g., "\umlBox" calls "\umlElement".
+% \item[Variable sharing] The variables of the superclass are also used
+% by the subclass. "\umlReference" is used by "\umlBox" as well as
+% "\umlElement". Of course, there is no support for namespaces in
+% \LaTeX{}, so this is easy and requires discipline at the same time.
+% \item[Use of named options] A list of named options is sent from the
+% subclass-command to the superclass-command. Ultimately, it is
+% evaluated in "\umlElement". Each command on the road can add its
+% own values in the named options; if it is placed last, it takes
+% precedence, if it placed first, it does not.
+%
+% E.g., "\umlClassifier" sets "grayness=0.85" first in its named
+% options, meaning that the default grayness is 0.85.
+% \end{description}
+%
+% \begin{figure}[htbp]
+% \begin{center}
+% \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
+% sizeY=12cm,innerBorder=2mm,ref=approachDiagramRelations ]{
+% }{}% End of diagram
+% \end{center}
+% \begin{tiny}
+% \umlSchema[pos=\umlTop{approachDiagramRelations},
+% posDelta={-.75em,-.5em},refpoint=tr,
+% abstract=, importedFrom=main,import=]{
+% Drawable}{
+% \umlAttribute[type=color]{import}
+% \umlAttribute[type=String,propertyString={quasi-static}]{type}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Contents}}{}{}
+% \umlSchema[pos=\umlTop{approachDiagramRelations},
+% posDelta={.75em,-.5em},refpoint=tl,
+% abstract, importedFrom=main,import=]{
+% Element}{
+% \umlAttribute{reference}
+% \umlAttribute{stereotype}
+% \umlAttribute{subof}
+% \umlAttribute[type=bool]{abstract}
+% \umlAttribute{importedFrom}
+% \umlAttribute{comment}
+% }{}{}{}{}
+% \umlSubclass[import=]{Element}{Drawable}
+% \umlSchema[posY=\umlBottomSep{Element},posX=\umlLeft{Element},
+% refpoint=tl,
+% comment=\pagesReference{Relation}]{
+% Relation}{
+% \umlAttribute[type=position]{posDelta[AB]}
+% \umlAttribute[type=length]{relationArmA}
+% \umlAttribute[type=angle]{relationAngleA}
+% \umlAttribute[type=angle]{relationArmAngleA}
+% \umlAttribute[default=solid]{linestyle}
+% \umlAttribute[type=color]{relationcolor}
+% \umlAttribute[type=color]{/linecolor}
+% \umlAttribute[type=length]{nodesep}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Node A}
+% \umlArgument{Node B}
+% \umlArgument{Other contents}
+% }{}{}
+% \umlSubclass{Relation}{Element}
+% \umlSchema[posY=\umlTop{Relation},
+% posX=\umlLeft{approachDiagramRelations},
+% refpoint=tl,
+% posDelta={1em,0},abstract=,
+% comment=\pagesReference{AssociationEnd}]{
+% AssociationEnd}{
+% \umlAttribute[type=length,default=0pt]{offset}
+% \umlAttribute[type=real+A+B+C+From+To,default=To]{pos}
+% \umlAttribute[type=length]{height}
+% \umlAttribute[type=angle]{angle}
+% \umlAttribute[type=angle]{posAngle}
+% \umlAttribute[type=?]{refpoint}
+% \umlAttribute[type={Subc.indicator},visibility=-]{type}
+% \umlAttribute[visibility=-]{/noderefClose}
+% \umlAttribute[visibility=-]{/noderefFar}
+% }{}{%
+% \umlArgument{[named options]}
+% \umlArgument{Relation}
+% \umlArgument{Symbol}
+% }{}{
+% \umlDiagram[box=,sizeX=2.5cm, sizeY=1cm,
+% outerBorder=\umlhsep,innerBorder=\umlhsep,
+% ref=AssociationEndDiagram]{
+% \umlSchema[pos=\umlBottomLeft{AssociationEndDiagram},
+% posDelta={1em,1em}, refpoint=bl,ref=AEUsePos]{%
+% A.E.UsePos}{}{}{}{}{}{}{}{}%
+% }\\
+% }
+% \umlAssociation{Relation}{AssociationEnd}
+% \umlLabelA[height=-2ex]{RelationAssociationEnd}{1}
+% \umlLabelB[height=-2ex]{RelationAssociationEnd}{2,*}
+% % \umlSubclass{AssociationEnd}{Drawable}
+% \umlSchema[pos=\umlBottomSep{Relation},
+% posDelta={-5em,0},refpoint=tr,
+% comment=\pagesReference{Subclass}]{
+% Subclass}{}{}{
+% \umlArgument{[named options]}
+% \umlArgument{Node A}
+% \umlArgument{Node B}
+% }{}{}{}{}
+% \umlSubclass{Subclass}{Relation}
+% \umlSchema[posY=\umlBottomSep{Subclass},posX=\umlRight{Subclass},
+% refpoint=tr,
+% comment=\pagesReference{Generalization}]{
+% Generalization}{}{}{}{}{}{}{}
+% \umlSubclass{Generalization}{Subclass}
+% \umlSchema[pos=\umlTopRight{Relation},
+% posDelta={3em,7em},refpoint=tl,
+% comment=\pagesReference{Association}]{
+% Association}{}{}{
+% \umlArgument{[named options]}
+% \umlArgument{Node A}
+% \umlArgument{Node B}
+% }{}{}{}{}
+% \umlSubclass{Association}{Relation}
+% \umlSchema[pos=\umlBottomLeft{Association},
+% posDelta={0,-1em},refpoint=tl,ref=Inner,
+% comment=\pagesReference{Inner}]{
+% Inner class}{}{}{
+% \umlArgument{[named options]}
+% \umlArgument{Node A}
+% \umlArgument{Node B}
+% }{}{}{}{}
+% \umlSubclass{Inner}{Relation}
+% \umlSchema[pos=\umlBottomLeft{Inner},
+% posDelta={0,-1em},refpoint=tl,
+% comment=\pagesReference{Composition}]{
+% Composition}{}{}{
+% \umlArgument{[named options]}
+% \umlArgument{Node A}
+% \umlArgument{Node B}
+% }{}{}{}{}
+% \umlSubclass{Composition}{Relation}
+% \umlSchema[pos=\umlBottomLeft{Composition},
+% posDelta={0,-1em},refpoint=tl,
+% comment=\pagesReference{Aggregation}]{
+% Aggregation}{}{}{
+% \umlArgument{[named options]}
+% \umlArgument{Node A}
+% \umlArgument{Node B}
+% }{}{}{}{}
+% \umlSubclass{Aggregation}{Relation}
+% \umlSchema[pos=\umlBottomSep{Relation},refpoint=tl,posDelta={-4em,0},
+% comment=\pagesReference{ToRelation}]{
+% ToRelation}{
+% \umlAttribute[type={0--1}, default=0.5]{posMeetLine}}{
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Node}
+% \umlArgument{Relation}}{}{}{}
+% \umlSubclass{ToRelation}{Relation}
+% \umlSchema[posX=\umlLeft{ToRelation},posY=\umlBottomSep{ToRelation},
+% refpoint=tl,
+% comment=\pagesReference{AssociationSchema}]{
+% AssociationSchema}{}{}{}{}{}{}{}
+% \umlSubclass{AssociationSchema}{ToRelation}
+% \umlSchema[pos=\umlBottomSep{AssociationSchema},
+% refpoint=t,
+% comment=\pagesReference{AssociationClass}]{
+% AssociationClass}{}{}{}{}{}{}{}
+% \umlSubclass{AssociationClass}{AssociationSchema}
+% \umlSchema[pos=\umlTopRight{AssociationSchema},
+% posDelta={1em,0},refpoint=tl,
+% comment=\pagesReference{Application}]{
+% Application}{
+% \umlAttribute[type={0--1}, default=0.2]{posMeetLine}}{
+% }{}{}{}{}{}
+% \umlSubclass{Application}{ToRelation}
+%
+% \umlSchema[pos=\umlBottomLeft{AssociationEnd},
+% posDelta={0em,-\umlNodeSep},refpoint=tl,
+% comment=\pagesReference{Label}]{
+% LabelA}{
+% }{}{}{}{}
+% \umlSubclass{LabelA}{AssociationEnd}
+% \umlSchema[posY=\umlTop{LabelA},posX=\umlRightSep{LabelA},
+% refpoint=tl,
+% comment=\pagesReference{Symbol}]{
+% SymbolA}{
+% }{}{}{}{}
+% \umlSubclass{SymbolA}{AssociationEnd}
+% \umlSchema[pos=\umlBottomSep{SymbolA}, refpoint=t,
+% comment=\pagesReference{Navigability}]{
+% NavigabilityA}{
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Relation}
+% }{}{}
+% \umlSubclass{NavigabilityA}{SymbolA}
+% \caption{Relation commands in uml.sty.}
+% \label{fig:useApproachRelations}
+% \end{tiny}
+% \end{figure}
+%
+%
+% \subsection{Colors}
+%
+%
+% Colors are explained in figure \ref{fig:useApproachColors}. For more
+% comments on that figure, see section \vref{sec:useColors}.
+%
+% \begin{figure}[htbp]
+% \begin{center}
+% \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
+% sizeY=13cm,innerBorder=2mm,ref=approachDiagramColors ]{
+% }{}% End of diagram
+% \end{center}
+% \begin{tiny}
+% \umlSchema[pos=\umlTopLeft{approachDiagramColors},
+% posDelta={1em, -1em}, refpoint=tl,
+% importedFrom={Main},
+% ]{Drawable}{}{}{}{}{}{}
+% \umlSchema[pos=\umlBottom{Drawable},
+% posDelta={0em, -2em}, refpoint=t,
+% importedFrom={Main},
+% ]{Classifier}{}{}{}{}{}{}
+% \umlSchema[pos=\umlBottom{Classifier},
+% posDelta={0em, -2em}, refpoint=t,
+% importedFrom={Main},
+% ]{Diagram}{}{}{}{}{}{}
+% \umlSchema[pos=\umlBottomRight{Diagram},
+% posDelta={2em, -2em}, refpoint=tl,
+% importedFrom={Main},
+% ]{Relation}{}{}{}{}{}{}
+% \umlSchema[pos=\umlTop{approachDiagramColors},
+% posDelta={0em,-1em},refpoint=tr,
+% abstract=, ,
+% comment=\pagesReference{Colorset}
+% ]{Colorset}{
+% \umlAttribute[type=color]{umlColor}
+% \umlAttribute[type=color]{umlLinecolor}
+% \umlAttribute[type=color]{umlFillcolor}
+% \umlAttribute[type=color]{umlClassifierFillcolor}
+% \umlAttribute[type=color]{umlDiagramFillcolor}
+% }{}{}{}{}{}{}{}
+% \umlSchema[pos=\umlTopRight{Colorset},
+% posDelta={2em,-2em}, refpoint=tl,
+% colorset=\umlColorsDefault,
+% ]{ColorsDefault}{
+% \umlAttribute[type=graycolor, default=0]{umlColor}
+% \umlAttribute[type=graycolor, default=0]{umlLinecolor}
+% \umlAttribute[type=graycolor, default=1]{umlFillcolor}
+% \umlAttribute[type=graycolor, default=0.85]{umlClassifierFillcolor}
+% \umlAttribute[type=graycolor, default=0.95]{umlDiagramFillcolor}
+% \umlAttribute[type=graycolor, default=0]{umlRelationColor}
+% }{}{}{}{}{}{}{}
+% \umlSchema[pos=\umlBottomLeft{ColorsDefault},
+% posDelta={0, -2em}, refpoint=tl,
+% colorset=\umlColorsGray,
+% ]{ColorsGray}{
+% \umlAttribute[type=graycolor, default=0.4]{umlColor}
+% \umlAttribute[type=graycolor, default=0.4]{umlLinecolor}
+% \umlAttribute[type=graycolor, default=1]{umlFillcolor}
+% \umlAttribute[type=graycolor, default=0.90]{umlClassifierFillcolor}
+% \umlAttribute[type=graycolor, default=0.98]{umlDiagramFillcolor}
+% \umlAttribute[type=graycolor, default=0]{umlRelationColor}
+% }{}{}{}{}{}{}{}
+% \umlSchema[pos=\umlBottomLeft{ColorsGray},
+% posDelta={0, -2em}, refpoint=tl,
+% colorset=\umlColorsImport,
+% ]{ColorsImport}{
+% \umlAttribute[type=rgbcolor, default={\{1 0 0\}}]{umlColor}
+% \umlAttribute[type=rgbcolor, default={\{1 0 0\}}]{umlLinecolor}
+% \umlAttribute[type=rgbcolor, default={\{1 0.8 0.8\}}]{umlFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{1 0.85 0.85\}}]{umlClassifierFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{1 0.95 0.95\}}]{umlDiagramFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{1 0 0\}}]{umlRelationColor}
+% }{}{}{}{}{}{}{}
+% \umlSchema[pos=\umlBottomLeft{ColorsImport},
+% posDelta={0, -2em}, refpoint=tl,
+% colorset=\umlColorsArgument,
+% ]{ColorsArgument}{
+% \umlAttribute[type=rgbcolor, default={\{0 1 0\}}]{umlColor}
+% \umlAttribute[type=rgbcolor, default={\{0 1 0\}}]{umlLinecolor}
+% \umlAttribute[type=rgbcolor, default={\{0.8 1 0.8\}}]{umlFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0.85 1 0.85\}}]{umlClassifierFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0.95 1 0.95\}}]{umlDiagramFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0 1 0\}}]{umlRelationColor}
+% }{}{}{}{}{}{}{}
+% \umlSchema[pos=\umlBottomLeft{ColorsArgument},
+% posDelta={0, -2em}, refpoint=tl,
+% colorset=\umlColorsRed,
+% ]{ColorsRed}{
+% \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlColor}
+% \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlLinecolor}
+% \umlAttribute[type=rgbcolor, default={\{0.8 0.8 1\}}]{umlFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0.85 0.85 1\}}]{umlClassifierFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0.95 0.95 1\}}]{umlDiagramFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlRelationColor}
+% }{}{}{}{}{}{}{}
+% \umlSchema[pos=\umlTopLeft{ColorsRed},
+% posDelta={-1em, 0}, refpoint=tr,
+% colorset=\umlColorsSub,
+% ]{ColorsSub}{
+% \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlColor}
+% \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlLinecolor}
+% \umlAttribute[type=rgbcolor, default={\{0.8 0.8 1\}}]{umlFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0.85 0.85 1\}}]{umlClassifierFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0.95 0.95 1\}}]{umlDiagramFillcolor}
+% \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlRelationColor}
+% }{}{}{}{}{}{}{}
+% \umlSubclass[angleA=180,colorset=\umlColorsDefault]{ColorsDefault}{Colorset}
+% \umlSubclass[angleA=180,colorset=\umlColorsImport]{ColorsImport}{Colorset}
+% \umlSubclass[angleA=180,colorset=\umlColorsGray]{ColorsGray}{Colorset}
+% \umlSubclass[angleA=180,colorset=\umlColorsArgument]{ColorsArgument}{Colorset}
+% \umlSubclass[angleA=180,colorset=\umlColorsRed]{ColorsRed}{Colorset}
+% \umlSubclass[colorset=\umlColorsSub]{ColorsSub}{Colorset}
+% \umlSubclass[import=]{Classifier}{Drawable}
+% \umlSubclass[import=,armB=1em,armAngleB=315,angleB=340]{Relation}{Drawable}
+% \umlSubclass[import=]{Diagram}{Classifier}
+% \umlAssociation{Drawable}{Colorset}
+% \umlAssociation{Classifier}{Colorset}
+% \umlAssociation{Diagram}{Colorset}
+% \umlAssociation{Relation}{Colorset}
+% \caption{Color commands in uml.sty. The colors in this figure is for
+% demonstration, and not necessarily correct. See also
+% \vref{sec:useColors}.}
+% \label{fig:useApproachColors}
+% \end{tiny}
+% \end{figure}
+%
+% \subsection{Positions}
+%
+% Positions are explained in figure \ref{fig:useApproachPositions}. For more
+% comments on that figure, see section \vref{sec:usePositions}.
+%
+% \newcommand\umlPrimitive[5][]{%
+% \umlClassifier[kind=Primitive,#1,stereotype={primitive},suppress]{#2}{%
+% \umlCompartment[name=example]{#3}
+% \umlCompartment[name=arguments]{#5}}}
+%
+% \begin{figure}[htbp]
+% \begin{center}
+% \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
+% sizeY=8cm,innerBorder=2mm,ref=approachDiagramPositions]{}{}% End of diagram
+% \end{center}
+% \begin{tiny}
+% \begin{umlColors}{\umlColorsImport}
+% \umlSchema[pos=\umlTopLeft{approachDiagramPositions},
+% posDelta={1em,-9em}, refpoint=tl,importedFrom=main,
+% ]{Relation}{}{}{}{}{}{}{}
+% \end{umlColors}
+% \begin{umlColors}{\umlColorsRed}
+% \umlCompartmentNamesShowtrue
+% \umlPrimitive[pos=\umlTop{approachDiagramPositions},
+% posDelta={0, -1em}, refpoint=t]{Coordinate}{}{}{}{}{}{}
+% \umlPrimitive[pos=\umlTopRight{Relation},
+% posDelta={3em,0em},
+% refpoint=tl,
+% ]{Node}{\umlCompartmentText{A}}{}{}{}{}{}
+% \umlPrimitive[pos=\umlTopRight{Node},ref=parNode,
+% posDelta={3em,0},refpoint=tl,
+% ]{[par]Node}{\umlCompartmentText{[angle=45]A}}{}{
+% \umlArgument{angle}
+% \umlArgument[type=length]{nodesep}
+% \umlArgument{offset}}{}{}{}
+% \umlPrimitive[pos=\umlTopRight{parNode},posDelta={1em,0},refpoint=tl,
+% ]{Polar}{\umlCompartmentText{3;110}}{}{}{}{}{}
+% \umlPrimitive[pos=\umlTopRight{Polar},ref=ps,posDelta={1em,0},refpoint=tl,
+% ]{!ps}{\umlCompartmentText{!3 110 cos mul 2}}{}{}{}{}{}
+% \umlPrimitive[pos=\umlTopRight{ps},ref=coors,posDelta={1em,0},refpoint=tl,
+% ]{{coor1Icoor2}}{\umlCompartmentText{A|1in;30}}{}{}{}{}{}
+% \umlPrimitive[pos=\umlTopRight{coors},posDelta={1em,0},refpoint=tl,
+% refpoint=tl]{Cartesian}{\umlCompartmentText{3,4}}{}{}{}{}{}
+% \umlSubclass[angleA=90,angleB=350]{Cartesian}{Coordinate}
+% \umlSubclass[angleA=90]{Polar}{Coordinate}
+% \umlSubclass[angleA=90]{Node}{Coordinate}
+% \umlSubclass[angleA=90]{parNode}{Coordinate}
+% \umlSubclass[angleA=90]{ps}{Coordinate}
+% \umlSubclass[angleA=90]{coors}{Coordinate}
+% \umlAggregation[angleA=70,armA=1em,armAngleA=90,
+% angleB=345]{coors}{Coordinate}
+% \umlLabel[height=-1ex,offset=1ex]{coorsCoordinate}{2}
+% \umlAggregation{Node}{parNode}
+% \end{umlColors}
+% \begin{umlColors}{\umlColorsImport}
+% \umlSchema[pos=\umlTopRight{approachDiagramPositions},
+% posDelta={-1em,-1em}, refpoint=tr,
+% importedFrom=main,
+% ]{Box}{}{}{}{}{}{}{}
+% \umlAssociation{Coordinate}{Box}
+% \umlLabelB{CoordinateBox}{pos}
+% \umlAssociation{Cartesian}{Box}
+% \umlLabelB[height=-1ex]{CartesianBox}{posDelta}
+% \end{umlColors}
+% \begin{umlColors}{\umlColorsImport}
+% \umlAssociation{Relation}{Node}
+% \umlLabelA{RelationNode}{Node[AB]}
+% \end{umlColors}
+% \umlSchema[posX=\umlLeft{approachDiagramPositions},
+% posY=\umlBottom{parNode},
+% posDelta={1em,2em}, refpoint=tl,
+% comment=\pagesReference{PlaceNode},
+% ]{PlaceNode}{
+% \umlAttribute[type=length, default=0pt]{leftside}
+% \umlAttribute[type=length, default=0pt]{rightside}
+% \umlAttribute[type=length, default=0pt]{top}
+% \umlAttribute[type=length, default=0pt]{bottom}
+% \umlAttribute[type=length, default=0pt]{left}
+% \umlAttribute[type=length, default=0pt]{right}
+% \umlAttribute[type=length, default=0pt]{up}
+% \umlAttribute[type=length, default=0pt]{down}
+% \umlAttribute[type=angle]{angle[ XY]}
+% \umlAttribute[type=offset]{offset[ XY]}
+% \umlAttribute[type=nodesep]{nodesep[ XY]}
+% }{}{
+% \umlArgument{[named options]}
+% \umlArgument{Node}
+% \umlArgument{New node name}
+% }{}{}{}
+% \umlSubclass{PlaceNode}{Node}
+% \umlSymbol[fraction=0.1,refpoint=b,angle=N]{PlaceNodeNode}{<<places>>}
+% \umlSchema[pos=\umlTopLeft{approachDiagramPositions},
+% posDelta={1em,-1em},refpoint=tl,
+% comment=\pagesReference{TopLeft}
+% ]{TopLeft}{}{}{\umlArgument{node}}{}{}{}{}
+% \umlSubclass{TopLeft}{Coordinate}
+% \caption{Position commands in uml.sty. See also
+% \vref{sec:usePositions}.}
+% \label{fig:useApproachPositions}
+% \label{fig:approachEnd}
+% \end{tiny}
+% \end{figure}
+%
+% In figure \ref{fig:useApproachPositions}, the blue stuff is imported
+% from diagram \ref{fig:useApproach}. The red stuff is derived from the
+% PSTricks manual. Only the black classes is defined here.
+%
+% \setlength\umlSymbolHeightDefault{2ex}
+% \setlength\umlSymbolWidthDefault{1ex}
+%
+%
+% \section{Drawable}\label{sec:useDrawable}
+%
+% A Drawable is an unspecified UML construct. It has no graphical
+% appearance itself, but is a common superclass for all uml.sty
+% constructs.
+%
+%
+% The syntax of "\umlDrawable" \DescribeMacro\umlDrawable is, as
+% indicated in figure~\vref{fig:useApproach},
+% "\umlDrawable["\meta{named options}"]"\meta{Contents}.
+%
+% "\umlDrawable" is an ``abstract command'', not ment to be used
+% directly by users. But "\umlDrawable[import=]{Contents}" would yield
+% \fbox{\umlDrawable[import=]{Contents}} (the border around is added
+% here to emphasize the example).
+%
+%
+%
+% \subsection{Named options}
+%
+% The named options "import=" and "noimport=" are described under the
+% next section.
+%
+%
+%
+%
+% \subsubsection{import}
+% \label{sec:useImport}
+%
+% \newcommand\namedO[1]{$#1$\DescribeMacro{#1-}}
+%
+% The named options \namedO{import}{} and \namedO{noimport}{} indicate
+% whether this construct are defined in another diagram, and only
+% imported here.
+%
+% They take no options.
+%
+% They make "\umlColorsImport" and "\umlColorsDefault",
+% \emph{henholdsvis}, take effect on the construct.
+%
+% See also the variable Element.importedFrom
+% (section~\ref{sec:useImportedFrom}).
+%
+%
+%
+%
+% \section{Element}
+% \label{sec:useElement}
+%
+% An element is an construct which can be referenced.
+%
+%
+% The syntax of "\umlElement" \DescribeMacro\umlElement is exactly the
+% same as that of "\umlDrawable". However, "\umlElement" has more named options.
+%
+% "\umlElement" is abstract too. It does not itself use much of the
+% information supplied by the named options. "\umlElement{Contents}"
+% would yield \fbox{\umlElement{Contents}}.
+%
+%
+% \subsection{Named options}
+% \label{sec:useElementNamed}
+%
+%
+% \subsubsection{Reference}
+% \label{sec:ref}
+%
+% Each element has a \namedO{reference}. $reference$
+% is used among other things when placing nodes.
+%
+% Legal values are valid PSTricks node names (\vref{sec:useNodeNames}).
+%
+% Default values differ between the constructs.
+%
+% $reference$ is also used by some commands to make several nodes with
+% derived names. E.g., "Aa"$reference$ of a relation is one
+% of the endpoints.
+%
+% \subsubsection{Stereotype}
+% \label{sec:useStereotype}
+%
+% The variable \namedO{stereotype}{} indicates the
+% stereotype of the construct. The value is not used by every
+% construct. Typically, the name is placed in <<guillements>> around or
+% in the construct.
+%
+% Legal values is any string. Default is no stereotype.
+%
+% \subsubsection{Subof}
+% \label{sec:useSubof}
+%
+% \index{generalization}The variable \namedO{subof}{} indicates the
+% superconstruct (in standard UML parlance, the \emph{generalization})
+% of this construct. The value is not used by every construct, but is
+% typically placed around or in the construct.
+%
+% Legal values is any string. Default is nothing.
+%
+% The $subof$ variable and the subclass relation
+% (section~\ref{sec:useSubclass}) are different ways of expressing the
+% same thing.
+%
+% \subsubsection{ImportedFrom}
+% \label{sec:useImportedFrom}
+%
+% The variable \namedO{importedFrom}{} indicates which package or digram this
+% construct is imported from. The value is not used by every construct,
+% but is typically placed around or in the construct.
+%
+% Legal values is any string. Default is nothing.
+%
+% \subsubsection{Comment}
+% \label{sec:useComment}
+%
+% The variable \namedO{comment}{} is a comment. The value is not used by every
+% construct, but is typically placed around or in the construct.
+%
+% Legal values is any string. Default is nothing.
+%
+%
+%
+%
+% \section{Box}
+% \label{sec:useBox}
+%
+% Box is an UML construct drawn as a box, i.e.\ with some areal. Boxes
+% has size, position and possibly a border.
+%
+% The syntax is "\umlBox["\meta{Named options}"]{"\meta{Contents}"}".
+%
+% "\umlBox[box=,border=2pt,innerBorder=2pt]{Contents}" would be typeset as
+% \fbox{\umlBox[box=,border=2pt,innerBorder=2pt]{Contents}} (The inner border is made by
+% the box).
+%
+% \subsection{Named options concerning location}
+% \label{sec:useBoxesLocation}
+%
+%
+% Boxes are positioned by various named options. The positioning
+% mechanism starts at ($pos$), given by the "pos" or "posX" and "posY" named
+% potions. Then, it moves to ($posDelta$), given by the "posDelta" or
+% "posDeltaX" and "posDeltaY" keywords. The $refpoint$ of that class
+% (e.g.\ top left corner), given by "refpoint" is placed at this point.
+%
+% All the named options with names starting with "pos" have legal values
+% coordinate pairs, as described \vpageref{sec:useSyntaxCoordinates}.
+%
+% \begin{description}
+% \item["pos"] sets \namedO{pos}. Default is to look at the values set by
+% "posX" and "posY".
+% \item["posX"] sets \DescribeMacro{posX-}$pos$ horizontally. Default is "0,0".
+% \item["posY"] sets \DescribeMacro{posY-}$pos$ vertically. Default is "0,0".
+% \item["posDelta"] sets \namedO{posDelta}. Default is to look at the values set by
+% "posDeltaX" and "posDeltaY".
+% \item["posDeltaX"] sets \DescribeMacro{posDeltaX-}$posDelta$ horizontally. Default is "0,0".
+% \item["posDeltaY"] sets \DescribeMacro{posDeltaY-}$posDelta$ vertically. Default is "0,0".
+% \item["refpoint"] \DescribeMacro{refpoint-}which point in the class to be placed. Can
+% be any of "l", "r", "t", "b" and "B", meaning left, right, top,
+% bottom and baseline, or any reasonable combination of them.
+% \end{description}
+%
+% E.g., if the named options are "[pos=Car, posDelta={1,-1}, refpoint=tl]",
+% the top left corner of the class are placed one unit to the right and
+% one down from the node Car.
+%
+% \subsection{Boxes in text}
+%
+% Default, an box is placed inside a zero size hbox.
+% While used in text, you want the class to be put inside a hbox with
+% the natural size of the box. This is done by means of the named
+% option "box". Note that a "=" must be present, even if nothing
+% follows it before the next ",". This option overrides the location
+% named options.
+%
+% \begin{description}
+% \item["box"] \DescribeMacro{box-}normally, the class is put in a hbox
+% of size (0,0), suitable for use in a diagram. With "box=" set, it
+% is put in a hbox with its natural size, suitable for use in text.
+% The class \umlClass[box=]{Class in text}{}{}, made by
+% "\umlClass[box=]{Class in text}{}{}", can serve as an example.
+% \end{description}
+%
+%
+% \subsection{Named options concerning visual appearance}
+% \label{sec:useBoxesVisual}
+%
+%
+% \subsubsection{grayness}
+%
+% \DescribeMacro{grayness-}The grayness in the background in the box,
+% from "0" (black) to "1" (white). Default value without named option
+% is 1 (white), with named option .85 (still quite bright).
+%
+%
+% \subsubsection{border}
+%
+% \DescribeMacro{border-}The width of the border. Legal values are
+% lengths. Default value without named option is 0 (no border), default
+% value with named option without value is 0.4~pt.
+%
+% \subsubsection{borderLine}
+%
+% \DescribeMacro{borderLine-}The style of the border. Legal values are
+% line styles (section~\ref{sec:useLinestyles}). Default is solid.
+%
+%
+% \subsubsection{innerBorder}
+%
+% \DescribeMacro{innerBorder-}The inner margin of the box. Legal values
+% are lengths. Default value is 0.
+%
+%
+% \subsection{Named options concerning size}
+% \label{sec:useBoxesSize}
+%
+% Some boxes (not all) allow the user to specify the size of the
+% interior of the box.
+% \begin{description}
+% \item["sizeX"] \DescribeMacro{sizeX-}The horizontal size of the box.
+% Must be a valid length.
+% \item["sizeY"] \DescribeMacro{sizeY-}The vertical size of the box.
+% Must be a valid length.
+% \end{description}
+%
+% The default size of the box is not specified here, but it normally is
+% the natural size of \meta{stuff}.
+%
+%
+%
+% \section{Diagram}
+% \label{sec:useDiagram}
+% \label{sec:useDiagrams}
+%
+%
+% \DescribeMacro{\umlDiagram}A diagram is an area, with a coordinate
+% system. Stuff like classes can be placed at the diagram. The syntax
+% of the "\umlDiagram" command
+% is "\umlDiagram["\meta{named options}"]{"\meta{stuff}"}".
+%
+% \meta{stuff} is placed inside the diagram. It can be positioned in
+% various ways, using mechanisms from \TeX{} or PSTricks or using named
+% options in "\umlClass" or "\umlSchema".
+%
+% Some positioning mechanisms are very sensitive to ``spurious spaces'',
+% \index{spurious spaces}\index{spaces!spurious}pushing some of the
+% \meta{stuff} to the right. Line breaks (without a comment sign
+% before) can create such mystical spurious spaces. Using named options
+% like "posX" and "posY" should eliminate this problem.
+%
+% "\umlDiagram" is an "\umlBox", and inherits all its named options.
+%
+% Once, I discovered that "\umlDiagram" also works without the "sizeX"
+% and "sizeY" options. Using it that way, you typically want to use
+% "innerBorder" on the diagram and "box" on the contents. You may still
+% use "sizeX" and "sizeY" as minimum size.
+%
+% The named option "box=" is always set to true in "\umlDiagram".
+%
+% \subsection{Example}
+%
+% The diagram in figure \vref{fig:diagram} is made by the code
+%
+% \begin{verbatim}
+% \umlDiagram[box=,border,sizeX=7cm,sizeY=4cm]{%
+% \umlClass[refpoint=bl, pos={3,3}]{ClassName}{}{}}
+% \end{verbatim}
+%
+% \begin{figure}[htbp]
+% \begin{center}
+% \umlDiagram[box=,border,sizeX=7cm,sizeY=4cm]{%
+% \umlClass[refpoint=bl, pos={3,3}]{ClassName}{}{}}
+% \caption{Example of a diagram}%
+% \label{fig:diagram}%
+% \end{center}%
+% \end{figure}%
+%
+% This creates a diagram which is 7~cm wide and 4~cm
+% high. It contains a class, with its bottom left corner positioned at
+% position (3,3).
+%
+% Note that the class, as a stretchbox, determines its size
+% on the basis of its contents, as opposed to a diagram, which has its
+% size given.
+%
+%
+%
+% \section{Stretchbox}
+% \label{sec:useStretchbox}
+%
+% A stretchbox is a box which determines its size on the basis of its
+% contents. It also has a name.
+%
+% The syntax\DescribeMacro{\umlStretchbox} is
+% "\umlStretchbox["\meta{named options}"]"\meta{name}\meta{contents}.
+%
+%
+% \subsection{Name, graphicalName and reference}
+%
+% "\umlStretchbox" takes a name as its second argument. Legal values is
+% strings. The name is a default reference. If the string contains spaces or something making
+% it a non-valid node name, remember to supply a reference with the
+% "reference=" named option.
+%
+% Subclasses of "\umlStretchBox" may make a
+% \DescribeMacro{graphicalName} graphicalName based on the name. The
+% graphical name is typically the string in a large font.
+%
+%
+% \section{Classifier}
+% \label{sec:useClassifier}
+%
+% \DescribeMacro{\umlClassifier}A classifier is a stretchbox which can
+% be instantiated. Classifier is direct superclass to Class.
+%
+% It has the same syntax as "\umlStretchbox". However, there is another
+% named option:
+%
+% \begin{description}
+% \item["object"] \DescribeMacro{object-}Makes the graphical name underlined.
+% \end{description}
+%
+% Classifiers are typically divided in \emph{compartments}, stacked on
+% top of each other. Standard UML classes are divided in three
+% compartments.
+%
+%
+% \section{Compartment}
+% \label{sec:useCompartment}
+%
+% \DescribeMacro{\umlCompartment}A compartment is a part (of a
+% classifier). The compartments are stacked on top of each other.
+%
+% The syntax is "\umlCompartment["\meta{Named
+% options}"]"\meta{Contents}. Compartments are to be placed inside
+% classifiers. In the implementation, "\umlClassifier" is implemented
+% as a table and "\umlCompartment" as table lines.
+%
+% "\umlCompartment" requires its contents to be ended by a linebreak
+% ("\\"). This is typically given by "\umlCompartmentline".
+%
+% Example: \fbox{%
+% \umlClassifier[box=]{Name}{%
+% \umlCompartment{First line\\}
+% \umlCompartment{Second line\\}
+% \umlCompartment{
+% \umlCompartmentline{Compartment line}}
+% }} was made by
+% \begin{verbatim}
+% \umlClassifier[box=]{Name}{%
+% \umlCompartment{First line\\}
+% \umlCompartment{Second line\\}}
+% \umlCompartment{%
+% \umlCompartmentline{Compartment line}}
+% \end{verbatim}
+%
+%
+% \subsection{Suppression}
+%
+% By default, empty compartments are drawn, indicating that the
+% compartment is empty. The UML specification [UML1.4, 3.22.3]
+% states that ``a separator line is not drawn for a missing
+% compartment.''
+%
+% Suppression is \emph{styrt} by the boolean variable
+% "umlCompartmentSuppress". You can set this to true
+% ("\umlCompartmentSuppresstrue") or false
+% ("\umlCompartmentSuppressfalse") whenever you wish.
+%
+% You can also use the named option
+% \DescribeMacro{suppress-}"suppress=" on one compartment or something
+% bigger (such as a classifier). Legal values are "true" and "false"
+% when used without value, default is "true".
+%
+%
+% \subsection{Name}
+%
+% You can set the name with the named option
+% \DescribeMacro{name-}"name=".
+%
+% If the boolean value "\umlCompartmentNameShow" are true, the name is
+% shown centered bold in the top of the compartment. You may say
+% "\umlCompartmentNameShowtrue" or "\umlCompartmentNameShowfalse" when
+% you wish.
+%
+% You can also use the named option \DescribeMacro{showname}"showname="
+% on a construct. Legal values are true and false, default is true.
+%
+%
+% \section{Compartmentline}
+% \label{sec:useCompartmentline}
+%
+% \DescribeMacro{\umlCompartmentline}This is a line in a compartment.
+% It ends with a line feed. Subcommands of "\umlCompartmentline" is
+% "\umlAttribute" and "\umlMethod".
+%
+% The syntax is as usual "\umlCompartmentline["\meta{named
+% options}"]"\meta{Contents}. For example, see above. Note the space
+% in front of the contents when using "\umlCompartmentline", as opposed
+% to raw text.
+%
+% All lines in compartments are required to end by a line break.
+% "\umlCompartmentline" supplies this.
+%
+%
+%
+% \section{Feature}
+% \label{sec:useFeature}
+%
+% \DescribeMacro{\umlFeature}A feature is a line in a compartment in a
+% classifier, such as a method, attribute or argument.
+%
+%
+% \subsubsection{visibility}
+%
+% \DescribeMacro{visibility-}Legal values for the visibility is
+% Visibility is typically one of + (public), \# (protected), -
+% (private) or "~" (package). Default is +.
+%
+% The command \DescribeMacro\umlTilde"\umlTilde" writes a \umlTilde.
+% \subsubsection{type}
+%
+% \DescribeMacro{type-}This is the type of an attribute or an argument,
+% or the return type of a method.
+%
+% \subsubsection{propertyString}
+%
+% \DescribeMacro{propertyString-}An UML property string.
+%
+%
+%
+%
+% \section{Method}
+% \label{sec:useMethod}
+%
+%
+%
+% "\umlMethod" \DescribeMacro\umlMethod is of the form
+% "\umlMethod["\meta{options}"]{"\meta{name}"}{"\meta{arguments}"}".
+%
+% "\umlMethod" provides "returntype"\DescribeMacro{returntype-}{} as an
+% alias for "type".
+%
+% "\umlMethod[visibility=\#, returntype=real]{sqrt}{int arg}"
+% makes \begin{tabular}{|c|}\hline\umlMethod[visibility=\#,
+% returntype=real]{sqrt}{int arg}\hline\end{tabular}.
+%
+%
+%
+% \section{Attribute}
+% \label{sec:useAttribute}
+%
+%
+% "\umlAttribute" \DescribeMacro\umlAttribute is of the form
+% "\umlAttribute["\meta{options}"]{"\meta{name}"}".
+%
+%
+% "\umlAttribute[visibility=\#, default=186, type=int]{height}"
+% makes
+% \begin{tabular}{|c|}\hline
+% \umlAttribute[visibility=\#, default=186, type=int]{height}\hline
+% \end{tabular}.
+%
+%
+% \section{Argument}
+% \label{sec:useArgument}
+%
+% Arguments to classifiers are not a standard UML construct. However,
+% we have included it here.
+%
+% "\umlArgument" \DescribeMacro\umlArgument is of the form
+% "\umlArgument["\meta{options}"]{"\meta{name}"}".
+%
+% "\umlArgument[type=Class]{nodetype}"
+% would be rendered as
+% \begin{tabular}{|c|}\hline
+% \umlArgument[type=Class]{nodetype}\hline
+% \end{tabular}.
+%
+% \section{Class}
+% \label{sec:useClass}
+%
+% \DescribeMacro{\umlClass}The macro "\umlClass" draws an UML class. Its
+% syntax is "\umlClass["\meta{named
+% options}"]"\meta{name}\meta{variables}\meta{methods}. The
+% \meta{variables} and \meta{methods} parts are typically drawn using
+% "\umlVariable" and "\umlMethod".
+%
+% Graphically, the class is divided in three compartments above each
+% other. The upper compartment contains the class name. The middle one
+% contains the variables, and the lower the methods.
+%
+%
+% \index{burger}Example: Figure \vref{fig:useClass} is coded as:
+% \begin{verbatim}
+% \umlClass[box=,
+% reference=AmericanMan,
+% stereotype=Man,
+% import=,
+% importedFrom=America,
+% comment=A man from America
+% ]{American Man}{%
+% \umlAttribute[visibility=\#, type=State]{State}
+% \umlAttribute[visibility=\#,
+% default=Mc Donalds]{Favourite burger}}{%
+% \umlMethod[visibility=]{Watch TV}{}
+% \umlMethod[visibility=-, returntype=int]{Vote}{Party party}
+% }
+% \end{verbatim}
+%
+% \begin{figure}[Ht]
+% \begin{center}
+% \iftrue
+% \umlClass[box=,
+% reference=AmericanMan,
+% stereotype=Man,
+% import=,
+% importedFrom=America,
+% comment=A man from America
+% ]{American Man}{%
+% \umlAttribute[visibility=\#, type=State]{State}
+% \umlAttribute[visibility=\#,
+% default=Mc Donalds]{Favourite burger}}{%
+% \umlMethod[visibility=]{Watch TV}{}
+% \umlMethod[visibility=-, returntype=int]{Vote}{Party party}
+% }
+% \caption{A class}
+% \label{fig:useClass}\label{fig:class}
+% \fi
+% \end{center}
+% \end{figure}
+%
+% Also, see figure \vref{fig:useSchema} for a larger example.
+%
+%
+%
+% \section{Schema}
+% \label{sec:useSchema}
+%
+% \emph{Schema} is not a standard UML construct. It is a generalization
+% of class I find very useful. A schema is a class which also can
+% \begin{itemize}
+% \item take arguments
+% \item be instantiated freely into other schemas
+% \item have an internal structure, typically using its arguments
+% \end{itemize}
+% Graphically, schemas look pretty much like classes, with attribute and
+% method compartments. In addition, it have more compartments. Here
+% are they all:
+% \begin{description}
+% \item[Name] compartment contains the name and possibly stereotype and
+% other symbols, just like in the Class symbol.
+% \item[Attributes] compartment contains the attributes, like in Class.
+% \item[Methods] compartment contains the methods, like in Class.
+% \item[Arguments] compartment contains the schema arguments. Each
+% argument is another schema (possibly an object).
+% \item[Constraints] compartment contains constraints.
+% \item[Structure] compartment typically contains a class diagram.
+% \end{description}
+%
+% \DescribeMacro{\umlSchema} This corresponds to more arguments to
+% "\umlSchema". The spec is
+% "\umlSchema["\meta{named options}"]{"\meta{Name}"}{"\meta{Attributes}%
+% "}{"\meta{Methods}"}\"\\"{"\meta{Arguments}"}{"\meta{Constraints}"}{"\meta{Structure}"}".
+% Almost everything said about "\umlClass" is also true about
+% "\umlSchema". The two commands inherit the same named options.
+%
+% "\umlSchema" is included for two reasons: Because I use them myself,
+% and to show how you can make your own classifiers yourself.
+%
+% \subsection{Example (Stack)}
+%
+% \index{Node!in stack}\noindent{}\begin{tabular}{@{}lc}
+% \noindent{}\parbox{.618\linewidth}{\label{Stack}The figure to the right
+% is a simple stack. To
+% start with the fourth compartment, the schema Stack takes an other
+% metaclass as argument (named \emph{type}). If \emph{type} is set to,
+% say, Procedure, we get a Stack of procedures. Stack has one
+% attribute, a private pointer to the first Node. This first node is of
+% type \emph{type}. There are two procedures, the well-known push and
+% pop, both public; push takes an instance of \emph{type} as argument,
+% pop returns a \emph{type}. There is one constraint, that a Stack
+% should be equal to itself pushed once and popped once.
+% }
+% &
+% \parbox[][][t]{.382\linewidth}{
+% \umlSchema[box=]{Stack}{%Attributes
+% \umlAttribute[visibility=-, type=\emph{type}, default=null, ]{firstNode}
+% }{% Methods
+% \umlMethod[visibility]{push}{\emph{type} x}
+% \umlMethod[visibility, type=\emph{type}]{pop}{}
+% }{% Arguments
+% \umlArgument[type=Metaclass]{type}
+% }{% Constraints
+% \umlCompartmentline{S:Stack = S.push(x).pop()}
+% }{% Structure
+% \umlDiagram[box=,innerBorder=2mm, sizeX=11em, sizeY=5em,
+% ref=StackDiagram, outerBorder=2mm]{%
+% \umlClass[pos={.5,.5}, ref=stackNode]{Node}{
+% \umlAttribute[visibility=\#, type=\emph{type}]{data}}{}
+% \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em
+% ]{stackNode}{stackNode}{
+% \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}
+% \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}
+% }% End of diagram
+% \cr}}% End of Stack
+% \end{tabular}
+%
+% The seventh compartment describes the internal structure of Stack.
+% Here, we do not bother distinguishing between the interface and the
+% internal implementation of Stack.
+%
+% The \LaTeX{} source is here:
+% \begin{verbatim}
+% \umlSchema[box=]{Stack}{%Attributes
+% \umlAttribute[visibility=-, type=\emph{type}, default=null, ]{firstNode}
+% }{% Methods
+% \umlMethod[visibility]{push}{\emph{type} x}
+% \umlMethod[visibility, type=\emph{type}]{pop}{}
+% }{% Arguments
+% \umlArgument[type=Metaclass]{type}
+% }{% Constraints
+% \umlCompartmentline{S:Stack = S.push(x).pop()}
+% }{% Structure
+% \umlDiagram[box=,innerBorder=2mm, sizeX=11em, sizeY=5em,
+% ref=StackDiagram, outerBorder=2mm]{%
+% \umlClass[pos={.5,.5}, ref=stackNode]{Node}{
+% \umlAttribute[visibility=\#, type=\emph{type}]{data}}{}%
+% \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em
+% ]{stackNode}{stackNode}{%
+% \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}%
+% \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}%
+% }
+% }% End of diagram
+% \cr}% End of Stack
+% \end{verbatim}
+%
+%
+% \section{Relation}\label{sec:useRelation}
+%
+% \emph{Relations} are all kinds of connections between classifiers (and
+% other nodes). Examples of relations include common associations, the
+% subclass (specialization) relation and the aggregation relation.
+% While these constructs are semantically very different, they can all
+% be drawn as connections between schemas.
+%
+% \DescribeMacro{\umlRelation}"\umlRelation" itself, like most of its
+% subclasses, is of the form "\umlRelation["\meta{Named
+% options}"]"\meta{From}\meta{To}\meta{Other contents}, where
+% \meta{From} and \meta{To} are references to nodes (e.g.\ classes and
+% nodes). \meta{Other contents} typically contains labels etc which
+% should have the same colors etc as the relation. The argument
+% \meta{Other contents} are new since version 0.09. This may cause
+% errors if one tries to use "\umlRelation" with the old arguments.
+%
+% Figure \vref{fig:generalRelation} shows some of the capabilities of
+% "uml.sty" relations.
+%
+% The source of figure \ref{fig:generalRelation} is:
+% \begin{verbatim}
+% \umlDiagram[box=,sizeX=7cm, sizeY=7cm, ref=relation]{%
+% \umlClass[pos=\umlBottomLeft{relation}, posDelta={1,1}, refpoint=bl,
+% reference=A]{Class A}{}{}%
+% \umlClass[pos=\umlTopRight{relation}, posDelta={-1,-1}, refpoint=tr,
+% reference=B]{Class B}{}{}%
+% \umlRelation{A}{B}{
+% \umlLabelA{AB}{*}
+% \umlLabelB{AB}{1}}
+% \umlLabel[fraction=.5,offset=0]{AB}{center}
+% \umlAssociationEnd[fraction=A, angle=U]{AB}{A}
+% \umlAssociationEnd[fraction=B, angle=R]{AB}{B}
+% \umlSubclass[ref=ABsub, angleA=0, armA=5, armAngleA=0,
+% angleB=300, linecolor=blue,nodesep=1ex]{A}{B}
+% \umlComposition[reference=ABComp,
+% angleA=120, arm=4, armAngleA=80,
+% angleB=180, armAngleB=190]{A}{B}
+% \umlNavigabilityA{ABComp}
+% }
+% \end{verbatim}
+%
+% \begin{figure}[htbp]
+% \begin{center}
+% \umlDiagram[box=,sizeX=7cm, sizeY=7cm, ref=relation]{
+% \umlClass[pos=\umlBottomLeft{relation}, posDelta={1,1}, refpoint=bl,
+% reference=A]{Class A}{}{}
+% \umlClass[pos=\umlTopRight{relation}, posDelta={-1,-1}, refpoint=tr,
+% reference=B]{Class B}{}{}
+% \umlRelation{A}{B}{
+% \umlLabelA{AB}{*}
+% \umlLabelB{AB}{1}}
+% \umlLabel[fraction=.5,offset=0]{AB}{center}
+% \umlAssociationEnd[fraction=A, angle=U]{AB}{A}
+% \umlAssociationEnd[fraction=B, angle=R]{AB}{B}
+% \umlSubclass[ref=ABsub, angleA=0, armA=5, armAngleA=0,
+% angleB=300, linecolor=blue,nodesep=1ex]{A}{B}
+% \umlComposition[reference=ABComp,
+% angleA=120, arm=4, armAngleA=80,
+% angleB=180, armAngleB=190]{A}{B}
+% \umlNavigabilityA{ABComp}
+% }
+% \caption{Some relations (silly relations, but good example)}
+% \label{fig:generalRelation}
+% \end{center}
+% \end{figure}
+%
+%
+%
+% \subsection{Appearance of the connector}
+%
+% The visual appearance of the connector is influenced by the following
+% named option:
+%
+% \begin{description}
+% \item["linestyle"] A\DescribeMacro{linestyle-} linestyle to draw the
+% connector. Default is "solid".
+% \item["linecolor"] The color of the line.\DescribeMacro{linecolor-}
+% \end{description}
+%
+% \subsection{Geometry of the connector}
+%
+% The connector consists of three line segments: A main part in the
+% middle and two arms. By default, the arms have zero length. The arms
+% are sometimes referred to as "A" and "B".
+%
+% In the example, figure \ref{fig:generalRelation}, the both arms of
+% the middle relation and one of the blue one have lengths zero.
+%
+% \paragraph{Where the connector hits the node}
+%
+% By default, the connector tries to be as short as possible. With no
+% named options, the connector will be a straight line between the
+% nodes. This can be overridden by the named option
+% \begin{description}
+% \item["angle", "angleA" and "angleB"] \DescribeMacro{angle-}Angle at
+% which the connector hits the node. "angleA" affects \meta{From},
+% "angleB" \meta{To} and "angle" both of them.
+% \end{description}
+%
+%
+% \paragraph{The arms}
+%
+% By default, there are no arms (they have lengths zero). This can be
+% overridden by the named options
+% \begin{description}
+% \item["arm", "armA" and "armB"] The \DescribeMacro{arm-}length of the
+% arm. Default is 0pt, which means there is no arm at all.
+% \item["armAngle", "armAngleA" and "armAngleB"] The
+% \DescribeMacro{armAngle-}direction of the arm. Default is 0
+% (meaning right).
+% \end{description}
+%
+%
+% \paragraph{Nodesep}
+%
+% It is possible to make a separation between the nodes and the
+% connector by the named options
+% \begin{description}
+% \item["nodesep", "nodesepA" and "nodesepB"] Legal values are lengths,
+% default is 0.
+% \end{description}
+%
+% \subsection{Reference and placement of nodes}
+%
+%
+% \index{nodes!in Relation}As "\umlElement"s, relations have references. Default is
+% \index{reference!default!in Relation}
+% the concatenation of the references of \meta{From} and
+% \meta{To}. This can as usual be overridden by the named option "reference".
+%
+% \begin{figure}[htbp]
+% \begin{center}
+% \umlDiagram[box=,sizeX=\textwidth, sizeY=5cm, ref=nodePlacement]{
+% \umlClass[pos=\umlBottomLeft{nodePlacement}, posDelta={1,1}, refpoint=bl,
+% reference=A]{Class A}{}{}
+% \umlClass[pos=\umlTopRight{nodePlacement}, posDelta={-1,-1}, refpoint=tr,
+% reference=B]{Class B}{}{}
+% \umlRelation[ref=ABnode, angleA=0, armA=5, armAngleA=0]{A}{B}{}
+% \rput{0}(AaABnode){\rput(1ex,0){Aa}}
+% \rput{0}(BaABnode){\rput(-6ex,.5ex){Ba and Bc}}
+% \rput{0}(AcABnode){Ac}
+%  \rput{0}(BcABnode){Bc}
+% }
+% \caption{Placement of relation nodes. In this case, Both SymbolAb
+% and SymbolBb is where Ac is (one line segment from resp.\ nodes).}
+% \label{fig:relationNodes}
+% \end{center}
+% \end{figure}
+%
+% \noindent{}With the reference set as \meta{reference}, the following nodes are
+% set:
+% \begin{itemize}
+% \item "Aa"\meta{reference} Where the connector hits node A (\meta{From})
+% \item "Ba"\meta{reference} Where the connector hits node B (\meta{To})
+% \item "Ab"\meta{reference} One line segment from "Aa"\meta{reference}.
+% \item "Bb"\meta{reference} One line segment from "Ba"\meta{reference}.
+% \item "Ac"\meta{reference} Where the main line segment hits arm or
+% node A
+% \item "Bc"\meta{reference} Where the main line segment hits arm or
+% node B
+% \end{itemize}
+%
+% The clever reader will understand that "Ab"\meta{reference} will be
+% the same location as "Ac"\meta{reference} (if there is an arm A) or as
+% "Bc"\meta{reference} (if there is not). In the latter case,
+% "Ac"\meta{reference} will be the same location as
+% "Aa"\meta{reference}. Similarly in the opposite direction.
+%
+% Tip: The connector is drawn with "\ncdiag". Just after making the
+% relation, you can make your own "\pnode" with something like
+% "\lput{:R}("\meta{a number 0--3}"){\pnode{"\meta{your reference}"}}".
+%
+%
+% \section{AssociationEnd}
+% \label{sec:useAssociationEnd}
+%
+% An relation may have different attachments attached to it. It may
+% have labels specifying multiplicities and a end-symbol (such as a
+% triangle in the subclass case). All this can be made with
+% "\umlAssociationEnd".
+%
+% Its syntax is \DescribeMacro\umlAssociationEnd
+% "\umlAssociationEnd["\meta{named
+% options}"]"\meta{relation}\meta{Symbol}, where \meta{relation} is the
+% reference of a relation and \meta{symbol} is the symbol to be placed
+% (e.g., an asterisk or a triangle).
+%
+%
+% \subsection{Placing of the symbol}
+% \label{sec:useAssociationEndPlacing}
+%
+% The location of the symbol is determined this way:
+% \begin{itemize}
+% \item You pick the direction along the relation
+% \item Relative\DescribeMacro{posAngle} to this direction, you pick the direction determined by
+% "posAngle". But, since this direction is
+% ":U", up, by default, you probably still move in the direction along
+% the relation. You probably don't want to modify posAngle.
+% \item In this direction, move the fraction specified by
+% "pos"\DescribeMacro{pos-} of the relation. This is default 0. But
+% if you specify "fraction=0.2", you move 20~\% along the line. Legal
+% values, in addition to real numbers, are "A" and "From", meaning
+% near node A, and "B" and "To", meaning you move from node B to A.
+% \item Still in this direction, \DescribeMacro{offset-}move the length
+% specified by "offset". If you say "offset=2ex", you are 20~\% of
+% the line + 2~ex away from the node now.
+% \item To \DescribeMacro{height-}the right of this direction, move the length specified by
+% "height".
+% \item Here, \DescribeMacro{refpoint-}place the point on the symbol
+% specified by "refpoint". This is default "B" (baseline).
+% \item Rotate \DescribeMacro{angle-}the symbol in the direction
+% specified by "angle". This is default "U" (up).
+% \end{itemize}
+%
+% Much of the point in "\umlLabel" and "\umlSymbol" is to provide other
+% defaults for different uses.
+%
+% Common relations have their specialized commands (like "\umlSubclass"
+% and "\umlAggregation"), to be explained later on. These commands call
+% "\umlRelation" and then "\umlSymbol" with the appropriate
+% symbol.
+%
+%
+% \section{Label}
+% \label{sec:useLabel}
+%
+% \DescribeMacro{\umlLabel}This is an association end which new defaults:
+% offset is 4~ex, height is 4~ex and direction is N (north, absolute
+% up). This is good defaults for label.
+%
+% In labels, if pos is "B" or "To", the height is inverted.
+%
+% The command\DescribeMacro\umlLabelA "\umlLabelA" is an "\umlLabel"
+% with fraction=A. "\umlLabelB" is an "\umlLabel" with fraction=B.
+%
+% In figure \ref{fig:generalRelation}, there are three labels: 1, * and
+% ``center''. ``A'' and ``B'' is implemented directly by means of
+% "\umlAssociationEnd".
+%
+% \section{Symbol}
+% \label{sec:useSymbol}
+%
+% This\DescribeMacro\umlSymbol is an association end with new defaults.
+% Refpoint is "t" (top).
+%
+% The command\DescribeMacro\umlSymbolA "\umlSymbolA" is an "\umlSymbol"
+% with fraction=A. "\umlSymbolB" is an "\umlSymbol" with fraction=B.
+%
+% In figure \ref{fig:generalRelation}, there are two symbols (the diamond
+% in the left one and the triangle in the right)
+%
+% \section{Navigability}
+% \label{sec:useNavigability}
+%
+%
+%
+% Navigability indicates which direction the relation can be followed.
+% Graphically, it looks like an open arrow.
+%
+% The syntax is "\umlNavigability["\meta{named
+% options}"]"\meta{Relation}. The symbol is predefined. Navigability
+% can also be drawn with the commands \DescribeMacro\umlNavigabilityA"\umlNavigabilityA" and
+% "\umlNavigabilityB".
+%
+% In figure \ref{fig:generalRelation}, there is one navigability symbol
+% (towards Class A).
+%
+%
+% \section{The different relations}
+%
+% There are several different relations; being semantically very
+% different, they all are connectors between nodes, and they all are
+% implemented as subcommands of "\umlRelation", with various end symbols.
+%
+% \subsubsection{Association}
+% \label{sec:useAssociation}
+%
+% \rput{0}(-1cm, -1ex){\pnode{AssociationA}}
+% \DescribeMacro{\umlAssociation}
+% "\umlAssociation" is only a wrapper to "\umlReference". Graphically,
+% an association is a reference without any fuzz. An example of an
+% association (between nothing, though) is shown
+% in the left margin of this text.
+% \rput{0}(AssociationA|-1cm, 0){\pnode{AssociationB}}
+% \umlAssociation{AssociationB}{AssociationA}
+%
+% \subsubsection{Subclass (generalization)}
+% \label{sec:useSubclass}
+% \label{sec:useGeneralization}
+%
+% \rput{0}(-1cm, -4ex){\pnode{SubclassA}}
+% \DescribeMacro{\umlSubclass}
+% \DescribeMacro{\umlGeneralization}
+% This relation is in UML named \emph{generalization}. We prefer to
+% name it the \emph{subclass relation} (really, more relations are about
+% generalization). However, for the sake of compatibility, the commands
+% "\umlSubclass" and "\umlGeneralization" are offered as equals.
+%
+% The relation goes from the most special node to the most general one.
+% Graphically, it is a solid line with a triangle at the general end.
+% \rput{0}(SubclassA|-1cm, 0){\pnode{SubclassB}}
+% \umlSubclass{SubclassB}{SubclassA}
+%
+%
+% \subsubsection{Inner class}
+% \label{sec:useInner}
+%
+% \rput{0}(-1cm, -1ex){\pnode{InnerA}}
+% \DescribeMacro{\umlInner}
+% The graphical notation for this is not part of standard UML, and not
+% very well worked through either. However, I find it very useful to
+% have a notation for this (without drawing the classes inside each
+% other).
+%
+% Bug: I have not been able to get rid of the gray thing borders made by
+% "\psClip".
+%
+% I have not investigated the differences and similarities in the
+% semantics of what I call Inner Class, Java Inner Classes, Schemas
+% which contain other classes and traditional UML composition.
+%
+% The command is "\umlInner".
+% \rput{0}(InnerA|-1cm, 0){\pnode{InnerB}}
+% \umlInner{InnerB}{InnerA}
+%
+%
+% \subsubsection{Instance}
+% \label{sec:useInstance}
+%
+% \rput{0}(-1cm, -1ex){\pnode{InstanceA}}
+% \DescribeMacro{\umlInstance}
+% This is the relation between a class and its metaclass. This is the
+% real ``is-a'' relation. It is the strongest kind of a generalization
+% relationship, even if it is not called generalization in standard
+% UML. Its symbol is an open arrow on a dashed line.
+%
+% The command is "\umlInstance".
+% \rput{0}(InstanceA|-1cm, 0){\pnode{InstanceB}}
+% \umlInstance{InstanceB}{InstanceA}
+%
+%
+%
+% \subsubsection{Aggregation}
+% \label{sec:useAggregation}
+%
+% \rput{0}(-1cm, -1ex){\pnode{AggregationA}}
+% \DescribeMacro{\umlAggregation}
+% The target class (the upper class in the left margin) is an aggregate; therefore, the source class is a
+% part. This is the weak form of aggregation, indicated by a hollow
+% diamond. The part may be contained in other aggregates. The
+% aggregation is optional, but not suppressible.
+% \rput{0}(AggregationA|-1cm, 0){\pnode{AggregationB}}
+% \umlAggregation{AggregationB}{AggregationA}
+%
+%
+% \subsubsection{Composition}
+% \label{sec:useComposition}
+%
+% \rput{0}(-1cm, -1ex){\pnode{CompositionA}}
+% \DescribeMacro{\umlComposition}
+% The strong form of aggregation, which requires that a part instance be
+% included in at most one composite at a time and that the composite
+% object has sole responsibility for the disposition of its parts. In
+% other words, a part can be part of at most one composite.
+% \rput{0}(CompositionA|-1cm, 0){\pnode{CompositionB}}
+% \umlComposition{CompositionB}{CompositionA}
+%
+% \subsubsection{Application}
+% \label{sec:useApplication}
+%
+% \rput{0}(-1cm, -1ex){\pnode{ApplicationA}}
+% \DescribeMacro{\umlApplication}
+% This is the relation between an abstraction (a schema taking
+% arguments) and the application (the schema with the arguments).
+% Application, and the entire argument idea, is not part of standard
+% UML. For example, see the section about Argument
+% \vpageref{sec:useArgument}.
+%
+% "\umlApplication" places a node "argument"\meta{reference} in addition
+% to the usual ones.
+% \rput{0}(ApplicationA|-1cm, 0){\pnode{ApplicationB}}
+% \umlApplication{ApplicationB}{ApplicationA}
+%
+% \subsection{Relations to Relations}
+% \label{sec:relationsTernary}
+% \label{sec:useToRelation}
+%
+% Some constructs can be viewed as relations between a classifier and a
+% relation. They are implemented as subcommands of
+% "\umlToRelation".\DescribeMacro\umlToRelation
+%
+% "\umlToRelation"\DescribeMacro{posMeetLine-} takes the named option
+% "posMeetLine", a real number between 0.0 and 1.0, which determines
+% where at the target relation the relation shall hit. Default is 0.5,
+% in the middle of the relation.
+%
+% The node "ToRelation"\meta{reference of this relation} is placed where
+% the lines meet.
+%
+% \subsubsection{AssociationClass}
+% \label{sec:useAssociationClass}
+% \label{sec:useAssociationSchema}
+%
+% \rput{0}(-2ex, -4ex){\pnode{AssociationClassA}}
+% \DescribeMacro{\umlAssociationClass}
+% \DescribeMacro{\umlAssociationSchema}
+% An association class is an association which also has attributes and
+% methods. Similarly, we can speak about an association schema.
+% Graphically, the schema is drawn as an usual schema with a dashed
+% connector to the association.
+% \rput{0}(AssociationClassA|-2ex, 0){\pnode{AssociationClassB}}
+% \umlAssociation{AssociationClassB}{AssociationClassA}
+% \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{%
+% AcAssociationClassB}{BcAssociationClassA}%
+% \lput{:R}(.5){\pnode{AssociationClassHeight}}%
+% \small{\umlSchema[pos=AssociationClassHeight, refpoint=r,
+% posDelta={-3ex, 0}, reference=AssCl]{Ass.Cl.}{}{}{}{}{}}
+% \umlAssociationClass{AssCl}{AssociationClassBAssociationClassA}
+%
+%
+% \subsubsection{ArgumentRelation}
+% \label{sec:useArgumentRelation}
+%
+% \rput{0}(-2ex, -1ex){\pnode{ArgumentA}}
+% \DescribeMacro{\umlArgument}
+% In this construct, we speak about three differenc classifiers:
+% \begin{itemize}
+% \item The \index{abstraction}\emph{abstraction} (Stack in figure \ref{fig:stack})
+% is the schema which can take argument.
+% \item The \index{application}\emph{application} (Stack of books) is
+% the abstraction after applying the argument. The application is
+% more special than the abstraction.
+% \item The \index{argument!and application}\emph{argument} (Book) is
+% what is filled in.
+% \end{itemize}
+%
+% Graphically, this is shown as two connectors: One solid with an arrow
+% from the application to the abstraction. It is made by
+% "\umlApplication". Then, a dotted from this line to the argument.
+% It is made by "\umlArgument".
+%
+% By default, the dotted line hits the solid one quite near the
+% application, at about 20\% of the main line segment (position 1.2).
+% \rput{0}(ArgumentA|-2ex, 0){\pnode{ArgumentB}}
+% \umlApplication{ArgumentB}{ArgumentA}
+% \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{%
+% AcArgumentB}{BcArgumentA}%
+% \lput{:R}(.5){\pnode{ArgumentHeight}}%
+% \small{\umlSchema[pos=ArgumentHeight, refpoint=r,
+% posDelta={-3ex, 0}, ]{Argument}{}{}{}{}{}}
+% \umlArgumentRelation{Argument}{ArgumentBArgumentA}
+%
+% \begin{figure}[htbp]
+% \begin{center}
+% \begin{footnotesize}
+% \umlDiagram[sizeX=10cm, sizeY=12cm,
+% ref=argumentDiagram,box=,border]{
+% \umlSchema[pos=\umlTopLeft{argumentDiagram}, posDelta={2ex, -2ex},
+% refpoint=tl]{Stack}{%Attributes
+% \umlAttribute[visibility=-, type=\emph{type}, default=null
+% ]{firstNode}
+% }{% Methods
+% \umlMethod[visibility=+]{push}{\emph{type} x}
+% \umlMethod[visibility=+, type=\emph{type}]{pop}{}
+% }{% Arguments
+% \umlArgument[type=Metaclass]{type}
+% }{% Constraints
+% \umlCompartmentline{S:Stack = S.push(x).pop()}
+% }{% Structure
+% \umlDiagram[ref=StackDiagramA, outerBorder,innerBorder=2mm,box=]{%
+% \umlClass[pos=\umlBottomLeft{StackDiagramA},
+% posDelta={1ex, 1ex}, box=,
+% ref=stackNode]{Node}{
+% \umlAttribute[visibility, type=\emph{type}]{data}}{}
+% \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em]{stackNode}{stackNode}{
+% \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}
+% \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}
+% }\cr% End of diagram
+% }% End of Stack
+% \umlSchema[refpoint=br, posY=\umlBottom{Stack},
+% posX=\umlRight{argumentDiagram},
+% posDelta={-2ex,0}]{
+% Book}{% Attributes
+% \umlAttribute[visibility, type=Integer]{pages}
+% }{% Methods
+% \umlMethod[visibility]{read}{}
+% }{% Arguments
+% }{% Constraints
+% }{% Structure
+% }% End of Book
+% \umlSchema[pos=\umlBottomLeft{argumentDiagram}, posDelta={2ex, 2ex}, refpoint=bl,
+% reference=StackofBooks]{Stack of books}{%Attributes
+% \umlAttribute[visibility=-, type=Book, default=null, ]{firstNode}
+% }{% Methods
+% \umlMethod[visibility=+]{push}{Book x}
+% \umlMethod[visibility=+, type=Book]{pop}{}
+% }{% Arguments
+% \umlCompartmentline{\emph{type} = Book}
+% }{% Constraints
+% }{% Structure
+% \umlDiagram[innerBorder=2mm,box=,innerBorder=2mm,outerBorder]{%
+% \umlClass[posDelta={1ex, 1ex}, ref=stackNode,box=]{Node}{
+% \umlAttribute[visibility, type=Book]{data}}{}
+% \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em]{stackNode}{stackNode}{
+% \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}
+% \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}
+% }\cr% End of diagram
+% }% End of Stack
+% \umlApplication[reference=ssb]{StackofBooks}{Stack}
+% \umlArgumentRelation{Book}{ssb}
+% \umlLabel[fraction=0.7]{Bookssb}{\emph{type}}
+% }% End of main diagram
+% \caption{Example of abstraction and application}
+% \label{fig:abstraction}\label{fig:stack}\label{fig:Stack}
+% \end{footnotesize}
+% \end{center}
+% \end{figure}
+%
+% \index{Stack!and abstraction}\index{Stack!of books}%
+% An example of this construct is shown in figure~\vref{fig:stack}. The
+% \LaTeX{} source is here:
+% \begin{verbatim}
+% \umlDiagram[sizeX=10cm, sizeY=12cm,
+% ref=argumentDiagram,box=,border]{
+% \umlSchema[pos=\umlTopLeft{argumentDiagram}, posDelta={2ex, -2ex},
+% refpoint=tl]{Stack}{%Attributes
+% \umlAttribute[visibility=-, type=\emph{type}, default=null
+% ]{firstNode}%
+% }{% Methods
+% \umlMethod[visibility=+]{push}{\emph{type} x}
+% \umlMethod[visibility=+, type=\emph{type}]{pop}{}
+% }{% Arguments
+% \umlArgument[type=Metaclass]{type}%
+% }{% Constraints
+% \umlCompartmentline{S:Stack = S.push(x).pop()}
+% }{% Structure
+% \umlDiagram[ref=StackDiagramA, outerBorder,innerBorder=2mm,box=]{%
+% \umlClass[pos=\umlBottomLeft{StackDiagramA},
+% posDelta={1ex, 1ex}, box=,
+% ref=stackNode]{Node}{%
+% \umlAttribute[visibility, type=\emph{type}]{data}}{}%
+% \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em]{stackNode}{stackNode}{%
+% \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}%
+% \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}%
+% }\cr% End of diagram
+% }% End of Stack
+% \umlSchema[refpoint=br, posY=\umlBottom{Stack},
+% posX=\umlRight{argumentDiagram},
+% posDelta={-2ex,0}]{%
+% Book}{% Attributes
+% \umlAttribute[visibility, type=Integer]{pages}
+% }{% Methods
+% \umlMethod[visibility]{read}{}
+% }{% Arguments
+% }{% Constraints
+% }{% Structure
+% }% End of Book
+% \umlSchema[pos=\umlBottomLeft{argumentDiagram}, posDelta={2ex, 2ex}, refpoint=bl,
+% reference=StackofBooks]{Stack of books}{%Attributes
+% \umlAttribute[visibility=-, type=Book, default=null, ]{firstNode}
+% }{% Methods
+% \umlMethod[visibility=+]{push}{Book x}
+% \umlMethod[visibility=+, type=Book]{pop}{}
+% }{% Arguments
+% \umlCompartmentline{\emph{type} = Book}
+% }{% Constraints
+% }{% Structure
+% \umlDiagram[innerBorder=2mm,box=,innerBorder=2mm,outerBorder]{%
+% \umlClass[posDelta={1ex, 1ex}, ref=stackNode,box=]{Node}{
+% \umlAttribute[visibility, type=Book]{data}}{}%
+% \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em]{stackNode}{stackNode}{%
+% \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}%
+% \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}%
+% }\cr% End of diagram
+% }% End of Stack
+% \umlApplication[reference=ssb]{StackofBooks}{Stack}
+% \umlArgumentRelation{Book}{ssb}
+% \umlLabel[fraction=0.7]{Bookssb}{\emph{type}}
+% }% End of main diagram
+% \end{verbatim}
+%
+%
+% \section{Package}
+% \label{sec:usePackage}
+%
+% A package is a collection of classes, relations and other elements.
+% It is simply a grouping of different elements.
+%
+% The graphic symbol consists of two rectangles above each other: The
+% upper one is small and contains the name. The lower one is typically
+% large and contains the elements. The lower rectangle typically
+% contains an "\umlDiagram".
+%
+% In uml.sty, packages are drawn by the command "\umlPackage["\meta{named
+% options}"]{"\meta{name}"}{"\meta{stuff}"}". "\umlPackage" is an
+% "\umlBox", and inherits all its named options.
+%
+%
+%
+% \subsection{Example}
+%
+% In figure \vref{fig:usePackage}, the package ``Package'' contains four
+% classes, four usual associations and one subclass relation.
+%
+% \begin{figure}[htbp]
+% \begin{center}
+% \umlPackage[box=,
+% subof=subof, stereotype=stereo, importedFrom=From,
+% comment=comment]{Package}{%
+% \umlDiagram[sizeX=7cm, sizeY=5cm,box=,ref=pack]{
+% \umlClass[pos=\umlBottomLeft{pack}, posDelta={2ex, 2ex}, refpoint=bl]{Book}{}{}
+% \umlClass[pos=\umlTopLeft{pack}, posDelta={2ex, -2ex}, refpoint=tl]{House}{}{}
+% \umlClass[pos=\umlTopRight{pack}, posDelta={-2ex,-2ex}, refpoint=tr]{Person}{}{}
+% \umlClass[pos=\umlBottomRight{pack}, posDelta={-2ex, 2ex}, refpoint=br]{Author}{}{}
+% \umlAssociation[]{Book}{House}
+% \umlLabelB{BookHouse}{is in}
+% \umlAssociation[]{Book}{Person}
+% \umlLabelA{BookPerson}{reads}
+% \umlSubclass{Author}{Person}
+% \umlAssociation{Book}{Author}
+% \umlLabelA[height=.5ex]{BookAuthor}{written}
+% \umlAssociation{House}{Person}
+% \umlLabelA{HousePerson}{lives in}
+% }% End of diagram
+% }% End of package
+% \caption{Example of package}
+% \label{fig:usePackages}
+% \label{fig:usePackage}
+% \end{center}
+% \end{figure}
+%
+%
+% The source:
+% \begin{small}
+% \begin{verbatim}
+% \umlPackage[border=,box=,
+% subof=subof, stereotype=stereo, importedFrom=From,
+% comment=comment]{Package}{%
+% \umlDiagram[sizeX=7cm, sizeY=5cm,box=,ref=pack]{
+% \umlClass[pos=\umlBottomLeft{pack}, posDelta={2ex, 2ex},
+% refpoint=bl]{Book}{}{}
+% \umlClass[pos=\umlTopLeft{pack}, posDelta={2ex, -2ex},
+% refpoint=tl]{House}{}{}
+% \umlClass[pos=\umlTopRight{pack}, posDelta={-2ex,-2ex},
+% refpoint=tr]{Person}{}{}
+% \umlClass[pos=\umlBottomRight{pack}, posDelta={-2ex, 2ex},
+% refpoint=br]{Author}{}{}
+% \umlAssociation[]{Book}{House}
+% \umlLabelB{BookHouse}{is in}
+% \umlAssociation[]{Book}{Person}
+% \umlLabelA{BookPerson}{reads}
+% \umlSubclass{Author}{Person}
+% \umlAssociation{Book}{Author}
+% \umlLabelA[height=.5ex]{BookAuthor}{written}
+% \umlAssociation{House}{Person}
+% \umlLabelA{HousePerson}{lives in}
+% }% End of diagram
+% }% End of package
+% \end{verbatim}
+% \end{small}
+%
+%
+% \subsection{Connecting packages}
+%
+%
+% Two packages can be connected in the same way, and using the same
+% function, as two classes. Symbols, labels etc.\ work the same way,
+% and you can even connect a package and a class. Not all these
+% possibilities make sense semantically.
+%
+% However, due to the geometrical shape of packages, there is some
+% problems with the connections. I have found no good solution to this.
+% Now, default, relations is connected to an imaginary rectangle
+% covering the entire package. The problem occur if the node hits the
+% package in the upper right corner, where the package does not fill out
+% the rectangle.
+%
+% To solve this problem preliminarily, two more nodes are placed: The
+% upper rectangle is given the name "small"\meta{reference}, and the
+% lower "big"\meta{reference}. You can make the connector connect to
+% one of these if desired.
+%
+% \section{Colors}
+% \label{sec:useColors}
+%
+% The metamodel for this is in figure \vref{fig:useApproachColors}.
+%
+% \subsection{Colorset}
+% \label{sec:useColorset}
+% \label{sec:useColorsColorset}
+%
+%
+% In uml.sty, there is always an \emph{color set}\index{color set} in
+% action. There are currently six defined color sets:
+% \begin{description}
+% \item[ColorsDefault] \index{ColorsDefault}uses normal black and white
+% colors.
+% \item[ColorsGray] \index{ColrosGray}uses more gray colors. Typically
+% used for constructs which not is to be emphazised.
+% \item[ColorsImport] \index{ColorsImport}uses blue colors. Typically
+% used for constructs which are defined in another document, and only
+% are imported here.
+% \item[ColorsArgument] \index{ColorsArgument}uses green colors.
+% Typically used for constructs given as arguments.
+% \item[ColorsRed] \index{ColorsRed}uses red colors. Use it as you
+% like.
+% \item[ColorsSub] \index{ColorsSub} is intended to be used on material
+% inherited from other material.
+% \end{description}
+% Demonstrations of this color sets is in figure
+% \ref{fig:useApproachColors}.
+%
+% If you want to make your own color set, you may say something like
+%
+% \noindent{\newcommand\myColorset{%
+% \umlColorset{%
+% \newrgbcolor{umlColor}{0 .4 .4}%
+% \newrgbcolor{umlLinecolor}{0.5 1 1}%
+% \newrgbcolor{umlFillcolor}{.8 1 1}%
+% \newrgbcolor{umlClassifierFillcolor}{.85 1 1}%
+% \newrgbcolor{umlDiagramFillcolor}{.95 1 1}%
+% \newrgbcolor{umlRelationColor}{0 1 1}%
+% }%
+% }%
+% \footnotesize%
+% \umlClass[colorset=\myColorset,
+% pos={-1em, -3em},posDelta={-1ex,0},refpoint=tr,
+% ]{Class}{\umlAttribute[default=myColorset]{Color set}}{}}%
+% \begin{verbatim}
+% \newcommand\myColorset{%
+% \umlColorsSet{%
+% \newrgbcolor{umlColor}{0 .4 .4}%
+% \newrgbcolor{umlLinecolor}{0.5 1 1}%
+% \newrgbcolor{umlFillcolor}{.8 1 1}%
+% \newrgbcolor{umlClassifierFillcolor}{.85 1 1}%
+% \newrgbcolor{umlDiagramFillcolor}{.95 1 1}%
+% \newrgbcolor{umlRelationColor}{0 1 1}%
+% }%
+% }
+% \end{verbatim}
+% You may want to use the commands
+% "\newrgbcolor{"\meta{name}"}{"\meta{red} \meta{green} \meta{blue}"}",
+% "\newgray{"\meta{name}"}{"\meta{grayness}"}",
+% "\newhsbcolor{"\meta{name}"}{"\meta{hue} \meta{saturation}
+% \meta{brightness}"}" or
+% "\newcmykcolor{"\meta{name}"}{"\meta{cyan} \meta{magenta}
+% \meta{yellow} \meta{black}"}", where
+% all the parameters except \meta{name} are real numbers between 0 and
+% 1.
+%
+% \subsection{Using the color sets}
+% \label{sec:useColorsets}
+%
+% You can use the color sets in different ways:
+% \begin{itemize}
+% \item You \DescribeMacro{\umlColors\dots}can use the command directly (e.g., say
+% "\umlColorsDefault"), and the color set will take effect on the
+% following constructs.
+% \item You can use the environment \DescribeEnv{umlColorset}, which
+% takes the color set as argument
+% (e.g. "\begin{umlColors}{\umlColorsDefault}").
+% \item In\DescribeMacro{colorSet-} drawables, (i.e., most constructs)
+% you can use the named option "colorSet" (e.g.,
+% "\umlClass[colorSet=\umlColorsDefault,...").
+% \item Some color sets are also implied in other named options
+% ("import=") and otherwise.
+% \end{itemize}
+%
+% Colors are primarily handled by Drawable. However, due to some
+% technical obscurities in \TeX{}, the implementation is done in the
+% known subclasses ("\umlElement", "\umlCompartment" and
+% "\umlCompartmentline").
+%
+% Technically, the commands only define another command
+% ("\umlColorsAdjust"), which is called in every construct. The value
+% of "\umlColorsAdjust" \emph{til enhver tid} is the color set in
+% action. See \ref{sec:impColorset} for more details on this.
+%
+%
+% \section{Positions}
+% \label{sec:usePositions}
+% \label{sec:useTopLeft}
+%
+% The metamodel for this is in figure \vref{fig:useApproachPositions}.
+%
+% In PSTricks, a Node can serve as a Coordinate. There exist other
+% types of coordinates too. Box.pos uses "\rput", and is a coordinate.
+% Box.posDelta should be a relative coordinate (a cartesian number
+% pair), but could really be any coordinate.
+%
+% Relation.NodeA and Relation.NodeB, however, uses "\ncdiag", and must
+% be Nodes. This is confusing. It is also confusing that coordinates
+% in PSTricks are written in parenthesis, while nodes are not. In
+% uml.sty, no parenthesis are used.
+%
+% This imply that relation only can be between Nodes, and not between
+% other coordinates. But sometimes, we want to use the power of other
+% coordinate kinds while placing relations.
+%
+%
+% \subsection{PlaceNode}
+% \label{sec:usePlaceNode}
+%
+% To do that, use the command
+% "\umlPlaceNode", which has a lot of
+% power, and places a node. Note that "\umlPlaceNode" only places a new
+% node (named after its third argument); it is no node itself.
+%
+% One may want to do something like
+% \begin{verbatim}
+% \umlPlaceNode[top=-2em,rightside]{A}{Aright}
+% \umlPlaceNode[top=-2em,leftside]{B}{Bleft}
+% \umlSubclass[ref=AB]{Aright}{Bleft}
+% \end{verbatim}
+%
+% Why should it not be legal to say something like
+% \begin{verbatim}
+% \umlSubclass[top=-2em,rightsideA, leftsideB]{A}{B}
+% \end{verbatim}
+% ?
+%
+% It is possible to implement the latter syntax, but that would require
+% a great amount of new nodes. It is already a problem that uml.sty
+% relations uses so many nodes, so I have chosen to keep the first
+% syntax. After all, I do not expect "\umlPlaceNode" to be used often.
+%
+% "\umlPlacenode"\DescribeMacro{\umlPlaceNode} takes three arguments:
+% Its named options, a node and a name to be used as a name of the new
+% node.
+%
+% It takes several named options:
+% \begin{description}
+% \item["leftside", "rightside", "top" and "bottom"]
+% \DescribeMacro{leftside-} \DescribeMacro{rightside-}
+% \DescribeMacro{top-} \DescribeMacro{bottom-} makes "\umlPlaceNode"
+% start at one side of the node. They all can take one length as
+% argument. One horizontal and one vertical of these can be combined.
+% \item["left", "right", "up" and "down"] \DescribeMacro{left-}
+% \DescribeMacro{right-} \DescribeMacro{up-} \DescribeMacro{down-}
+% These makes "\umlPlaceNode" go in one of the four directions.
+% Several (even of the same type) can be combined. Legal values are
+% lengths.
+% \item["angle", "angleX" and "angleY"] \DescribeMacro{angle-}angle from the node to start
+% with.
+% \item["offset", "offsetX" and "offsetY"] \DescribeMacro{offset-}
+% \item["nodesep", "nodesepX" and "nodesepY"] \DescribeMacro{nodesep-}separation from the node.
+% \end{description}
+%
+% \subsection{Coordinates}
+% \label{sec:useSyntaxCoordinates}
+%
+% \index{coordinates}Legal \emph{coordinates} are:
+% \begin{description}
+% \item \textbf{\meta{x}"," \meta{y}} The usual Cartesian coordinate. E.g.,
+% "3,4".
+% \item \textbf{\meta{r}";"\meta{a}} Polar coordinate, with radius \meta{r} and
+% angle \meta{a}. The default unit for \meta{r} is the PSTricks
+% "unit". E.g., "3;110".
+% \item \index{node!as coordinate}\textbf{\meta{node}} The center of
+% \meta{node}. \meta{node} can be any valid PSTricks node. Various
+% commands in "uml.sty" places a number of nodes, which can be used as
+% reference points.
+% \begin{itemize}
+% \item Most constructs can be given a node name using the
+% "reference=" named option.
+% \item For classes and schemas, default node name (when "reference="
+% is not used) is the Class name or Schema name itself.
+% \item Relations place nodes, see documentation in \vref{sec:useRelation}.
+% \end{itemize}
+% \item \textbf{"["\meta{par}"]"\meta{node}} The position relative to
+% \meta{node} determined using the "angle", "nodesep" and "offset"
+% parameters. E.g., "([angle=90]Car)".
+% \item \textbf{\meta{coor1}"|"\meta{coor2}} The $x$ coordinate from
+% \meta{coor1} and the $y$ coordinate from \meta{coor2}. \meta{coor1}
+% and \meta{coor2} can be any other coordinates. For example,
+% "(Car|1in;30)". However, you may instead want to use named options
+% such as "posX" and "deltaPosY" to achieve this.
+% \item[Position commands] take a node as parameter and return an
+% coordinate. The different position commands are shown below. E.g.,
+% "\umlClass[pos=\umlBottomRight{Car}]{Wheel}{}{}".
+% \end{description}
+%
+% Note that you should usually omit the parentheses in "uml.sty". This
+% is due to the fact that the "("\meta{coor1}"|"\meta{coor2}")"
+% construct requires two parts without parentheses.
+%
+% Also note that coordinate pairs containing parentheses as values to
+% named options my cause problems. You have to enclose them in braces.
+% E.g., "\umlClass[pos={3,3}]{Car}{}{}".
+%
+% \subsubsection{Coordinate commands}
+%
+% This is kept for backward compatibility. However, only the first
+% group of Coordinate commands should be useful now. The others are
+% deprecated.
+%
+% A coordinate command takes an node (and possibly other things) as
+% argument, and return a coordinate.
+%
+% Several groups of coordinate commands exist:
+%
+%
+% \DescribeMacro{\umlTop}
+% \DescribeMacro{\umlRight}
+% \DescribeMacro{\umlBottom}
+% \DescribeMacro{\umlLeft}
+% \DescribeMacro{\umlTopRight}
+% \DescribeMacro{\umlBottomRight}
+% \DescribeMacro{\umlBottomLeft}
+% \DescribeMacro{\umlTopLeft}
+% \begin{description}
+% \item[Simple commands] The
+% commands "\umlTop", "\umlRight", "\umlBottom",
+% "\umlLeft", "\umlTopRight", "\umlBottomRight", "\umlBottomLeft" and
+% "\umlTopLeft" all take one argument: the node
+% \DescribeMacro{\umlTopSep}
+% \DescribeMacro{\umlRightSep}
+% \DescribeMacro{\umlBottomSep}
+% \DescribeMacro{\umlLeftSep}
+% \DescribeMacro{\umlTopRightSep}
+% \DescribeMacro{\umlBottomRightSep}
+% \DescribeMacro{\umlBottomLeftSep}
+% \DescribeMacro{\umlTopLeftSep}
+% \DescribeMacro{\umlNodeSep}
+% \item[Commands with separation] The commands "\umlTopSep",
+% "\umlRightSep", "\umlBottomSep", "\umlLeftSep", "\umlTopRightSep",
+% "\umlBottomRightSep", "\umlBottomLeftSep" and "\umlTopLeftSep"
+% returns a position "\umlNodeSep" from the position of the argument.
+% "\umlNodeSep" is default 1em, but may be changed by the user.
+% \DescribeMacro{\umlTopOpt}
+% \DescribeMacro{\umlRightOpt}
+% \DescribeMacro{\umlBottomOpt}
+% \DescribeMacro{\umlLeftOpt}
+% \DescribeMacro{\umlTopRightOpt}
+% \DescribeMacro{\umlBottomRightOpt}
+% \DescribeMacro{\umlBottomLeftOpt}
+% \DescribeMacro{\umlTopLeftOpt}
+% \item[Commands taking options] The commands "\umlTopOpt", "\umlRightOpt", "\umlBottomOpt",
+% "\umlLeftOpt", "\umlTopRightOpt", "\umlBottomRightOpt", "\umlBottomLeftOpt" and
+% "\umlTopLeftOpt" takes two arguments, both mandatory: a
+% comma-separated list of \meta{key}"="\meta{value} pairs, where
+% \meta{key} can be "angle" (value: number), "nodesep" (value: length)
+% or "offset" (value: length). The second argument is the node
+% \DescribeMacro{\umlTopSepOpt}
+% \DescribeMacro{\umlRightSepOpt}
+% \DescribeMacro{\umlBottomSepOpt}
+% \DescribeMacro{\umlLeftSepOpt}
+% \DescribeMacro{\umlTopRightSepOpt}
+% \DescribeMacro{\umlBottomRightSepOpt}
+% \DescribeMacro{\umlBottomLeftSepOpt}
+% \DescribeMacro{\umlTopLeftSepOpt}
+% \DescribeMacro{\umlNodeSepOpt}
+% \item[Commands with separation taking options] The commands "\umlTopSepOpt",
+% "\umlRightSepOpt", "\umlBottomSepOpt", "\umlLeftSepOpt", "\umlTopRightSepOpt",
+% "\umlBottomRightSepOpt", "\umlBottomLeftSepOpt" and "\umlTopLeftSepOpt"
+% takes two arguments and do just what you expect them to.
+% \end{description}
+%
+% \label{useSchemaSourceEnd}
+%
+% \section{A large example (Abstract Data Structures)}
+%
+% \index{Abstract Data Structure}Figure \vref{fig:useSchema}
+% is a more large model of some standard ADTs. It is an example of both
+% "\umlSchema" and some relations. It also is an example of the Schema
+% construct itself, but is primarily intended to be a "uml.sty" example,
+% and is not intended to be a good ADT model.
+%
+% \begin{figure}[htbp]
+% \centering
+% \footnotesize
+% \umlADTExample
+% \caption{ADT model. Bad model, good uml.sty example.}\label{fig:ADTExample}
+% \label{fig:useSchema}
+% \end{figure}
+%
+% \paragraph{The command}
+% Technically, the following source defines a command
+% "\umlADTExample", which is used in figure \vref{fig:ADTExample}.
+%\begin{lstlisting}
+% \providecommand\umlADTExample{
+%\end{lstlisting}
+%
+% \paragraph{The diagram}
+% The diagram is a box which uses room. It is 15~cm wide and 16~cm
+% high, and has the reference "ADTdiagram". It has a grayness of
+% 92~\%. If we did not supply a grayness, it would get the
+% "umlDiagramFillcolor" of the current color set.
+%
+% Note that, technically, it is not necessary to have the semantical
+% contents of the diagram inside its \LaTeX{} argument.
+%\begin{lstlisting}
+% \umlDiagram[box=,sizeX=15cm, sizeY=16cm,ref=ADTdiagram,
+% grayness=0.92]{}% End of diagram
+%\end{lstlisting}
+%
+% \paragraph{ADT}
+% The schema (or class) ADT is located in the top right corner of
+% the diagram (which had reference "ADTdiagram". More accurately, its
+% top right ("tr") corner is placed half an unit left and half an unit
+% down relative the the top right corner.
+%\begin{lstlisting}
+% \umlSchema[pos=\umlTopRight{ADTdiagram}, posDelta={-.5,-.5},
+% refpoint=tr]{ADT}{% Attributes
+% \umlAttribute[visibility,type=String]{name}}{}{}{}{}
+%\end{lstlisting}
+%
+% \paragraph{ADT-example}
+% The schema ADT-example is located in the upper left corner of the
+% diagram.
+% It is an abstract schema, giving italics name in the diagram.
+% Because the class name contains a dash, a reference ("ADTexample")
+% must be supplied.
+%
+% This schema also takes an \emph{argument} (type). This is not the
+% place to fully explain the semantics of arguments, but \emph{type} can
+% be given any Metaclass as value.
+
+% Everywhere in the schemas an argument is
+% used, {\umlColorsArgument\umlColorsAdjust this color} is used.
+% Here, the code is getting a bit \emph{clogged up} with color
+% code. If you read this the first time, please ignore the commands
+% starting with "\umlColor".
+%\begin{lstlisting}
+% \umlSchema[pos=\umlTopLeft{ADTdiagram}, posDelta={.5,-1},
+% refpoint=lt, abstract,
+% ref=ADTexample]{ADT-example}{%
+% \umlAttribute[visibility=-,
+% type=\emph{\umlColorsArgument\umlColorsAdjust type},default=null]{%
+% firstNode}
+% }{ %Methods
+% }{ %Arguments
+% \umlArgument[type=Metaclass]{type}
+% }{ %Constraints
+% }{ %Structure
+% \umlDiagram[box=,innerBorder=2mm,outerBorder]{%
+% \umlClass[pos={.5,.5}, ref=adtNode,box=]{Node}{%
+% \umlAttribute[visibility,
+% type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+% data}}{}%
+% \umlAssociation[angleA=20, angleB=-20,
+% arm=1em, arm=1em]{adtNode}{adtNode}%
+% }\cr% End of Diagram
+% }% End of ADT-example
+%\end{lstlisting}
+%
+% Then the isInstance relation between ADT-example and ADT.
+% This is shown as a dashed arrown with an arrowhead towards ADT.
+%\begin{lstlisting}
+% \umlInstance{ADTexample}{ADT}%
+%\end{lstlisting}
+%
+% \paragraph{Graph}
+% Graph is a subclass (subschema) of ADT-example. Thus, it is
+% implicitly inheriting the attribute firstNode, the argument
+% \emph{type}, the structure Node (with the relation), and the
+% isInstance-relationwhip to ADT.
+%
+% What is added, is four well-known procedures, the *--*-specification
+% of the Node--Node-relation, and the association class Edge.
+%
+% What is inherited from ADT-example (Node and the
+% Node--Node-relation) is drawn with the "\umlColorsSub" color set.
+% Note that the relation is brown, while the relation multiplicities is black.
+%
+% All the nodes are given references, in order to separate them from each
+% other (they have equal class names). However, it might work to let "Node"
+% mean the last defined Node all the time.
+%\begin{lstlisting}
+% \umlSchema[pos=\umlRight{ADTexample}, posDelta={3,-1},
+% refpoint=tl, ]{Graph}{% Attributes
+% }{% Methods
+% \umlMethod[visibility,]{%
+% insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% \umlMethod[visibility,
+% type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+% dijkstra}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% \umlMethod[visibility, type=boolean]{%
+% insertEdge}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% \umlMethod[visibility, ]{%
+% delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% }{% Arguments
+% }{% Constraints
+% }{% Structure
+% \umlDiagram[box=,innerBorder=2mm, outerBorder,
+% sizeX=11em,sizeY=3.5em,ref=GraphDiagram]{%
+% \begin{umlColors}{\umlColorsSub}
+% \umlClass[pos=\umlBottomLeft{GraphDiagram},
+% posDelta={1,1}, ref=graphNode]{Node}{}{}%
+% \umlAssociation[angleA=20, angleB=-20, armA=1em, armB=1em
+% ]{graphNode}{graphNode}%
+% \end{umlColors}
+% \umlLabelA[height=0mm,offset=1ex]{graphNodegraphNode}{*}%
+% \umlLabelB[height=0mm,offset=1ex,refpoint=t
+% ]{graphNodegraphNode}{*}%
+% \umlSymbol[fraction=.5]{graphNodegraphNode}{\pnode{gngn}}
+% \umlClass[pos=gngn, posDelta={2,0},
+% ref=graphEdge, refpoint=l]{Edge}{%
+% \umlAttribute[type=real]{cost}}{}%
+% \umlAssociationClass[]{graphEdge}{gngn}%
+% }\cr% End of diagram
+% }% End of Graph
+%\end{lstlisting}
+% Graph is an subschema of ADT-example.
+%\begin{lstlisting}
+% \umlSubclass{Graph}{ADTexample}
+%\end{lstlisting}
+%
+% \paragraph{Search Tree}
+% This schema is vertically positioned relative to ADT-example,
+% and horizontally below Graph.
+%
+% It has four well-known methods. It has two arguments (in addition
+% to \emph{type}); \emph{arity} is an integer which default to 2, giving
+% a binary tree. \emph{sort} is a function itself taking as arguments
+% two instances of \emph{type} and returning true or false. It defaults
+% to ``greater than''.
+%
+%\begin{lstlisting}
+% \umlSchema[posX=\umlLeft{ADTexample}, posDelta={3em,-1em},
+% posY=\umlBottom{Graph},
+% refpoint=tl, ref=searchTree]{Search Tree}{% Attributes
+% }{% Methods
+% \umlMethod[visibility,]{%
+% insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% \umlMethod[visibility,
+% type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+% search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% \umlMethod[visibility, type=boolean]{%
+% search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% \umlMethod[visibility, ]{%
+% delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% }{% Arguments
+% \umlArgument[type=Integer, initialValue=2]{arity}
+% \umlArgument[type={${\umlColorsArgument\umlColorsAdjust type}
+% \times {\umlColorsArgument\umlColorsAdjust type}\rightarrow$
+% boolean}, default=>]{sort}
+% }{% Constraints
+% }{% Structure
+% \umlDiagram[box=, sizeX=14em, sizeY=4em,
+% innerBorder=2mm, outerBorder]{%
+% \begin{umlColors}{\umlColorsSub}
+% \umlClass[pos={.5, .5}, ref=treeNode]{Node}{}{}%
+% \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
+% ]{treeNode}{treeNode}%
+% \end{umlColors}
+% \umlLabelA[height=1mm, offset=4mm,refpoint=l
+% ]{treeNodetreeNode}{%
+% \emph{\umlColorsArgument\umlColorsAdjust arity}}%
+% \umlLabelB[refpoint=tl,height=-1mm, offset=4mm,
+% ]{treeNodetreeNode}{1}%
+% }\cr% End of diagram
+% }%
+% \umlSubclass{searchTree}{ADTexample}%
+%\end{lstlisting}
+% \paragraph{List}
+% There is not much new here.
+%\begin{lstlisting}
+% \umlSchema[pos=\umlBottomLeft{searchTree},posDelta={0,-1},
+% refpoint=lt]{List}{%Attributes
+% }{% Methods
+% }{% Arguments
+% }{% Constraints
+% }{% Structure
+% \umlDiagram[box=, sizeX=6em, sizeY=4em,
+% innerBorder=2mm, outerBorder]{%
+% \begin{umlColors}{\umlColorsSub}
+% \umlClass[pos={.5, .5}, ref=listNode]{Node}{}{}%
+% \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
+% ]{listNode}{listNode}%
+% \end{umlColors}
+% \umlLabelA[height=1mm, offset=5mm, refpoint=l
+% ]{listNodelistNode}{1}%
+% \umlLabelB[refpoint=tl, height=-1mm,offset=5mm
+% ]{listNodelistNode}{1}%
+% }\cr% End of diagram
+% }% End of Schema List
+%\end{lstlisting}
+% Before making the actual subclass relation from List to ADT-example,
+% we place node to point to and from.
+% This is in order to better control the placement of the end
+% points. (Really, it is to demonstrate "\umlPlaceNode" :-)
+%
+% The first one is called "Listtl", and is placed 1~em below the top
+% left corner of List.
+% The second is named "ADTexamplebl", and placed
+% 2~em to the right of the bottom left corner of ADT-example.
+%
+% The subclass relation itself has an arm A of 1~em sticking out from List.
+%\begin{lstlisting}
+% \umlPlaceNode[leftside, top, down=1em]{List}{Listtl}
+% \umlPlaceNode[leftside,right=2em,bottom]{ADTexample}{ADTexamplebl}
+% \umlSubclass[armA=1.4142em, armAngleA=135]{Listtl}{ADTexamplebl}%
+%\end{lstlisting}
+% \paragraph{Queue}
+% A Queue inherits pretty much from List, ADT-example and ADT.
+% Only two methods and one constraint (in natural language) is added explicitly.
+%\begin{lstlisting}
+% \umlSchema[pos=\umlTopRight{List},posDelta={1em,-2em},
+% refpoint=tl]{Queue}{% Attributes
+% }{\umlMethod[visibility]{%
+% enqueue}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+% dequeue}{}}{%Arguments
+% }{%Constraints
+% \umlCompartmentline{First come, first served.}
+% }{% Structure
+% }% End of Queue
+% \umlPlaceNode[rightside, top, down=1em]{List}{Listtr}
+% \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Queue}{Listtr}%
+%\end{lstlisting}
+% \paragraph{Stack}
+% Remember, Stack is still a subclass of List and of ADT-example, and an
+% instance of ADT. Thus, Stack really resembles figure \vref{fig:Stack}
+% closely.
+%\begin{lstlisting}
+% \umlSchema[pos=\umlTopRight{Queue},posDelta={\umlNodeSep,0em},
+% refpoint=tl]{Stack}{%Attributes
+% }{% Methods
+% \umlMethod[visibility]{
+% push}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+% \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+% pop}{}
+% }{% Arguments
+% }{% Constraints
+% \umlCompartmentline{S:Stack = S.push(x).pop()}
+% }{% Structure
+% }% End of Stack
+% \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Stack}{Listtr}%
+%}
+%\end{lstlisting}
+%
+%
+% \section{Typesetting the implementation}
+%
+% I want the line numbers and the macro names to be right-aligned
+% together, close to the text. It is important to make a virtual
+% vertical line in order to make some order in the pages.
+
+% However, "doc.sty" contains a spurious space (in "\m@cro@", where
+% "\PrintMacroName" and where "\PrintEnvName" are used). This space
+% shows up after the macro name. To overcome this, I make a length
+% "\minusSpace" of length one negative space in the right font, and make
+% a "\hspace" of this length.
+%
+% \setlength\MacroIndent{0pt}
+% \newlength\minusSpace
+% \settowidth\minusSpace{\rmfamily\scriptsize \ }
+% \setlength\minusSpace{-\minusSpace}
+% \def\PrintMacroName#1{\strut \MacroFont \string #1\hspace*\minusSpace}
+% \def\PrintDescribeMacro#1{\strut \MacroFont \string #1\hspace*\minusSpace}
+% \def\PrintDescribeEnv#1{\strut \MacroFont #1\hspace*\minusSpace}
+% \def\PrintEnvName#1{\strut \MacroFont #1\hspace*\minusSpace}
+% \def\packageName#1{\texttt{#1}}
+%
+% \subsection{The documentation driver file}
+%
+% The next bit of code contains the documentation driver file for
+% \TeX{}, i.e., the file that will produce the documentation you are
+% currently reading. It will be extracted from this file by the
+% \texttt{docstrip} program. Since it is the first code in the file
+% one can alternatively process this file directly with \LaTeXe{} to
+% obtain the documentation.
+%
+% \setcounter{CodelineNo}{0}
+%<*package>
+% \section{Introductory code}\label{sec:implementationIntroduction}
+% \subsection{Identification}\label{sec:impIdentification}
+
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{uml}
+% \end{macrocode}
+
+% \subsection{Processing of options}\label{sec:impOptions}
+
+% \subsubsection{debug}
+
+% \begin{macro}{debug}
+% The option "debug" is used if you want some extra lines shown.
+% Intended for debugging of this package.
+% \begin{macrocode}
+\DeclareOption{debug}{
+ \def\umlDebugLineStyle{dashed}
+ \def\umlDebugLength{1pt}
+ }
+\DeclareOption{nodebug}{
+ \def\umlDebugLineStyle{none}
+ \def\umlDebugLength{0pt}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlDebugLinestyle}
+% A linestyle normally none. The linestyle of invisible leading lines.
+% \begin{macrocode}
+\def\umlDebugLinestyle{none}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlDebugLength}
+% A length normally 0pt. E.g., the breadth of invisible lines.
+% \begin{macrocode}
+\def\umlDebugLength{0pt}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{index}
+% \begin{macro}{index}
+% The option "index" makes all Stretchboxes and Features (all
+% Drawables with names make an index entry of the form
+% \meta{name}!\meta{type}.
+% \begin{macrocode}
+\newcommand\umlIndexOn{\renewcommand\umlIndex[2]{\index{##1!##2}}}
+\newcommand\umlIndexOff{\renewcommand\umlIndex[2]{}}
+\DeclareOption{index}{\umlIndexOn}
+\DeclareOption{noindex}{\umlIndexOff}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlIndex}
+% Takes two arguments: Type and Name.
+% \begin{macrocode}
+\newcommand\umlIndex[2]{\index{#1!#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Processing the options}
+% \noindent{}Default is the "index"\index{nodebug option} option.
+% \begin{macrocode}
+\ExecuteOptions{nodebug}
+\ProcessOptions
+% \end{macrocode}
+%
+% \subsection{Using other packages}\label{sec:impUsing}
+%
+% \packageName{uml.sty} relies heavily on the \LaTeX{} packages
+% \index{PSTricks}
+% \packageName{pstricks} and \packageName{pst-node} [PSTricks].
+% Most of the graphics is displayed using \packageName{pstricks}.
+% \begin{macrocode}
+\RequirePackage{pstricks}
+\RequirePackage{pst-node}
+% \end{macrocode}
+
+% \noindent\packageName{xkeyval} [xKeyval] is the package which handles
+% \index{keyval}\index{xkeyval} Keys can be set as usual for PStricks related
+% package with "\psset[uml]{...}", where the family name "uml" is optional.
+% named options (like \verb+[name=Name, reference=Ref]+).
+% \begin{macrocode}
+\RequirePackage{pst-xkey}
+\pst@addfams{uml,umlAE,umlPlaceNode}
+% \end{macrocode}
+
+% \noindent\packageName{relsize} [Relsize] handles relative sizes, with
+% macros like "\Larger" and "\relsize{-1}".
+% \index{relsize}
+% \begin{macrocode}
+\RequirePackage{relsize}
+% \end{macrocode}
+
+% We also need the \packageName{color} package, which is already loaded by the
+% \verb+pstricks+ package.% \index{color}
+
+% \section{General syntax}\label{sec:impSyntax}
+
+% Users used to \LaTeX{} and PSTricks will recognize a lot of syntax.
+%
+% An important implementation point is that any contents (which can
+% affect variables) is typeset after all the variables is used. If it
+% is not,
+% the different boxes inside each other get intertwined with strange
+% results.
+% "\umlDiagram" uses "\expandafter" to assert this.
+% \index{intertwined boxes}\index{evaluation sequence}
+
+% \begin{macrocode}
+\def\umlTrueVariable{true}
+% \end{macrocode}
+%
+% \subsection{Lengths}
+% \label{sec:impSyntaxLengths}
+
+% \begin{macrocode}
+\psset{unit=1em}
+% \end{macrocode}
+%
+% \subsection{Angles}\label{sec:impSyntaxAngles}
+%
+% \section{Drawable}\label{sec:impDrawable}
+%
+% Each main "uml.sty" command (those drawn as schemas at pages
+% \pageref{fig:approachStart}--\pageref{fig:approachEnd}) is implemented
+% in the same pattern.
+%
+% \begin{macro}{\umlDrawableNull}
+% First, all the variables (in the "\umlDrawable" case, just one) are
+% set to their default values.
+% \begin{macrocode}
+\def\umlDrawableNull{%
+ \def\umlImport{}%
+ \def\umlKind{Drawable}%
+ \gdef\umlName{DrawableNameDefault}%
+ \def\umlNameDefault{DrawableNameDefault}%
+ %\ifx\umlName\umlNameDefault\else umlName is changed
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Named options}
+%
+% Of course, it would be more elegant to treat one variable at a time,
+% setting it to its default value and handling its named options at the
+% same place. However, I have not found any way to do so.
+
+% Then, the named options are handled. Most of them modify the
+% variables. In this case, there is only one named option ("import")
+% which modify one variable ("\umlColor"). In most cases, the named
+% option and the variable has corresponding names.
+%
+% \begin{macro}{kind-}
+% The kind (type, metaclass) of the Drawable, e.g., "Class".
+% \begin{macrocode}
+\define@key[psset]{uml}{kind}{\def\umlKind{#1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{name-}
+% The name of the Drawable, e.g., "Car".
+% \begin{macrocode}
+\define@key[psset]{uml}{name}{\gdef\umlName{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Colors}
+%
+% As said in section \ref{sec:useDrawableColors}, colors are primarily
+% handled by Drawable. However, due to some technical obscurities in
+% \TeX{}, the implementation is done in the known subclasses
+% ("\umlElement", "\umlCompartment" and "\umlCompartmentline").
+
+% The technical obscurities in \TeX{} is this: The brackets ("{}")
+% needed to limit the scope of colors, cannot contain table line breaks.
+% "\umlCompartmentline", which uses to be placed inside a table
+% ("\umlClassifier"), must put the line break outside the brackets.
+
+% \begin{macro}{import-}
+% \begin{macrocode}
+\define@key[psset]{uml}{import}{\umlColorsImport}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{noimport-}
+% \begin{macrocode}
+\define@key[psset]{uml}{noimport}{\umlColorsDefault}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{argument-}
+% \begin{macrocode}
+\define@key[psset]{uml}{argument}{\umlColorsArgument}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{argument-}
+% \begin{macrocode}
+\define@key[psset]{uml}{colorset}[\umlColorsDefault]{#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The command}
+% And then the command itself.
+% \begin{macro}{\umlDrawable}
+% This command does not do much work. It just process the nmed options.
+% \begin{macrocode}
+\newcommand\umlDrawable[2][]{%
+% \end{macrocode}
+% It sets its variables to default values,
+% \begin{macrocode}
+ \umlDrawableNull%
+% \end{macrocode}
+% process the named options
+% \begin{macrocode}
+ \psset[uml]{kind=Drawable,#1}%
+% \end{macrocode}
+% and typesets it second argument. This argument, the contents,
+% typically uses some of the variables.
+% \begin{macrocode}
+ #2%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Element}\label{sec:impElement}
+% \begin{macro}{\umlElementNull}
+% "\umlElement" follows the same pattern as "\umlDrawable" and the other
+% main commands; first, it sets its variables to the default values,
+% then handles the named options, and least define the command itself to
+% call its ``supercommand''.
+% \begin{macrocode}
+\def\umlElementNull{%
+ \def\umlReference{refdef}%
+ \def\umlStereotype{}%
+ \def\umlSubof{}%
+ \def\umlImportedFrom{}%
+ \def\umlComment{}%
+ \def\umlAbstract{}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{reference-}
+% "ref" is provided as an short-form for "reference".
+% \begin{macrocode}
+\define@key[psset]{uml}{reference}{\def\umlReference{#1}}
+\define@key[psset]{uml}{ref}{\def\umlReference{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{stereotype-}
+% The \LaTeX{} variable itself sometimes contains not only the
+% value itself, but some grahical stuff around.
+% \begin{macrocode}
+\define@key[psset]{uml}{stereotype}{%
+ \def\umlStereotype{{\hfil\phantom{x}<<#1>>\phantom{x}\hfil}\\}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{subof-}
+% \begin{macrocode}
+\define@key[psset]{uml}{subof}{\def\umlSubof{{~Sub of: #1}\\}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{abstract-}
+% The "abstract" named option also affects the graphical name in "\umlStretchbox".
+% \begin{macrocode}
+\define@key[psset]{uml}{abstract}[]{\def\umlAbstract{\emph}}%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{importedFrom-}
+% \begin{macrocode}
+\define@key[psset]{uml}{importedFrom}{%
+ \def\umlImportedFrom{{~From: #1}\\}%
+ \umlColorsImport%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{comment-}
+% \begin{macrocode}
+\define@key[psset]{uml}{comment}{\def\umlComment{{~#1}\\}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlElement}
+% The command itself just calls "\umlDrawable".
+% \begin{macrocode}
+\newcommand\umlElement[2][]{%
+ \umlElementNull%
+ {\umlDrawable[kind=Element,#1]{%
+ \umlColorsAdjust%
+ #2}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Box}\label{sec:impBox}
+%
+% \subsection{Positioning}\label{sec:implementationClassPositions}
+% One of the main responsibilities of "\umlBox" is to place the box in
+% the right position. In order to achieve this, "\umlBox" uses two
+% macros, "\umlBoxPosCommand" and "\umlBoxPosDeltaCommand". Each of
+% these, in turn, uses other macros, which ultimately are set to default
+% values. How this happends is indicated in figure \ref{fig:impBoxPos}.
+%
+% The user can modify this tree by the named options "pos", "posX",
+% "posY", "posDelta", "posDeltaX", "posDeltaY" and "refpoint".
+%
+% \newcommand\myBox[4]{
+% \rput(#1,#2){\rnode{#3}{
+% \begin{tabular}{c}#4\end{tabular}}}}
+% \begin{figure}[htbp]
+% \begin{center}
+% \rule{0mm}{7cm}% Why does not \pspicture make the space itself?
+% \hspace*{-1cm}
+% \pspicture(-3cm,-5cm)(8cm,1.5cm)
+% \begin{small}
+% \myBox{2.5cm}{1.5cm}{Box}{"\bslash{}umlBox"}
+% \myBox{0cm}{0cm}{Command}{"\bslash{}umlBoxPosCommand"}
+% \myBox{-2cm}{-2cm}{Refpoint}{"\bslash{}umlRefpoint"\\"refpoint="}
+% \myBox{-2cm}{-4cm}{RefpointValue}{"bl"}
+% \myBox{2cm}{-2cm}{Pos}{"\bslash{}umlPos"\\"pos="}
+% \myBox{1cm}{-4cm}{XPos}{"\bslash{}umlPosX"\\"posX="}
+% \myBox{3cm}{-4cm}{YPos}{"\bslash{}umlPosY"\\"posY="}
+% \myBox{1cm}{-5cm}{XPosValue}{"(0,"{\gray "0"}")"}
+% \myBox{3cm}{-5cm}{YPosValue}{"("{\gray "0"}",0)"}
+% \ncline{<-}{Command}{Box}
+% \ncline{<-}{Refpoint}{Command}
+% \ncline{<-}{RefpointValue}{Refpoint}
+% \ncline{<-}{Pos}{Command}
+% \ncline{<-}{XPos}{Pos}
+% \ncline{<-}{YPos}{Pos}
+% \ncline{<-}{YPosValue}{YPos}
+% \ncline{<-}{XPosValue}{XPos}
+% \myBox{7cm}{0cm}{DCommand}{"\bslash{}umlBoxPosDeltaCommand"}
+% \myBox{7cm}{-2cm}{PosDelta}{"\bslash{}umlPosDelta"\\"posDelta="}
+% \myBox{6cm}{-4cm}{XPosDelta}{"\bslash{}umlPosDeltaX"\\"posDeltaX="}
+% \myBox{8cm}{-4cm}{YPosDelta}{"\bslash{}umlPosDeltaY"\\"posDeltaY="}
+% \myBox{6cm}{-5cm}{XPosDeltaValue}{"(0,"{\gray "0"}")"}
+% \myBox{8cm}{-5cm}{YPosDeltaValue}{"("{\gray "0"}",0)"}
+% \ncline{<-}{DCommand}{Box}
+% \ncline{<-}{Refpoint}{DCommand}
+% \ncline{<-}{RefpointValue}{Refpoint}
+% \ncline{<-}{PosDelta}{DCommand}
+% \ncline{<-}{XPosDelta}{PosDelta}
+% \ncline{<-}{YPosDelta}{PosDelta}
+% \ncline{<-}{YPosDeltaValue}{YPosDelta}
+% \ncline{<-}{XPosDeltaValue}{XPosDelta}
+% \end{small}
+% \endpspicture
+% \caption{Positioning of boxes. The arrows here means
+% ``calls''. The user can affects this tree by
+% several named options.}
+% \label{fig:impBoxPos}
+% \end{center}
+% \end{figure}
+%
+% \begin{macro}{\umlBoxNullPositions}
+% First, the variables are set to their null values. This command is
+% called from "\umlBox" via "\umlBoxNull".
+%
+% \begin{macrocode}
+\def\umlBoxNullPositions{%
+ \def\umlPosCommand{%
+ \rput[\umlRefpoint](\umlPos)}%
+ \def\umlPos{\umlPosX|\umlPosY}%
+ \def\umlPosX{0,0}%
+ \def\umlPosY{0,0}%
+ \def\umlPosDeltaCommand{%
+ \rput[\umlRefpoint](\umlPosDelta)}%
+ \def\umlPosDelta{\umlPosDeltaX|\umlPosDeltaY}%
+ \def\umlPosDeltaX{0,0}%
+ \def\umlPosDeltaY{0,0}%
+ \def\umlRefpoint{bl}%
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{pos-}
+% Note that all the named options starting with "pos"
+% takes legal values as arguments. You
+% must write "posX={1em,0}" even if he zero is ignored.
+% \label{pos}
+%
+% \begin{macrocode}
+\define@key[psset]{uml}{pos}[0,0]{\def\umlPos{#1}}
+\define@key[psset]{uml}{posX}[0,0]{\def\umlPosX{#1}}
+\define@key[psset]{uml}{posY}[0,0]{\def\umlPosY{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{posDelta-}
+% The reference point of the box is placed at $pos + posDelta$.
+% \begin{macrocode}
+\define@key[psset]{uml}{posDelta}[0,0]{\def\umlPosDelta{#1}}
+\define@key[psset]{uml}{posDeltaX}[0,0]{\def\umlPosDeltaX{#1}}
+\define@key[psset]{uml}{posDeltaY}[0,0]{\def\umlPosDeltaY{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{refpoint-}
+% Legal values are \emph{reference points} (sec.\ \ref{sec:useReference})
+% \begin{macrocode}
+\define@key[psset]{uml}{refpoint}{\def\umlRefpoint{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Boxes in text}
+%
+% \begin{macro}{\umlBoxNullBoxes}
+% Normally, a box is an empty hbox. This can be changed using
+% the named option "box=". It takes no values (i.e.\
+% possible values are ignored). It makes the box taking
+% the natural size of its contents.
+% \begin{macrocode}
+\def\umlBoxNullBoxes{%
+% \end{macrocode}
+% This is how the box is made a zero size hbox then the "box=" named
+% option are not in effect.
+% \begin{macrocode}
+ \def\umlBoxH{\hbox to 0cm}%
+ \def\umlBoxV{\smash}%
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{box-}
+% This gives the box its natural size.
+% \begin{macrocode}
+\define@key[psset]{uml}{box}{%
+ \def\umlBoxH{}% no \hbox to 0cm
+ \def\umlBoxV{}% no \smash anymore
+ \def\umlPosCommand{}% no \rput... anymore
+ \def\umlPosDeltaCommand{}}% Ditto
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The visual appeareance}
+% \begin{macro}{\umlBoxNullVisual}
+% \begin{macrocode}
+\def\umlBoxNullVisual{%
+ \def\umlGrayness{1}%
+ \def\umlBorder{0mm}%
+ \def\umlInnerBorder{0mm}%
+ \def\umlOuterBorder{0mm}%
+ \def\umlFillcolorCommand{umlFillcolor}%
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{grayness-}
+% The grayness of the background in the box.
+% Legal values are real numbers between 0 (black) and 1 (white).
+% Default without named option is 1. Default with named option
+% is 0.85.
+% \begin{macrocode}
+\define@key[psset]{uml}{grayness}[.85]{\definecolor{umlFillcolor}{gray}{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{fillcolorCommand-}
+% "\umlFillcolorCommand" returns the name of the current fill color.
+% \begin{macrocode}
+\define@key[psset]{uml}{fillcolorCommand}[umlFillcolor]{%
+ \def\umlFillcolorCommand{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{border-}
+% The thickness of the outer border. Default without named option is
+% 0~mm, with 0.4~pt. Legal values are lengths.
+% \begin{macrocode}
+\define@key[psset]{uml}{border}[0.4pt]{\gdef\umlBorder{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{outerBorder-}
+% The margin around the border.
+% Default is "\umlhsep".
+% \begin{macrocode}
+\define@key[psset]{uml}{outerBorder}[1pt]{\def\umlOuterBorder{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{innerBorder-}
+% The space left between the edge of the box and its contents.
+% Default is "\umlhsep".
+% \begin{macrocode}
+\define@key[psset]{uml}{innerBorder}[\umlhsep]{\def\umlInnerBorder{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Size}
+% \begin{macro}{\umlBoxNullSize}
+% The minimum size of the box (or rather, the space left for the contents).
+% Different boxes (i.e., "\umlStretchBox" and "\umlDiagram" use
+% different algorithms for sizeing the box.
+% \begin{macrocode}
+\def\umlBoxNullSize{%
+% \end{macrocode}
+% \begin{macrocode}
+ \def\umlSizeX{5mm}%
+ \def\umlSizeY{7mm}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{size-}
+% Minimum values, used mostly by "\umlDiagram".
+% Legal values are lengths.
+% \begin{macrocode}
+\define@key[psset]{uml}{sizeX}{\def\umlSizeX{#1}}
+\define@key[psset]{uml}{sizeY}{\def\umlSizeY{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Holding together all the named options}
+% \begin{macro}{\umlBoxNull}
+% Just to invoke the other macros.
+% \begin{macrocode}
+\def\umlBoxNull{%
+ \umlBoxNullPositions%
+ \umlBoxNullBoxes%
+ \umlBoxNullVisual%
+ \umlBoxNullSize%
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The command}\label{sec:impBoxCommand}
+% \begin{macro}{\umlBox}
+% A box is a rectangle with position and size.
+% "\umlBox" takes two arguments: The named options and the contents.
+% \begin{macrocode}
+\newcommand\umlBox[2][]{\leavevmode%
+% \end{macrocode}
+% The variables are set to default
+% \begin{macrocode}
+ \umlBoxNull%
+% \end{macrocode}
+% and "\umlElement" is invoked, with new contents.
+% \begin{macrocode}
+ \umlElement[kind=Box,#1]{%
+% \end{macrocode}
+% Determines how large hbox \LaTeX{} should think this is
+% \begin{macrocode}
+ \umlBoxH{% \hbox to 0cm or nothing
+ \umlBoxV{% \smash or nothing
+% \end{macrocode}
+% rputs the stuff the right place
+% \begin{macrocode}
+ \umlPosCommand{%
+ \umlPosDeltaCommand{%
+% \end{macrocode}
+% the box is a node
+% \begin{macrocode}
+ \rnode{\umlReference}{%
+% \end{macrocode}
+% with outer margin
+% \begin{macrocode}
+ \setlength{\fboxrule}{0mm}%
+ \setlength{\fboxsep}{\umlOuterBorder}%
+ \fbox{%
+% \end{macrocode}
+% border
+% \begin{macrocode}
+% \setlength{\fboxrule}{\umlBorder}%
+% \setlength{\fboxsep}{0mm}%
+% \fbox{%
+% \end{macrocode}
+% and some color and inner margin
+% \begin{macrocode}
+ \psframebox[framesep=\umlInnerBorder,
+ linewidth=\umlBorder,
+ fillcolor=\umlFillcolorCommand, fillstyle=solid]{%
+% \end{macrocode}
+% around the contents.
+% \begin{macrocode}
+ #2}%
+% }%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Diagram}\label{sec:impDiagram}
+%
+% A diagram determines its size before typesetting the contents. This in
+% order to be able to place the contents relative to the borders of the diagram.
+
+% \begin{macro}{\umlDiagramNull}
+% The macro "\umlDiagramNull" sets the variables to their
+% default variables.
+% \begin{macrocode}
+\newcommand\umlDiagramNull{%
+ \def\umlGrid{}%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{grid-}
+% \begin{macrocode}
+\define@key[psset]{uml}{grid}[1]{\message{named option grid is deprecated and of no use}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The command}\label{sec:impDiagramCommand}
+% \begin{macro}{\umlDiagram}
+% \begin{macrocode}
+\newcommand\umlDiagram[2][]{%
+% \end{macrocode}
+% First, the variables are set to their default values.
+% \begin{macrocode}
+ \umlDiagramNull%
+% \end{macrocode}
+% For some reason, "\umlDiagram" without the "box=" named option gives
+% an error. I do not understand why, but it appears to be an illegal
+% paragraph break at "\umlBoxV" in "\umlBox".
+% \begin{macrocode}
+ \umlBox[kind=Diagram, fillcolorCommand=umlDiagramFillcolor,
+ box=,#1]{%
+% \end{macrocode}
+% \index{grayness-!default in Diagram}
+% \#2 is the contents. The rules are to make sure the diagram is big
+% enough. The rules are normally invisible, because "\umlDebugLength"
+% normally is 0~pt.
+
+% However, the rules must be evaluated before the contents,
+% so possible "\umlBox"es does not inflict on "\umlSizeX"
+% and "\umlSizeY". Thus, the "\expandafter", which assert that "#2"
+% is typeset before, but expanded after, the rules.
+% \begin{macrocode}
+ \expandafter{#2}{%
+ \rule{\umlDebugLength}{\umlSizeY}%
+ \rule{\umlSizeX}{\umlDebugLength}}%
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+
+% \section{Stretchbox}\label{sec:impStretchbox}
+%
+% "\umlStretchbox" is the first command to take three arguments: The
+% optional named options, a name and some contents.
+
+% \begin{macro}{\umlStretchboxNull}
+% \begin{macrocode}
+\newcommand\umlStretchboxNull{%
+ \def\umlGraphicalName{StrechboxDefault{\umlAbstract\umlName}\\}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\umlGraphicalName}
+% "\umlGraphicalName" is a name, possibly with some graphical fuzz, to
+% be printed in the box.
+% \end{macro}
+
+% \begin{macro}{\umlStretchbox}
+% The macro itself just handles the name. The reference is by default
+% set to the name.
+
+% A stretchbox first typesets its contents,
+% and then take size depending on the contents.
+% This as opposed to a diagram, which determine the size first.
+% \begin{macrocode}
+\newcommand\umlStretchbox[3][]{%
+ \umlStretchboxNull%
+ \umlBox[kind=Stretchbox, name={#2}, ref={#2}, #1]{%
+ \umlIndex{\umlName}{\umlKind}%
+ \rnode{\umlReference}{#3}%
+ }%
+ }%
+% \end{macrocode}
+% \index{reference-!default in Stretchbox}
+% \end{macro}
+
+% \section{Package}\label{sec:impPackage}
+% \begin{macro}{\umlPackage}
+% \begin{macrocode}
+\newcommand\umlPackage[3][]{%
+ % Null unneccessary
+ \def\umlName{#1}%
+ \begin{tabular}{@{}l@{}}%
+% \end{macrocode}
+% \index{border-!default in Package}
+% The upper rectangle. It may seem natural to make this a
+% "\umlStretchbox", but then we risk variable interference between the
+% two instances of "\umlStretchbox". It does not work in practice either.
+% \begin{macrocode}
+ \umlStretchbox[kind=Package, border=0.4pt,#1]{#2}{%
+ \def\umlGraphicalName{%
+ {\umlhspace\hfill\relsize{2}\textbf{\umlName}%
+ \rule{0mm}{2.3ex}\hfill\umlhspace}\\%
+ }%
+ \rnode{small\umlReference}{%
+ \begin{tabular}{@{}l@{}}%
+ \umlStereotype%
+ \umlGraphicalName%
+ \umlImportedFrom%
+ \umlComment%
+ \umlSubof%
+ \end{tabular}}}%
+% \end{macrocode}
+% There is no need for double width border between the parts
+% of the package, so we step back a bit.
+% \begin{macrocode}
+ \cr\noalign{\vskip -\umlBorder}%
+% \end{macrocode}
+% The lower rectangle
+% \begin{macrocode}
+ \umlStretchbox[kind=Package,border=0.4pt,#1]{#2}{%
+ \rnode{big\umlReference}{%
+ \begin{tabular}{@{}l@{}}%
+% \end{macrocode}
+% Start the boxes in the lower rectangle
+% \begin{macrocode}
+% \end{macrocode}
+% Insert the contents
+% \begin{macrocode}
+ #3%
+ \cr%
+% \end{macrocode}
+% Here (in the "\cr"?), there is some vertical space. I still have
+% some work to do to understand the vertical lengths in tabular.
+% \begin{macrocode}
+ \end{tabular}}}% End of lower rectangle
+ \end{tabular}%
+ }%
+% \end{macrocode}
+% \end{macro}
+
+% \section{Classifier}
+% \label{sec:impClassifier}
+%
+% A classifier is a stretchbox which contains compartments.
+% A classifier can be instanciated, or be an instance.
+
+% \begin{macro}{\umlClassifierNull}
+% \begin{macrocode}
+\newcommand\umlClassifierNull{%
+ \def\umlObject{}%
+ \umlClassifierEmptytrue%
+}
+\newif\ifumlClassifierEmpty%
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{object-}
+% This makes the classifier be an instance (object).
+% Graphically, this is shown by an line under the classifier name.
+% Note that instances cannot be abstract.
+% \begin{macrocode}
+\define@key[psset]{uml}{object}{\def\umlObject{\underbar}}
+% \end{macrocode}
+% \end{macro}
+
+
+% \begin{macro}{suppress-}
+% Makes "\umlSuppressionOn" active in the classifier
+% (empty compartments are not shown). For implementation: see
+% \vpageref{suppress}.
+% \end{macro}
+
+
+% \begin{macro}{instance-}
+% "instance" is provided as an equivalent to "object".
+% \begin{macrocode}
+\define@key[psset]{uml}{instance}{\def\umlObject{\underbar}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\umlClassifier}
+% "\umlClassifier" is implemented as a table inside a "\umlStretchbox".
+% The contents must be able to be inside a table.
+% The contents is typically "\umlCompartment"s.
+% \begin{macrocode}
+\newcommand\umlClassifier[3][]{%
+% \end{macrocode}
+% Variables set to default values
+% \begin{macrocode}
+ \umlClassifierNull%
+% \end{macrocode}
+% Names fixed. Uses "\umlAbstract".
+% \begin{macrocode}
+ \def\umlName{#2}%
+% \end{macrocode}
+% Grayness and border are given default values,
+% possible to override.
+% \begin{macrocode}
+ \umlStretchbox[kind=Classifier,border=.4pt,
+ fillcolorCommand=umlClassifierFillcolor,#1]{#2}{%
+% \end{macrocode}
+%\index{grayness-!default in Classifier}\index{border-!default in Classifier}
+% "\umlGraphicalName" must be defined here not to be overridden by
+% "\umlStretchboxNull".
+% Note the invisible rule to make some space.
+% \begin{macrocode}
+ \def\umlGraphicalName{%
+ \rule{0mm}{2.8ex}%
+ \umlhspace\larger\hfill\textbf{%
+ \umlAbstract{\umlObject{\umlName}}}\hfill\umlhspace\\}%
+ \begin{tabular}[tl]{@{}l@{}}%
+ \umlStereotype%
+ \umlGraphicalName%
+ \umlImportedFrom%
+ \umlComment%
+ \umlSubof%
+ #3%
+% \ifhmode hmode\else not\fi
+% \\\noalign{\vskip -15pt}%
+ \ifumlClassifierEmpty\\\noalign{\vskip -2.5ex}\fi
+ \end{tabular}%
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+
+% \section{Class}\label{sec:impClass}
+
+% \begin{macro}{\umlClass}
+% A class is a classifier with the three usual compartments.
+%
+% There is not much work left for "\umlClass":
+% \begin{macrocode}
+\newcommand\umlClass[4][]{%
+% \end{macrocode}
+% A "\umlClassNull" is unneccessary, as there is no variables here.
+% \begin{macrocode}
+ \umlClassifier[kind=Class,#1]{#2}{%
+ \umlCompartment[name=attributes]{#3}%
+ \umlCompartment[name=operations]{#4}%
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+
+% \section{Schema}
+% \label{sec:impSchema}
+
+% \begin{macro}{\umlSchema}
+% A schema is a classifier with some more compartments.
+% \begin{macrocode}
+\newcommand\umlSchema[7][]{%
+% \end{macrocode}
+% "Null" unneccessary here too.
+% \begin{macrocode}
+ \umlClassifier[kind=Schema,#1]{#2}{%
+ \umlCompartment[name=attributes]{#3}% Attributes
+ \umlCompartment[name=operations]{#4}% Methods
+ \umlCompartment[name=arguments]{#5}% Arguments
+ \umlCompartment[name=constraints]{#6}% Constraints
+ \umlCompartment[name=structure]{#7}% Structure
+ }%
+ }%
+% \end{macrocode}
+
+% \end{macro}
+
+% \section{Compartment}
+% \label{sec:impCompartment}
+
+% Classifiers (e.g., classes) are drawn as compartments (boxes) below each other.
+
+% "\umlCompartment" takes two arguments: a optional list of named
+% options, and the contents.
+
+% \begin{macro}{\umlCompartmentNull}
+% \begin{macrocode}
+\newcommand\umlCompartmentNull{%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifisnull}
+% A handy command stolen from [AdvancedTeX, p.126].
+% If first argument is empty, execute the second; else execute the third.
+% \begin{macrocode}
+\def\ifisnull#1#2#3{\def\inner{#1}%
+ \ifx\inner\empty%
+ #2\else{}#3%
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{last-}
+% \begin{macrocode}
+\define@key[psset]{uml}{last}[]{%
+ \message{The named option last= is deprecated and of no use.}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Suppression}
+% \label{suppress}
+
+%\SpecialMainIndex{\umlCompartmentSuppresstrue}
+%\SpecialMainIndex{\umlCompartmentSuppressfalse}
+% \begin{macro}{\ifumlCompartmentSuppress}
+% The boolean variable "umlCompartmentSuppress" affects whether empty
+% compartments should be suppressed or not.
+
+% You can set the variable (saying "\umlCompartmentSuppresstrue" or
+% "\umlCompartmentSuppressfalse") whenever you like.
+% \begin{macrocode}
+\newif\ifumlCompartmentSuppress
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{suppress-}
+% You can also set it for a construct (e.g., one compartment or an
+% entire classifier) with the named option suppress. When used, it is
+% default true.
+% \begin{macrocode}
+\define@key[psset]{uml}{suppress}[true]{%
+ \def\arg{#1}%
+ \ifx\arg\umlTrueVariable\umlCompartmentSuppresstrue%
+ \else\umlCompartmentSuppressfalse%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \subsection{Compartment names}
+
+%\SpecialMainIndex{\umlCompartmentNamesShowtrue}
+%\SpecialMainIndex{\umlCompartmentNamesShowfalse}
+% \begin{macro}{\ifumlCompartmentNamesShow}
+% The boolean variable "umlCompartmentNamesShow" affects whether
+% compartment names should be shown or not.
+
+% Compartment names are shown top centered in a distinct font in the compartment.
+
+% You can set the variable (saying "\umlCompartmentNamesShowtrue" or
+% "\umlCompartmentNamesShowfalse") when you like.
+% \begin{macrocode}
+\newif\ifumlCompartmentNamesShow
+% \end{macrocode}
+% \end{macro}
+
+
+% \begin{macro}{showname-}
+% You may also use the named option "showname" for one compartment or
+% another construct.
+% \begin{macrocode}
+\define@key[psset]{uml}{showname}[true]{%
+ \def\arg{#1}%
+ \ifx\arg\umlTrueVariable\umlCompartmentNamesShowtrue%
+ \else\umlCompartmentNamesShowfalse%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \subsection{The implementation}
+
+% The implementation of "\umlCompartment" caused me some trouble. This
+% is partly due to the many different possibilities, partly due to the
+% funny scope rules in \LaTeX{} tables (in "\halign").
+
+% In tables, it seems like every line is a scope. A variable modified
+% with "\def" in one line gets its old value when passing a line break.
+
+% Also, we cannot place the line break inside the body of an if
+% sentence.
+
+% This is very, very odd, took me some time to detect, and destroys much
+% beauty.
+
+% In short: \TeX{} is a \emph{scanalous} bad programming language,
+% but you can make absolutely everyting in it (including object oriented
+% programs :-)
+
+% A compartment composes classifiers, and is itself composed
+% of compartment lines. Every compartment line ends with a line break.
+% Every compartment starts with a "\hline" and ends with a line break.
+
+% \begin{macro}{\umlCompartmentCommon}
+% \begin{macrocode}
+\newcommand\umlCompartmentCommon[2][]{%
+% \end{macrocode}
+% Even if every compartment should be preceded by a line break,
+% we assert this is really true.
+
+% Of couse, the following line is an ad hoc hack, but I have no
+% better solution right now.
+% \begin{macrocode}
+ \ifhmode \vspace*{-2.5ex}\\\fi%
+% \end{macrocode}
+% The actual line between this and the following compartment.
+% \begin{macrocode}
+ \hline%
+% \end{macrocode}
+% The compartment name (if it should be shown).
+% I miss an and operator in \TeX.
+% \begin{macrocode}
+ \ifumlCompartmentNamesShow%
+ \ifx\umlName\umlNameDefault\else%
+ \omit\hfil\textbf{\umlName}\hfil\\%
+ \fi%
+ \fi%
+% \end{macrocode}
+% This is really not neccesary, as it is defined in "\umlCompartment".
+% \begin{macrocode}
+ \def\umlCompartmentContents{#2}%
+% \end{macrocode}
+% If the compartment is empty (but not suppressed),
+% It looks better to make it shorter.
+% (But why isn't this like "\hline\hline" in the first place?
+% \begin{macrocode}
+ \ifx\umlCompartmentContents\empty%
+ \vspace*{-1.5ex}%
+ \else% There is contents
+ \umlClassifierEmptyfalse%
+ #2%
+ \fi%
+% \end{macrocode}
+% Assuring we end with a line break.
+% \begin{macrocode}
+ \ifhmode\\\fi%
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\umlCompartment}
+% "\umlCompartment" itself mainly calls "\umlCompartmentCommon".
+% \begin{macrocode}
+\newcommand\umlCompartment[2][]{%
+ \umlCompartmentNull%
+ \def\umlCompartmentContents{#2}%
+ \umlDrawable[kind=Compartment,#1]{%
+ \umlColorsAdjust%
+ \ifumlCompartmentSuppress%
+ \ifx\umlCompartmentContents\empty\else%
+ \umlCompartmentCommon[#1]{#2}%
+ \fi%
+ \else%
+ \umlClassifierEmptyfalse%
+ \umlCompartmentCommon[#1]{#2}%
+ \fi}}%
+% \end{macrocode}
+% \end{macro}
+
+% \section{Compartmentline}\label{sec:impCompartmentline}
+
+% A compartmentline is a line of text designed to be in a compartment.
+% Such a line should have some room before and after it, in order not
+% to touch the compartment border.
+
+% \begin{macro}{\umlhspace}
+% This make some horizontal space.
+% \begin{macrocode}
+\def\umlhsep{.5ex}
+\newcommand\umlhspace{\hspace*{\umlhsep}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\umlCompartmentline}
+% This should be straight-forward\dots
+% \begin{macrocode}
+\newcommand\umlCompartmentline[2][]{%
+ \umlDrawable[kind=Compartmentline,#1]{%
+ {\umlColorsAdjust\umlhspace{}#2{}\umlhspace}\\}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\umlCompartmentText}
+% Provided for backward compatibility.
+% \begin{macrocode}
+\newcommand\umlCompartmentText[1]{%
+ \umlhspace#1\umlhspace}
+% \end{macrocode}
+% \end{macro}
+
+
+% \section{Feature}
+% \label{sec:impFeature}
+%
+% A feature is something attached to a classifier.
+
+% \begin{macro}{\umlVisibilityLength}
+% This is the hspace in front of the attribute name, where the
+% visibility is placed.
+% \begin{macrocode}
+\def\umlVisibilityLength{2ex}
+% \end{macrocode}
+%\end{macro}
+
+% \begin{macro}{\umlFeatureNull}
+% \begin{macrocode}
+\newcommand\umlFeatureNull{%
+ \def\umlVisibility{}%
+ \def\umlType{}%
+ \def\umlPropertyString{}%
+ \def\umlInitialValue{}%
+ \def\umlName{FeatureNameDefault}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{visibility-}
+% \begin{macrocode}
+\define@key[psset]{uml}{visibility}[+]{%
+ \def\umlVisibility{\hbox to \umlVisibilityLength{#1\hfil}}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\umlTilde}
+% Prints a tilde.
+% \begin{macrocode}
+\newcommand\umlTilde{\ensuremath{\sim}}
+% \end{macrocode}
+% \end{macro}
+
+%
+% \begin{macro}{propertyString-}
+% \begin{macrocode}
+\define@key[psset]{uml}{propertyString}{%
+ \def\umlPropertyString{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{type-}
+% The data type returned from the feature.
+% \begin{macrocode}
+\define@key[psset]{uml}{type}{%
+ \def\umlType{: #1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{initialValue-}
+% \begin{macrocode}
+\define@key[psset]{uml}{initialValue}{%
+ \def\umlInitialValue{= #1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlFeature}
+% "\umlFeature" is implemented as a table inside a "\umlStretchbox".
+% The contents must be able to be inside a table.
+% The contents is typically "\umlCompartment"s.
+% \begin{macrocode}
+\newcommand\umlFeature[2][]{%
+ \umlFeatureNull%
+ \umlCompartmentline[kind=Feature, #1]{%
+ \umlIndex{\umlName}{\umlKind}%
+ #2}%
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Attribute}\label{sec:impAttribute}
+%
+% \begin{macro}{\umlAttributeNull}
+% \begin{macrocode}
+\def\umlAttributeNull{%
+ \def\umlMultiplicity{}%
+ \def\umlOrdering{}%
+ \def\umlMultiplicityOrdering{}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{default-}
+% This is provided as an alias to "initialValue" for the sake
+% of backward compatibility. Use is deprecated.
+% \begin{macrocode}
+\define@key[psset]{uml}{default}{%
+ \def\umlInitialValue{ = #1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{multiplicity-}
+% Examples of legal values are "{[1]}", "{[1..*]}" and "{[1..3,5..]}".
+% \begin{macrocode}
+\define@key[psset]{uml}{multiplicity}{%
+ \def\umlMultiplicity{#1}%
+ \def\umlMultiplicityOrdering{[\umlMultiplicity{} \umlOrdering]}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ordering-}
+% Legal values are "ordered" and "unordered".
+% Absent value imply unordered. Default value with named option is ordered.
+% \begin{macrocode}
+\define@key[psset]{uml}{ordering}[ordered]{%
+ \def\umlOrdering{#1}%
+ \def\umlMultiplicityOrdering{[\umlMultiplicity{} \umlOrdering]}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\umlAttribute}
+% \begin{macrocode}
+\newcommand\umlAttribute[2][]{%
+ \umlAttributeNull%
+ \umlFeature[kind=Attribute, name={#2}, #1]{%
+ \umlVisibility #2 \umlType \umlMultiplicityOrdering
+ \umlInitialValue \umlPropertyString}}
+% \end{macrocode}
+% \end{macro}
+
+% \subsection{Method}\label{sec:impMethod}
+
+
+% \begin{macro}{\umlMethodNull}
+% \begin{macrocode}
+\newcommand\umlMethodNull{%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{returntype-}
+% Alias to "type=".
+% \begin{macrocode}
+\define@key[psset]{uml}{returntype}{%
+ \def\umlType{: #1}}
+% \end{macrocode}
+% \end{macro}
+
+
+% \begin{macro}{\umlMethod}
+% \begin{macrocode}
+\newcommand\umlMethod[3][]{%
+ \umlMethodNull%
+ \def\umlName{#2}%
+ \umlFeature[kind=Method, name={#2}, #1]{%
+ \umlVisibility #2(#3) \umlType \umlPropertyString}}
+% \end{macrocode}
+% \end{macro}
+
+% \subsection{Argument}\label{sec:impArgument}
+
+
+% \begin{macro}{\umlArgumentNull}
+% \begin{macrocode}
+\newcommand\umlArgumentNull{%
+}
+% \end{macrocode}
+% \end{macro}
+
+
+
+% \begin{macro}{\umlArgument}
+% \begin{macrocode}
+\newcommand\umlArgument[2][]{%
+ \umlArgumentNull%
+ \def\umlName{#2}%
+ \umlFeature[kind=Argument, name={#2}, #1]{%
+ \emph{#2} \umlType \umlInitialValue}}
+% \end{macrocode}
+% \end{macro}
+
+% \section{Relation}\label{sec:impRelation}
+
+% \subsection{Node connection points}
+
+
+% \begin{macro}{\umlRelationNullConnection}
+% \begin{macrocode}
+\newcommand\umlRelationNullConnection{%
+ \def\umlNodesepA{0pt}%
+ \def\umlNodesepB{0pt}%
+ \def\umlOffsetA{0pt}%
+ \def\umlOffsetB{0pt}%
+ \def\umlAngleA{}%
+ \def\umlAngleB{}%
+}%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{angle-}
+% This is the angle at which the connector hits the node
+% \begin{macrocode}
+\define@key[psset]{uml}{angleA}{\def\umlAngleA{#1}}
+\define@key[psset]{uml}{angleB}{\def\umlAngleB{#1}}
+\define@key[psset]{uml}{angle}{\def\umlAngleA{#1}\def\umlAngleB{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{nodesep-}
+% The distance from the node to the connector end.
+% Legal values are lengths.
+% \begin{macrocode}
+\define@key[psset]{uml}{nodesepA}{\def\umlNodesepA{#1}}
+\define@key[psset]{uml}{nodesepB}{\def\umlNodesepB{#1}}
+\define@key[psset]{uml}{nodesep}{\def\umlNodesepA{#1}\def\umlNodesepB{#1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{offset-}
+% After the connection point is calculated, it is shift right (assumed
+% direction onto node) by this value. Legal values are lengths.
+% \begin{macrocode}
+\define@key[psset]{uml}{offsetA}{\def\umlOffsetA{#1}}
+\define@key[psset]{uml}{offsetB}{\def\umlOffsetB{#1}}
+\define@key[psset]{uml}{offset}{\def\umlOffsetA{#1}\def\umlOffsetB{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Arm geometry}
+%
+% \begin{macro}{\umlRelationNullArmGeometry}
+% \begin{macrocode}
+\newcommand\umlRelationNullArmGeometry{%
+ \pssetlength\umlArmA{0pt}%
+ \pssetlength\umlArmB{0pt}%
+ \def\umlArmAngleA{0}%
+ \def\umlArmAngleB{0}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{armA-}
+% This is the lengths of the arms.
+% \begin{macrocode}
+\newlength\umlArmA
+\newlength\umlArmB
+\define@key[psset]{uml}{armA}{\pssetlength\umlArmA{#1}}
+\define@key[psset]{uml}{armB}{\pssetlength\umlArmB{#1}}
+\define@key[psset]{uml}{arm}{%
+ \pssetlength\umlArmA{#1}%
+ \pssetlength\umlArmB{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{armAngle-}
+% This is the angle of the arm.
+% \begin{macrocode}
+\define@key[psset]{uml}{armAngleA}{\def\umlArmAngleA{#1}}
+\define@key[psset]{uml}{armAngleB}{\def\umlArmAngleB{#1}}
+\define@key[psset]{uml}{armAngle}{%
+ \def\umlArmAngleA{#1}%
+ \def\umlArmAngleB{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Visual appeareance}
+%
+% \begin{macro}{\umlRelationNullVisual}
+% \begin{macrocode}
+\newcommand\umlRelationNullVisual{%
+ \def\umlLinestyle{solid}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{linestyle-}
+% Legal values are "none", "solid", "hashed" and "dotted".
+% \begin{macrocode}
+\define@key[psset]{uml}{linestyle}{\def\umlLinestyle{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{relationColor-}
+% The color of the line.
+% \begin{macrocode}
+\define@key[psset]{uml}{relationColor}[black]{\pst@getcolor{#1}\pslinecolor}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{lineColor-}
+% Alias for "relationColor=".
+% \begin{macrocode}
+\define@key[psset]{uml}{linecolor}{\pst@getcolor{#1}\pslinecolor}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlRelationNull}
+% \begin{macrocode}
+\newcommand\umlRelationNull{%
+ \umlRelationNullConnection%
+ \umlRelationNullArmGeometry%
+ \umlRelationNullVisual%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The macro}
+% \begin{macro}{\umlRelation}
+% The command itself:
+% \begin{macrocode}
+\newcommand\umlRelation[4][]{%
+ \umlRelationNull%
+% \end{macrocode}
+% The default reference is the concatenation of the two references
+% \begin{macrocode}
+ \umlElement[kind=Relation,ref={#2#3}, #1]{%
+% \end{macrocode}
+% Putting the "Aa" and "Ba" nodes, default (without "angle=") first
+% \begin{macrocode}
+ \ncline[linecolor=green, linestyle=\umlDebugLinestyle,
+ offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
+ offsetB=\umlOffsetB, nodesepB=\umlNodesepB]{#2}{#3}%
+ \lput{:R}(0){\pnode{Aa\umlReference}}%
+ \lput{:R}(1){\pnode{Ba\umlReference}}%
+% \end{macrocode}
+% Then modifying "Aa", if "angleA=" or "angle=" is used
+% \begin{macrocode}
+ \ifx\umlAngleA\empty \else
+ \ncdiag[linestyle=\umlDebugLinestyle, linecolor=magenta, %
+ angleA=\umlAngleA,
+ offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
+ offsetB=\umlOffsetB, nodesepB=\umlNodesepB
+ ]{#2}{#2}%
+ \lput{:R}(0){\pnode{Aa\umlReference}}\fi%
+% \end{macrocode}
+% And "Ba".
+% \begin{macrocode}
+ \ifx\umlAngleB\empty \else
+ \ncdiag[linestyle=\umlDebugLinestyle, linecolor=magenta, %
+ angleA=\umlAngleB,
+ offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
+ offsetB=\umlOffsetB, nodesepB=\umlNodesepB
+ ]{#3}{#3}%
+ \lput{:R}(0){\pnode{Ba\umlReference}}\fi%
+% \end{macrocode}
+% Now, we can draw the line, from the "Aa" to the "Ba" node.
+% \begin{macrocode}
+ \ncdiag[linestyle=\umlLinestyle, linecolor=umlLinecolor,
+ angleA=\umlArmAngleA, angleB=\umlArmAngleB,
+ armA=\umlArmA, armB=\umlArmB
+ ]{%
+ Aa\umlReference}{%
+ Ba\umlReference}%
+% \end{macrocode}
+% Placing nodes "Ab" and "Bb".
+% If there is no arm A,
+% \begin{macrocode}
+ \ifdim \umlArmA=0pt \lput{:R}(2){\pnode{Ab\umlReference}}%
+% \end{macrocode}
+% Else, if there is
+% \begin{macrocode}
+ \else \lput{:R}(1){\pnode{Ab\umlReference}} \fi%
+% \end{macrocode}
+% If there is no arm B,
+% \begin{macrocode}
+ \ifdim \umlArmB=0pt \lput{:R}(1){\pnode{Bb\umlReference}}%
+% \end{macrocode}
+% Else, if there is
+% \begin{macrocode}
+ \else \lput{:R}(2){\pnode{Bb\umlReference}} \fi%
+% \end{macrocode}
+% Final nodes
+% \begin{macrocode}
+ \lput{:R}(1){\pnode{Ac\umlReference}}%
+ \lput{:R}(2){\pnode{Bc\umlReference}}%
+% \end{macrocode}
+% Other contents
+% \begin{macrocode}
+ #4}% of \umlElement
+}
+% \end{macrocode}
+% \end{macro}
+
+% \subsection{About the spesific relations}
+
+% The different relations are specialized relations; they typically call
+% "\umlRelation" and "\umlSymbol" with an appropriate symbol.
+
+
+% \label{lengths}
+% \begin{macro}{\umlSymbolHeightDefault}
+% All the symbols are drawn with "0" as the upper border,
+% "-\umlSymbolHeightDefault" as the lower,
+% "-\umlSymbolWidthDefault" as the left and
+% "\umlSymbolWidthDefault" as the right one. These lengths can
+% be changed by the user. See, however, section \vref{sec:impInner}.
+% \begin{macrocode}
+\newlength\umlSymbolHeightDefault
+\setlength\umlSymbolHeightDefault{1em}
+\newlength\umlSymbolWidthDefault
+\setlength\umlSymbolWidthDefault{.5em}
+% \end{macrocode}
+% \end{macro}
+
+% \subsection{Association}\label{sec:impAssociation}
+
+% \label{sec:association}
+% \begin{macro}{\umlAssociation}
+% "\umlAssociation" is a relation without any other contents.
+% \begin{macrocode}
+\newcommand\umlAssociation[3][]{%
+ \umlRelation[kind=Association, #1]{#2}{#3}{}%
+}
+% \end{macrocode}
+% \end{macro}
+
+
+% \subsection{Subclass (generalization)}
+% \label{sec:impSubclass}
+% \label{sec:impGeneralization}
+
+% \begin{macro}{\umlSubclass}
+% A simple relation with a triangle as an endsymbol.
+% \begin{macrocode}
+\newcommand\umlSubclass[3][]{%
+ \def\umlEndSymbol{%
+ \pspolygon*[linecolor=white](0,0)%
+ (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ \pspolygon[](0,0)% Why does not dimen=inner work?
+ (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ }%
+% \def\umlEndSymbol{% Alternative \umlEndSymbol
+% \pstriangle[dimen=inner](0,-\umlSymbolHeightDefault)%
+% (\umlSymbolWidthDefault,\umlSymbolHeightDefault)}
+% \end{macrocode}
+% \begin{macrocode}
+ \umlRelation[kind=Subclass, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}%
+ }
+\def\umlGeneralization{\umlSubclass}
+% \end{macrocode}
+% \end{macro}
+
+% \subsection{Inner class}
+% \label{sec:impInner}
+% \label{sec:inner}
+
+% The making of this symbol gave some problems. After experimenting
+% with different interpolations and Bézier curves, I defined it to
+% consist of two clipped wedges. Each should of course have width $w
+% = $ "\umlWidthDefault" and height
+% $h = $"\umlHeightDefault".
+% \index{circle}
+% The radius of the circle is $r$, and $r
+% = v + w$. This gives figure \vref{fig:innerSymbol}.
+% \begin{figure}[htbp]
+% This figure is drawn with an angle of 60 degrees.
+% \begin{center}{%
+% \psset{unit=1.5cm}
+% \begin{pspicture}(-2,-2)(2,.25)%
+% %\psgrid[subgriddiv=0,griddots=10](0,0)(-2,-2)(1,.25)
+% \psline(-2,0)(2,0)
+% \pswedge(0,-.866){1}{120}{180}
+% \pscircle[](0,-.866){1}
+% \psarc[linewidth=2.4pt](0,-.866){1}{120}{180}
+% \psline(-.5,0)(-.5,-.866)
+% The symbols
+% \psbezier(-1,-.866)(-1,-.933)(-.75,-.933)(-.75,-1)
+% \psbezier(-.5,-.866)(-.5,-.933)(-.75,-.933)(-.75,-1)
+% \rput[t](-.75,-1){\rput(0,-1ex){$v$}}
+% \psbezier(-.5,-.866)(-.5,-.933)(-.25,-.933)(-.25,-1)
+% \psbezier(-0,-.866)(-0,-.933)(-.25,-.933)(-.25,-1)
+% \rput[t](-.25,-1){\rput(0,-1ex){$w$}}
+% \psbezier(0,0)(0.067,0)(0.067,-.433)(0.134,-.433)
+% \psbezier(0,-.866)(0.067,-.866)(0.067,-.433)(0.134,-.433)
+% \rput[l](.134,-.433){~$h$}
+% \end{pspicture}
+% \hspace{1cm}
+% \begin{pspicture}(-2,-2)(1,.25)%
+% \psline(-2,0)(1,0)
+% \psarc[linewidth=2.4pt](0,-.866){1}{120}{180}
+% \psarc[linewidth=2.4pt](-1,-.866){1}{0}{60}
+% \psline[linewidth=2.4pt](-1,-.866)(0,-.866)
+% \psline[linewidth=2.4pt](-.5,-1.75)(-.5,-.866)
+% \end{pspicture}
+% \caption{The inner class symbol}
+% \label{fig:innerSymbol}}
+% \end{center}
+% \end{figure}
+
+% \index{Pythagoras}
+% We have $$r = v + w$$ and, from Pythagoras, $$r^2 = h^2 + w^2$$
+% This gives $$r=\frac{h^2}{2v} + \frac{v}{2}$$ and
+% $$w=\frac{h^2}{2v}-\frac{v}{2}$$ and we know where to locate the
+% wedge.
+%
+% \index{addition!of lengths}\index{subtraction!of lengths}
+% \index{multiplication!of lengths}\index{division!of lengths}
+% However, while addition and subtraction of lengths is easy in
+% PSTricks (only stepping back and forth), multiplication and division
+% of lengths is difficult, if not impossible. I really haven't found a
+% good solution to this problem.
+%
+% The not-so-good problem is to define $w$ and $r$ as \TeX{} lengths
+% ("\umlInnerWidthDefault" and
+% "\umlInnerRadiusDefault")
+% and then assign them values manually. We
+% have to remember, then, that Pythagoras still should work.
+%
+% Page \pageref{lengths} assign the default values $h=1$ em, $v=.5$ em.
+% This gives
+%
+% \begin{macro}{\umlInnerWidthDefault}
+% $w=0.75$ em
+% \begin{macrocode}
+\newlength\umlInnerWidthDefault
+\setlength\umlInnerWidthDefault{0.75em}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\umlInnerRadiusDefault}
+% and $r=1.25$ em.
+% \begin{macrocode}
+\newlength\umlInnerRadiusDefault
+\setlength\umlInnerRadiusDefault{1.25em}
+% \end{macrocode}
+% \end{macro}
+%
+% If we should implement the symbol by "\umlArc", we had to know some
+% angles. They would be easy to compute using trigonometry,
+% but that is difficult within \TeX. Then, we use "\umlCircle" and
+% "\psclip" instead.
+%
+% Maybe this could be done easily using raw postscript?
+%
+% \begin{macro}{\umlInner}
+% On some systems, the clipping makes some borders.
+% \begin{macrocode}
+\newcommand\umlInner[3][]{%
+ \def\umlEndSymbol{%
+ \pspolygon*[linecolor=white](0,0)%
+ (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ \psclip{%
+ \psframe[linewidth=0pt]%
+ (-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)(0,0)}
+ \pscircle(\umlInnerWidthDefault,-\umlSymbolHeightDefault)%
+ {\umlInnerRadiusDefault}
+ \endpsclip
+ \psclip{%
+ \psframe[linewidth=0pt]%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)(0,0)}
+ \pscircle(-\umlInnerWidthDefault,-\umlSymbolHeightDefault)%
+ {\umlInnerRadiusDefault}
+ \endpsclip
+ \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)}
+ \umlRelation[kind=Inner, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}
+ }}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Instance}\label{sec:instance}\label{sec:impInstance}
+%
+% \begin{macro}{\umlInstance}
+% The only new thing about "\umlInstance" is the addition of one named
+% option, the linestyle.
+% \begin{macrocode}
+\newcommand\umlInstance[3][]{%
+ \def\umlEndSymbol{%
+ \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)}%
+ \umlRelation[kind={Instance-of}, linestyle=dashed, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
+ }
+% \end{macrocode}
+% \index{linestyle-!dashed in Instance}
+% \end{macro}
+%
+% \subsection{Aggregation}\label{sec:aggregation}\label{sec:impAggregation}
+%
+% \begin{macro}{\umlAggregation}
+% Endpoint is a diamond.\index{diamond}
+% \begin{macrocode}
+\newcommand\umlAggregation[3][]{%
+ \def\umlEndSymbol{%
+% \end{macrocode}
+% Anyone said addition of lengths in PSTricks was difficult?
+% \begin{macrocode}
+ \rput(0,-\umlSymbolHeightDefault){%
+ \psline*[linecolor=white](-\umlSymbolWidthDefault, 0)%
+ (0,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault, 0)}
+ \psline*[linecolor=white]%
+ (-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)
+ \rput(0,-\umlSymbolHeightDefault){%
+ \psline(-\umlSymbolWidthDefault, 0)%
+ (0,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault, 0)}
+ \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault,
+ -\umlSymbolHeightDefault)}
+ \umlRelation[kind=Aggregation, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Composition}\label{sec:composition}\label{sec:impComposition}
+%
+% \begin{macro}{\umlComposition}
+% End symbol is a filled diamond. \index{diamond!filled}\index{filled diamond}
+% \begin{macrocode}
+\newcommand\umlComposition[3][]{%
+ \def\umlEndSymbol{%
+ \rput(0,-\umlSymbolHeightDefault){%
+ \psline*(-\umlSymbolWidthDefault, 0)%
+ (0,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault, 0)}
+ \psline*(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault,
+ -\umlSymbolHeightDefault)}
+ \umlRelation[kind=Composition, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Application}\label{sec:application}\label{sec:impApplication}
+%
+% \begin{macro}{\umlApplication}
+% End symbol is a filled arrow.\index{arrow!endpoint in Application}
+% \begin{macrocode}
+\newcommand\umlApplication[3][]{%
+ \def\umlEndSymbol{%
+ \pspolygon*(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,-\umlSymbolWidthDefault)}%
+ \umlRelation[kind=Application, #1]{#2}{#3}{%
+ \lput(1.2){\pnode{argument\umlReference}}%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{ToRelation}\label{sec:impToRelation}
+%
+% \begin{macro}{\umlToRelationNull}
+% \begin{macrocode}
+\newcommand\umlToRelationNull{%
+ \def\umlPosMeetLine{.5}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{posMeetLine-}
+% Where this relation shall meet the relation.
+% \begin{macrocode}
+\define@key[psset]{uml}{posMeetLine}[.5]{\def\umlPosMeetLine{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlAssociationClass}
+% Relation from a relation to a classifier
+% \begin{macrocode}
+\newcommand\umlToRelation[3][]{%
+ \umlToRelationNull%
+% \end{macrocode}
+% We have to process the "posMeetLine" option before the "\lput".
+% This introduces some overhead, as "\psset" is run twice.
+% However, I expect this to be used relatively few times.
+% \begin{macrocode}
+ \psset[uml]{kind=ToRelation, #1}%
+ \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{Ac#3}{Bc#3}%
+ \lput{:R}(\umlPosMeetLine){\pnode{ToRelation#3}}%
+ \umlRelation[ref={#2#3}, #1]{#2}{ToRelation#3}{}%
+}
+% \end{macrocode}
+% \index{reference-!default in ToRelation}
+% \end{macro}
+%
+% \subsection{AssociationClass and AssociationSchema}\label{sec:associationClass}
+% \label{sec:impAssociationClass}
+% \label{sec:impAssociationSchema}
+%
+% \begin{macro}{\umlAssociationClass}
+% Relation from a relation to a schema symbol.
+%\index{linestyle!dashed in AssociationClass}
+% \index{posMeetLine!AssociationClass}
+% \begin{macrocode}
+\newcommand\umlAssociationSchema[3][]{%
+ \umlToRelation[kind=AssociationSchema,
+ posMeetLine=.5, linestyle=dashed,#1]{#2}{#3}%
+}
+\newcommand\umlAssociationClass[3][]{%
+ \umlAssociationSchema[kind=AssociationClass,#1]{#2}{#3}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{ArgumentRelation}\label{sec:argument}
+% \label{sec:impArgumentRelation}
+%
+% \begin{macro}{\umlArgumentRelation}
+% Relation from an application to an argument.
+%\index{linestyle!dottedin ArgumentRelation}
+% \index{posMeetLine!ArgumentRelation}
+% \begin{macrocode}
+\newcommand\umlArgumentRelation[3][]{%
+ \umlToRelation[kind=ArgumentRelation,
+ posMeetLine=.2,linestyle=dotted,#1]{#2}{#3}%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \section{AssociationEnd}\label{sec:impAssociationEnd}
+%
+% \begin{macro}{\umlAssociationEndNull}
+% \begin{macrocode}
+\newcommand\umlAssociationEndNull{%
+ \def\umlAEOffset{\umlAEOffsetDefault}%
+ \def\umlAEOffsetDefault{0pt}%
+ \def\umlAEFraction{0}%
+ \def\umlAEFractionAngle{\umlAEFractionAngleDefault}%
+ \def\umlAEFractionAngleDefault{:U}%
+ \def\umlAEAngle{\umlAEAngleDefault}%
+ \def\umlAEAngleDefault{U}%
+ \def\umlAERefpoint{B}%
+ \def\umlAEHeight{\umlAEHeightDefault}%
+ \def\umlAEHeightDefault{0pt}%
+ \def\umlAENoderefClose{Ac}%
+ \def\umlAENoderefFar{Bc}%
+ \def\umlAEType{AssociationEnd}%
+ \def\umlAEKind{AssociationEnd}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{import-}
+% \begin{macrocode}
+\define@key[psset]{umlAE}{import}{\def\umlAEColor{red}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{type-}
+% \begin{macrocode}
+\define@key[psset]{umlAE}{type}{\def\umlType{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{kind-}
+% E.g., AssociationEnd.
+% \begin{macrocode}
+\define@key[psset]{umlAE}{kind}{\def\umlKind{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{offset-}
+% \begin{macrocode}
+\define@key[psset]{umlAE}{offset}{\def\umlAEOffset{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{angle-}
+% Angle used to rotate the symbol itself.
+% \begin{macrocode}
+\define@key[psset]{umlAE}{angle}{\def\umlAEAngle{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{fractionAngle-}
+% The angle used when positioning the symbol.
+% Legal values includes angles preceded by a colon (:),
+% indicting positioning relative to the relation.
+% This is expected to be used by subcommands, but
+% seldom by users.
+% \begin{macrocode}
+\define@key[psset]{umlAE}{fractionAngle}{\def\umlAEFractionAngle{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{height-}
+% \begin{macrocode}
+\define@key[psset]{umlAE}{height}{\def\umlAEHeight{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{refpoint-}
+% \begin{macrocode}
+\define@key[psset]{umlAE}{refpoint}{\def\umlAERefpoint{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{refpoint-}
+% \begin{macrocode}
+%% \define@key[psset]{umlAE}{type}{\def\umlAEType{#1}}% %%%%%%%%%%%%
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Fraction}
+%
+% \begin{macro}{fraction-}
+% This value is used by "\umlAEFixFractionLabel" and "\umlAEFixFractionSymbol".
+% \begin{macrocode}
+\define@key[psset]{umlAE}{fraction}{\def\umlAEFraction{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlFromTo}
+% A handy little procedure. If its first argument is "A" or "From", it
+% executes the second argument. If it is "B" or "To", it executes the
+% third. Used in the procedures like "\umlAssociationEndMakeA",
+% "\umlLabelMakeA" and "\umlSymbolMakeA".
+% \begin{macrocode}
+\newcommand\umlFromTo[3]{%
+ \edef\umlAEFractionArgument{#1}%
+ \def\umlAEFractionTmp{From}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#2\fi%
+ \def\umlAEFractionTmp{A}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#2\fi%
+ \def\umlAEFractionTmp{To}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#3\fi%
+ \def\umlAEFractionTmp{B}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#3\fi%
+}
+%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlAssociationEndUseFraction}
+% If "\umlFraction" is "A" or something (i.e., if "fraction=A" or sth),
+% adjust some other parameters.
+% \begin{macrocode}
+\newcommand\umlAssociationEndUseFraction{%
+% \begin{macrocode}
+ \umlFromTo{\umlAEFraction}{% If A or From
+ \def\umlAENoderefClose{Aa}%
+ \def\umlAENoderefFar{Ab}%
+ \def\umlAEFraction{0}%
+ }{%
+ \def\umlAENoderefClose{Ba}% If B or To
+ \def\umlAENoderefFar{Bb}%
+ \def\umlAEFraction{0}%
+% \end{macrocode}
+% If this is a ``"B"'' type association end,
+% and this is an Label type association end,
+% invert the height.
+% \begin{macrocode}
+ \def\umlTmp{Label}%
+ \ifx\umlTmp\umlAEType%
+ \edef\umlAEHeight{-\umlAEHeight}\fi%
+ }%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The command}
+%
+% \begin{macro}{\umlAssociationEnd}
+% This places a symbol (third argument) on the \meta{From} end of
+% the relation (indicated by the second argument).
+% \begin{macrocode}
+\newcommand\umlAssociationEnd[3][]{%
+ \umlAssociationEndNull%
+ \psset[umlAE]{kind=AssociationEnd,#1}%
+ \umlAssociationEndUseFraction%
+% AE:#2:\umlAENoderefClose:\umlAENoderefFar:
+ \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{%
+ \umlAENoderefClose#2}{\umlAENoderefFar#2}%
+ {\umlColorsAdjust%
+ \lput[\umlAERefpoint]{\umlAEFractionAngle}(\umlAEFraction){%
+ \rput[\umlAERefpoint]{\umlAEAngle}(\umlAEOffset, \umlAEHeight){%
+ #3}%
+ }%
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Label}\label{Labels}\label{sec:labels}
+% \label{sec:impLabel}
+%
+% \begin{macro}{\umlLabel}
+% A label is a symbol with default height and offset.
+% \begin{macrocode}
+\newcommand\umlLabel[3][]{% Null unneccesary
+ \umlAssociationEnd[kind=Label,offset=4ex,height=2ex,angle=N, #1]{#2}{#3}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\umlLabelA}
+% "\umlLabelA" and "\umlLabelB" are
+% provided for convenience and backward compatibility.
+% \begin{macrocode}
+\newcommand\umlLabelA[2][]{\umlLabel[#1,fraction=A]{#2}}
+\newcommand\umlLabelB[2][]{\umlLabel[#1,fraction=B]{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Symbol}\label{Symbols}\label{sec:symbols}
+% \label{sec:impSymbol}
+%
+% \begin{macro}{\umlSymbol}
+% A symbol is a symbol with default height and offset.
+% \begin{macrocode}
+\newcommand\umlSymbol[3][]{% Null unneccesary
+ \umlAssociationEnd[kind=Symbol,offset=0ex,height=0ex,
+ fractionAngle=:L,refpoint=t,#1]{%
+ #2}{\umlSymbolUseFraction%
+ #3}}
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\umlAssociationEndUseFraction}
+% \begin{macrocode}
+\newcommand\umlSymbolUseFraction{%
+ \umlFromTo{\umlAEFraction}{%
+ }{%
+ }%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlSymbolA}
+% "\umlSymbolA" and "\umlSymbolB" are
+% provided for convenience and backward compatibility.
+% \begin{macrocode}
+\newcommand\umlSymbolA[2][]{\umlSymbol[#1,fraction=A]{#2}}
+\newcommand\umlSymbolB[2][]{\umlSymbol[#1,fraction=B]{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Navigability}\label{sec:impNavigability}
+%
+% \begin{macro}{\umlNavigability}
+% A specialized version of "\umlAssociationEnd".
+% Takes two arguments: a list of named options, and the relation reference.
+% \begin{macrocode}
+\newcommand\umlNavigability[2][]{
+ \def\umlEndSymbol{\psline%
+ (-1ex, -1.618ex)%
+ (0,0)%
+ (1ex, -1.618ex)}%
+ \umlSymbol[kind=Navigability, #1]{#2}{\umlEndSymbol}%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlNavigabilityA}
+% "\umlNavigabilityA" and "\umlNavigabilityB" are
+% provided for convenience and backward compatibility.
+% \begin{macrocode}
+\newcommand\umlNavigabilityA[2][]{\umlNavigability[#1,fraction=A]{#2}}
+\newcommand\umlNavigabilityB[2][]{\umlNavigability[#1,fraction=B]{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Colors}\label{sec:impColors}
+%
+% \subsection{Colorset}\label{sec:impColorset}
+%
+% \begin{macro}{\umlColorset}
+% Every "\umlDrawable" (really, every instance of a subcommand) calls
+% "\umlColorsAdjust". Then, the colors is set anew for the Drawable.
+% The effect then depends on the value of "\umlColorsAdjust". This
+% value is set by "\umlColorsDefault", "\umlColorsImport" etc.
+% \begin{macrocode}
+\newcommand\umlColorset[1]{%
+ \def\umlColorsAdjust{#1%
+ \psset{linecolor=umlLinecolor, fillcolor=umlFillcolor}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlColorsDefault}
+% \begin{macrocode}
+\newcommand\umlColorsDefault{%
+ \umlColorset{%
+ \definecolor{umlColor}{gray}{0}%
+ \definecolor{umlLinecolor}{gray}{0}%
+ \definecolor{umlFillcolor}{gray}{1}%
+ \definecolor{umlClassifierFillcolor}{gray}{0.85}%
+ \definecolor{umlDiagramFillcolor}{gray}{0.95}%
+ \definecolor{umlRelationColor}{gray}{0}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlColorsGray}
+% \begin{macrocode}
+\newcommand\umlColorsGray{%
+ \umlColorset{%
+ \definecolor{umlColor}{gray}{0.4}%
+ \definecolor{umlLinecolor}{gray}{0.4}%
+ \definecolor{umlFillcolor}{gray}{1}%
+ \definecolor{umlClassifierFillcolor}{gray}{0.90}%
+ \definecolor{umlDiagramFillcolor}{gray}{0.98}%
+ \definecolor{umlRelationColor}{gray}{0.4}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlColorsImport}
+% The import color set makes the boxes blue.
+% \begin{macrocode}
+\newcommand\umlColorsImport{%
+ \umlColorset{%
+ \definecolor{umlColor}{rgb}{0, 0, 0.4}%
+ \definecolor{umlLinecolor}{rgb}{0, 0, 0.4}%
+ \definecolor{umlFillcolor}{rgb}{.8, .8, 1}%
+ \definecolor{umlClassifierFillcolor}{rgb}{.85, .85, 1}%
+ \definecolor{umlDiagramFillcolor}{rgb}{.95, .95, 1}%
+ \definecolor{umlRelationColor}{rgb}{0, 0, 0.4}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlColorsArgument}
+% This color set makes the boxes green.
+% \begin{macrocode}
+\newcommand\umlColorsArgument{%
+ \umlColorset{%
+ \definecolor{umlColor}{rgb}{0, 0.4, 0}%
+ \definecolor{umlLinecolor}{rgb}{0, 0.4, 0}%
+ \definecolor{umlFillcolor}{rgb}{.8, 1, .8}%
+ \definecolor{umlClassifierFillcolor}{rgb}{.85, 1, .85}%
+ \definecolor{umlDiagramFillcolor}{rgb}{.95, 1, .95}%
+ \definecolor{umlRelationColor}{rgb}{0, 0.7, 0}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlColorsRed}
+% \begin{macrocode}
+\newcommand\umlColorsRed{%
+ \umlColorset{%
+ \definecolor{umlColor}{rgb}{0.4, 0, 0}%
+ \definecolor{umlLinecolor}{rgb}{0.4, 0, 0}%
+ \definecolor{umlFillcolor}{rgb}{1, .8, .8}%
+ \definecolor{umlClassifierFillcolor}{rgb}{1, .85, .85}%
+ \definecolor{umlDiagramFillcolor}{rgb}{1, .95, .95}%
+ \definecolor{umlRelationColor}{rgb}{0.4, 0, 0}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlColorsSub}
+% \begin{macrocode}
+\newcommand\umlColorsSub{%
+ \umlColorset{%
+ \definecolor{umlColor}{rgb}{.6, .2, .2}%
+ \definecolor{umlLinecolor}{rgb}{.6, .2, .2}%
+ \definecolor{umlFillcolor}{rgb}{.9, .8, .8}%
+ \definecolor{umlClassifierFillcolor}{rgb}{.9, .8, .8}%
+ \definecolor{umlDiagramFillcolor}{rgb}{.97, .95, .95}%
+ \definecolor{umlRelationColor}{rgb}{.6, .2, .2}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\umlColorsDefault
+\umlColorsAdjust
+% \end{macrocode}
+%
+% \subsection{Using color sets}
+% \begin{macro}{\umlColors}
+% \begin{macrocode}
+\newenvironment{umlColors}[1]{\bgroup#1}{\egroup}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Positions}\label{sec:impSyntaxPositions}
+%
+% \begin{macrocode}
+\SpecialCoor
+\newlength{\umlNodeSep}
+\setlength{\umlNodeSep}{1em}
+% \end{macrocode}
+%
+% A historical note here: First, "\umlBox" used to throw lots of pnodes
+% around. However, this used huge memory space. This way works much
+% better. However, I have not found any way to do the corresponding
+% thing in the relations.
+%
+%\subsection{PlaceNode}\label{sec:impPlaceNode}
+%
+% \begin{macrocode}
+\newlength\umlPlaceNodeX
+\newlength\umlPlaceNodeY
+% \end{macrocode}
+%
+% \begin{macro}{\umlPlaceNodeNull}
+% \begin{macrocode}
+\newcommand\umlPlaceNodeNull{%
+ \def\umlPlaceNodeNodesepX{0pt}%
+ \def\umlPlaceNodeNodesepY{0pt}%
+ \def\umlPlaceNodeAngleX{}%
+ \def\umlPlaceNodeAngleY{}%
+ \def\umlPlaceNodeOffsetX{}%
+ \def\umlPlaceNodeOffsetY{}%
+ \setlength\umlPlaceNodeX{0pt}%
+ \setlength\umlPlaceNodeY{0pt}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{leftside-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{leftside}[0pt]{%
+ \def\umlPlaceNodeAngleX{,angle=180}%
+ \def\umlPlaceNodeNodesepX{#1}}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{rightside-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{rightside}[0pt]{%
+ \def\umlPlaceNodeAngleX{,angle=0}%
+ \def\umlPlaceNodeNodesepX{#1}}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{up-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{top}[0pt]{%
+ \def\umlPlaceNodeAngleY{,angle=90}%
+ \def\umlPlaceNodeNodesepY{#1}}%
+% \end{macrocode}%
+% \end{macro}
+% \begin{macro}{bottom-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{bottom}[0pt]{%
+ \def\umlPlaceNodeAngleY{,angle=270}%
+ \def\umlPlaceNodeNodesepY{#1}}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{left-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{left}[0pt]{%
+ \addtolength\umlPlaceNodeX{-#1}}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{right-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{right}[0pt]{\addtolength\umlPlaceNodeX{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{up-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{up}[0pt]{\addtolength\umlPlaceNodeY{#1}}
+% \end{macrocode}%
+% \end{macro}
+% \begin{macro}{down-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{down}[0pt]{\addtolength\umlPlaceNodeY{-#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{angle-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{angle}{%
+ \def\umlPlaceNodeAngleX{,angle=#1}%
+ \def\umlPlaceNodeAngleY{,angle=#1}}%
+\define@key[psset]{umlPlaceNode}{angleX}{\def\umlPlaceNodeAngleX{,angle=#1}}%
+\define@key[psset]{umlPlaceNode}{angleY}{\def\umlPlaceNodeAngleY{,angle=#1}}%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{offset-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{offset}{
+ \def\umlPlaceNodeOffsetX{,offset=#1}%
+ \def\umlPlaceNodeOffsetY{,offset=#1}}%
+\define@key[psset]{umlPlaceNode}{offsetX}{\def\umlPlaceNodeOffsetX{,offset=#1}}%
+\define@key[psset]{umlPlaceNode}{offsetY}{\def\umlPlaceNodeOffsetY{,offset=#1}}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{nodesep-}
+% \begin{macrocode}
+\define@key[psset]{umlPlaceNode}{nodesep}{%
+ \def\umlPlaceNodeNodesepX{#1}%
+ \def\umlPlaceNodeNodesepY{#1}}%
+\define@key[psset]{umlPlaceNode}{nodesepX}{\def\umlPlaceNodeNodesepX{#1}}%
+\define@key[psset]{umlPlaceNode}{nodesepY}{\def\umlPlaceNodeNodesepY{#1}}%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlPlaceNode}
+% \begin{macrocode}
+\newcommand\umlPlaceNode[3][]{%
+ \umlPlaceNodeNull%
+ \psset[umlPlaceNode]{#1}%
+% \end{macrocode}
+% Placement relative to the node
+% \begin{macrocode}
+ \rput(%
+ [nodesep=\umlPlaceNodeNodesepX\umlPlaceNodeOffsetX\umlPlaceNodeAngleX]#2|%
+ [nodesep=\umlPlaceNodeNodesepY\umlPlaceNodeOffsetY\umlPlaceNodeAngleY]#2){%
+% \end{macrocode}
+% Placement relative to that
+% \begin{macrocode}
+% \rput(\umlPlaceNodeX, \umlPlaceNodeY){%
+% \end{macrocode}
+% The new node is placed
+% \begin{macrocode}
+ \pnode(\umlPlaceNodeX, \umlPlaceNodeY){#3}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlRight}
+% \label{sec:impTopLeft}
+% The first coordinate commands are very simple.
+% They takes as argument node.
+% \begin{macrocode}
+\newcommand\umlRight[1]{[angle=0]#1}
+\newcommand\umlTop[1]{[angle=90]#1}
+\newcommand\umlLeft[1]{[angle=180]#1}
+\newcommand\umlBottom[1]{[angle=270]#1}
+\newcommand\umlTopRight[1]{[angle=0]#1|[angle=90]#1}
+\newcommand\umlBottomRight[1]{[angle=0]#1|[angle=270]#1}
+\newcommand\umlTopLeft[1]{[angle=180]#1|[angle=90]#1}
+\newcommand\umlBottomLeft[1]{[angle=180]#1|[angle=270]#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlRightSep}
+% The "Sep" coordinate commands use "\umlNodeSep" to make
+% some space between the nodes.
+% \begin{macrocode}
+\newcommand\umlRightSep[1]{[angle=0, nodesep=\umlNodeSep]#1}
+\newcommand\umlTopSep[1]{[angle=90, nodesep=\umlNodeSep]#1}
+\newcommand\umlLeftSep[1]{[angle=180, nodesep=\umlNodeSep]#1}
+\newcommand\umlBottomSep[1]{[angle=270, nodesep=\umlNodeSep]#1}
+\newcommand\umlTopRightSep[1]{%
+ [angle=0, nodesep=\umlNodeSep]#1|[angle=90, nodesep=\umlNodeSep]#1}
+\newcommand\umlBottomRightSep[1]{%
+ [angle=0, nodesep=\umlNodeSep]#1|[angle=270, nodesep=\umlNodeSep]#1}
+\newcommand\umlTopLeftSep[1]{%
+ [angle=180, nodesep=\umlNodeSep]#1|[angle=90, nodesep=\umlNodeSep]#1}
+\newcommand\umlBottomLeftSep[1]{%
+ [angle=180, nodesep=\umlNodeSep]#1|[angle=270, nodesep=\umlNodeSep]#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlRightOpt}
+% This takes two mandatory arguments: Named options and the usual
+% node.
+%
+% Of course, it would be nice to make the first argument optional, thus
+% combining "\umlRight" and "\umlRightOpt". However,
+% this does not work together with mandatory argument in "\umlBox". I
+% have found no elegant solution to this (despite some nights\dots)
+% \begin{macrocode}
+\newcommand\umlRightOpt[2]{[angle=0, #1]#2}
+\newcommand\umlTopOpt[2]{[angle=90, #1]#2}
+\newcommand\umlLeftOpt[2]{[angle=180, #1]#2}
+\newcommand\umlBottomOpt[2]{[angle=270, #1]#2}
+\newcommand\umlTopRightOpt[2]{[angle=0, #1]#2|[angle=90, #1]#2}
+\newcommand\umlBottomRightOpt[2]{[angle=0, #1]#2|[angle=270, #1]#2}
+\newcommand\umlTopLeftOpt[2]{[angle=180, #1]#2|[angle=90, #1]#2}
+\newcommand\umlBottomLeftOpt[2]{[angle=180, #1]#2|[angle=270, #1]#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\umlRightSep}
+% \begin{macrocode}
+\newcommand\umlRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlTopSepOpt[2]{[angle=90, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlLeftSepOpt[2]{[angle=180, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlBottomSepOpt[2]{[angle=270, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlTopRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2|[angle=90, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlBottomRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2|[angle=270, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlTopLeftSepOpt[2]{%
+ [angle=180, nodesep=\umlNodeSep, #1]#2|[angle=90, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlBottomLeftSepOpt[2]{%
+ [angle=180, nodesep=\umlNodeSep, #1]#2|[angle=270, nodesep=\umlNodeSep, #1]#2}
+% \end{macrocode}
+% \end{macro}
+%
+%\iffalse
+%</package>
+%\fi
+% \GlossaryPrologue{}
+%
+% \IfFileExists{uml.gls}{\PrintChanges}
+% {\begin{quote}You should create the list of changes by
+%
+% ~~~ \texttt{makeindex -s gglo.ist -o uml.gls uml.glo}
+%
+% and running \texttt{latex uml.drv} again.\end{quote}}
+%
+%\iffalse
+%<*example>
+\newcommand\umlADTExample{%
+ \umlDiagram[box=,sizeX=15cm, sizeY=16cm,ref=ADTdiagram,
+ grayness=0.92]{}% End of diagram
+ \umlSchema[pos=\umlTopRight{ADTdiagram}, posDelta={-.5,-.5},
+ refpoint=tr]{ADT}{% Attributes
+ \umlAttribute[visibility,type=String]{name}}{}{}{}{}
+ \umlSchema[pos=\umlTopLeft{ADTdiagram}, posDelta={.5,-1},
+ refpoint=lt, abstract,
+ ref=ADTexample]{ADT-example}{%
+ \umlAttribute[visibility=-,
+ type=\emph{\umlColorsArgument\umlColorsAdjust type},default=null]{%
+ firstNode}
+ }{%Methods
+ }{%Arguments
+ \umlArgument[type=Metaclass]{type}
+ }{%Constraints
+ }{%Structure
+ \umlDiagram[box=,innerBorder=2mm,outerBorder]{%
+ \umlClass[pos={.5,.5}, ref=adtNode,box=]{Node}{%
+ \umlAttribute[visibility,
+ type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ data}}{}%
+ \umlAssociation[angleA=20, angleB=-20,
+ arm=1em, arm=1em]{adtNode}{adtNode}%
+ }\cr% End of Diagram
+ }% End of ADT-example
+ \umlInstance{ADTexample}{ADT}%
+ \umlSchema[pos=\umlRight{ADTexample}, posDelta={3,-1},
+ refpoint=tl, ]{Graph}{% Attributes
+ }{% Methods
+ \umlMethod[visibility,]{%
+ insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility,
+ type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ dijkstra}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, type=boolean]{%
+ insertEdge}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, ]{%
+ delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ }{% Arguments
+ }{% Constraints
+ }{% Structure
+ \umlDiagram[box=,innerBorder=2mm, outerBorder,
+ sizeX=11em,sizeY=3.5em,ref=GraphDiagram]{%
+ \begin{umlColors}{\umlColorsSub}
+ \umlClass[pos=\umlBottomLeft{GraphDiagram},
+ posDelta={1,1}, ref=graphNode]{Node}{}{}%
+ \umlAssociation[angleA=20, angleB=-20, armA=1em, armB=1em
+ ]{graphNode}{graphNode}%
+ \end{umlColors}
+ \umlLabelA[height=0mm,offset=1ex]{graphNodegraphNode}{*}%
+ \umlLabelB[height=0mm,offset=1ex,refpoint=t
+ ]{graphNodegraphNode}{*}%
+ \umlSymbol[fraction=.5]{graphNodegraphNode}{\pnode{gngn}}
+ \umlClass[pos=gngn, posDelta={2,0},
+ ref=graphEdge, refpoint=l]{Edge}{%
+ \umlAttribute[type=real]{cost}}{}%
+ \umlAssociationClass[]{graphEdge}{gngn}%
+ }\cr% End of diagram
+ }% End of Graph
+ \umlSubclass{Graph}{ADTexample}
+ \umlSchema[posX=\umlLeft{ADTexample}, posDelta={3em,-1em},
+ posY=\umlBottom{Graph},
+ refpoint=tl, ref=searchTree]{Search Tree}{% Attributes
+ }{% Methods
+ \umlMethod[visibility,]{%
+ insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility,
+ type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, type=boolean]{%
+ search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, ]{%
+ delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ }{% Arguments
+ \umlArgument[type=Integer, initialValue=2]{arity}
+ \umlArgument[type={${\umlColorsArgument\umlColorsAdjust type}
+ \times {\umlColorsArgument\umlColorsAdjust type}\rightarrow$
+ boolean}, default=>]{sort}
+ }{% Constraints
+ }{% Structure
+ \umlDiagram[box=, sizeX=14em, sizeY=4em,
+ innerBorder=2mm, outerBorder]{%
+ \begin{umlColors}{\umlColorsSub}
+ \umlClass[pos={.5, .5}, ref=treeNode]{Node}{}{}%
+ \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
+ ]{treeNode}{treeNode}%
+ \end{umlColors}
+ \umlLabelA[height=1mm, offset=4mm,refpoint=l
+ ]{treeNodetreeNode}{%
+ \emph{\umlColorsArgument\umlColorsAdjust arity}}%
+ \umlLabelB[refpoint=tl,height=-1mm, offset=4mm,
+ ]{treeNodetreeNode}{1}%
+ }\cr% End of diagram
+ }%
+ \umlSubclass{searchTree}{ADTexample}%
+ \umlSchema[pos=\umlBottomLeft{searchTree},posDelta={0,-1},
+ refpoint=lt]{List}{%Attributes
+ }{% Methods
+ }{% Arguments
+ }{% Constraints
+ }{% Structure
+ \umlDiagram[box=, sizeX=6em, sizeY=4em,
+ innerBorder=2mm, outerBorder]{%
+ \begin{umlColors}{\umlColorsSub}
+ \umlClass[pos={.5, .5}, ref=listNode]{Node}{}{}%
+ \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
+ ]{listNode}{listNode}%
+ \end{umlColors}
+ \umlLabelA[height=1mm, offset=5mm, refpoint=l
+ ]{listNodelistNode}{1}%
+ \umlLabelB[refpoint=tl, height=-1mm,offset=5mm
+ ]{listNodelistNode}{1}%
+ }\cr% End of diagram
+ }% End of Schema List
+ \umlPlaceNode[leftside, top, down=1em]{List}{Listtl}
+ \umlPlaceNode[leftside,right=2em,bottom]{ADTexample}{ADTexamplebl}
+ \umlSubclass[armA=1.4142em, armAngleA=135]{Listtl}{ADTexamplebl}%
+ \umlSchema[pos=\umlTopRight{List},posDelta={1em,-2em},
+ refpoint=tl]{Queue}{% Attributes
+ }{\umlMethod[visibility]{%
+ enqueue}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ dequeue}{}}{%Arguments
+ }{%Constraints
+ \umlCompartmentline{First come, first served.}
+ }{% Structure
+ }% End of Queue
+ \umlPlaceNode[rightside, top, down=1em]{List}{Listtr}
+ \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Queue}{Listtr}%
+ \umlSchema[pos=\umlTopRight{Queue},posDelta={\umlNodeSep,0em},
+ refpoint=tl]{Stack}{%Attributes
+ }{% Methods
+ \umlMethod[visibility]{
+ push}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
+ \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
+ pop}{}
+ }{% Arguments
+ }{% Constraints
+ \umlCompartmentline{S:Stack = S.push(x).pop()}
+ }{% Structure
+ }% End of Stack
+ \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Stack}{Listtr}%
+}
+%</example>
+%\fi
+%
+%
+% \Finale
+\endinput
diff --git a/Master/texmf-dist/source/latex/uml/uml.ins b/Master/texmf-dist/source/latex/uml/uml.ins
new file mode 100644
index 00000000000..b79d1759153
--- /dev/null
+++ b/Master/texmf-dist/source/latex/uml/uml.ins
@@ -0,0 +1,17 @@
+\def\filedate{2006/11/26}
+\def\batchfile{uml.ins}
+\input docstrip.tex
+\generateFile{uml.sty}{t}{\from{uml.dtx}{package}}
+\generateFile{example.tex}{f}{\from{uml.dtx}{example}}
+%
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* All the files with the extension '.sty'}
+\Msg{*}
+\Msg{* To produce the documentation run the .drv File through LaTeX.}
+\Msg{*}
+\Msg{* Happy TeXing}
+\Msg{***************************************************************}
diff --git a/Master/texmf-dist/tex/latex/uml/uml.sty b/Master/texmf-dist/tex/latex/uml/uml.sty
new file mode 100644
index 00000000000..58a18f1ab7c
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/uml/uml.sty
@@ -0,0 +1,935 @@
+%%
+%% This is file `uml.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% uml.dtx (with options: `package')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from uml.sty.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file uml.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+\def\filedate{2006/11/28}
+\def\docdate{2006/11/28}
+\def\fileversion{0.10}
+\def\basename{uml}
+%% Package 'uml' to use with LaTeX2e and PSTricks
+%% Copyright 2006 by Ellef Fange Gjelstad.
+%% http://www.ifi.uio.no/~ellefg/uml.sty/
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN archives
+%% in directory macros/latex/base/lppl.txt.
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+
+
+
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{uml}
+
+
+
+\DeclareOption{debug}{
+ \def\umlDebugLineStyle{dashed}
+ \def\umlDebugLength{1pt}
+ }
+\DeclareOption{nodebug}{
+ \def\umlDebugLineStyle{none}
+ \def\umlDebugLength{0pt}
+}
+\def\umlDebugLinestyle{none}
+\def\umlDebugLength{0pt}
+\newcommand\umlIndexOn{\renewcommand\umlIndex[2]{\index{##1!##2}}}
+\newcommand\umlIndexOff{\renewcommand\umlIndex[2]{}}
+\DeclareOption{index}{\umlIndexOn}
+\DeclareOption{noindex}{\umlIndexOff}
+\newcommand\umlIndex[2]{\index{#1!#2}}
+\ExecuteOptions{nodebug}
+\ProcessOptions
+\RequirePackage{pstricks}
+\RequirePackage{pst-node}
+
+\RequirePackage{pst-xkey}
+\pst@addfams{uml,umlAE,umlPlaceNode}
+
+\RequirePackage{relsize}
+
+
+
+
+\def\umlTrueVariable{true}
+
+\psset{unit=1em}
+\def\umlDrawableNull{%
+ \def\umlImport{}%
+ \def\umlKind{Drawable}%
+ \gdef\umlName{DrawableNameDefault}%
+ \def\umlNameDefault{DrawableNameDefault}%
+ %\ifx\umlName\umlNameDefault\else umlName is changed
+}
+
+\define@key[psset]{uml}{kind}{\def\umlKind{#1}}
+
+\define@key[psset]{uml}{name}{\gdef\umlName{#1}}
+
+
+\define@key[psset]{uml}{import}{\umlColorsImport}
+\define@key[psset]{uml}{noimport}{\umlColorsDefault}
+\define@key[psset]{uml}{argument}{\umlColorsArgument}
+\define@key[psset]{uml}{colorset}[\umlColorsDefault]{#1}
+\newcommand\umlDrawable[2][]{%
+ \umlDrawableNull%
+ \psset[uml]{kind=Drawable,#1}%
+ #2%
+}
+\def\umlElementNull{%
+ \def\umlReference{refdef}%
+ \def\umlStereotype{}%
+ \def\umlSubof{}%
+ \def\umlImportedFrom{}%
+ \def\umlComment{}%
+ \def\umlAbstract{}%
+}
+
+\define@key[psset]{uml}{reference}{\def\umlReference{#1}}
+\define@key[psset]{uml}{ref}{\def\umlReference{#1}}
+\define@key[psset]{uml}{stereotype}{%
+ \def\umlStereotype{{\hfil\phantom{x}<<#1>>\phantom{x}\hfil}\\}}
+\define@key[psset]{uml}{subof}{\def\umlSubof{{~Sub of: #1}\\}}
+\define@key[psset]{uml}{abstract}[]{\def\umlAbstract{\emph}}%
+\define@key[psset]{uml}{importedFrom}{%
+ \def\umlImportedFrom{{~From: #1}\\}%
+ \umlColorsImport%
+}
+\define@key[psset]{uml}{comment}{\def\umlComment{{~#1}\\}}
+\newcommand\umlElement[2][]{%
+ \umlElementNull%
+ {\umlDrawable[kind=Element,#1]{%
+ \umlColorsAdjust%
+ #2}}}
+\def\umlBoxNullPositions{%
+ \def\umlPosCommand{%
+ \rput[\umlRefpoint](\umlPos)}%
+ \def\umlPos{\umlPosX|\umlPosY}%
+ \def\umlPosX{0,0}%
+ \def\umlPosY{0,0}%
+ \def\umlPosDeltaCommand{%
+ \rput[\umlRefpoint](\umlPosDelta)}%
+ \def\umlPosDelta{\umlPosDeltaX|\umlPosDeltaY}%
+ \def\umlPosDeltaX{0,0}%
+ \def\umlPosDeltaY{0,0}%
+ \def\umlRefpoint{bl}%
+ }%
+\define@key[psset]{uml}{pos}[0,0]{\def\umlPos{#1}}
+\define@key[psset]{uml}{posX}[0,0]{\def\umlPosX{#1}}
+\define@key[psset]{uml}{posY}[0,0]{\def\umlPosY{#1}}
+\define@key[psset]{uml}{posDelta}[0,0]{\def\umlPosDelta{#1}}
+\define@key[psset]{uml}{posDeltaX}[0,0]{\def\umlPosDeltaX{#1}}
+\define@key[psset]{uml}{posDeltaY}[0,0]{\def\umlPosDeltaY{#1}}
+\define@key[psset]{uml}{refpoint}{\def\umlRefpoint{#1}}
+\def\umlBoxNullBoxes{%
+ \def\umlBoxH{\hbox to 0cm}%
+ \def\umlBoxV{\smash}%
+ }%
+\define@key[psset]{uml}{box}{%
+ \def\umlBoxH{}% no \hbox to 0cm
+ \def\umlBoxV{}% no \smash anymore
+ \def\umlPosCommand{}% no \rput... anymore
+ \def\umlPosDeltaCommand{}}% Ditto
+\def\umlBoxNullVisual{%
+ \def\umlGrayness{1}%
+ \def\umlBorder{0mm}%
+ \def\umlInnerBorder{0mm}%
+ \def\umlOuterBorder{0mm}%
+ \def\umlFillcolorCommand{umlFillcolor}%
+ }%
+\define@key[psset]{uml}{grayness}[.85]{\definecolor{umlFillcolor}{gray}{#1}}
+\define@key[psset]{uml}{fillcolorCommand}[umlFillcolor]{%
+ \def\umlFillcolorCommand{#1}}
+\define@key[psset]{uml}{border}[0.4pt]{\gdef\umlBorder{#1}}
+\define@key[psset]{uml}{outerBorder}[1pt]{\def\umlOuterBorder{#1}}
+\define@key[psset]{uml}{innerBorder}[\umlhsep]{\def\umlInnerBorder{#1}}
+\def\umlBoxNullSize{%
+ \def\umlSizeX{5mm}%
+ \def\umlSizeY{7mm}%
+}
+\define@key[psset]{uml}{sizeX}{\def\umlSizeX{#1}}
+\define@key[psset]{uml}{sizeY}{\def\umlSizeY{#1}}
+\def\umlBoxNull{%
+ \umlBoxNullPositions%
+ \umlBoxNullBoxes%
+ \umlBoxNullVisual%
+ \umlBoxNullSize%
+ }%
+\newcommand\umlBox[2][]{\leavevmode%
+ \umlBoxNull%
+ \umlElement[kind=Box,#1]{%
+ \umlBoxH{% \hbox to 0cm or nothing
+ \umlBoxV{% \smash or nothing
+ \umlPosCommand{%
+ \umlPosDeltaCommand{%
+ \rnode{\umlReference}{%
+ \setlength{\fboxrule}{0mm}%
+ \setlength{\fboxsep}{\umlOuterBorder}%
+ \fbox{%
+ \psframebox[framesep=\umlInnerBorder,
+ linewidth=\umlBorder,
+ fillcolor=\umlFillcolorCommand, fillstyle=solid]{%
+ #2}%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }
+
+\newcommand\umlDiagramNull{%
+ \def\umlGrid{}%
+ }
+\define@key[psset]{uml}{grid}[1]{\message{named option grid is deprecated and of no use}}
+\newcommand\umlDiagram[2][]{%
+ \umlDiagramNull%
+ \umlBox[kind=Diagram, fillcolorCommand=umlDiagramFillcolor,
+ box=,#1]{%
+
+ \expandafter{#2}{%
+ \rule{\umlDebugLength}{\umlSizeY}%
+ \rule{\umlSizeX}{\umlDebugLength}}%
+ }%
+ }%
+
+
+\newcommand\umlStretchboxNull{%
+ \def\umlGraphicalName{StrechboxDefault{\umlAbstract\umlName}\\}%
+}
+
+
+
+\newcommand\umlStretchbox[3][]{%
+ \umlStretchboxNull%
+ \umlBox[kind=Stretchbox, name={#2}, ref={#2}, #1]{%
+ \umlIndex{\umlName}{\umlKind}%
+ \rnode{\umlReference}{#3}%
+ }%
+ }%
+
+\newcommand\umlPackage[3][]{%
+ % Null unneccessary
+ \def\umlName{#1}%
+ \begin{tabular}{@{}l@{}}%
+ \umlStretchbox[kind=Package, border=0.4pt,#1]{#2}{%
+ \def\umlGraphicalName{%
+ {\umlhspace\hfill\relsize{2}\textbf{\umlName}%
+ \rule{0mm}{2.3ex}\hfill\umlhspace}\\%
+ }%
+ \rnode{small\umlReference}{%
+ \begin{tabular}{@{}l@{}}%
+ \umlStereotype%
+ \umlGraphicalName%
+ \umlImportedFrom%
+ \umlComment%
+ \umlSubof%
+ \end{tabular}}}%
+ \cr\noalign{\vskip -\umlBorder}%
+ \umlStretchbox[kind=Package,border=0.4pt,#1]{#2}{%
+ \rnode{big\umlReference}{%
+ \begin{tabular}{@{}l@{}}%
+ #3%
+ \cr%
+ \end{tabular}}}% End of lower rectangle
+ \end{tabular}%
+ }%
+
+
+\newcommand\umlClassifierNull{%
+ \def\umlObject{}%
+ \umlClassifierEmptytrue%
+}
+\newif\ifumlClassifierEmpty%
+
+\define@key[psset]{uml}{object}{\def\umlObject{\underbar}}
+
+
+\define@key[psset]{uml}{instance}{\def\umlObject{\underbar}}
+
+\newcommand\umlClassifier[3][]{%
+ \umlClassifierNull%
+ \def\umlName{#2}%
+ \umlStretchbox[kind=Classifier,border=.4pt,
+ fillcolorCommand=umlClassifierFillcolor,#1]{#2}{%
+ \def\umlGraphicalName{%
+ \rule{0mm}{2.8ex}%
+ \umlhspace\larger\hfill\textbf{%
+ \umlAbstract{\umlObject{\umlName}}}\hfill\umlhspace\\}%
+ \begin{tabular}[tl]{@{}l@{}}%
+ \umlStereotype%
+ \umlGraphicalName%
+ \umlImportedFrom%
+ \umlComment%
+ \umlSubof%
+ #3%
+ \ifumlClassifierEmpty\\\noalign{\vskip -2.5ex}\fi
+ \end{tabular}%
+ }%
+ }%
+
+
+\newcommand\umlClass[4][]{%
+ \umlClassifier[kind=Class,#1]{#2}{%
+ \umlCompartment[name=attributes]{#3}%
+ \umlCompartment[name=operations]{#4}%
+ }%
+ }%
+
+
+\newcommand\umlSchema[7][]{%
+ \umlClassifier[kind=Schema,#1]{#2}{%
+ \umlCompartment[name=attributes]{#3}% Attributes
+ \umlCompartment[name=operations]{#4}% Methods
+ \umlCompartment[name=arguments]{#5}% Arguments
+ \umlCompartment[name=constraints]{#6}% Constraints
+ \umlCompartment[name=structure]{#7}% Structure
+ }%
+ }%
+
+
+
+
+
+\newcommand\umlCompartmentNull{%
+}
+\def\ifisnull#1#2#3{\def\inner{#1}%
+ \ifx\inner\empty%
+ #2\else{}#3%
+ \fi}
+\define@key[psset]{uml}{last}[]{%
+ \message{The named option last= is deprecated and of no use.}%
+}
+
+
+\newif\ifumlCompartmentSuppress
+
+\define@key[psset]{uml}{suppress}[true]{%
+ \def\arg{#1}%
+ \ifx\arg\umlTrueVariable\umlCompartmentSuppresstrue%
+ \else\umlCompartmentSuppressfalse%
+ \fi%
+}
+
+
+
+
+\newif\ifumlCompartmentNamesShow
+
+\define@key[psset]{uml}{showname}[true]{%
+ \def\arg{#1}%
+ \ifx\arg\umlTrueVariable\umlCompartmentNamesShowtrue%
+ \else\umlCompartmentNamesShowfalse%
+}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+
+
+
+
+\newcommand\umlCompartmentCommon[2][]{%
+
+ \ifhmode \vspace*{-2.5ex}\\\fi%
+ \hline%
+ \ifumlCompartmentNamesShow%
+ \ifx\umlName\umlNameDefault\else%
+ \omit\hfil\textbf{\umlName}\hfil\\%
+ \fi%
+ \fi%
+ \def\umlCompartmentContents{#2}%
+ \ifx\umlCompartmentContents\empty%
+ \vspace*{-1.5ex}%
+ \else% There is contents
+ \umlClassifierEmptyfalse%
+ #2%
+ \fi%
+ \ifhmode\\\fi%
+ }
+\newcommand\umlCompartment[2][]{%
+ \umlCompartmentNull%
+ \def\umlCompartmentContents{#2}%
+ \umlDrawable[kind=Compartment,#1]{%
+ \umlColorsAdjust%
+ \ifumlCompartmentSuppress%
+ \ifx\umlCompartmentContents\empty\else%
+ \umlCompartmentCommon[#1]{#2}%
+ \fi%
+ \else%
+ \umlClassifierEmptyfalse%
+ \umlCompartmentCommon[#1]{#2}%
+ \fi}}%
+
+
+
+\def\umlhsep{.5ex}
+\newcommand\umlhspace{\hspace*{\umlhsep}}
+
+\newcommand\umlCompartmentline[2][]{%
+ \umlDrawable[kind=Compartmentline,#1]{%
+ {\umlColorsAdjust\umlhspace{}#2{}\umlhspace}\\}}
+
+\newcommand\umlCompartmentText[1]{%
+ \umlhspace#1\umlhspace}
+
+
+\def\umlVisibilityLength{2ex}
+
+\newcommand\umlFeatureNull{%
+ \def\umlVisibility{}%
+ \def\umlType{}%
+ \def\umlPropertyString{}%
+ \def\umlInitialValue{}%
+ \def\umlName{FeatureNameDefault}%
+}
+
+\define@key[psset]{uml}{visibility}[+]{%
+ \def\umlVisibility{\hbox to \umlVisibilityLength{#1\hfil}}}
+
+\newcommand\umlTilde{\ensuremath{\sim}}
+
+\define@key[psset]{uml}{propertyString}{%
+ \def\umlPropertyString{#1}}
+\define@key[psset]{uml}{type}{%
+ \def\umlType{: #1}}
+\define@key[psset]{uml}{initialValue}{%
+ \def\umlInitialValue{= #1}}
+\newcommand\umlFeature[2][]{%
+ \umlFeatureNull%
+ \umlCompartmentline[kind=Feature, #1]{%
+ \umlIndex{\umlName}{\umlKind}%
+ #2}%
+ }%
+\def\umlAttributeNull{%
+ \def\umlMultiplicity{}%
+ \def\umlOrdering{}%
+ \def\umlMultiplicityOrdering{}%
+}
+\define@key[psset]{uml}{default}{%
+ \def\umlInitialValue{ = #1}}
+\define@key[psset]{uml}{multiplicity}{%
+ \def\umlMultiplicity{#1}%
+ \def\umlMultiplicityOrdering{[\umlMultiplicity{} \umlOrdering]}}
+\define@key[psset]{uml}{ordering}[ordered]{%
+ \def\umlOrdering{#1}%
+ \def\umlMultiplicityOrdering{[\umlMultiplicity{} \umlOrdering]}}
+
+\newcommand\umlAttribute[2][]{%
+ \umlAttributeNull%
+ \umlFeature[kind=Attribute, name={#2}, #1]{%
+ \umlVisibility #2 \umlType \umlMultiplicityOrdering
+ \umlInitialValue \umlPropertyString}}
+
+
+\newcommand\umlMethodNull{%
+}
+
+\define@key[psset]{uml}{returntype}{%
+ \def\umlType{: #1}}
+
+\newcommand\umlMethod[3][]{%
+ \umlMethodNull%
+ \def\umlName{#2}%
+ \umlFeature[kind=Method, name={#2}, #1]{%
+ \umlVisibility #2(#3) \umlType \umlPropertyString}}
+
+
+\newcommand\umlArgumentNull{%
+}
+
+\newcommand\umlArgument[2][]{%
+ \umlArgumentNull%
+ \def\umlName{#2}%
+ \umlFeature[kind=Argument, name={#2}, #1]{%
+ \emph{#2} \umlType \umlInitialValue}}
+
+
+
+\newcommand\umlRelationNullConnection{%
+ \def\umlNodesepA{0pt}%
+ \def\umlNodesepB{0pt}%
+ \def\umlOffsetA{0pt}%
+ \def\umlOffsetB{0pt}%
+ \def\umlAngleA{}%
+ \def\umlAngleB{}%
+}%
+\define@key[psset]{uml}{angleA}{\def\umlAngleA{#1}}
+\define@key[psset]{uml}{angleB}{\def\umlAngleB{#1}}
+\define@key[psset]{uml}{angle}{\def\umlAngleA{#1}\def\umlAngleB{#1}}
+\define@key[psset]{uml}{nodesepA}{\def\umlNodesepA{#1}}
+\define@key[psset]{uml}{nodesepB}{\def\umlNodesepB{#1}}
+\define@key[psset]{uml}{nodesep}{\def\umlNodesepA{#1}\def\umlNodesepB{#1}}
+
+\define@key[psset]{uml}{offsetA}{\def\umlOffsetA{#1}}
+\define@key[psset]{uml}{offsetB}{\def\umlOffsetB{#1}}
+\define@key[psset]{uml}{offset}{\def\umlOffsetA{#1}\def\umlOffsetB{#1}}
+\newcommand\umlRelationNullArmGeometry{%
+ \pssetlength\umlArmA{0pt}%
+ \pssetlength\umlArmB{0pt}%
+ \def\umlArmAngleA{0}%
+ \def\umlArmAngleB{0}%
+}
+\newlength\umlArmA
+\newlength\umlArmB
+\define@key[psset]{uml}{armA}{\pssetlength\umlArmA{#1}}
+\define@key[psset]{uml}{armB}{\pssetlength\umlArmB{#1}}
+\define@key[psset]{uml}{arm}{%
+ \pssetlength\umlArmA{#1}%
+ \pssetlength\umlArmB{#1}}
+\define@key[psset]{uml}{armAngleA}{\def\umlArmAngleA{#1}}
+\define@key[psset]{uml}{armAngleB}{\def\umlArmAngleB{#1}}
+\define@key[psset]{uml}{armAngle}{%
+ \def\umlArmAngleA{#1}%
+ \def\umlArmAngleB{#1}%
+}
+\newcommand\umlRelationNullVisual{%
+ \def\umlLinestyle{solid}%
+}
+\define@key[psset]{uml}{linestyle}{\def\umlLinestyle{#1}}
+\define@key[psset]{uml}{relationColor}[black]{\pst@getcolor{#1}\pslinecolor}
+\define@key[psset]{uml}{linecolor}{\pst@getcolor{#1}\pslinecolor}
+\newcommand\umlRelationNull{%
+ \umlRelationNullConnection%
+ \umlRelationNullArmGeometry%
+ \umlRelationNullVisual%
+}
+\newcommand\umlRelation[4][]{%
+ \umlRelationNull%
+ \umlElement[kind=Relation,ref={#2#3}, #1]{%
+ \ncline[linecolor=green, linestyle=\umlDebugLinestyle,
+ offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
+ offsetB=\umlOffsetB, nodesepB=\umlNodesepB]{#2}{#3}%
+ \lput{:R}(0){\pnode{Aa\umlReference}}%
+ \lput{:R}(1){\pnode{Ba\umlReference}}%
+ \ifx\umlAngleA\empty \else
+ \ncdiag[linestyle=\umlDebugLinestyle, linecolor=magenta, %
+ angleA=\umlAngleA,
+ offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
+ offsetB=\umlOffsetB, nodesepB=\umlNodesepB
+ ]{#2}{#2}%
+ \lput{:R}(0){\pnode{Aa\umlReference}}\fi%
+ \ifx\umlAngleB\empty \else
+ \ncdiag[linestyle=\umlDebugLinestyle, linecolor=magenta, %
+ angleA=\umlAngleB,
+ offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
+ offsetB=\umlOffsetB, nodesepB=\umlNodesepB
+ ]{#3}{#3}%
+ \lput{:R}(0){\pnode{Ba\umlReference}}\fi%
+ \ncdiag[linestyle=\umlLinestyle, linecolor=umlLinecolor,
+ angleA=\umlArmAngleA, angleB=\umlArmAngleB,
+ armA=\umlArmA, armB=\umlArmB
+ ]{%
+ Aa\umlReference}{%
+ Ba\umlReference}%
+ \ifdim \umlArmA=0pt \lput{:R}(2){\pnode{Ab\umlReference}}%
+ \else \lput{:R}(1){\pnode{Ab\umlReference}} \fi%
+ \ifdim \umlArmB=0pt \lput{:R}(1){\pnode{Bb\umlReference}}%
+ \else \lput{:R}(2){\pnode{Bb\umlReference}} \fi%
+ \lput{:R}(1){\pnode{Ac\umlReference}}%
+ \lput{:R}(2){\pnode{Bc\umlReference}}%
+ #4}% of \umlElement
+}
+
+
+
+\newlength\umlSymbolHeightDefault
+\setlength\umlSymbolHeightDefault{1em}
+\newlength\umlSymbolWidthDefault
+\setlength\umlSymbolWidthDefault{.5em}
+
+
+\newcommand\umlAssociation[3][]{%
+ \umlRelation[kind=Association, #1]{#2}{#3}{}%
+}
+
+
+\newcommand\umlSubclass[3][]{%
+ \def\umlEndSymbol{%
+ \pspolygon*[linecolor=white](0,0)%
+ (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ \pspolygon[](0,0)% Why does not dimen=inner work?
+ (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ }%
+ \umlRelation[kind=Subclass, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}%
+ }
+\def\umlGeneralization{\umlSubclass}
+
+
+
+\newlength\umlInnerWidthDefault
+\setlength\umlInnerWidthDefault{0.75em}
+\newlength\umlInnerRadiusDefault
+\setlength\umlInnerRadiusDefault{1.25em}
+\newcommand\umlInner[3][]{%
+ \def\umlEndSymbol{%
+ \pspolygon*[linecolor=white](0,0)%
+ (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
+ \psclip{%
+ \psframe[linewidth=0pt]%
+ (-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)(0,0)}
+ \pscircle(\umlInnerWidthDefault,-\umlSymbolHeightDefault)%
+ {\umlInnerRadiusDefault}
+ \endpsclip
+ \psclip{%
+ \psframe[linewidth=0pt]%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)(0,0)}
+ \pscircle(-\umlInnerWidthDefault,-\umlSymbolHeightDefault)%
+ {\umlInnerRadiusDefault}
+ \endpsclip
+ \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)}
+ \umlRelation[kind=Inner, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}
+ }}
+\newcommand\umlInstance[3][]{%
+ \def\umlEndSymbol{%
+ \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)}%
+ \umlRelation[kind={Instance-of}, linestyle=dashed, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
+ }
+\newcommand\umlAggregation[3][]{%
+ \def\umlEndSymbol{%
+ \rput(0,-\umlSymbolHeightDefault){%
+ \psline*[linecolor=white](-\umlSymbolWidthDefault, 0)%
+ (0,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault, 0)}
+ \psline*[linecolor=white]%
+ (-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)
+ \rput(0,-\umlSymbolHeightDefault){%
+ \psline(-\umlSymbolWidthDefault, 0)%
+ (0,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault, 0)}
+ \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault,
+ -\umlSymbolHeightDefault)}
+ \umlRelation[kind=Aggregation, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
+}
+\newcommand\umlComposition[3][]{%
+ \def\umlEndSymbol{%
+ \rput(0,-\umlSymbolHeightDefault){%
+ \psline*(-\umlSymbolWidthDefault, 0)%
+ (0,-\umlSymbolHeightDefault)%
+ (\umlSymbolWidthDefault, 0)}
+ \psline*(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault,
+ -\umlSymbolHeightDefault)}
+ \umlRelation[kind=Composition, #1]{#2}{#3}{%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
+}
+\newcommand\umlApplication[3][]{%
+ \def\umlEndSymbol{%
+ \pspolygon*(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,0)%
+ (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
+ (0,-\umlSymbolWidthDefault)}%
+ \umlRelation[kind=Application, #1]{#2}{#3}{%
+ \lput(1.2){\pnode{argument\umlReference}}%
+ \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
+ }
+\newcommand\umlToRelationNull{%
+ \def\umlPosMeetLine{.5}%
+}
+\define@key[psset]{uml}{posMeetLine}[.5]{\def\umlPosMeetLine{#1}}
+\newcommand\umlToRelation[3][]{%
+ \umlToRelationNull%
+ \psset[uml]{kind=ToRelation, #1}%
+ \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{Ac#3}{Bc#3}%
+ \lput{:R}(\umlPosMeetLine){\pnode{ToRelation#3}}%
+ \umlRelation[ref={#2#3}, #1]{#2}{ToRelation#3}{}%
+}
+\newcommand\umlAssociationSchema[3][]{%
+ \umlToRelation[kind=AssociationSchema,
+ posMeetLine=.5, linestyle=dashed,#1]{#2}{#3}%
+}
+\newcommand\umlAssociationClass[3][]{%
+ \umlAssociationSchema[kind=AssociationClass,#1]{#2}{#3}}
+\newcommand\umlArgumentRelation[3][]{%
+ \umlToRelation[kind=ArgumentRelation,
+ posMeetLine=.2,linestyle=dotted,#1]{#2}{#3}%
+ }
+\newcommand\umlAssociationEndNull{%
+ \def\umlAEOffset{\umlAEOffsetDefault}%
+ \def\umlAEOffsetDefault{0pt}%
+ \def\umlAEFraction{0}%
+ \def\umlAEFractionAngle{\umlAEFractionAngleDefault}%
+ \def\umlAEFractionAngleDefault{:U}%
+ \def\umlAEAngle{\umlAEAngleDefault}%
+ \def\umlAEAngleDefault{U}%
+ \def\umlAERefpoint{B}%
+ \def\umlAEHeight{\umlAEHeightDefault}%
+ \def\umlAEHeightDefault{0pt}%
+ \def\umlAENoderefClose{Ac}%
+ \def\umlAENoderefFar{Bc}%
+ \def\umlAEType{AssociationEnd}%
+ \def\umlAEKind{AssociationEnd}
+}
+\define@key[psset]{umlAE}{import}{\def\umlAEColor{red}}
+\define@key[psset]{umlAE}{type}{\def\umlType{#1}}
+\define@key[psset]{umlAE}{kind}{\def\umlKind{#1}}
+\define@key[psset]{umlAE}{offset}{\def\umlAEOffset{#1}}
+\define@key[psset]{umlAE}{angle}{\def\umlAEAngle{#1}}
+\define@key[psset]{umlAE}{fractionAngle}{\def\umlAEFractionAngle{#1}}
+\define@key[psset]{umlAE}{height}{\def\umlAEHeight{#1}}
+\define@key[psset]{umlAE}{refpoint}{\def\umlAERefpoint{#1}}
+%% \define@key[psset]{umlAE}{type}{\def\umlAEType{#1}}% %%%%%%%%%%%%
+\define@key[psset]{umlAE}{fraction}{\def\umlAEFraction{#1}}
+\newcommand\umlFromTo[3]{%
+ \edef\umlAEFractionArgument{#1}%
+ \def\umlAEFractionTmp{From}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#2\fi%
+ \def\umlAEFractionTmp{A}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#2\fi%
+ \def\umlAEFractionTmp{To}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#3\fi%
+ \def\umlAEFractionTmp{B}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#3\fi%
+}
+\newcommand\umlAssociationEndUseFraction{%
+ \umlFromTo{\umlAEFraction}{% If A or From
+ \def\umlAENoderefClose{Aa}%
+ \def\umlAENoderefFar{Ab}%
+ \def\umlAEFraction{0}%
+ }{%
+ \def\umlAENoderefClose{Ba}% If B or To
+ \def\umlAENoderefFar{Bb}%
+ \def\umlAEFraction{0}%
+ \def\umlTmp{Label}%
+ \ifx\umlTmp\umlAEType%
+ \edef\umlAEHeight{-\umlAEHeight}\fi%
+ }%
+ }
+\newcommand\umlAssociationEnd[3][]{%
+ \umlAssociationEndNull%
+ \psset[umlAE]{kind=AssociationEnd,#1}%
+ \umlAssociationEndUseFraction%
+ \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{%
+ \umlAENoderefClose#2}{\umlAENoderefFar#2}%
+ {\umlColorsAdjust%
+ \lput[\umlAERefpoint]{\umlAEFractionAngle}(\umlAEFraction){%
+ \rput[\umlAERefpoint]{\umlAEAngle}(\umlAEOffset, \umlAEHeight){%
+ #3}%
+ }%
+ }%
+ }%
+\newcommand\umlLabel[3][]{% Null unneccesary
+ \umlAssociationEnd[kind=Label,offset=4ex,height=2ex,angle=N, #1]{#2}{#3}%
+}
+\newcommand\umlLabelA[2][]{\umlLabel[#1,fraction=A]{#2}}
+\newcommand\umlLabelB[2][]{\umlLabel[#1,fraction=B]{#2}}
+\newcommand\umlSymbol[3][]{% Null unneccesary
+ \umlAssociationEnd[kind=Symbol,offset=0ex,height=0ex,
+ fractionAngle=:L,refpoint=t,#1]{%
+ #2}{\umlSymbolUseFraction%
+ #3}}
+\newcommand\umlSymbolUseFraction{%
+ \umlFromTo{\umlAEFraction}{%
+ }{%
+ }%
+ }
+\newcommand\umlSymbolA[2][]{\umlSymbol[#1,fraction=A]{#2}}
+\newcommand\umlSymbolB[2][]{\umlSymbol[#1,fraction=B]{#2}}
+\newcommand\umlNavigability[2][]{
+ \def\umlEndSymbol{\psline%
+ (-1ex, -1.618ex)%
+ (0,0)%
+ (1ex, -1.618ex)}%
+ \umlSymbol[kind=Navigability, #1]{#2}{\umlEndSymbol}%
+ }
+\newcommand\umlNavigabilityA[2][]{\umlNavigability[#1,fraction=A]{#2}}
+\newcommand\umlNavigabilityB[2][]{\umlNavigability[#1,fraction=B]{#2}}
+\newcommand\umlColorset[1]{%
+ \def\umlColorsAdjust{#1%
+ \psset{linecolor=umlLinecolor, fillcolor=umlFillcolor}}}
+\newcommand\umlColorsDefault{%
+ \umlColorset{%
+ \definecolor{umlColor}{gray}{0}%
+ \definecolor{umlLinecolor}{gray}{0}%
+ \definecolor{umlFillcolor}{gray}{1}%
+ \definecolor{umlClassifierFillcolor}{gray}{0.85}%
+ \definecolor{umlDiagramFillcolor}{gray}{0.95}%
+ \definecolor{umlRelationColor}{gray}{0}%
+}}
+\newcommand\umlColorsGray{%
+ \umlColorset{%
+ \definecolor{umlColor}{gray}{0.4}%
+ \definecolor{umlLinecolor}{gray}{0.4}%
+ \definecolor{umlFillcolor}{gray}{1}%
+ \definecolor{umlClassifierFillcolor}{gray}{0.90}%
+ \definecolor{umlDiagramFillcolor}{gray}{0.98}%
+ \definecolor{umlRelationColor}{gray}{0.4}%
+}}
+\newcommand\umlColorsImport{%
+ \umlColorset{%
+ \definecolor{umlColor}{rgb}{0, 0, 0.4}%
+ \definecolor{umlLinecolor}{rgb}{0, 0, 0.4}%
+ \definecolor{umlFillcolor}{rgb}{.8, .8, 1}%
+ \definecolor{umlClassifierFillcolor}{rgb}{.85, .85, 1}%
+ \definecolor{umlDiagramFillcolor}{rgb}{.95, .95, 1}%
+ \definecolor{umlRelationColor}{rgb}{0, 0, 0.4}%
+}}
+\newcommand\umlColorsArgument{%
+ \umlColorset{%
+ \definecolor{umlColor}{rgb}{0, 0.4, 0}%
+ \definecolor{umlLinecolor}{rgb}{0, 0.4, 0}%
+ \definecolor{umlFillcolor}{rgb}{.8, 1, .8}%
+ \definecolor{umlClassifierFillcolor}{rgb}{.85, 1, .85}%
+ \definecolor{umlDiagramFillcolor}{rgb}{.95, 1, .95}%
+ \definecolor{umlRelationColor}{rgb}{0, 0.7, 0}%
+}}
+\newcommand\umlColorsRed{%
+ \umlColorset{%
+ \definecolor{umlColor}{rgb}{0.4, 0, 0}%
+ \definecolor{umlLinecolor}{rgb}{0.4, 0, 0}%
+ \definecolor{umlFillcolor}{rgb}{1, .8, .8}%
+ \definecolor{umlClassifierFillcolor}{rgb}{1, .85, .85}%
+ \definecolor{umlDiagramFillcolor}{rgb}{1, .95, .95}%
+ \definecolor{umlRelationColor}{rgb}{0.4, 0, 0}%
+}}
+\newcommand\umlColorsSub{%
+ \umlColorset{%
+ \definecolor{umlColor}{rgb}{.6, .2, .2}%
+ \definecolor{umlLinecolor}{rgb}{.6, .2, .2}%
+ \definecolor{umlFillcolor}{rgb}{.9, .8, .8}%
+ \definecolor{umlClassifierFillcolor}{rgb}{.9, .8, .8}%
+ \definecolor{umlDiagramFillcolor}{rgb}{.97, .95, .95}%
+ \definecolor{umlRelationColor}{rgb}{.6, .2, .2}%
+}}
+\umlColorsDefault
+\umlColorsAdjust
+\newenvironment{umlColors}[1]{\bgroup#1}{\egroup}
+\SpecialCoor
+\newlength{\umlNodeSep}
+\setlength{\umlNodeSep}{1em}
+\newlength\umlPlaceNodeX
+\newlength\umlPlaceNodeY
+\newcommand\umlPlaceNodeNull{%
+ \def\umlPlaceNodeNodesepX{0pt}%
+ \def\umlPlaceNodeNodesepY{0pt}%
+ \def\umlPlaceNodeAngleX{}%
+ \def\umlPlaceNodeAngleY{}%
+ \def\umlPlaceNodeOffsetX{}%
+ \def\umlPlaceNodeOffsetY{}%
+ \setlength\umlPlaceNodeX{0pt}%
+ \setlength\umlPlaceNodeY{0pt}%
+}
+\define@key[psset]{umlPlaceNode}{leftside}[0pt]{%
+ \def\umlPlaceNodeAngleX{,angle=180}%
+ \def\umlPlaceNodeNodesepX{#1}}%
+\define@key[psset]{umlPlaceNode}{rightside}[0pt]{%
+ \def\umlPlaceNodeAngleX{,angle=0}%
+ \def\umlPlaceNodeNodesepX{#1}}%
+\define@key[psset]{umlPlaceNode}{top}[0pt]{%
+ \def\umlPlaceNodeAngleY{,angle=90}%
+ \def\umlPlaceNodeNodesepY{#1}}%
+\define@key[psset]{umlPlaceNode}{bottom}[0pt]{%
+ \def\umlPlaceNodeAngleY{,angle=270}%
+ \def\umlPlaceNodeNodesepY{#1}}%
+\define@key[psset]{umlPlaceNode}{left}[0pt]{%
+ \addtolength\umlPlaceNodeX{-#1}}%
+\define@key[psset]{umlPlaceNode}{right}[0pt]{\addtolength\umlPlaceNodeX{#1}}
+\define@key[psset]{umlPlaceNode}{up}[0pt]{\addtolength\umlPlaceNodeY{#1}}
+\define@key[psset]{umlPlaceNode}{down}[0pt]{\addtolength\umlPlaceNodeY{-#1}}
+\define@key[psset]{umlPlaceNode}{angle}{%
+ \def\umlPlaceNodeAngleX{,angle=#1}%
+ \def\umlPlaceNodeAngleY{,angle=#1}}%
+\define@key[psset]{umlPlaceNode}{angleX}{\def\umlPlaceNodeAngleX{,angle=#1}}%
+\define@key[psset]{umlPlaceNode}{angleY}{\def\umlPlaceNodeAngleY{,angle=#1}}%
+\define@key[psset]{umlPlaceNode}{offset}{
+ \def\umlPlaceNodeOffsetX{,offset=#1}%
+ \def\umlPlaceNodeOffsetY{,offset=#1}}%
+\define@key[psset]{umlPlaceNode}{offsetX}{\def\umlPlaceNodeOffsetX{,offset=#1}}%
+\define@key[psset]{umlPlaceNode}{offsetY}{\def\umlPlaceNodeOffsetY{,offset=#1}}%
+\define@key[psset]{umlPlaceNode}{nodesep}{%
+ \def\umlPlaceNodeNodesepX{#1}%
+ \def\umlPlaceNodeNodesepY{#1}}%
+\define@key[psset]{umlPlaceNode}{nodesepX}{\def\umlPlaceNodeNodesepX{#1}}%
+\define@key[psset]{umlPlaceNode}{nodesepY}{\def\umlPlaceNodeNodesepY{#1}}%
+\newcommand\umlPlaceNode[3][]{%
+ \umlPlaceNodeNull%
+ \psset[umlPlaceNode]{#1}%
+ \rput(%
+ [nodesep=\umlPlaceNodeNodesepX\umlPlaceNodeOffsetX\umlPlaceNodeAngleX]#2|%
+ [nodesep=\umlPlaceNodeNodesepY\umlPlaceNodeOffsetY\umlPlaceNodeAngleY]#2){%
+ \pnode(\umlPlaceNodeX, \umlPlaceNodeY){#3}}%
+}
+\newcommand\umlRight[1]{[angle=0]#1}
+\newcommand\umlTop[1]{[angle=90]#1}
+\newcommand\umlLeft[1]{[angle=180]#1}
+\newcommand\umlBottom[1]{[angle=270]#1}
+\newcommand\umlTopRight[1]{[angle=0]#1|[angle=90]#1}
+\newcommand\umlBottomRight[1]{[angle=0]#1|[angle=270]#1}
+\newcommand\umlTopLeft[1]{[angle=180]#1|[angle=90]#1}
+\newcommand\umlBottomLeft[1]{[angle=180]#1|[angle=270]#1}
+\newcommand\umlRightSep[1]{[angle=0, nodesep=\umlNodeSep]#1}
+\newcommand\umlTopSep[1]{[angle=90, nodesep=\umlNodeSep]#1}
+\newcommand\umlLeftSep[1]{[angle=180, nodesep=\umlNodeSep]#1}
+\newcommand\umlBottomSep[1]{[angle=270, nodesep=\umlNodeSep]#1}
+\newcommand\umlTopRightSep[1]{%
+ [angle=0, nodesep=\umlNodeSep]#1|[angle=90, nodesep=\umlNodeSep]#1}
+\newcommand\umlBottomRightSep[1]{%
+ [angle=0, nodesep=\umlNodeSep]#1|[angle=270, nodesep=\umlNodeSep]#1}
+\newcommand\umlTopLeftSep[1]{%
+ [angle=180, nodesep=\umlNodeSep]#1|[angle=90, nodesep=\umlNodeSep]#1}
+\newcommand\umlBottomLeftSep[1]{%
+ [angle=180, nodesep=\umlNodeSep]#1|[angle=270, nodesep=\umlNodeSep]#1}
+\newcommand\umlRightOpt[2]{[angle=0, #1]#2}
+\newcommand\umlTopOpt[2]{[angle=90, #1]#2}
+\newcommand\umlLeftOpt[2]{[angle=180, #1]#2}
+\newcommand\umlBottomOpt[2]{[angle=270, #1]#2}
+\newcommand\umlTopRightOpt[2]{[angle=0, #1]#2|[angle=90, #1]#2}
+\newcommand\umlBottomRightOpt[2]{[angle=0, #1]#2|[angle=270, #1]#2}
+\newcommand\umlTopLeftOpt[2]{[angle=180, #1]#2|[angle=90, #1]#2}
+\newcommand\umlBottomLeftOpt[2]{[angle=180, #1]#2|[angle=270, #1]#2}
+\newcommand\umlRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlTopSepOpt[2]{[angle=90, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlLeftSepOpt[2]{[angle=180, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlBottomSepOpt[2]{[angle=270, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlTopRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2|[angle=90, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlBottomRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2|[angle=270, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlTopLeftSepOpt[2]{%
+ [angle=180, nodesep=\umlNodeSep, #1]#2|[angle=90, nodesep=\umlNodeSep, #1]#2}
+\newcommand\umlBottomLeftSepOpt[2]{%
+ [angle=180, nodesep=\umlNodeSep, #1]#2|[angle=270, nodesep=\umlNodeSep, #1]#2}
+\endinput
+%%
+%% End of file `uml.sty'.
diff --git a/Master/texmf-dist/tpm/uml.tpm b/Master/texmf-dist/tpm/uml.tpm
new file mode 100644
index 00000000000..41e99e382c3
--- /dev/null
+++ b/Master/texmf-dist/tpm/uml.tpm
@@ -0,0 +1,33 @@
+<!DOCTYPE rdf:RDF SYSTEM "../../support/tpm.dtd">
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:TPM="http://texlive.dante.de/">
+ <rdf:Description about="http://texlive.dante.de/texlive/Package/uml.zip">
+ <TPM:Name>uml</TPM:Name>
+ <TPM:Type>Package</TPM:Type>
+ <TPM:Date>2006/12/19 17:53:41</TPM:Date>
+ <TPM:Version></TPM:Version>
+ <TPM:Creator>karl</TPM:Creator>
+ <TPM:Title>The uml package.</TPM:Title>
+ <TPM:Description></TPM:Description>
+ <TPM:Author></TPM:Author>
+ <TPM:Size>849507</TPM:Size>
+ <TPM:License></TPM:License>
+ <TPM:Build/>
+ <TPM:RunFiles size="31873">
+texmf-dist/tex/latex/uml/uml.sty
+texmf-dist/tpm/uml.tpm
+ </TPM:RunFiles>
+ <TPM:DocFiles size="621713">
+texmf-dist/doc/latex/uml/Changes
+texmf-dist/doc/latex/uml/README
+texmf-dist/doc/latex/uml/example.tex
+texmf-dist/doc/latex/uml/uml.pdf
+ </TPM:DocFiles>
+ <TPM:SourceFiles size="197030">
+texmf-dist/source/latex/uml/Makefile
+texmf-dist/source/latex/uml/uml.dtx
+texmf-dist/source/latex/uml/uml.ins
+ </TPM:SourceFiles>
+ <TPM:Provides>Package/uml</TPM:Provides>
+ </rdf:Description>
+</rdf:RDF>
+
diff --git a/Master/texmf/lists/uml b/Master/texmf/lists/uml
new file mode 100644
index 00000000000..531f8faba0e
--- /dev/null
+++ b/Master/texmf/lists/uml
@@ -0,0 +1,11 @@
+texmf-dist/doc/latex/uml/Changes
+texmf-dist/doc/latex/uml/README
+texmf-dist/doc/latex/uml/example.tex
+texmf-dist/doc/latex/uml/uml.pdf
+texmf-dist/source/latex/uml/Makefile
+texmf-dist/source/latex/uml/uml.dtx
+texmf-dist/source/latex/uml/uml.ins
+texmf-dist/tex/latex/uml/uml.sty
+texmf-dist/tpm/uml.tpm
+
+texmf/lists/uml
diff --git a/Master/texmf/tpm/collection-pstricks.tpm b/Master/texmf/tpm/collection-pstricks.tpm
index e1c050516f9..9098408db05 100644
--- a/Master/texmf/tpm/collection-pstricks.tpm
+++ b/Master/texmf/tpm/collection-pstricks.tpm
@@ -50,6 +50,7 @@
<TPM:Package name="pst-vue3d"/>
<TPM:Package name="pstricks"/>
<TPM:Package name="pstricks-add"/>
+ <TPM:Package name="uml"/>
<TPM:TLCore name="collection-basic"/>
</TPM:Requires>
<TPM:Provides>TLCore/collection-pstricks</TPM:Provides>