\def\filedate{2010/03/17}
\def\docdate{2010/03/17}
\def\fileversion{0.11}
\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]{umllinestyle}
% \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["umllinestyle"] A\DescribeMacro{umllinestyle-} umllinestyle 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{pst-xkey} [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}{umllinestyle-}
% Legal values are "none", "solid", "hashed" and "dotted".
% \begin{macrocode}
\define@key[psset]{uml}{umllinestyle}{\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}, umllinestyle=dashed, #1]{#2}{#3}{%
\umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
}
% \end{macrocode}
% \index{umllinestyle-!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{umllinestyle!dashed in AssociationClass}
% \index{posMeetLine!AssociationClass}
% \begin{macrocode}
\newcommand\umlAssociationSchema[3][]{%
\umlToRelation[kind=AssociationSchema,
posMeetLine=.5, umllinestyle=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{umllinestyle!dottedin ArgumentRelation}
% \index{posMeetLine!ArgumentRelation}
% \begin{macrocode}
\newcommand\umlArgumentRelation[3][]{%
\umlToRelation[kind=ArgumentRelation,
posMeetLine=.2,umllinestyle=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