\def\filedate{2010/03/25}
\def\docdate{2010/09/25}
\def\fileversion{0.16}
\def\basename{pst-dbicons}
%
% \iffalse meta-comment
%
% Package 'pst-dbicons' to use with LaTeX2e and PSTricks
% (formerly dbicons)
% Copyright 1997-2010 by Wolfgang May. All rights reserved.
%
% This package is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
%
% Written and maintained by
% Wolfgang May
%
% Error Reports in case of UNCHANGED versions to
%
% Wolfgang May
% Institut f"ur Informatik, Universit"at G"ottingen
% Goldschmidtstrasse 7
% D-37077 Goettingen, Germany
% e-mail:
[email protected]
%
% You are not allowed to change this file.
%
% You are allowed to distribute this file under the condition that
% it is distributed UNCHANGED. You are NOT ALLOWED to take money for
% the distribution or use of either this file or a changed version,
% except for a nominal charge for copying etc.
% \fi
%
% \CheckSum{576}
%% \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 \~}
%
% \RecordChanges
%
% \MakeShortVerb{\|}
% \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{PSTricks Macros for Databases\thanks{This
% file has version number \fileversion{}, last revised \filedate.}}
% \author{Wolfgang May\\
% \texttt{
[email protected]}\\
% Institut f\"ur Informatik \\
% Universit\"at G\"ottingen \\
% Goldschmidtstrasse 7 \\
% D-37077 G\"ottingen\\
% Germany}
% \date{\filedate}
% \maketitle
%
% \begin{abstract}
% \noindent
% The \emph{pst-dbicons} package (originally called \em{dbicons} only)
% provides some useful macros in the
% database area. It focusses on typesetting ER-Diagrams in a
% declarative style, i.e., by positioning some nodes and defining
% the position of all other nodes relative to them by using the
% standard database terminology.
% The PSTricks package is required for using pst-dbicons, but
% there is no deep knowledge of PSTricks commands required
% (although this is useful for exploiting the full functionality).
% \end{abstract}
%
% \section{Commands}
%
% \subsection{ER-Diagrams}
%
% ER-Diagrams are a widely used graphical representation
% formalism for conceptual modeling; especially used in the
% database community. Their main notions are \emph{entities}
% (e.g., persons, cities, or countries), \emph{attributes} of
% entities (e.g., name, id-number, age), and relationships
% between entities (e.g., belongs\_to, is\_capital\_of).
%
% \DescribeMacro\seticonparams
% With
% \begin{quote}
% |\seticonparams{|\meta{icon-type}|}{|\meta{graphics parameters}|}|
% \end{quote}
% the graphical layout of icons (entities, relationships, and attributes)
% can be specified (by giving the optional argument for PSTricks'
% boxes). Default is
% |[fillstyle=none]| for all of them.
% in this documentation, we modify it to
%
%\begin{verbatim}
%\seticonparams{entity}{shadow=true,fillcolor=lightgray,fillstyle=solid}
%\seticonparams{attribute}{fillcolor=lightgray,fillstyle=solid}
%\seticonparams{relationship}{shadow=true,fillcolor=lightgray,fillstyle=solid}\end{verbatim}
%\seticonparams{entity}{shadow=true,fillcolor=lightgray,fillstyle=solid}
%\seticonparams{attribute}{fillcolor=lightgray,fillstyle=solid}
%\seticonparams{relationship}{shadow=true,fillcolor=lightgray,fillstyle=solid}
%
% From the user's point of view, every ER-icon (entities, relationships,
% attributes)
% has a name which should be typeset in the respective box. Additionally,
% there are \emph{internal} identifiers of the boxes/nodes to allow for
% referencing by graphics commands in the standard PSTricks way.
% These \emph{internal id}'s must start with a letter and must contain
% only letters
% and digits. In general, id's must be unique on every
% page.\footnote{people who are familiar with PSTricks know under which
% conditions non-unique node identifiers can be used.}
% Often, the \emph{name} of the entity/relationship/attribute satisfies
% these conditions; in these cases, the name is also used as id.
% in other cases, name and id must be specified.
%
% Thus, for all commands for typesetting ER-icons, the node id
% \emph{must} be given, whereas the name to be typeset in the box
% is optional; if no name is specified, the id is typeset as the name.
%
%
% \subsection{Entities and Attributes}
% \DescribeMacro\entity
% With
% \begin{quote}
% |\entity[|\meta{property}|]{|\meta{id}|}[|\meta{text}|]|
% \end{quote}
% an entity type is set as a rectangular node.
% If the optional argument \meta{text} is not given, \meta{id} also
% provides the entity's text. \meta{property} is used for \emph{weak}
% entitiy types which are denoted by double lines:
%
% Here is a simple entity |\entity{Person}| \quad\entity{Person}\quad where
% |Person| serves also as node text; |\entity[weak]{cty}[City]|
% \entity[weak]{cty}[City] makes up a weak entity type where the
% displayed name is different from the internal name.
%
%
% \DescribeMacro\attribute
% Attribute icons are set as an oval nodes by
% \begin{quote}
% |\attribute[|\meta{property}|]{|\meta{id}|}[|\meta{text}|]|
% \end{quote}
% Here, the optional argument \meta{property} can take the
% values |mv| (multivalued; resulting in a double-lined oval) or
% |key| (key attribute; resulting in underlining the attribute name).
% Here are three attributes:
% \begin{itemize}
% \item an ordinary one, |\attribute{phone}[phone\_no]|
% \quad\attribute{phone}[phone\_no]\quad,
% \item a multivalued attribute, |\attribute[mv]{nickname}|
% \quad\attribute[mv]{nickname}\quad,
% \item a key attribute, |\attribute[key]{pid}[person\_id]|
% \quad\attribute[key]{pid}[person\_id]\quad.
% \end{itemize}
% Note that with \emph{phone\_no}, the optional argument is
% used for the node text (in case that the node text contains
% stuff that is not allowed in internal postscript ids --
% as a rough rule, only characters (and since dbicons v1.14,
% underscores) are allowed in ids).
%
% In Section~\ref{sec-relationships}, relationship nodes are defined
% analogously.
% \DescribeMacro\attributeof
% \DescribeMacro\attrdist
% At first, it is described how to attach attributes with entities:
%
% \begin{quote}
% |\attributeof{|\meta{id}|}[|\meta{dist}|]{|\ignorespaces
% \meta{angle}|}[|\meta{property}|]{|\meta{id$_2$}|}[|\meta{text}|]|
% \end{quote}
% typesets an attribute node at angle \meta{angle} in distance
% \meta{dist} from the node which is identified by \meta{id}
% (which can be either an entity node or a relationship node).
% The attribute is made a node named \meta{id$_2$}.
% \meta{id$_2$} and \meta{text} work as for |\entity|.
% The argument \meta{dist} is optional, it has not to be given
% with \emph{every} attribute. By |\attrdist{|\meta{dist}|}|, this
% value can be set to a default (as startup default, 2em is set).
%
%
% \attrdist2.5em
% \hspace*{0.5cm}\entity{Person}\hspace*{2cm}
% \attributeof{Person}{30}[key]{Name}
% \attributeof{Person}{90}[mv]{Nickname}
% \attributeof{Person}[4em]{150}{phone}[phone\_no]
% \attributeof{Person}[2em]{270}[mv]{wt}[weight\_at]
% \attributeof{wt}{240}{date}
% \attributeof{wt}{300}{weight}
% \begin{tabular}{p{8.2cm}}
% \attrdist2.5em
% |\entity{Person}| \\
% |\attributeof{Person}{30}[key]{Name}| \\
% |\attributeof{Person}{90}[mv]{Nickname}| \\
% |\attributeof{Person}[4em]{150}| \\
% | {phone}[phone\_no]| \\
% |\attributeof{Person}{270}[mv]{wt}[weight\_at]| \\
% |\attributeof{wt}{220}{date}| \\
% |\attributeof{wt}{300}{weight}| \bigskip\\
%
% Note that \emph{phone\_no} is set with a bigger distance to
% \emph{person}.
% Additionally, the example shows how complex attributes can be set
% with these commands.
% \end{tabular}
%
%\subsection{Relationships}\label{sec-relationships}
% \DescribeMacro\relationship
% With |\relationship[|\meta{property}|]{|\meta{id}|}[|\meta{text}|]|, a relationship
% type is set as a diamond-shaped node.
% Here, the optional argument \meta{property} is used to represent
% \emph{identifying} relationships, used for \emph{weak} entities --
% thus \meta{property} can be equivalently |weak| or |ident| which
% results in a double-lined relationship type.
%
% \DescribeMacro\relationshipbetween
% For declaratively specifying nodes representing relationships
% between entities,
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]{|\meta{entity-is$_1$}|}{|\meta{entity-id$_2$}|}|\\
% | {|\meta{relationship-id}|}[|\meta{relationship-name}|]|
% \end{quote}
% is used (which can be augmented with several optional arguments).
% In the simplest version, as given above, a relationship node is set
% in-between two entity nodes:
%
% \begin{quote}
% | \entity{Person} \hspace*{6cm} \entity{Company}| \\
% | \relationshipbetween{Person}{Company}{worksat}[works\_at]|
% \bigskip \\
% \entity{Person} \hspace*{6cm} \entity{Company}
% \relationshipbetween{Person}{Company}{worksat}[works\_at]
% \end{quote}
%
% Additionally, the \emph{roles} of the entities in the relationship,
% and the cardinalities can be given (both as independent optional
% arguments):
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]|\\
% | {|\meta{entity-id$_1$}|}(|\ignorespaces
% \meta{role$_1$}|)[|\meta{card$_1$}|]|\\
% | {|\meta{entity-id$_2$}|}(|\ignorespaces
% \meta{role$_2$}|)[|\meta{card$_2$}|]|\\
% | {|\meta{relationship-id}|}[|\meta{relationship-name}|]|
% \end{quote}
%
% \begin{quote}
% |\entity{Country} \hspace*{6cm} \entity{City}| \\
% |\relationshipbetween{Country}(of)[1:1]{City}(is)[0:1]{capital}|
% \bigskip \\
% \entity{Country} \hspace*{6cm} \entity{City}
% \relationshipbetween{Country}(of)[1:1]{City}(is)[0:1]{capital}
% \end{quote}
%
% Moreover, the placement of the relationship node wrt.\ the
% entities can be specified: above, the relationship node was
% put in the middle of an imaginary line in-between the entity
% nodes.
%
% As a first, small, extension, the placement ratio of the
% diamond between the entities can be changed (default: 0.5):
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]{|\meta{entity-id$_1$}|}...{|\ignorespaces
% \meta{entity-id$_2$}|}...|\\
% | {|\meta{relationship-id}|}[|\ignorespaces
% \meta{relationship-name}|](|\meta{placement-ratio}|)|
% \end{quote}
%
% \begin{quote}
% |\entity{Country} \hspace*{6cm} \entity[weak]{City}| \\
% |\relationshipbetween[ident]{Country}[0:n]{City}[1:1]{in}(0.8)|
% \bigskip \\
% \entity{Country} \hspace*{6cm} \entity[weak]{City}
% \relationshipbetween[ident]{Country}[0:n]{City}[1:1]{in}(0.8)
% \end{quote}
%
% If this is still not enough, instead of an imaginary straight line,
% any other PSTricks node connection command can be used, most
% likely |\ncarc[...]| with suitable optional arguments:
%
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]| \\
% | {|\meta{entity-id$_1$}|}...{|\ignorespaces
% \meta{entity-id$_2$}|}...|\\
% | {|\meta{relationship-id}|}[|\ignorespaces
% \meta{relationship-name}|]|\\
% | /|\meta{connection}|/(|\meta{placement-ratio}|)|
% \end{quote}
% \begin{quote}
% |\entity{Country} \hspace*{6cm} \entity{City}| \\
% |\relationshipbetween{Country}[0:n]{City}[1:1]|\\
% | {in}/\ncarc[arcangle=20]/(0.4)|
% \vspace*{1cm} \\
% \entity{Country} \hspace*{6cm} \entity{City}
% \relationshipbetween{Country}[0:n]{City}[1:1]{in}/\ncarc[arcangle=20]/(0.4)
% \end{quote}
%
% For \TeX-insiders: Note that the use of |/.../| as argument delimiter
% avoids collisions with the delimiters used by PSTricks which
% thus can be used inside |/.../|.
%
% In the above example, although the relationship is placed on an
% imaginary arc, the \emph{connections} are straight lines.
% For these lines, PSTricks commands can be given, too.
% With this, the \emph{full} syntax is
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]|\\
% | {|\meta{entity-id$_1$}|}(|\ignorespaces
% \meta{role$_1$}|)[|\meta{card$_1$}|]/|\meta{connection$_1$}|/|\\
% | {|\meta{entity-id$_2$}|}(|\meta{role$_2$}|)[|\ignorespaces
% [\meta{card$_2$}|]/|\meta{connection$_2$}|/|\\
% | {|\meta{relationship-id}|}[|\meta{relationship-name}|]/|%
% \meta{connection}|/(|\meta{placement-ratio}|)|
% \end{quote}
%
% where all arguments embraced with |(...)|, |[...]|, or |/.../| are
% optional.
%
% With this, an example can be given where two different relationships
% can hold between a pair of entity types:
%
% \begin{quote}
% |\entity{Country} \hspace*{6cm} \entity{City}| \\
% |\relationshipbetween{Country}[0:n]{City}[1:1]{in}|\\
% |/\ncarc[arcangle=20]/(0.4)|\\
% |\relationshipbetween{Country}[1:1]/\ncarc[arcangle=-18]/|\\
% | {City}[0:1]/\ncarc[arcangle=-12]/|\\
% | {Capital}/\ncarc[arcangle=-30]/(0.6)|
% \vspace*{1cm} \\
% \entity{Country} \hspace*{6cm} \entity{City}
% \relationshipbetween{Country}[0:n]{City}[1:1]{in}/\ncarc[arcangle=20]/(0.4)
% \relationshipbetween{Country}[1:1]/\ncarc[arcangle=-18]/
% {City}[0:1]/\ncarc[arcangle=12]/
% {Capital}/\ncarc[arcangle=-30]/(0.6)
% \vspace*{1.2cm}
% \end{quote}
% Note that for \emph{capital}, |\ncarc| is used for the lines,
% where the |arcangle| of the whole arc is divided suitably
% to the placement ratio of the diamond node, and that the
% |arcangle| of the second entity is negative (since the connection
% always points from the entity to the relationship).
%
% There is one more interesting special case of binary relationships:
% recursive relationships. There, the entity node cannot be set
% ``between'' the nodes -- it has to be placed relative to the
% entity type which is involved in the relationship.
%
% In this case, the argument \meta{connection} has no effect, and last
% argument (\meta{placement ratio}) has the syntax
% |(|\meta{distance},\meta{angle}|)|: the relationship node is set
% at angle \meta{angle} in distance \meta{dist} from the entity node.
% The default for \meta{connection$_1$} and \meta{connection$_2$}
% is set to |\ncarc[arcangleA=10,arcangleB=45]}| and \\
% |\ncarc[arcangleA=-10,arcangleB=-45]|,
% respectively.
% \begin{quote}
% |\hspace*{6cm}\entity{Country}|\\
% |\relationshipbetween{Country}(A)[0:n]{Country}(B)[0:n]|\\
% | {Neighbor}(8em,180)|
% \vspace*{0.8cm}\\
% \hspace*{6cm}\entity{Country}
% \relationshipbetween{Country}(A)[0:n]{Country}(B)[0:n]{Neighbor}(8em,180)
% \bigskip
% \end{quote}
%
% With the above commands, only binary relationships can be
% represented. Thus, there is one more macro, relating
% entity nodes with already existing relationship nodes:
%
% \DescribeMacro\inrelationship
% \begin{quote}
% |\inrelationship[|\meta{property}|]{|\meta{entity-id}|}(|\meta{role}|)[|\ignorespaces
% \meta{card}|]|\\
% | /|\meta{connection}|/{|\meta{relationship-id}|}|
% \end{quote}
%
% With this, n-ary relations can be represented:
% \begin{quote}
% |\begin{tabular}{c}| \\
% |\entity{Person} \hspace*{6cm} \entity{Project} \\[2cm]| \\
% |\entity{Machine}| \\
% |\end{tabular}| \\
% |\relationshipbetween{Person}{Project}{worksatwith}|\ignorespaces
% |[works\_at\_with]|\\
% | /\ncarc[arcangle=-20]/|\\
% |\inrelationship{Machine}{worksatwith}|
% \bigskip\\
% \begin{tabular}{c}
% \entity{Person} \hspace*{6cm} \entity{Project} \\[2cm]
% \entity{Machine}
% \end{tabular}
% \relationshipbetween{Person}{Project}{worksatwith}[works\_at\_with]
% /\ncarc[arcangle=-20]/
% \inrelationship{Machine}{worksatwith}
% \end{quote}
%
% Additionally, there is a straightforward extension of
% |\inrelationship| to relationship
% nodes which do not already exist but are set by the command:
%
% \begin{quote}
% |\inrelationship{|\meta{entity-id}|}(|\meta{role}|)|\ignorespaces
% |[|\meta{card}|]/|\meta{connection}|/|\\
% | {|\meta{relationship-id}|}[|\meta{relationship-name}|]|\ignorespaces
% |(|\meta{distance},\meta{angle}|)|
% \end{quote}
%
% \begin{quote}
% |\begin{tabular}{c}| \\
% |\entity{Person} \hspace*{6cm} \entity{Project} \\[2cm]| \\
% |\entity{Machine}| \\
% |\end{tabular}| \\
% |\inrelationship{Machine}{worksatwith}[works\_at\_with](4em,90)| \\
% |\inrelationship{Person}{worksatwith}| \\
% |\inrelationship{Project}{worksatwith}|
% \bigskip \\
% \begin{tabular}{c}
% \entity{Person} \hspace*{6cm} \entity{Project} \\[2cm]
% \entity{Machine}
% \end{tabular}
% \inrelationship{Machine}{worksatwith}[works\_at\_with](4em,90)
% \inrelationship{Person}{worksatwith}
% \inrelationship{Project}{worksatwith}
% \end{quote}
%
% \DescribeMacro\rolepos
% The position where roles and cardinalities are placed on the
% node connection is determined by |\rolepos| and |\cardpos| which
% \DescribeMacro\cardpos
% can be set by |\rolepos{|\meta{number}|}| and
% |\cardpos{|\meta{number}|}|, where number underlies the same
% constraints as for |npos| in PSTricks (i.e., for |\ncline| and
% |\ncarc|, it has to be between 0 and 1, other values are allowed
% e.g.\ for |\ncbar|). The default setting is |\cardpos{0.5}| and
% |\rolepos{0.85}|.
%
% \subsection{Annotations to Objects}
% \DescribeMacro\annote
% With
% \begin{quote}
% |\annote{|\meta{id}|}{|\meta{text}|}(|\meta{distance},\meta{angle}|)|
% \end{quote}
% a node \meta{id} can be annoted with a comment \meta{text}.
%
% \subsection{Usage}
%
% The package is intended to be used for two purposes:
% \begin{itemize}
% \item Typesetting small fragments of ER-diagrams, e.g., for
% lecture notes and slides: as shown in the above
% documentation, fragments of ER-diagrams can easily be integrated
% with the running text.
% \item Typesetting ER-Diagrams for project documentation:
% here the standard procedure is to design the ER-diagram based
% on a |tabular| environment in which the entity nodes are positioned;
% Then, attributes and relationships are positioned in the above
% declarative way. Using basic PSTricks commands, additional
% entity nodes can also be placed declaratively.
% \end{itemize}
%
% There are the following advantages compared to using graphics tools,
% e.g., xfig:
% \begin{itemize}
% \item the source code of the diagrams is written into the running
% source code of the document, thus there is no need for a bunch
% of separate |.fig| and |.eps| files.
% \item more flexibility wrt.\ renaming and layout changes.
% \item given the positions of some basic objects, the other
% objects are set with declarative commands, i.e.\ they
% automatically adjust when the positions change.
% \end{itemize}
%
% \subsection{Example}
%
% TO BE FILLED
%
% \subsection{Miscellaneous}
%
% \DescribeMacro\nodeconnections
% With |\nodeconnections{|\meta{PSTricks-node-connections}|}|,
% the PSTricks-node connections and label commands do not require any
% extra horizontal or vertical space.
%
% \DescribeMacro\database
% The command
% \begin{quote}
% |\database[|\meta{pos}|]{|\meta{width}|}{|\ignorespaces
% \meta{height}|}[|\meta{graph\_params}|]{|\ignorespaces
% \meta{text}|}[|\meta{id}|]|
% \end{quote}
% defines a database barrel as a tabular which is vertically
% centered as given in the optional argument \meta{pos} (Default: |[c]|).
% \meta{text} is the text to be written on the front of the barrel,
% \meta{width} and \meta{height} give the width and height of the
% barrel; both must be a dimension, e.g., {2cm}. With the optional
% graphics parameter \meta{graph\_params}, the pstricks parameters
% \textsf{fillstyle} and
% \textsf{fillcolor} for the database can be set (see example below).
% The optional argument \meta{id} is used as an internal name,
% it must start with a letter and must contain only letters and
% digits. \meta{id} is used for |\rnode| definitions:
% \meta{id} is the whole barrel
% |lu|\meta{id}, |ru|\meta{id}, |mu|\meta{id}, and |muf|\meta{id}
% denote the points at the upper left corner, upper right corner,
% upper middle behind and aupper middle in front of the barrel.
% Analogously, |ll|\meta{id}, |rl|\meta{id}, and |ml|\meta{id},
% denote the lower left and lower right corner and lower middle in
% front of the barrel. \medskip
%
% \begin{tabular}{lc}
% |\psset{nodesep=2pt}|\\
% |\begin{tabular}{lc}| \\
% | &\rnode{lu}{lu}\quad\rnode{mu}{mu}\quad| \\
% | \rnode{muf}{muf}\quad\rnode{ru}{ru}\\[1em]| \\
% | \rnode{db}{database}|\\
% | &\database[t]{2cm}{1cm}| \\
% | [fillstyle=solid,fillcolor=red]| \\
% | {database}[example] \\[5em]| \\
% | &\rnode{ll}{ll}\qquad\rnode{ml}{ml}|\\
% | \qquad\rnode{rl}{rl}| \\
% |\end{tabular}| \\
% |\nodeconnections{%| \\
% |\ncline{->}{lu}{luexample}| \\
% |\ncline{->}{mu}{muexample}| \\
% |\ncline{->}{muf}{mufexample}| \\
% |\ncline{->}{ru}{ruexample}| \\
% |\ncline{->}{ll}{llexample}| \\
% |\ncline{->}{ml}{mlexample}| \\
% |\ncline{->}{db}{example}| \\
% |\ncline{->}{rl}{rlexample}}|
% \end{tabular}
% \hspace*{-1.5cm}
% \psset{nodesep=2pt}
%\begin{tabular}{lc}
% &\rnode{lu}{lu}\quad\rnode{mu}{mu}\quad
% \rnode{muf}{muf}\quad\rnode{ru}{ru}\\[1em]
% \rnode{db}{database}
% &\database[t]{2cm}{1cm}
% [fillstyle=solid,fillcolor=red]
% {database}[example] \\[5em]
% &\rnode{ll}{ll}\qquad\rnode{ml}{ml}\qquad\rnode{rl}{rl}
% \end{tabular}
% \nodeconnections{%
% \ncline{->}{lu}{luexample}
% \ncline{->}{mu}{muexample}
% \ncline{->}{muf}{mufexample}
% \ncline{->}{ru}{ruexample}
% \ncline{->}{ll}{llexample}
% \ncline{->}{ml}{mlexample}
% \ncline{->}{db}{example}
% \ncline{->}{rl}{rlexample}}
%
% \section{Code Documentation}\label{sec:code}
% \iffalse
% \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.
%
% \begin{macrocode}
%<*driver>
\documentclass{ltxdoc} \usepackage{latexsym}
\usepackage{pstricks,pst-node} \usepackage{pst-dbicons}
\parindent0pt\hfuzz2pt \setlength{\textwidth}{360pt}
\begin{document}
\DocInput{pst-dbicons.dtx}
\end{document}
%</driver>
% \end{macrocode}
%\fi
% \setcounter{CodelineNo}{0}
%\iffalse
%<*package>\fi
% \begin{macrocode}
\typeout{Style `\basename', Version \fileversion\space <\filedate>}
\ProvidesPackage{pst-dbicons}[\filedate \space\fileversion]
% \end{macrocode}
%
% \begin{macro}{\seticonparams}
% |\seticonparams{#1}{#2}|
% \Codelabel{seticonparams}
% \begin{macrocode}
\def\seticonparams#1#2{\expandafter\def\csname #1@parm\endcsname{[#2]}}
\seticonparams{entity}{fillstyle=none}
\seticonparams{relationship}{fillstyle=none}
\seticonparams{attribute}{fillstyle=none}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\purifylabel}
% \changes{v0.14}{02/11/21}{macro added}
% Macro |\@purifylabel| expands the string given in |#2|
% and stores the result in command given in |#1|.
% Supported TeX commands in string |#2|:
% |\_|, |\textunderscore|
% Example: |\@purifylabel{\templabel}{has\_hq\_in}|, then use
% |\templabel| as nodelabel for pstricks.
% \Codelabel{purifylabel}
% \begin{macrocode}
\def\dbi@purifylabel#1#2{%
\begingroup
\edef\_{\string_}%
\edef\textunderscore{\string_}%
\edef\x{\endgroup
\def\noexpand#1{#2}%
}%
\x
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\entity}
% \changes{v0.11}{98/10/15}{added optional property of entities}
% |\entity[#1a]{#1b}[#2]|
% \Codelabel{entity}
% \begin{macrocode}
\def\entity{%
\@ifnextchar[{\entity@i}{\entity@i[normal]}}
\def\entity@i[#1]#2{%
\@ifnextchar[{\entity@ii{#1}{#2}}{\entity@ii{#1}{#2}[#2]}}
\def\entity@ii#1#2[#3]{\csname entity@#1\endcsname{#2}{#3}}
\def\entity@normal#1#2{%
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\rnode{\dbi@prfd@nodename}{\expandafter\psframebox\entity@parm{\strut#2}}}
\def\entity@weak#1#2{%
{\psset{doubleline=true}%
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\rnode{\dbi@prfd@nodename}{\expandafter\psframebox\entity@parm{\strut#2}}}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\attribute}
% |\attribute[#1]{#2}[#3]|
% \Codelabel{attribute}
% \begin{macrocode}
\def\attribute{%
\@ifnextchar[{\attribute@i}{\attribute@i[sv]}}
\def\attribute@i[#1]#2{%
\@ifnextchar[{\attribute@ii{#1}{#2}}{\attribute@ii{#1}{#2}[#2]}}
\def\attribute@ii#1#2[#3]{\csname attribute@#1\endcsname{#2}{#3}}
\def\attribute@mv#1#2{{\psset{doubleline=true}%
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\expandafter\ovalnode\attribute@parm{\dbi@prfd@nodename}{#2}}}
\def\attribute@sv#1#2{%
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\expandafter\ovalnode\attribute@parm{\dbi@prfd@nodename}{#2}}
\def\attribute@key#1#2{
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\expandafter\ovalnode\attribute@parm{\dbi@prfd@nodename}{\underline{#2}}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\attributeof}
% |\attributeof{#1}[#2]{#3}[#4]{#5}[#6]|
% \begin{macrocode}
\newdimen\@attrdist
\@attrdist2em % Default value for distance of attribute from entity
\def\attrdist#1{\@attrdist#1} % set default distance
% \end{macrocode}
%
% \Codelabel{attributeof}
% \changes{v0.16}{2010/03/25}{fixed first optional argument}
% \begin{macrocode}
\def\attributeof#1{%
\@ifnextchar[{\attributeof@i{#1}}{\attributeof@i{#1}[\@attrdist]}}
\def\attributeof@i#1[#2]#3{%
\@ifnextchar[{\attributeof@ii{#1}[#2]{#3}}{\attributeof@ii{#1}[#2]{#3}[sv]}}
\def\attributeof@ii#1[#2]#3[#4]#5{%
\@ifnextchar[{\attributeof@iii{#1}[#2]{#3}[#4]{#5}}%
{\attributeof@iii{#1}[#2]{#3}[#4]{#5}[#5]}}
\def\attributeof@iii#1[#2]#3[#4]#5[#6]{%
\SpecialCoor
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\uput{#2}[#3]{0}(\dbi@prfd@nodename){\attribute[#4]{#5}[#6]}%
\NormalCoor
\ncline{-}{#1}{#5}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\relationship}
% \changes{v0.11}{98/10/15}{added optional property of relationships}
% |\relationship[#1a]{#1b}[#2]|
% \Codelabel{relationship}
% \begin{macrocode}
\def\relationship{%
\@ifnextchar[{\relationship@i}{\relationship@i[normal]}}
\def\relationship@i[#1]#2{%
\@ifnextchar[{\relationship@ii{#1}{#2}}{\relationship@ii{#1}{#2}[#2]}}
\def\relationship@ii#1#2[#3]{\csname relationship@#1\endcsname{#2}{#3}}
\def\relationship@normal#1#2{%
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\expandafter\dianode\relationship@parm{\dbi@prfd@nodename}{#2}}
\def\relationship@weak#1#2{%
{\psset{doubleline=true}%
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\expandafter\dianode\relationship@parm{\dbi@prfd@nodename}{#2}}}
\let\relationship@ident\relationship@weak
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\relationshipbetween}
% \changes{v0.11}{98/10/15}{added optional property of relationships}
% |\relationshipbetween[#1a]{#1b}(#2)[#3]/#4/{#5}(#6)[#7]/#8/{#9}[#10]/#11/(#12)|
% \Codelabel{relationshipbetween}
% \begin{macrocode}
\newtoks\rolepos
\rolepos{0.85}%
\newtoks\cardpos
\cardpos{0.5}%
\newif\ifdbi@recursive
\def\relationshipbetween{%
\@ifnextchar[{\relationshipbetween@type}{\relationshipbetween@type[normal]}}
\def\relationshipbetween@type[#1]#2{\dbi@recursivefalse%
\def\relationtype{#1}%
\@ifnextchar({\relationshipbetween@i@role{#2}}%
{\relationshipbetween@i@role{#2}(\relax)}}
\def\relationshipbetween@i@role#1(#2){%
\@ifnextchar[{\relationshipbetween@i@card{#1}{#2}}%
{\relationshipbetween@i@card{#1}{#2}[\relax]}}
\def\relationshipbetween@i@card#1#2[#3]{%
\@ifnextchar/{\relationshipbetween@i@linetype{#1}{#2}{#3}}%
{\relationshipbetween@i@linetype{#1}{#2}{#3}/\relax/}}%
\def\relationshipbetween@i@linetype#1#2#3/#4/#5{%
\def\dbi@linecmd@i{#4}%
\def\dbi@tempa{#1}\def\dbi@tempb{#5}%
\ifx\dbi@tempa\dbi@tempb\dbi@recursivetrue\fi
\ifx#4\relax
\ifdbi@recursive
\def\dbi@linecmd@i{\ncarc[arcangleA=10,arcangleB=45]}%
\else\def\dbi@linecmd@i{\ncline}\fi\fi
\@ifnextchar({\relationshipbetween@ii@role{#1}{#2}{#3}{#5}}%
{\relationshipbetween@ii@role{#1}{#2}{#3}{#5}(\relax)}}%
\def\relationshipbetween@ii@role#1#2#3#4(#5){%
\@ifnextchar[{\relationshipbetween@ii@card{#1}{#2}{#3}{#4}{#5}}%
{\relationshipbetween@ii@card{#1}{#2}{#3}{#4}{#5}[\relax]}}
\def\relationshipbetween@ii@card#1#2#3#4#5[#6]{%
\@ifnextchar/{\relationshipbetween@ii@linetype{#1}{#2}{#3}{#4}{#5}{#6}}%
{\relationshipbetween@ii@linetype{#1}{#2}{#3}{#4}{#5}{#6}%
/\relax/}}%
\def\relationshipbetween@ii@linetype#1#2#3#4#5#6/#7/#8{%
\def\dbi@linecmd@ii{#7}%
\ifx#7\relax
\ifdbi@recursive
\def\dbi@linecmd@ii{\ncarc[arcangleA=-10,arcangleB=-45]}%
\else\def\dbi@linecmd@ii{\ncline}\fi\fi
\@ifnextchar[{\relationshipbetween@optname{#1}{#2}{#3}{#4}{#5}{#6}{#8}}%
{\relationshipbetween@optname{#1}{#2}{#3}{#4}{#5}{#6}{#8}[#8]}}%
\def\relationshipbetween@optname#1#2#3#4#5#6#7[#8]{%
\@ifnextchar/{\relationshipbetween@linetype{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}%
{\relationshipbetween@linetype{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
/\ncline/}}%
\def\relationshipbetween@linetype#1#2#3#4#5#6#7#8/#9/{%
\def\dbi@linecmd{#9}%
\@ifnextchar({\relationshipbetween@pos{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}%
{\relationshipbetween@pos{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}(0.5)}}%
\def\relationshipbetween@pos#1#2#3#4#5#6#7#8(#9){%
\ifdbi@recursive
\relationshipbetween@rec{#1}{#2}{#3}{#5}{#6}{#7}{#8}(#9)\else
\relationshipbetween@nonrec{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}(#9)\fi}
% \end{macrocode}
%
% \Codelabel{relationshipbetweennonrec}
% \begin{macrocode}
\def\relationshipbetween@nonrec#1#2#3#4#5#6#7#8(#9){%
\dbi@purifylabel{\dbi@prfd@nodename@i}{#1}%
\dbi@purifylabel{\dbi@prfd@nodename@ii}{#4}%
\dbi@purifylabel{\dbi@prfd@nodename@iii}{#7}%
{\psset{linestyle=none}%
\dbi@linecmd{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}}%
\ncput[npos=#9]{\relationship[\relationtype]{#7}[#8]}%
\dbi@linecmd@i{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@iii}%
\ifx#3\relax\else\ncput*[npos=\the\cardpos]{#3}\fi
\ifx#2\relax\else\ncput*[npos=\the\rolepos]{#2}\fi
\dbi@linecmd@ii{-}{\dbi@prfd@nodename@ii}{\dbi@prfd@nodename@iii}%
\ifx#6\relax\else\ncput*[npos=\the\cardpos]{#6}\fi
\ifx#5\relax\else\ncput*[npos=\the\rolepos]{#5}\fi}
% \end{macrocode}
%
% \Codelabel{relationshipbetweenrec}
% \begin{macrocode}
\def\relationshipbetween@rec#1#2#3#4#5#6#7(#8,#9){%
\dbi@purifylabel{\dbi@prfd@nodename@i}{#1}%
\dbi@purifylabel{\dbi@prfd@nodename@ii}{#6}%
\SpecialCoor
\uput{#8}[#9]{0}(\dbi@prfd@nodename@i)%
{\relationship[\relationtype]{#6}[#7]}%
\NormalCoor
\dbi@linecmd@i{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}%
\ifx#3\relax\else\ncput*[npos=\the\cardpos]{#3}\fi
\ifx#2\relax\else\ncput*[npos=\the\rolepos]{#2}\fi
\dbi@linecmd@ii{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}%
\ifx#5\relax\else\ncput*[npos=\the\cardpos]{#5}\fi
\ifx#4\relax\else\ncput*[npos=\the\rolepos]{#4}\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\inrelationship}
% \changes{v0.11}{98/10/15}{added optional property of relationships}
% |\inrelationship[#1a]{#1b}(#2)[#3]/#4/{#5}[#6](#7,#8)|
% \Codelabel{inrelationship}
% \begin{macrocode}
\def\inrelationship{%
\@ifnextchar[{\inrelationship@type}{\inrelationship@type[normal]}}
\def\inrelationship@type[#1]#2{%
\def\relationtype{#1}%
\@ifnextchar({\inrelationship@role{#2}}%
{\inrelationship@role{#2}(\relax)}}
\def\inrelationship@role#1(#2){%
\@ifnextchar[{\inrelationship@card{#1}{#2}}%
{\inrelationship@card{#1}{#2}[\relax]}}
\def\inrelationship@card#1#2[#3]{%
\@ifnextchar/{\inrelationship@linetype{#1}{#2}{#3}}%
{\inrelationship@linetype{#1}{#2}{#3}/\ncline/}}%
\def\inrelationship@linetype#1#2#3/#4/#5{%
\dbi@purifylabel{\dbi@prfd@nodename@i}{#1}%
\dbi@purifylabel{\dbi@prfd@nodename@ii}{#5}%
\def\dbi@linecmd{#4}%
\@ifnextchar[{\inrelationship@newrel{#1}{#2}{#3}{#5}}%
{\@ifnextchar({%
\inrelationship@newrel{#1}{#2}{#3}{#5}[#5]}%
{\dbi@linecmd{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}
\ifx#3\relax\else\ncput*[npos=\the\cardpos]{#3}\fi
\ifx#2\relax\else\ncput*[npos=\the\rolepos]{#2}\fi}}}%
% \end{macrocode}
%
% \Codelabel{inrelationshipnewrel}
% \begin{macrocode}
\def\inrelationship@newrel#1#2#3#4[#5]{%
\@ifnextchar({\inrelationship@newrel@pos{#1}{#2}{#3}{#4}{#5}}%
{\PackageError{\basename}{Position of relationship #4
undefined.}\@eha}}
\def\inrelationship@newrel@pos#1#2#3#4#5(#6,#7){%
\SpecialCoor
\dbi@purifylabel{\dbi@prfd@nodename@i}{#1}%
\dbi@purifylabel{\dbi@prfd@nodename@ii}{#4}%
\uput{#6}[#7]{0}(\dbi@prfd@nodename@i){\relationship[\relationtype]{#4}[#5]}%
\NormalCoor
\dbi@linecmd{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}
\ifx#3\relax\else\ncput*[npos=\the\cardpos]{#3}\fi
\ifx#2\relax\else\ncput*[npos=\the\rolepos]{#2}\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\annote}
% \setcounter{CodelineNo}{0}
% \changes{v0.11}{98/09/24}{added annote}
% \begin{macrocode}
\def\annote#1#2(#3,#4){%
\dbi@purifylabel{\dbi@prfd@nodename}{#1}%
\SpecialCoor
\uput{#3}[#4]{0}(\dbi@prfd@nodename){#2}%
\NormalCoor}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\nodeconnections}
% \setcounter{CodelineNo}{0}
% \begin{macrocode}
\def\nodeconnections#1{\hbox to 0cm{\vbox to 0cm {#1}}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\database}
% \changes{v0.13}{98/11/22}{added graphics parameters to database}
% \changes{v0.15}{05/09/09}{debugged vertical placement}
% |\database[#1]{#2}{#3}[#4]{#5}[#6]|
% \Codelabel{database}
% \begin{macrocode}
\def\database{\@ifnextchar[{\database@i}{\database@i[c]}}
\def\database@i[#1]#2#3{%
\@ifnextchar[{\database@ii{#1}{#2}{#3}}%
{\database@ii{#1}{#2}{#3}[fillstyle=none]}}
\def\database@ii#1#2#3[#4]#5{%
\@ifnextchar[{\database@iii{#1}{#2}{#3}{#4}{#5}}%
{\database@iii{#1}{#2}{#3}{#4}{#5}[#5]}}
\def\database@iii#1#2#3#4#5[#6]{%
\psset{nodesep=0pt}%
\dbi@purifylabel{\dbi@prfd@nodename}{#6}%
\rnode{\dbi@prfd@nodename}{%
\begin{tabular}[#1]{c}%
\rnode{lu\dbi@prfd@nodename}{}\hspace{#2}\rnode{ru\dbi@prfd@nodename}{}\\[#3]
\rnode{ll\dbi@prfd@nodename}{}\hspace{#2}\rnode{rl\dbi@prfd@nodename}{}%
\end{tabular}}%
\nodeconnections{%
\ncbar[linestyle=none,#4,
angleA=180,angleB=180,armB=0]{ru\dbi@prfd@nodename}{ll\dbi@prfd@nodename}
\ncbar[linestyle=none,#4,
angleA=0,angleB=0,armA=0]{ru\dbi@prfd@nodename}{ll\dbi@prfd@nodename}
\nccurve[#4,angleA=90,angleB=90,ncurv=.6]{lu\dbi@prfd@nodename}{ru\dbi@prfd@nodename}%
\ncput{\rnode{mu\dbi@prfd@nodename}{}}%
\nccurve[angleA=-90,angleB=-90,ncurv=.6]{lu\dbi@prfd@nodename}{ru\dbi@prfd@nodename}%
\ncput{\rnode{muf\dbi@prfd@nodename}{}}%
\nccurve[#4,angleA=-90,angleB=-90,ncurv=.6]{ll\dbi@prfd@nodename}{rl\dbi@prfd@nodename}%
\ncput{\rnode{ml\dbi@prfd@nodename}{}}%
\ncline{lu\dbi@prfd@nodename}{ll\dbi@prfd@nodename}%
\ncline{ru\dbi@prfd@nodename}{rl\dbi@prfd@nodename}%
\ncline[linestyle=none]{muf\dbi@prfd@nodename}{ml\dbi@prfd@nodename}\ncput[npos=0.4]{#5}}}
% \end{macrocode}
% \end{macro}
%
%\iffalse
%</package>\fi
% \GlossaryPrologue{}
%
% \IfFileExists{pst-dbicons.gls}{\PrintChanges}
% {\begin{quote}You should create the list of changes by
%
% ~~~ \texttt{makeindex -s gglo.ist -o pst-dbicons.gls pst-dbicons.glo}
%
% and running \texttt{latex pst-dbicons.drv} again.\end{quote}}
%
%
% \subsection{Acknowledgements}
%
% Thanx to Heiko Oberdiek for adding the handling of ids for
% internal use in postcsript (used in the |purifylabel| macro).
%
% \Finale
\endinput
% Local Variables:
% TeX-command-default: "LaTeX"
% TeX-master: t
% End:
% mode: latex