summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/metapost/expressg
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/metapost/expressg')
-rw-r--r--Master/texmf-dist/source/metapost/expressg/expressg.dtx6553
-rw-r--r--Master/texmf-dist/source/metapost/expressg/expressg.ins114
2 files changed, 6667 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/metapost/expressg/expressg.dtx b/Master/texmf-dist/source/metapost/expressg/expressg.dtx
new file mode 100644
index 00000000000..f8a737c8e51
--- /dev/null
+++ b/Master/texmf-dist/source/metapost/expressg/expressg.dtx
@@ -0,0 +1,6553 @@
+% \iffalse meta-comment
+%
+% expressg.dtx
+% Author: Peter Wilson (CUA) now at peter.r.wilson@boeing.com until June 2004
+% (or: pandgwilson at earthlink dot net)
+% Copyright 1996, 2003, 2004 Peter R. Wilson
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3 of this license or (at your option) any
+% later version.
+% The latest version of the license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of
+% LaTeX version 2003/06/01 or later.
+%
+% This work has the LPPL maintenance status "author-maintained".
+%
+% This work consists of the files listed in the README file.
+%
+% If you do not have the docmfp package (available from CTAN in
+% tex-archive/macros/latex/contrib/supported), comment out the
+% \usepackage{docmfp} line below and uncomment the line following it.
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{docmfp}
+%%%% \newenvironment{variable}[1]{}{} \newenvironment{routine}[1]{}{}
+\providecommand{\DescribeVariable}[1]{} \providecommand{\DescribeRoutine}[1]{}
+\providecommand{\variablestring}{} \renewcommand{\variablestring}{\space(v)}
+\providecommand{\routinestring}{} \renewcommand{\routinestring}{\space(r)}
+\EnableCrossrefs
+\CodelineIndex
+\setcounter{StandardModuleDepth}{1}
+
+\begin{document}
+ \DocInput{expressg.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+% \CheckSum{171}
+%
+% \DoNotIndex{\',\.,\@M,\@@input,\@addtoreset,\@arabic,\@badmath}
+% \DoNotIndex{\@centercr,\@cite}
+% \DoNotIndex{\@dotsep,\@empty,\@float,\@gobble,\@gobbletwo,\@ignoretrue}
+% \DoNotIndex{\@input,\@ixpt,\@m}
+% \DoNotIndex{\@minus,\@mkboth,\@ne,\@nil,\@nomath,\@plus,\@set@topoint}
+% \DoNotIndex{\@tempboxa,\@tempcnta,\@tempdima,\@tempdimb}
+% \DoNotIndex{\@tempswafalse,\@tempswatrue,\@viipt,\@viiipt,\@vipt}
+% \DoNotIndex{\@vpt,\@warning,\@xiipt,\@xipt,\@xivpt,\@xpt,\@xviipt}
+% \DoNotIndex{\@xxpt,\@xxvpt,\\,\ ,\addpenalty,\addtolength,\addvspace}
+% \DoNotIndex{\advance,\Alph,\alph}
+% \DoNotIndex{\arabic,\ast,\begin,\begingroup,\bfseries,\bgroup,\box}
+% \DoNotIndex{\bullet}
+% \DoNotIndex{\cdot,\cite,\CodelineIndex,\cr,\day,\DeclareOption}
+% \DoNotIndex{\def,\DisableCrossrefs,\divide,\DocInput,\documentclass}
+% \DoNotIndex{\DoNotIndex,\egroup,\ifdim,\else,\fi,\em,\endtrivlist}
+% \DoNotIndex{\EnableCrossrefs,\end,\end@dblfloat,\end@float,\endgroup}
+% \DoNotIndex{\endlist,\everycr,\everypar,\ExecuteOptions,\expandafter}
+% \DoNotIndex{\fbox}
+% \DoNotIndex{\filedate,\filename,\fileversion,\fontsize,\framebox,\gdef}
+% \DoNotIndex{\global,\halign,\hangindent,\hbox,\hfil,\hfill,\hrule}
+% \DoNotIndex{\hsize,\hskip,\hspace,\hss,\if@tempswa,\ifcase,\or,\fi,\fi}
+% \DoNotIndex{\ifhmode,\ifvmode,\ifnum,\iftrue,\ifx,\fi,\fi,\fi,\fi,\fi}
+% \DoNotIndex{\input}
+% \DoNotIndex{\jobname,\kern,\leavevmode,\let,\leftmark}
+% \DoNotIndex{\list,\llap,\long,\m@ne,\m@th,\mark,\markboth,\markright}
+% \DoNotIndex{\month,\newcommand,\newcounter,\newenvironment}
+% \DoNotIndex{\NeedsTeXFormat,\newdimen}
+% \DoNotIndex{\newlength,\newpage,\nobreak,\noindent,\null,\number}
+% \DoNotIndex{\numberline,\OldMakeindex,\OnlyDescription,\p@}
+% \DoNotIndex{\pagestyle,\par,\paragraph,\paragraphmark,\parfillskip}
+% \DoNotIndex{\penalty,\PrintChanges,\PrintIndex,\ProcessOptions}
+% \DoNotIndex{\protect,\ProvidesClass,\raggedbottom,\raggedright}
+% \DoNotIndex{\refstepcounter,\relax,\renewcommand,\reset@font}
+% \DoNotIndex{\rightmargin,\rightmark,\rightskip,\rlap,\rmfamily,\roman}
+% \DoNotIndex{\roman,\secdef,\selectfont,\setbox,\setcounter,\setlength}
+% \DoNotIndex{\settowidth,\sfcode,\skip,\sloppy,\slshape,\space}
+% \DoNotIndex{\symbol,\the,\trivlist,\typeout,\tw@,\undefined,\uppercase}
+% \DoNotIndex{\usecounter,\usefont,\usepackage,\vfil,\vfill,\viiipt}
+% \DoNotIndex{\viipt,\vipt,\vskip,\vspace}
+% \DoNotIndex{\wd,\xiipt,\year,\z@}
+%
+% \changes{v1.0}{1996/05/09}{First public release}
+% \changes{v1.1}{1999/10/30}{Improved documentation using docmfp package}
+% \changes{v1.1}{1999/10/30}{Reordered descriptions and code}
+% \changes{v1.1}{1999/10/30}{Deleted Express Book examples}
+% \changes{v1.1}{1999/10/30}{Updated references}
+% \changes{v1.2}{1999/11/15}{Reincluded Express Book examples, plus NIAM and S-M}
+% \changes{v1.3}{2000/05/22}{Added smoothing, drawdrum, and others}
+% \changes{v1.4}{2000/07/10}{Added sharp and smooth lines}
+% \changes{v1.5}{2003/07/31}{Minor bug fixes}
+% \changes{v1.6}{2004/02/29}{More boxes}
+% \changes{v1.61}{2004/03/17}{Minor namespace feature fix}
+%
+% \newcommand{\dtxfilename}{\texttt{expressg.dtx}}
+% ^^A \def\fileversion{v1.0}
+% \def\firstfiledate{1996/05/09}
+% ^^A \def\fileversion{v1.1}
+% ^^A \def\filedate{1999/10/30}
+% ^^A \def\fileversion{v1.2}
+% ^^A \def\filedate{1999/11/15}
+% ^^A \def\fileversion{v1.3}
+% ^^A \def\filedate{2000/05/22}
+% \def\fileversion{v1.4} \def\filedate{2000/07/10}
+% \def\fileversion{v1.5} \def\filedate{2003/07/31}
+% \def\fileversion{v1.6} \def\filedate{2004/02/29}
+% \def\fileversion{v1.61} \def\filedate{2004/03/17}
+% \newcommand*{\Lpack}[1]{\textsf {#1}} ^^A typeset a package
+% \newcommand*{\Lopt}[1]{\textsf {#1}} ^^A typeset an option
+% \newcommand*{\file}[1]{\texttt {#1}} ^^A typeset a file
+% \newcommand*{\Lcount}[1]{\textsl {\small#1}} ^^A typeset a counter
+% \newcommand*{\pstyle}[1]{\textsl {#1}} ^^A typeset a pagestyle
+% \newcommand*{\Lenv}[1]{\texttt {#1}} ^^A typeset an environment
+% \newcommand*{\Express}{\textsc{express}}
+% \newcommand*{\ExpressG}{\textsc{express-g}}
+% \newcommand*{\Mpost}{\textsc{MetaPost}}
+% \newcommand*{\Mfont}{METAFONT}
+% \newcommand*{\fref}[1]{Figure~\ref{#1}}
+% \newcommand*{\pref}[1]{page~\pageref{#1}}
+% \newcommand*{\PS}{PostScript}
+% \newcommand*{\EPS}{Encapsulated \PS}
+% \newcommand*{\pdflatex}{pdf\LaTeX}
+%
+% \title{The \Lpack{Expressg} \Mpost{} package for drawing
+% box-line-annotation diagrams\thanks{This
+% file (\dtxfilename) has version number \fileversion, last revised
+% \filedate.}}
+%
+% \author{%
+% Peter Wilson\\
+% Catholic University of America \\
+% Now at \texttt{peter.r.wilson@boeing.com}
+% }
+% \date{(First published \firstfiledate) \\ \filedate}
+% \maketitle
+% \begin{abstract}
+% The \Lpack{expressg} \Mpost{} package provides facilities to assist in
+% drawing diagrams that consist of boxes, lines, and annotations.
+% Particular support is provided for creating \ExpressG{} diagrams
+% \end{abstract}
+% \tableofcontents
+% \listoffigures
+%
+% \StopEventually{}
+%
+% \section{Introduction}
+%
+% \ExpressG{} is an ISO international standard graphical information
+% modeling
+% language~\cite{STEP11,EBOOK}, and is a subset of the \Express{} lexical
+% object-flavoured information modeling language. Like most graphical
+% modeling languages, \ExpressG{} diagrams consist of boxes, lines, and
+% annotations associated with the boxes and the lines. As a colleague
+% of mine once put it, these kinds of graphical languages are BLA
+% (boxes, lines, annotations) with respect to lexical languages.
+%
+% \Mpost~\cite{MPOST} is a powerful lexical language for producing
+% \EPS\footnote{\PS{} is a registered trademark of Adobe
+% Systems Incorporated.} diagrams, and is based on the \Mfont~\cite{MFONT}
+% language for creating fonts.
+%
+% The \Lpack{expressg} package provides extensions to the base
+% \Mpost{} language to facilitate the creation of \ExpressG{} diagrams.
+% The package may also be used as is, or certainly by
+% extension, for the creation of other BLA diagrams.
+%
+% \Mpost{} is typically used to generate pictures for inclusion
+% in \LaTeX{} documents~\cite{LATEX}. By default it uses \TeX{} for
+% typesetting any text; this behaviour can be modified so that \LaTeX{}
+% is used instead. If standard \PS{} fonts (like Times) are
+% used, then \LaTeX{} typesetting may be avoided altogether. Running
+% \Mpost{} and methods of including \Mpost{} diagrams in (pdf)LaTeX
+% documents are described in~\cite{METAFP}.
+%
+%
+% The \Lpack{expressg} package has been some years
+% in the making. For
+% occasional diagrams I got by with using either the simple \LaTeX{}
+% picture commands,
+% or general GUI drawing packages. As time went on and the number
+% and complexity of the diagrams increased it became, to me at least, more
+% important to use a robust and powerful drawing language than fancy
+% GUI packages. This was especially important if a diagram had to be
+% changed at a later date, as the language denoted exactly how the drawing
+% had been produced. With the GUI tools all that you had was the picture
+% and whatever graphics file format the tool used --- there was no
+% user-sensible record
+% of how any result was achieved. Also, generally speaking I find it quicker
+% to use \Mpost{} than a GUI tool as too much time has to be spent using
+% a mouse or a cursor to reposition and rescale the drawing elements.
+%
+% Section~\ref{sec:usc} describes the facilities provided by the package.
+% Several worked
+% example diagrams are presented in Section~\ref{sec:example}, together
+% with information on how to run \Mpost.
+% Commented code for the package macros\footnote{If requested,
+% I may be prepared to consider providing additional macros, but no promises.}
+% is in Section~\ref{sec:mf}.
+%
+% It is assumed that the reader has some understanding of \Mpost, although
+% the example in Section~\ref{sec:example} does provide an
+% \textit{aide-memoire} for most of the \Mpost{} constructs that are likely
+% to be used in creating BLA diagrams. The definitive \Mpost{}
+% manual is~\cite{MPOST} but both~\cite{HOENIG98} and~\cite{GOOSSENS97}
+% give some interesting examples of how to use it; in fact the front cover
+% of Hoenig's book is a \Mpost{} picture.
+% Similarly, some familiarity with
+% BLA diagramming would be of assistance.
+%
+% I suggest that on first reading it may be sensible to skim
+% Section~\ref{sec:usc} first
+% and then peruse the example in Section~\ref{sec:example} more closely.
+% After this
+% go back and re-read Section~\ref{sec:usc} as it then should make
+% more sense.
+%
+% This manual is typeset according to the conventions of the
+% \LaTeX{} \textsc{docstrip} utility which enables the automatic
+% extraction of the \LaTeX{} macro source files~\cite{GOOSSENS94}.
+%
+%
+%
+% \section{The \Lpack{expressg} package} \label{sec:usc}
+%
+% \subsection{Internal variables}
+%
+% The package includes several internal variables that are initialised to
+% commonly appropriate values.
+% This section describes the principal internal variables.
+% Short descriptions
+% of the others, which
+% are likely to be used in diagrams only very occasionally, can be found
+% in Section~\ref{sec:mf}.
+%
+% The values of internal variables in \Mpost{} can only be changed via
+% assignment. For example:
+% \begin{verbatim}
+% internal_variable := expression;
+% \end{verbatim}
+%
+% \DescribeVariable{u}
+% \DescribeVariable{maxx}
+% \DescribeVariable{maxy}
+% |u| is the value of the unit of length for a diagram; it is initialised
+% to 1mm. All lengths, except for line thicknesses,
+% are defined in terms of |u|.
+% |maxx| and |maxy| are the maximum x and y coordinate values
+% for a diagram. These are initialised to the maximum size for a diagram
+% within an ISO standard document (i.e., |maxx:=159.5u| and |maxy:=210u|).
+%
+% The next set of variables control the thickness of lines and the
+% dimensions of line end styles.
+%
+% \DescribeVariable{normalpen}
+% Lines with normal linethickness are drawn with |normalpen|.
+%
+% \DescribeVariable{thickpen}
+% Thick lines are drawn with |thickpen|.
+%
+% \DescribeVariable{thinpenpen}
+% Thin lines are drawn with |thinpen|.
+%
+% \DescribeVariable{dotspen}
+% Dotted lines are drawn with |dotspen|.
+%
+% \DescribeVariable{dotpen}
+% |dotpen| is for drawing the black dot line end style.
+%
+% \DescribeVariable{dotdiam}
+% |dotdiam| is the diameter of an open circle or dot line end style.
+%
+% \DescribeVariable{smoothrad}
+% |smoothrad| is the radius of the circular arc used to round the join between
+% two straight lines.
+%
+% \DescribeVariable{drumlid}
+% |drumlid| is the ratio of the minor to major diameter of the ellipse
+% forming the top of the drum box; the larger the value the more the
+% apparent viewpoint shifts to above the drum. The default value is 0.2.
+%
+% \begin{figure}
+% \setlength{\unitlength}{1mm}
+% \centering
+% \begin{picture}(105,40)
+% \put(0,0){\framebox(105,40){}}
+% \put(5,0){\begin{picture}(60,40)
+% ^^A \put(0,0){\framebox(60,40){}}
+% \thicklines
+% \put(0,20){\line(1,0){10}}
+% \put(10,10){\line(2,1){20}}
+% \put(10,30){\line(2,-1){20}}
+% \put(10,10){\line(0,1){20}}
+% \thinlines
+% \put(10,5){\vector(1,0){20}} \put(10,5){\vector(-1,0){0}}
+% \put(20,3){\makebox(0,0)[t]{length}}
+% \put(35,10){\vector(0,1){20}} \put(35,10){\vector(0,-1){0}}
+% \put(40,20){\makebox(0,0)[l]{base width}}
+% \end{picture}}
+% \put(65,0){\begin{picture}(35,40)
+% ^^A \put(0,0){\framebox(60,40){}}
+% \thicklines
+% \put(5,20){\line(1,0){30}}
+% \put(5,10){\line(2,1){20}}
+% \put(5,30){\line(2,-1){20}}
+% \thinlines
+% \put(5,5){\vector(1,0){20}} \put(5,5){\vector(-1,0){0}}
+% \put(15,3){\makebox(0,0)[t]{length}}
+% \put(0,10){\vector(0,1){20}} \put(0,10){\vector(0,-1){0}}
+% \end{picture}}
+% \end{picture}
+% \caption{Length parameters for arrowhead and fanin line end styles}\label{fig:trifan}
+% \end{figure}
+%
+%
+% \DescribeVariable{gal}
+% \DescribeVariable{gab}
+% An arrowhead is defined by the height of the triangle and the base of
+% the triangle forming the arrowhead, as shown in \fref{fig:trifan}.
+% |gal| and |gab| are the length
+% and base width of arrows for arrowed line end styles.
+%
+% \DescribeVariable{gfl}
+% \DescribeVariable{gfb}
+% Like an arrowhead, a fanin is defined by the height and the base of
+% the triangular fan shape, as shown in \fref{fig:trifan}.
+% |gfl| and |gfb| are the length and base
+% width of fans for fanin line end styles. They are initialised to the
+% default values.
+%
+% The next set of variables control certain geometric aspects of
+% the various \ExpressG{} boxes.
+%
+% \DescribeVariable{onelineh}
+% |onelineh| is the minimum height of a box that encloses a single
+% line of text. This is initialised to |5u|.
+%
+% \begin{figure}
+% \setlength{\unitlength}{1mm}
+% \centering
+% \begin{picture}(65,40)
+% \put(0,0){\framebox(65,40){}}
+% \put(5,0){\begin{picture}(60,40)
+% ^^A \put(0,0){\framebox(60,40){}}
+% \thicklines
+% \put(0,10){\framebox(40,15){}}
+% \put(30,10){\line(0,1){15}}
+% \thinlines
+% \put(0,5){\vector(1,0){40}} \put(0,5){\vector(-1,0){0}}
+% \put(20,3){\makebox(0,0)[t]{length}}
+% \put(45,10){\vector(0,1){15}} \put(45,10){\vector(0,-1){0}}
+% \put(47,17.5){\makebox(0,0)[l]{height}}
+% \put(40,30){\vector(-1,0){10}} \put(40,30){\vector(1,0){0}}
+% \put(35,32){\makebox(0,0)[b]{inset}}
+% \end{picture}}
+% \end{picture}
+% \caption{Parameters for (inset) boxes}\label{fig:bool}
+% \end{figure}
+%
+% \DescribeVariable{sdtbl}
+% \DescribeVariable{sdtbh}
+% \DescribeVariable{sdtbs}
+% The length (|sdtbl|), height (|sdtbh|) and line inset (|sdtbs|) for
+% simple data type boxes (e.g., a BOOLEAN data type box), as illustrated
+% in \fref{fig:bool}. These are
+% initialised as |22u|, |onelineh| and |2u| respectively.
+%
+% \DescribeVariable{sdtebl}
+% \DescribeVariable{sdtebh}
+% \DescribeVariable{sdtebs}
+% The length (|sdtebl|), height (|sdtebh|) and line inset (|sdtebs|)
+% for a simple data type EXPRESSION box. The value of |sdtebl| is |28u|,
+% and the other values are the same as for the other simple data type boxes.
+%
+% \DescribeVariable{sdtbgel}
+% \DescribeVariable{sdtbgeh}
+% \DescribeVariable{sdtbges}
+% The length (|sdtbgel|), height (|sdtbgeh|) and inset for GENERICENT
+% data type boxes. The value of |sdtbgel| is |38u|,
+% and the other values are the same as for the other simple data type boxes.
+%
+% \DescribeVariable{pconl}
+% \DescribeVariable{pconh}
+% The length (|pconl|) of an average numeric (proxy) page connector
+% (e.g., for |(9,9 (9,9))|)
+% and the height (|pconh|)
+% of an average page connector, which is initialised for one line of text.
+%
+% \DescribeVariable{enth}
+% \DescribeVariable{typeh}
+% \DescribeVariable{schemah}
+% The heights of an average entity (|enth|),
+% type --- including enumeration and select --- (|typeh|),
+% and schema (|schemah|) boxes. These are all initialised to cater for
+% one line of text.
+%
+% \DescribeVariable{ish}
+% \DescribeVariable{isrh}
+% |ish| is the height of an interschema reference box with one line of text.
+% |isrh| is the height of an interschema reference box with a rename, where
+% there is one line of text each for the original and renamed
+% names.
+%
+% \DescribeVariable{eventh}
+% \DescribeVariable{eventslope}
+% The height (|eventh|) of a one-lined event box, and the slope (|eventslope|)
+% of the sides of an
+% event box (e.g., 0.25 or 1/4).
+%
+% The next set of variables control the amount of space surrounding text
+% on \ExpressG{} diagrams.
+%
+% \DescribeVariable{nextra}
+% |nextra| is the margin around names when put into entity, schema,
+% interschema reference,
+% page connector, and event boxes.
+%
+% \DescribeVariable{niextra}
+% |niextra| is the margin around names when put into type boxes.
+%
+% \DescribeVariable{ndextra}
+% |ndextra| is the margin around names when used on attribute lines.
+%
+% \subsection{Routines}
+%
+% The principal aspects of an \ExpressG{} diagram are lines and line ends of
+% various styles, and boxes of several different kinds. Many routines
+% are provided for positioning and drawing these on a diagram.
+%
+% The following sections describe most of the routines. Short descriptions
+% of the others, which
+% are effectively only used as internal support routines, can be found
+% in Section~\ref{sec:mf}.
+%
+% A note on naming conventions used in describing the routines:
+% \begin{itemize}
+% \item As usual with \Mpost, a name starting with |z| is a point, and
+% names staring with |x| or |y| are x- and y-coordinates respectively.
+% \item The letters |i| through |n| denote (point, coordinate) suffixes.
+% Suffixes are usually a number, such as |37|, but may also have
+% alphanumeric characters after the number (e.g., |37C2D|).
+% \end{itemize}
+%
+%
+% \subsubsection{Utility routines}
+%
+% Several utility routines are provided defining some shortcuts and
+% to ease some of the calculations
+% that may be required when producing a diagram.
+%
+% \DescribeRoutine{VH}
+% |VH(j, k)| calculates the intersection point, |zjvh|, between the vertical
+% line through the point |zj| and the horizontal line through the point |zk|,
+% as shown in \fref{fig:vhvh}.
+%
+%
+% \DescribeRoutine{VhV}
+% |VhV(j, k)| calculates the point |zjvhv| on the vertical line through
+% the point |zj| and the point |zkvhv| on the vertical line through the
+% point |zk|, such that the line |zjvhv--zkvhv| is horizontal and centered
+% vertically between the two given points,
+% as shown in \fref{fig:vhvh}.
+%
+% \begin{figure}
+% \setlength{\unitlength}{1mm}
+% \centering
+% \begin{picture}(130,50)
+% \put(0,0){\framebox(120,50){}}
+% \put(5,5){\begin{picture}(30,40)
+% ^^A \put(0,0){\framebox(30,40){}}
+% \put(5,35){\circle*{2}}
+% \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
+% \put(25,5){\circle*{2}}
+% \put(27,3){\makebox(0,0)[tl]{\texttt{zk}}}
+% \put(5,5){\circle{2}}
+% \put(3,3){\makebox(0,0)[tr]{\texttt{zjvh}}}
+% \put(5,0){\line(0,1){40}}
+% \put(0,5){\line(1,0){30}}
+% \end{picture}}
+% \put(45,5){\begin{picture}(30,40)
+% ^^A \put(0,0){\framebox(30,40){}}
+% \put(5,35){\circle*{2}}
+% \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
+% \put(25,5){\circle*{2}}
+% \put(27,3){\makebox(0,0)[tl]{\texttt{zk}}}
+% \put(5,20){\circle{2}}
+% \put(3,18){\makebox(0,0)[tr]{\texttt{zjvhv}}}
+% \put(25,20){\circle{2}}
+% \put(27,22){\makebox(0,0)[bl]{\texttt{zkvhv}}}
+% \put(5,40){\line(0,-1){25}}
+% \put(0,20){\line(1,0){30}}
+% \put(25,0){\line(0,1){25}}
+% \end{picture}}
+% \put(85,5){\begin{picture}(30,40)
+% ^^A \put(0,0){\framebox(30,40){}}
+% \put(5,35){\circle*{2}}
+% \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
+% \put(25,5){\circle*{2}}
+% \put(27,3){\makebox(0,0)[tl]{\texttt{zk}}}
+% \put(15,35){\circle{2}}
+% \put(17,37){\makebox(0,0)[bl]{\texttt{zjhvh}}}
+% \put(15,5){\circle{2}}
+% \put(13,3){\makebox(0,0)[tr]{\texttt{zkhvh}}}
+% \put(15,0){\line(0,1){40}}
+% \put(0,35){\line(1,0){20}}
+% \put(30,5){\line(-1,0){20}}
+% \end{picture}}
+% \end{picture}
+% \caption[Results of the \texttt{VH}, \texttt{VhV} and \texttt{HvH}
+% routines]%
+% {Results of the \texttt{VH} (left), \texttt{VhV} (middle)
+% and \texttt{HvH} (right) routines}\label{fig:vhvh}
+% \end{figure}
+%
+% \DescribeRoutine{HvH}
+% |HvH(j, k)| calculates the point |zjhvh| on the horizontal line through
+% the point |zj| and the point |zkhvh| on the horizontal line through the
+% point |zk|, such that the line |zjhvh--zkhvh| is vertical and centered
+% horizontally between the two given points,
+% as shown in \fref{fig:vhvh}.
+%
+% \DescribeRoutine{VyV}
+% |VyV(j, i, k)| is a generalisation of the |VhV| routine. It calculates
+% the point |zjvyv| which is on the vertical line through |zj| and the
+% horizontal line through |yi|, and the point |zkvyv| which is on the
+% vertical line through |zk| and the horizontal line through |yi|. An example
+% result is shown in \fref{fig:vyxh}.
+%
+% \begin{figure}
+% \setlength{\unitlength}{1mm}
+% \centering
+% \begin{picture}(90,50)
+% \put(0,0){\framebox(90,50){}}
+% \put(10,5){\begin{picture}(30,40)
+% \put(5,35){\circle*{2}}
+% \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
+% \put(25,5){\circle{2}}
+% \put(27,3){\makebox(0,0)[tl]{\texttt{zkvyv}}}
+% \put(5,5){\circle{2}}
+% \put(3,3){\makebox(0,0)[tr]{\texttt{zjvyv}}}
+% \put(25,20){\circle*{2}}
+% \put(27,22){\makebox(0,0)[bl]{\texttt{zk}}}
+% \put(5,40){\line(0,-1){40}} ^^A V through zj
+% \put(0,5){\line(1,0){30}} ^^A H through yi
+% \put(32,5){\makebox(0,0)[bl]{\texttt{yi}}}
+% \put(25,0){\line(0,1){25}} ^^A V through zk
+% \end{picture}}
+% \put(50,5){\begin{picture}(30,40)
+% \put(5,35){\circle*{2}}
+% \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
+% \put(25,5){\circle{2}}
+% \put(27,3){\makebox(0,0)[tl]{\texttt{zkhxh}}}
+% \put(25,35){\circle{2}}
+% \put(27,33){\makebox(0,0)[tl]{\texttt{zjhxh}}}
+% \put(15,5){\circle*{2}}
+% \put(13,3){\makebox(0,0)[tr]{\texttt{zk}}}
+% \put(25,0){\line(0,1){40}} ^^A V through xi
+% \put(25,42){\makebox(0,0)[b]{\texttt{xi}}}
+% \put(0,35){\line(1,0){30}} ^^A H through zj
+% \put(30,5){\line(-1,0){20}} ^^A H through zk
+% \end{picture}}
+% \end{picture}
+% \caption[Results of the \texttt{VyV} and \texttt{HxH}
+% routines]%
+% {Results of the \texttt{VyV} (left) and \texttt{HxH} (right)
+% routines}\label{fig:vyxh}
+% \end{figure}
+%
+% \DescribeRoutine{HxH}
+% |HxH(j, i, k)| is a generalisation of the |HvH| routine. It calculates
+% the point |zjhxh| which is on the horizontal line through |zj| and the
+% vertical line through |xi|, and the point |zkhxh| which is on the
+% horizontal line through |zk| and the vertical line through |xi|. An example
+% result is shown in \fref{fig:vyxh}.
+%
+% \DescribeRoutine{namespace}
+% |namespace(|\meta{name}|)(|\meta{margin}|)| calculates the length of
+% the text string \meta{name} plus the \meta{margin} length. You may
+% use it like: \\
+% |c = 3/2namespace(btex name etex)(4u)|
+%
+%
+% \DescribeRoutine{dashes}
+% |dashes| is shorthand for a dashed linestyle. Use it like: |draw ... dashes;|.
+%
+% \DescribeRoutine{dots}
+% |dots| is shorthand for a dotted linestyle. Use it like: |draw ... dots;|.
+%
+% \DescribeRoutine{drawgrid}
+% |drawgrid| draws a 16 by 21cm, 1cm spaced grid composed of thin dashed lines.
+% Labels are typeset giving the distance of the lines from the bottom left
+% corner of the grid in millimetres.
+%
+% \subsubsection{Path routines}
+%
+% The package provides some general path making routines.
+%
+% \DescribeRoutine{sharply}
+% |sharply(zi, zj, ... zn)| will generate a piecewise linear
+% path consisting of the
+% straight lines from point |zi| to point |zj| \ldots to point |zn|.
+% It may be used like: \\
+% |draw sharply(z1, z2, z3, z4);| \\
+% to draw a line through the given points.
+%
+% \DescribeRoutine{smoothly}
+% Like the |sharply| routine, |smoothly(zi, zj, ... zn)| will generate a
+% piecewise linear path consisting of the
+% straight lines from point |zi| to point |zj| \ldots to point |zn|, except
+% that the corners of the path at the interior points are rounded with an
+% arc of radius |smoothrad|.
+% It may be used like: \\
+% |draw smoothly(z1, z2, z3, z4) dashes;| \\
+% to draw a dashed line with rounded corners at the given points. Or if
+% a dotted line is needed:
+% \begin{verbatim}
+% pickup dotspen;
+% draw smoothly(z1, z2, z3, z4) dots;
+% pickup normalpen;
+% \end{verbatim}
+%
+% \DescribeRoutine{~}
+% Like the |&| operator, the binary |~| operator concatenates two paths
+% replacing the sharp join with a circular arc of radius |smoothrad|.
+%
+% \subsubsection{Line drawing routines}
+%
+% Routines are provided for drawing a variety of lines with differing line
+% ending styles. Line styles include dotted, dashed, and continuous, and line
+% thicknesses may be normal or thick. Line end styles include open circles,
+% black dots, open and closed (black) arrowheads, and a fanin style.
+%
+% The final uppercase characters of a line drawing routine indicate the kind
+% of line end style that will be used.
+% The character |O| (uppercase O, not zero) is for an \textbf{O}pen circle,
+% |D| is for a black \textbf{D}ot,
+% |OA| is for an \textbf{O}pen \textbf{A}rrowhead,
+% |CA| is for a \textbf{C}losed (black) \textbf{A}rrowhead,
+% and |F| is for a \textbf{F}anin.
+%
+% The line ending drawing routines are described first.
+% \DescribeRoutine{drawO}
+% |drawO(i, j)| draws an open circle, diameter |dotdiam|, at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+% \DescribeRoutine{drawD}
+% |drawD(i, j)| draws a black dot, diameter |dotdiam|, at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+% \DescribeRoutine{drawOA}
+% |drawOA(i, j)| draws an open arrowhead, length |gal| and base width
+% |gab|, at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+% \DescribeRoutine{drawCA}
+% |drawCA(i, j)| draws a closed (black) arrowhead, length |gal| and base width
+% |gab|, at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+% \DescribeRoutine{drawF}
+% |drawF(i, j)| draws a fanin, length |gfl| and base width |gfb|,
+% at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+% The line drawing routines are essentially prepackaged versions of
+% different combinations of the path and line ending routines.
+%
+% \DescribeRoutine{drawdots}
+% |drawdots(i, j)| draws the dotted line |zi--zj|.
+%
+% \DescribeRoutine{drawdotsthree}
+% |drawdotsthree(i, j, k)| draws the dotted piecewise linear line |zi--zj--zk|.
+%
+% \DescribeRoutine{drawdotsfour}
+% |drawdotsfour(i, j, k, l)| draws the dotted piecewise linear line |zi--zj--zk--zl|.
+%
+% \DescribeRoutine{drawdotsO}
+% |drawdotsO(i, j)| draws the dotted line |zi--zj|,
+% ending in an open circle, diameter |dotdiam|, at |zj|.
+%
+% \DescribeRoutine{drawdotsthreeO}
+% |drawdotsthreeO(i, j, k)| draws the dotted piecewise linear line |zi--zj--zk|.
+% ending in an open circle, diameter |dotdiam|, at |zk|.
+%
+% \DescribeRoutine{drawdotsfourO}
+% |drawdotsfourO(i, j, k, l)| draws the dotted piecewise linear line |zi--zj--zk--zl|,
+% ending in an open circle, diameter |dotdiam|, at |zl|.
+%
+% \DescribeRoutine{drawdotsOO}
+% |drawdotsOO(i, j)| draws the dotted line |zi--zj|,
+% ending in open circles, diameter |dotdiam|, at |zi| and |zj|.
+%
+% \DescribeRoutine{drawdash}
+% |drawdash(i, j)| draws the dashed line |zi--zj|.
+%
+% \DescribeRoutine{drawdashthree}
+% |drawdashthree(i, j, k)| draws the dashed piecewise linear line |zi--zj--zk|.
+%
+% \DescribeRoutine{drawdashfour}
+% |drawdashfour(i, j, k, l)| draws the dashed piecewise linear line |zi--zj--zk--zl|.
+%
+% \DescribeRoutine{drawdashO}
+% |drawdashO(i, j)| draws the dashed line |zi--zj|,
+% ending in an open circle, diameter |dotdiam|, at |zj|.
+%
+% \DescribeRoutine{drawdashthreeO}
+% |drawdashthreeO(i, j, k)| draws the dashed piecewise linear line |zi--zj--zk|.
+% ending in an open circle, diameter |dotdiam|, at |zk|.
+%
+% \DescribeRoutine{drawdashfourO}
+% |drawdashfourO(i, j, k, l)| draws the dashed piecewise linear line |zi--zj--zk--zl|.
+% ending in an open circle, diameter |dotdiam|, at |zl|.
+%
+% \DescribeRoutine{drawdashOO}
+% |drawdashOO(i, j)| draws the dashed line |zi--zj--zk--zl|.
+% ending in open circles, diameter |dotdiam|, at |zi| and |zj|.
+%
+% \DescribeRoutine{drawnormal}
+% |drawnormal(i, j)| draws the normal thickness line |zi--zj|.
+%
+% \DescribeRoutine{drawnormalthree}
+% |drawnormalthree(i, j, k)| draws the normal thickness piecewise linear
+% line |zi--zj--zk|.
+%
+% \DescribeRoutine{drawnormalfour}
+% |drawnormalfour(i, j, k, l)| draws the normal thickness piecewise linear
+% line |zi--zj--zk--zl|.
+%
+% \DescribeRoutine{drawnormalO}
+% |drawnormalO(i, j)| draws the normal thickness line |zi--zj|,
+% ending in an open circle, diameter |dotdiam|, at |zj|.
+%
+% \DescribeRoutine{drawnormalthreeO}
+% |drawnormalthreeO(i, j, k)| draws the normal thickness piecewise linear
+% line |zi--zj--zk|,
+% ending in an open circle, diameter |dotdiam|, at |zk|.
+%
+% \DescribeRoutine{drawnormalfourO}
+% |drawnormalfourO(i, j, k, l)| draws the normal thickness piecewise linear
+% line |zi--zj--zk--zl|,
+% ending in an open circle, diameter |dotdiam|, at |zl|.
+%
+% \DescribeRoutine{drawnormalOO}
+% |drawnormalOO(i, j)| draws the normal thickness line |zi--zj|,
+% ending in open circles, diameter |dotdiam|, at |zi| and |zj|.
+%
+% \DescribeRoutine{drawnormalD}
+% |drawnormalD(i, j)| draws the normal thickness line |zi--zj|,
+% ending in a black dot, diameter |dotdiam|, at |zj|.
+%
+% \DescribeRoutine{drawnormalthreeD}
+% |drawnormalthreeD(i, j, k)| draws the normal thickness piecewise linear
+% line |zi--zj--zk|,
+% ending in a black dot, diameter |dotdiam|, at |zk|.
+%
+% \DescribeRoutine{drawnormalfourD}
+% |drawnormalfourD(i, j, k, l)| draws the normal thickness piecewise linear
+% line |zi--zj--zk--zl|,
+% ending in a black dot, diameter |dotdiam|, at |zl|.
+%
+% \DescribeRoutine{drawnormalDD}
+% |drawnormalDD(i, j)| draws the normal thickness line |zi--zj|,
+% ending in black dots, diameter |dotdiam|, at |zi| and |zj|.
+%
+% \DescribeRoutine{drawnormalCA}
+% |drawnormalCA(i, j)| draws the normal thickness line |zi--zj|,
+% ending in a closed (black) arrowhead, length |gal| and base width |gab|,
+% at |zj|.
+%
+% \DescribeRoutine{drawnormalthreeCA}
+% |drawnormalthreeCA(i, j, k)| draws the normal thickness piecewise linear
+% line |zi--zj--zk|
+% ending in a closed (black) arrowhead, length |gal| and base width |gab|,
+% at |zk|.
+%
+% \DescribeRoutine{drawnormalfourCA}
+% |drawnormalfourCA(i, j, k, l)| draws the normal thickness piecewise linear
+% line |zi--zj--zk--zl|
+% ending in a closed (black) arrowhead, length |gal| and base width |gab|,
+% at |zl|.
+%
+% \DescribeRoutine{drawnormalOA}
+% |drawnormalOA(i, j)| draws the normal thickness line |zi--zj|,
+% ending in an open arrowhead, length |gal| and base width |gab|,
+% at |zj|.
+%
+% \DescribeRoutine{drawnormalF}
+% |drawnormalF(i, j)| draws the normal thickness line |zi--zj|,
+% ending in a fanin, length |gfl| and base width |gfb|,
+% at |zj|.
+%
+% \DescribeRoutine{drawnormalFO}
+% |drawnormalFO(i, j)| draws the normal thickness line |zi--zj|,
+% ending in a fanin, length |gfl| and base width |gfb|,
+% at |zi| and an open circle, diameter |dotdiam|, at |zj|.
+%
+% \DescribeRoutine{drawthick}
+% |drawthick(i, j)| draws the thick line |zi--zj|.
+%
+% \DescribeRoutine{drawthickO}
+% |drawthickO(i, j)| draws the thick line |zi--zj|,
+% ending in an open circle, diameter |dotdiam|, at |zj|.
+%
+% \DescribeRoutine{drawthickOO}
+% |drawthickOO(i, j)| draws the thick line |zi--zj|,
+% ending in open circles, diameter |dotdiam|, at |zi| and |zj|.
+%
+% \DescribeRoutine{smooth}
+% |smooth(i, j, k)| replaces the sharp corner on the line |zi--zj--zk|
+% with an arc radius |smoothrad|.
+%
+% \DescribeRoutine{smoothtwo}
+% |smoothtwo(i, j, k, l)| replaces the sharp corners on the line |zi--zj--zk--zl|
+% with arcs radius |smoothrad|.
+%
+% \DescribeRoutine{smoothdash}
+% |smoothdash(i, j, k)| replaces the sharp corner on the dashed line |zi--zj--zk|
+% with an arc radius |smoothrad|.
+%
+% \DescribeRoutine{smoothdots}
+% |smoothdots(i, j, k)| replaces the sharp corner on the dotted line |zi--zj--zk|
+% with an arc radius |smoothrad|.
+%
+%
+%
+% \subsubsection{Box drawing routines}
+%
+% Routines are provided for drawing the different kinds of \ExpressG{}
+% boxes.
+%
+% The first argument to the box drawing routines is the suffix of the
+% point that will be the left-hand bottom corner point of the box. The
+% last argument, except where noted below, is the text that is to be placed
+% at the center of the box. Intermediate arguments, if any, are the length
+% and height of the box.
+%
+% Every box routine calculates the four corner points of the box and the
+% midpoints of each side of the box. For example, if the suffix is |j|,
+% then as illustrated in figure~\ref{fig:boxpoints}, the corner points
+% will be called |zjbl|, |zjbr|, |zjtr| and |zjtl| and the midpoints
+% will be called |zjbm|, |zjmr|, |zjtm| and |zjml|. The center point for
+% postioning the text is |zjc| and the center of the text is placed at
+% this point.
+%
+% The text center point is not necessarily the geometric center of the box.
+% The geometric center is not calculated but lies at the intersection of
+% the lines |zjml--zjmr| and |zjbm--zjtm|.
+%
+% \begin{figure}
+% \centering
+% \setlength{\unitlength}{1mm}
+% \begin{picture}(50,40)
+% \put(0,0){\framebox(50,40){}}
+% \put(10,10){\begin{picture}(30,20)
+% \put(0,0){\framebox(30,20){}}
+% \multiput(0,0)(15,0){3}{\circle*{2}}
+% \multiput(0,10)(15,0){3}{\circle*{2}}
+% \multiput(0,20)(15,0){3}{\circle*{2}}
+% \put(-2,-2){\makebox(0,0)[tr]{\texttt{zjbl}}}
+% \put(15,-2){\makebox(0,0)[t]{\texttt{zjbm}}}
+% \put(32,-2){\makebox(0,0)[tl]{\texttt{zjbr}}}
+% \put(-2,10){\makebox(0,0)[r]{\texttt{zjml}}}
+% \put(13,10){\makebox(0,0)[r]{\texttt{zjc}}}
+% \put(32,10){\makebox(0,0)[l]{\texttt{zjmr}}}
+% \put(-2,22){\makebox(0,0)[br]{\texttt{zjtl}}}
+% \put(15,22){\makebox(0,0)[b]{\texttt{zjtm}}}
+% \put(32,22){\makebox(0,0)[bl]{\texttt{zjtr}}}
+% \end{picture}}
+% \end{picture}
+% \setlength{\unitlength}{1pt}
+% \caption[Calculated points on rectangular boxes]%
+% {Calculated points on rectangular boxes
+% (suffix is \texttt{j} and located at \texttt{zjbl=zj})}
+% \label{fig:boxpoints}
+% \end{figure}
+%
+% \DescribeRoutine{drawSCHEMA}
+% A SCHEMA box is rectangular with a normal perimeter and the box is divided
+% into top and bottom halves by a horizontal line.
+%
+% |drawSCHEMA(j, len, ht)(btex schema\_a etex)| draws a SCHEMA double rectangular
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |schema_a| is placed at the text center of the box,
+% which is central within the upper half.
+%
+% \DescribeRoutine{drawBINARY}
+% A simple data type box is rectangular with a solid boundary and a solid
+% interior vertical line near the right hand edge.
+%
+% |drawBINARY(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |BINARY| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawBOOLEAN}
+% |drawBOOLEAN(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |BOOLEAN| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawCOMPLEX}
+% |drawCOMPLEX(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |COMPLEX| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawEXPRESSION}
+% |drawEXPRESSION(j)| draws a simple data type rectangular
+% box of length |sdtbel| and height |sdtbeh| with its left-hand bottom corner
+% at |zj|. The string |EXPRESSION| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawGENERIC}
+% |drawGENERIC(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |GENERIC| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawINTEGER}
+% |drawINTEGER(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |INTEGER| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawLOGICAL}
+% |drawLOGICAL(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |LOGICAL| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawNUMBER}
+% |drawNUMBER(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |NUMBER| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawREAL}
+% |drawREAL(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |REAL| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawSTRING}
+% |drawSTRING(j)| draws a simple data type rectangular
+% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
+% at |zj|. The string |STRING| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawENUM}
+% An ENUMERATION box is a rectangular box with a dashed perimeter and an
+% interior dashed vertical line near the right hand edge.
+%
+% |drawENUM(j, len, ht)(btex an\_enum etex)| draws a rectangular dashed ENUMERATION type
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |an_enum| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawSELECT}
+% A SELECT box is rectangular with a dashed boundary and an interior
+% dashed vertical
+% line near the left hand edge.
+%
+% |drawSELECT(j, len, ht)(btex a\_select etex)| draws a rectangular dashed SELECT type
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |a_select| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawTYPE}
+% A TYPE box is rectangular with a dashed boundary.
+%
+% |drawTYPE(j, len, ht)(btex a\_type etex)| draws a rectangular dashed TYPE type
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |a_type| is placed at the text center of the box,
+% which is central within the main part of the box.
+%
+% \DescribeRoutine{drawENT}
+% An ENTITY box is a rectangular box with a solid boundary.
+%
+% |drawENT(j, len, ht)(btex an\_entity etex)| draws a rectangular ENTITY type
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |an_entity| is placed at the text center of the box,
+% which is also the geometric center of the box.
+%
+% \DescribeRoutine{drawPREF}
+% A page reference box is a rectangle with rounded ends and a solid boundary.
+%
+% |drawPREF(j, len, ht)(btex page ref etex)| draws an oval page
+% reference
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |page ref| is placed at the text center of the box,
+% which is also the geometric center of the box.
+%
+% \DescribeRoutine{drawISU}
+% An interschema box is a rectangle surrounding a page reference like box.
+% The rectangular box may have either a solid or a dashed boundary.
+%
+% |drawISU(j, len, ht)(btex sch.ent etex)| draws a three-part rectangular
+% interschema USE
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |sch.ent| is placed at the text center of the box,
+% which is also the geometric center of the box.
+%
+% \DescribeRoutine{drawISUR}
+% |drawISUR(j, len, ht)(btex sch.ent etex)(btex newname etex)| draws a three-part rectangular
+% interschema USE and RENAME
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |sch.ent| is placed at the text center of the box,
+% which is also the geometric center of the box. The string |newname| is
+% placed at the geometric center of the bottom third of the box (this is
+% the point |zjrnm|).
+%
+% \DescribeRoutine{drawISR}
+% |drawISR(j, len, ht)(btex sch.ent etex)| draws a three-part rectangular
+% dashed interschema REFERENCE
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |sch.ent| is placed at the text center of the box,
+% which is also the geometric center of the box.
+%
+% \DescribeRoutine{drawISRR}
+% |drawISRR(j, len, ht)(btex sch.ent etex)(btex newname etex)| draws a three-part rectangular
+% dashed interschema REFERENCE and RENAME
+% box of length |len| and height |ht| with its left-hand bottom corner
+% at |zj|. The string |sch.ent| is placed at the text center of the box,
+% which is also the geometric center of the box. The string |newname| is
+% placed at the geometric center of the bottom third of the box (this is
+% the point |zjrnm|).
+%
+% \DescribeRoutine{drawLEVENT}
+% An EVENT box is a rhomboid with a solid boundary.
+%
+% |drawLEVENT(j, len, ht)(btex local\_event etex)| draws a rhomboidal
+% Local EVENT
+% box of length |len|, height |ht| and slope |eventslope| with its left-hand bottom corner
+% at |zj|. The string |local_event| is placed at the text center of the box,
+% which is also the geometric center of the box. Like the rectangular boxes,
+% the calculated bottom and top middle points are vertically below and above
+% the geometric center, but this means that they are \emph{not} midway
+% beteen the bottom and top corner points. This is illustrated in
+% \fref{fig:eventpoints}.
+%
+% \begin{figure}
+% \centering
+% \setlength{\unitlength}{1mm}
+% \begin{picture}(55,40)
+% \put(0,0){\framebox(55,40){}}
+% \put(10,10){\begin{picture}(40,20)
+% ^^A \put(0,0){\framebox(30,20){}}
+% \put(0,0){\line(1,0){30}}
+% \put(5,20){\line(1,0){30}}
+% \put(0,0){\line(1,4){5}}
+% \put(30,0){\line(1,4){5}}
+% \multiput(0,0)(30,0){2}{\circle*{2}}
+% \multiput(2.5,10)(30,0){2}{\circle*{2}}
+% \multiput(5,20)(30,0){2}{\circle*{2}}
+% \multiput(17.5,0)(0,10){3}{\circle*{2}}
+% \put(-2,-2){\makebox(0,0)[tr]{\texttt{zjbl}}}
+% \put(17.5,-2){\makebox(0,0)[t]{\texttt{zjbm}}}
+% \put(32,-2){\makebox(0,0)[tl]{\texttt{zjbr}}}
+% \put(0.5,10){\makebox(0,0)[r]{\texttt{zjml}}}
+% \put(15.5,10){\makebox(0,0)[r]{\texttt{zjc}}}
+% \put(34.5,10){\makebox(0,0)[l]{\texttt{zjmr}}}
+% \put(3,22){\makebox(0,0)[br]{\texttt{zjtl}}}
+% \put(17.5,22){\makebox(0,0)[b]{\texttt{zjtm}}}
+% \put(37,22){\makebox(0,0)[bl]{\texttt{zjtr}}}
+% \end{picture}}
+% \end{picture}
+% \setlength{\unitlength}{1pt}
+% \caption[Calculated points on rhomboidal boxes]%
+% {Calculated points on rhomboidal boxes
+% (suffix is \texttt{j} and located at \texttt{zjbl=zj})}
+% \label{fig:eventpoints}
+% \end{figure}
+%
+% \DescribeRoutine{drawGEVENT}
+% |drawGEVENT(j, len, ht)(btex global\_event etex)| draws a thick rhomboidal
+% Global EVENT
+% box of length |len|, height |ht| and slope |eventslope| with its left-hand bottom corner
+% at |zj|. The string |global_event| is placed at the text center of the box,
+% which is also the geometric center of the box.
+%
+%
+% \DescribeRoutine{drawcirclebox}
+% A circle box is a circle with a solid boundary.
+%
+% |drawcirclebox(j, diam)(btex ABC etex)| draws a circle diameter |diam|
+% and center at |zj|. The string |ABC| is placed at the center of the circle.
+% In this case the four midside points, |zjbm|, |zjmr|, |zjtm| and |zjml|,
+% are at on the circle at the extreme bottom, right, top and left (i.e., at
+% the S, E, N and W compass points). The
+% corner points, |zjbl|, |zjbr|, |zjtr| and |zjtl|, are also on the
+% circumference midway between the midpoints (i.e., at the SW, SE, NE and NW
+% compass points).
+%
+% \DescribeRoutine{drawdashcircle}
+% |drawdashcircle(j, diam)| draws a dashed circle. The location
+% and size parameters are the same as for |drawcirclebox|, as are the
+% calculated points.
+%
+% \subsection{Extra BLA variables and routines}
+%
+% In addition to the facilities described above for \ExpressG{}
+% diagrams, extra line styles and boxes are provided for other
+% kinds of diagrams.
+%
+% Additional line end styles are coded by:
+% |A| for an \textbf{A}rrowhead,
+% |OD| for an \textbf{O}pen \textbf{D}iamond,
+% |CD| for a \textbf{C}losed \textbf{D}iamond.
+%
+% \DescribeVariable{gdl}
+% \DescribeVariable{gdb}
+% The variables |gdl| and |gdb| hold the the length and base width of
+% diamond line end styles (see \fref{fig:diales}),
+% analagous to the corresponding variables
+% for arrow heads and fanin. By default, |gdl| is twice the default
+% arrowhead length and |gdb| is three quarters of the default
+% arrowhead base width.
+%
+% \begin{figure}
+% \setlength{\unitlength}{1mm}
+% \centering
+% \begin{picture}(90,40)
+% \put(0,0){\framebox(90,40){}}
+% \put(5,0){\begin{picture}(85,40)
+% ^^A \put(0,0){\framebox(85,40){}}
+% \thicklines
+% \put(0,20){\line(1,0){10}}
+% ^^A \put(10,10){\line(2,1){20}}
+% ^^A \put(10,30){\line(2,-1){20}}
+% ^^A \put(10,10){\line(0,1){20}}
+% \put(10,20){\line(2,1){20}}
+% \put(10,20){\line(2,-1){20}}
+% \put(50,20){\line(-2,1){20}}
+% \put(50,20){\line(-2,-1){20}}
+% \thinlines
+% ^^A \put(10,5){\vector(1,0){20}} \put(10,5){\vector(-1,0){0}}
+% ^^A \put(20,3){\makebox(0,0)[t]{length}}
+% ^^A \put(35,10){\vector(0,1){20}} \put(35,10){\vector(0,-1){0}}
+% ^^A \put(40,20){\makebox(0,0)[l]{base width}}
+% \put(10,5){\vector(1,0){40}} \put(10,5){\vector(-1,0){0}}
+% \put(30,3){\makebox(0,0)[t]{length}}
+% \put(55,10){\vector(0,1){20}} \put(55,10){\vector(0,-1){0}}
+% \put(60,20){\makebox(0,0)[l]{base width}}
+% \end{picture}}
+% \end{picture}
+% \caption{Length parameters for diamond line end styles}\label{fig:diales}
+% \end{figure}
+%
+% \DescribeRoutine{drawA}
+% |drawA(i, j)| draws a simple arrowhead, length |gal| and base width
+% |gab|, at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+%
+% \DescribeRoutine{drawDCA}
+% |drawDCA(i, j)| draws a double closed arrowhead, each of length |gal|
+% and base width
+% |gab|, at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+%
+% \DescribeRoutine{drawOD}
+% |drawOD(i, j)| draws an open diamond, length |gdl| and base width
+% |gdb|, at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+% \DescribeRoutine{drawCD}
+% |drawCD(i, j)| draws a closed (black) diamond, length |gdl| and base width
+% |gdb|, at the |zj| end
+% of the vector from |zi| to |zj|.
+%
+%
+% \DescribeRoutine{drawdashA}
+% |drawdashA(i, j)| draws the dashed line |zi--zj|,
+% ending in an arrowhead, length |gal| and base width |gab|,
+% at |zj|.
+%
+% \DescribeRoutine{drawdashOA}
+% |drawdashOA(i, j)| draws the dashed line |zi--zj|,
+% ending in an open arrowhead, length |gal| and base width |gab|,
+% at |zj|.
+%
+% \DescribeRoutine{drawnormalOD}
+% |drawnormalOD(i, j)| draws the normal thickness line |zi--zj|,
+% ending in an open diamond, length |gdl| and base width |gdb|,
+% at |zj|.
+%
+% \DescribeRoutine{drawnormalCD}
+% |drawnormalCD(i, j)| draws the normal thickness line |zi--zj|,
+% ending in a closed (black) diamond, length |gdl| and base width |gdb|,
+% at |zj|.
+%
+% \DescribeRoutine{drawcircleA}
+% |drawcircleA(j, diam)| draws a circle diameter |diam| centered at |zj|.
+% A counterclockwise pointing arrow is placed at the top of the circle.
+% The midside and `corner' points are the same as calculated by
+% the |drawcirclebox| routine.
+%
+% \DescribeRoutine{drawDot}
+% |drawDot(j, diam)| draws a black dot, diameter |diam| centered at |zj|.
+% There are no calculated points.
+%
+% \DescribeRoutine{drawCircledDot}
+% |drawCircledDot(j, diam)| draws a black dot with a circle outside
+% it, overall diameter |diam|, centered at |zj|.
+% There are no calculated points. This could be used for a UML
+% `bullseye'. The white ring should obscure anything
+% drawn earlier that lies underneath it (by definition the black dot covers
+% up anything underneath itself). For example:
+% \begin{verbatim}
+% draw z1--z2; % line from z1 to z2
+% drawCircledDot(2, len); % obscures last len of above line
+% draw z3--z2; % not obscured
+% \end{verbatim}
+%
+% Commands of the form |draw...box| have a text argument
+% which is printed at the center of the box. If an empty box is
+% required the text argument should be an empty string (|""|). For
+% example |draw...box(...)("")|.
+%
+% \DescribeRoutine{drawcardbox}
+% |drawcardbox(j, len, ht, fold)(btex note etex)| draws a rectangular
+% box, length |len| and height |ht|, with its bottom left corner at |zj|.
+% The top right corner of the box is folded down, with the side length
+% of the fold given by |fold|. The string |note| is placed at the
+% center of the box. If no text is required, then use an empty string (i.e.,
+% |""|), as in \\
+% |\drawcardbox(23, el, eh, 1/8eh)("")|
+%
+% \DescribeRoutine{drawdiamondbox}
+% |drawdiamondbox(j, len, ht)(btex str etex)| draws a diamond shaped
+% box, length |len| and height |ht|, with its center at |zj|. The usual
+% corner, center and midpoints are also calculated except that the points
+% |z$tm| etc., are at the corners of the diamond and the points |z$tl| etc.,
+% are at the middle of each line, as shown in \fref{fig:diamondpoints}.
+% The text |str| is placed at the center of the box.
+%
+% \begin{figure}
+% \centering
+% \setlength{\unitlength}{1mm}
+% \begin{picture}(50,40)
+% \put(0,0){\framebox(50,40){}}
+% \put(10,10){\begin{picture}(30,20)
+% ^^A \put(0,0){\framebox(30,20){}}
+% \put(0,10){\line(3,2){15}}
+% \put(0,10){\line(3,-2){15}}
+% \put(30,10){\line(-3,2){15}}
+% \put(30,10){\line(-3,-2){15}}
+% \multiput(0,10)(15,0){3}{\circle*{2}}
+% \multiput(15,0)(0,20){2}{\circle*{2}}
+% \multiput(7.5,5)(0,10){2}{\circle*{2}}
+% \multiput(22.5,5)(0,10){2}{\circle*{2}}
+% \put(13,10){\makebox(0,0)[r]{\texttt{zjc}}}
+% \put(15,-2){\makebox(0,0)[t]{\texttt{zjbm}}}
+% \put(-2,10){\makebox(0,0)[r]{\texttt{zjml}}}
+% \put(32,10){\makebox(0,0)[l]{\texttt{zjmr}}}
+% \put(15,22){\makebox(0,0)[b]{\texttt{zjtm}}}
+%
+% \put(5.5,3){\makebox(0,0)[tr]{\texttt{zjbl}}}
+% \put(24.5,3){\makebox(0,0)[tl]{\texttt{zjbr}}}
+% \put(5.5,17){\makebox(0,0)[br]{\texttt{zjtl}}}
+% \put(24.5,17){\makebox(0,0)[bl]{\texttt{zjtr}}}
+% \end{picture}}
+% \end{picture}
+% \setlength{\unitlength}{1pt}
+% \caption[Calculated points on diamond boxes]%
+% {Calculated points on diamond boxes
+% (suffix is \texttt{j} and located at \texttt{zjc=zj})}
+% \label{fig:diamondpoints}
+% \end{figure}
+%
+%
+% \DescribeRoutine{drawtwodiamondbox}
+% |drawtwodiamondbox(j, len, ht, inset)(btex str etex)| draws a diamond shaped
+% box, length |len| and height |ht|, with its center at |zj|.
+% The text |str| is placed at the center of the box.
+% A second diamond is drawn inside the first. The parameter |inset| is
+% the space between adjacent outer and inner lines.
+% No calculated points are available for the inner diamond.
+%
+% \DescribeRoutine{drawdoublerectangle}
+% |drawdoublerectangle(j, len, ht, tf)| draws a rectangular box, length |len|
+% and height |ht|, located with its bottom left corner at |zj|. The box
+% is divided horizontally
+% into a top and bottom portion, with the height of the top portion being
+% the fraction |tf| of the total height of the box. The center points of
+% the two portions are calculated as |zjct| and |zjcb| for the top and
+% bottom respectively.
+% The ends of the dividing line are at |zjtfl| and |zjtfr|.
+%
+% \DescribeRoutine{drawtriplerectangle}
+% |drawtriplerectangle(j, len, ht, tf, bf)| draws a rectangular box, length |len|
+% and height |ht|, located with its bottom left corner at |zj|. The box
+% is divided horizontally
+% into a top, middle and bottom portion.
+% The height of the top portion is the fraction |tf| of the total height
+% of the box.
+% The height of the bottom portion is the fraction |bf| of the total height
+% of the box.
+% The center points of
+% the three portions are calculated as |zjct|, |zjcm| and |zjcb| for the
+% top, middle and bottom respectively.
+% The ends of the dividing lines are at |zjtfl| and |zjtfr| for the upper
+% line, and at |zjbfl| and |zjbfr| for the lower line.
+%
+% \DescribeRoutine{hiderectangle}
+% |hiderectangle(j, len, ht)| draws an invisible rectangular box, length |len|
+% and height |ht|, located with its bottom left corner at |zj|. The box
+% covers up anything underneath it. Note that unlike all the other boxes
+% the only point handle to the box is the bottom left corner --- the
+% |zjbl|, |zjtr|, etc., points are not available and hence cannot
+% be used for positioning or alignment purposes.
+%
+% \DescribeRoutine{drawdashboxover}
+% |drawdashboxover(j, len, ht)| draws a dashed rectangular box, length |len|
+% and height |ht|, located with its bottom left corner at |zj|. The box
+% covers up anything underneath it.
+%
+% \DescribeRoutine{drawindexbox}
+% |drawindexbox(j, len, ht, lenp, htp)(btex str etex)|
+% draws a rectangular box, length |len|
+% and height |ht|, located with its bottom left corner at |zj|. Another
+% rectangular box, length |lenp| and height |htp|, is drawn with its
+% bottom left corner at the top left corner of the first box (like an index
+% card). The main box points are |zjbl| etc., but the secondary box
+% points are |zjP.bl|, |zjP.bm| etc. The text |str| is placed at the center
+% (|zjP.c|) of the secondary box.
+%
+% \DescribeRoutine{drawroundedbox}
+% |drawroundedbox(j, len, ht, rad)(btex str etex)|
+% draws a rectangular box, length |len|
+% and height |ht|, located with its bottom left corner at |zj|. The corners
+% of the box are rounded using radius |rad|. If |2rad| is greater
+% than |len| or |ht|, then |2rad| is reduced to the lesser of |len| and
+% |ht|, thereby producing at least one pair of semicircular sides.
+% The text |str| is placed at the center of the box.
+%
+% \DescribeRoutine{drawovalbox}
+% |drawovalbox(j, len, ht)(btex str etex)|
+% draws an elliptical box,
+% horizontal diameter |len|
+% and vertical diameter |ht|, located with its center at |zj|. Like the
+% diamond box, |zjtm|, |zjmr|, etc., are at the extremes of the ellipse
+% and the points |zjtr|, |zjbr|, etc., are on the ellipse approximately
+% halfway between the extremum points, similar to the positions shown
+% in \fref{fig:diamondpoints}. The text |str| is placed at the center
+% of the box.
+%
+% \DescribeRoutine{drawoutputbox}
+% |drawoutputbox(j, len, ht)(btex str etex)|
+% draws a box,
+% length |len| and height |ht|, located with its bottom left corner at |zj|.
+% The bottom of the box is a wavy line and the other three sides
+% are straight. The text |str| is placed at the center of the box.
+% This kind of box is often used as a flowchart symbol for output;
+% it is meant to be a represention of printed paper which has been
+% torn from a long continuous roll.
+%
+%
+% \DescribeRoutine{drawdashellipse}
+% |drawdashellipse(j, len, ht)|
+% draws a dashed ellipse. The location and dimensional parameters
+% correspond to those for |drawovalbox|, as do the calculated points.
+%
+% \DescribeRoutine{drawdrum}
+% |drawdrum(j, len, ht)(btex str etex)|
+% draws a `drum' box. This is constructed as a rectangular box of width
+% width |len| and height |ht|, with its bottom left hand corner at |zj|.
+% The horizontal line at the bottom of the
+% rectangle is replaced by a half-ellipse with a major diameter of |len|
+% and the minor diameter given by |drumlid*len|. The horizontal line
+% at the top is replaced by a full ellipse with the same dimensions.
+%
+%\begin{figure}
+%\centering
+%\setlength{\unitlength}{0.6mm}
+%
+%\begin{picture}(100,100)
+% \put(0,0){\framebox(120,120){}}
+% \put(20,20){\begin{picture}(80,80)
+% \put(0,10){\line(0,1){60}}
+% \put(80,10){\line(0,1){60}}
+% \qbezier(0,10)(0,0)(40,0)
+% \qbezier(40,0)(80,0)(80,10)
+%
+% \qbezier(0,70)(0,80)(40,80)
+% \qbezier(40,80)(80,80)(80,70)
+% \qbezier(0,70)(0,60)(40,60)
+% \qbezier(40,60)(80,60)(80,70)
+%
+% \multiput(0,10)(0,30){3}{\circle*{2}}
+% \put(-2,10){\makebox(0,0)[r]{\texttt{zjbl}}}
+% \put(-2,40){\makebox(0,0)[r]{\texttt{zjml}}}
+% \put(-2,70){\makebox(0,0)[r]{\texttt{zjtl}}}
+% \multiput(80,10)(0,30){3}{\circle*{2}}
+% \put(82,10){\makebox(0,0)[l]{\texttt{zjbr}}}
+% \put(82,40){\makebox(0,0)[l]{\texttt{zjmr}}}
+% \put(82,70){\makebox(0,0)[l]{\texttt{zjtr}}}
+% \put(40,0){\circle*{2}}
+% \put(40,-2){\makebox(0,0)[t]{\texttt{zjbm}}}
+% \put(40,80){\circle*{2}}
+% \put(40,82){\makebox(0,0)[b]{\texttt{zjtm}}}
+% \put(40,35){\circle*{2}}
+% \put(40,37){\makebox(0,0)[b]{\texttt{zjc}}}
+%
+% \put(20,1){\circle*{2}}
+% \put(20,-1){\makebox(0,0)[t]{\texttt{zjbml}}}
+% \put(60,1){\circle*{2}}
+% \put(60,-1){\makebox(0,0)[t]{\texttt{zjbmr}}}
+% \put(20,79){\circle*{2}}
+% \put(20,81){\makebox(0,0)[b]{\texttt{zjtml}}}
+% \put(60,79){\circle*{2}}
+% \put(60,81){\makebox(0,0)[b]{\texttt{zjtmr}}}
+%
+% \end{picture}}
+%\end{picture}
+%\setlength{\unitlength}{1pt}
+%\caption[Calculated points on a drum]{Calculated points on a drum
+% (suffix is \texttt{j} and located at \texttt{zjbl=zj})}
+% \label{fig:drum}
+%\end{figure}
+%
+% As shown in Figure~\ref{fig:drum},
+% the calculated points on the vertical sides of the drum are the same
+% as for a rectangular box. There are three calculated points on the base
+% of the drum, called |zjbml|, |zjbm| and |zjbmr|. Similarly there are
+% three points on the top of the drum called |zjtml|, |zjtm| and |zjtmr|.
+% The center point, |zjc| is halfway between the sides and halfway between
+% the two lower ellipse halves. The text |str| is placed at this center point.
+%
+% \DescribeRoutine{drawstickman}
+% |drawstickman(j, len, ht)|
+% draws a genderless full frontal (or rear) stick figure enclosed in
+% an invisible box,
+% length |len| and height |ht|, located with its bottom left corner at |zj|.
+% This can be used, for example to represent an actor in a UML Use Case
+% diagram. Setting the height to be twice the length produces a reasonable
+% result, for instance:
+% \verb?drawstickman(3, wd, 2wd);?
+%
+%
+% \section{An example} \label{sec:example}
+%
+% The example attempts to bring out the main methods that can be used
+% in defining \ExpressG{} diagrams. The code for eleven diagrams is provided, none
+% of which necessarily has anything to do with a real example of \ExpressG{}
+% modeling, but rather is meant to be illustrative of diagramming techniques.
+%
+% This section is best studied with a copy of the printed diagrams to
+% hand. Section~\ref{sec:run} on \pref{sec:run} explains briefly how
+% to run the example and obtain the diagrams.
+%
+% The default extension for a \Mpost{} file is \file{.mp}.
+% \begin{macrocode}
+%<*eg>
+%%% EXPEG.MP Example MetaPost EXPRESS-G diagrams
+
+% \end{macrocode}
+%
+% Assuming that the diagrams are to be eventually embedded in, or processed
+% through, a \LaTeX{} document then any \TeX{} macros must come at the
+% start of the file between a |verbatimtex| \ldots |etex| pair. When dealing
+% with text, \Mpost{} does not handle more than a single line. The macro
+% below is to enable two lines of text to be handled by \Mpost.
+%
+% \begin{macrocode}
+
+% use btex \twolines{first}{second} etex for two-line labels
+verbatimtex \def\twolines#1#2{\vbox{\hbox{#1} \hbox{#2}}} etex
+
+% \end{macrocode}
+%
+% The \Lpack{expressg} package file has to be input to make the routines
+% available.
+% \begin{macrocode}
+input expressg
+
+% \end{macrocode}
+%
+% \subsection{Diagram 1: Some boxes and lines}
+%
+% Many diagrams can be defined in one file. Each diagram starts with
+% |beginfig(N)|, where N is a unique integer, and ends with |endfig;|.
+% \EPS{} for each diagram is written to a file called
+% \file{mproot.N}, where \file{mproot} is the root name of the input file.
+% In our
+% case the output files will be \file{expeg.1} through \file{expeg.11}.
+% \begin{macrocode}
+beginfig(1)
+
+% \end{macrocode}
+%
+% The first diagram consists of some of the \Lpack{expressg} box and line styles.
+% The main point is to illustrate how \Mpost{} allows the boxes to be aligned.
+% Start off by defining a point |z1| at the origin. By default, a variable name
+% starting with the letter |z| is assumed to be a point. Similarly, variables
+% starting with |x| and |y| are assumed to be x- and y-coordinates. If |zk|
+% is defined with a value then automatically |xk| is the value of the x
+% coordinate of
+% the point |zk| and |yk| is the value of the
+% y coordinate. Conversely, if |xj| and |yj| are defined, |zj| is automatically
+% defined.
+%
+% Note that the |=| sign denotes an equation, not an assignment. The power
+% of \Mpost{} comes from its ability to solve linear equations.
+%
+% Having defined the point |z1|, draw an EXPRESSION box with its bottom
+% left hand corner at |z1|.
+% \begin{macrocode}
+z1=(0,0);
+drawEXPRESSION(1);
+
+% \end{macrocode}
+%
+% Remember that when a box is drawn, its corner and mid points are
+% calculated. These can be used in defining other points. In particular
+% there is the point |z1tr| which is the top right hand corner
+% of the EXPRESSION box. Also, if another box is drawn at point |z2| then
+% it will have its bottom left hand corner at |z2bl|.
+%
+% The point |z2bl| is defined by a linear equation with respect to
+% the point |z2|. As \Mpost{} can solve linear equations, given the
+% point |z2bl| it can solve for the point |z2|.
+%
+% The next box has its bottom left hand corner at the top right hand
+% corner of the EXPRESSION box, by specifying that the
+% point |z2bl| and |z1tr| are the same location and then drawing a box located
+% at |z2|. The third (BOOLEAN) box is also stacked in the same way with
+% respect to the second (INTEGER) box.
+%
+% \begin{macrocode}
+z2bl=z1tr;
+drawINTEGER(2);
+
+z3bl=z2tr;
+drawBOOLEAN(3);
+
+% \end{macrocode}
+%
+% Next a piece of circled text is drawn. Using the same method as before,
+% the bottom of the circle is made to be coincident with the middle of the top
+% of the BOOLEAN box. The |namespace| routine is used to specify the circle
+% diameter. Note that an argument to a routine can itself be a routine.
+% \begin{macrocode}
+z4bm=z3tm;
+drawcirclebox(4, namespace(btex ABS etex)(nextra))(btex ABS etex);
+
+% \end{macrocode}
+%
+% \Mpost{} is a typed language, and new variables can be declared of a
+% particular type. A |numeric| variable holds a number (or a length).
+% The diameter of the circle just drawn is going to be used as a length
+% in later parts of this diagram, so it is sensible to store its value
+% in a new variable called |diam|. We then use it in drawing another
+% circle directly on top of the first one.
+% \begin{macrocode}
+numeric diam;
+diam = namespace(btex ABS etex)(nextra);
+
+z5bm=z4tm;
+drawcirclebox(5, diam)(btex SAB etex);
+
+% \end{macrocode}
+%
+% The next element in the diagram is an ENTITY box.
+% We use the default height for the entity box and the default page connector
+% length as its length (no reason, but it saves inventing another variable
+% or value).
+%
+% The ENTITY box is positioned with respect to the SAB circle, but in a
+% slightly more complicated way than earlier positions. We want the left hand
+% side of the box to align with the right hand side of the circle. Also,
+% the middle of the box should align with the top of the circle.
+%
+% The ENTITY box will be located at point |z6|. The easiest way is to
+% specify |z6| is |z6ml=(x5mr, y5tm)|, but to demonstrate more of \Mpost's
+% equation solving abilities a more complicated approach is taken to the
+% specification of the x coordinate. The horizontal distance between the
+% points |z5ml| and |z5tl| on the circle is the same as the distance
+% between the points |z5tr| and |z5mr|. We can express this as
+% |x5ml-x5tl = x5tr-x5mr|. As we want |x6ml|, which is the same as |x6bl|,
+% to be the same as |x5mr| we
+% can substitute into this equation, as done in the code below. Note that
+% \Mpost{} can solve for the unknown |x6bl| even though it is on
+% the right hand side
+% of the equation because the other three values are known.
+%
+% The y coordinate of the point |z6mr| is specified as
+% equal to the y coordinate of the top of the circle. Because of the linear
+% relations involving all the points on a box, it is sufficient to provide
+% one x coordinate and one y coordinate to fix all the points on the box.
+% \begin{macrocode}
+x5ml-x5tl = x5tr-x6bl;
+y6mr=y5tm;
+drawENT(6, pconl, enth)(btex an\_ent etex);
+
+% \end{macrocode}
+%
+% The geometric center of the next box, an LEVENT, is vertically above
+% the geometric center of the ENTITY box, and the bottom of LEVENT is slightly
+% (one lenth unit) above the top of the ENTITY box. This is accomplished here
+% by specifying |z7bm| in terms of expressions involving the coordinates
+% of the point |z6tm|.
+% \begin{macrocode}
+z7bm=(x6tm,y6tm+u);
+drawLEVENT(7, pconl, eventh)(btex levent etex);
+
+% \end{macrocode}
+%
+% At point |z8| a GEVENT box is drawn. It's bottom left hand corner is
+% vertically above the top left hand corner of the LEVENT box. If you look
+% at the resulting diagram, you will see that GEVENT is shifted right with
+% respect to LEVENT. For vertical alignment of EVENT boxes it is best to
+% use the middle rather than corner points.
+% \begin{macrocode}
+z8=(x7tl, y7tr+u);
+drawGEVENT(8, pconl, eventh)(btex gevent etex);
+
+% \end{macrocode}
+%
+% \DescribeRoutine{mediation}
+% For the last of the aligned boxes another aspect of \Mpost{} is used.
+% \Mpost{} provides a \emph{mediation} facility whose syntax is |frac[a,b]|.
+% The result of a mediation is a value that is |frac| between the value |a|
+% and the value |b|. For example, the result of |0.25[10,30]| is 15. Similarly,
+% the result of |1/3[zj,zk]| is the point one third of the way between point
+% |zj| and point |zk|.
+%
+% The SCHEMA box is positioned with its bottom right hand corner at one
+% eighth of the way along, and at the top of, the BOOLEAN box.
+% \begin{macrocode}
+z9br=1/8[z3tl,z3tr];
+drawSCHEMA(9, pconl, schemah)(btex a\_schema etex);
+
+% \end{macrocode}
+%
+% The second half of the diagram illustrates various line and end
+% styles. These are all horizontal, the same length and are aligned
+% vertically, so
+% define the x coordinate |xmid| of the left hand end of the lines, and
+% the length |len| of the lines.
+% \begin{macrocode}
+numeric xmid, len;
+xmid = x8tr + diam;
+len = 2diam;
+
+% \end{macrocode}
+%
+% \DescribeRoutine{shifted}
+% The next line of code exhibits another \Mpost{} function. A point can
+% be specified as being some other point that is \emph{shifted} by given
+% amounts in the x and y directions. More precisely, the shift is specified
+% by a pair of values, written as |(a,b)|. The first line is aligned
+% vertically with the center of the first box and its start point is |z11|.
+% The end point, |z111|, is specified as being the start point shifted
+% horizontally by the length of the line.
+% \begin{macrocode}
+z11=(xmid, y1ml); z111=z11 shifted (len, 0);
+drawdashO(11, 111);
+
+% \end{macrocode}
+%
+% Because we will be using the same horizontal shift for all the lines,
+% define a \emph{pair}, called |moveright|, that is the required shift.
+% The next two lines are also aligned vertically with the centers of the
+% second and third boxes.
+% \begin{macrocode}
+pair moveright;
+moveright = (len, 0);
+
+z12=(xmid, y2ml); z121=z12 shifted moveright;
+drawnormalO(12, 121);
+
+z13=(xmid, y3ml); z131=z13 shifted moveright;
+drawthickO(13, 131);
+
+% \end{macrocode}
+%
+% The remaining lines will have the same vertical spacing as the first three,
+% so define another pair, |moveup|, that we can use for vertical shift.
+% \begin{macrocode}
+pair moveup;
+moveup = (0, y13-y12);
+
+z14=z13 shifted moveup; z141=z14 shifted moveright;
+drawnormalD(14, 141);
+
+z15=z14 shifted moveup; z151=z15 shifted moveright;
+drawnormalCA(15, 151);
+
+z16=z15 shifted moveup; z161=z16 shifted moveright;
+drawnormalOA(16, 161);
+
+z17=z16 shifted moveup; z171=z17 shifted moveright;
+drawnormalF(17, 171);
+
+% \end{macrocode}
+%
+% The upper part of the diagram illustrates some of the additional
+% line styles and boxes provided that are not part of the
+% \ExpressG{} language.
+% \changes{v1.1}{1999/10/30}{Extended upper half of diagram 1 for new box
+% types}
+%
+% The upper half is seperated from the bottom half by a dashed line, just
+% to make the distinction. The line is set above the highest box so far,
+% which is located at |z8|, and extends across the width of the diagram.
+% \begin{macrocode}
+z300=(0,y8tm+diam); z301=(x111,y300);
+draw z300--z301 dashes;
+
+% \end{macrocode}
+% Define |mup| to be a distance, which we will use for vertical seperation.
+% \begin{macrocode}
+numeric mup; mup := onelineh;
+
+% \end{macrocode}
+%
+% As previously, we'll start with the boxes which will be placed in
+% a column at the left side of the diagram. The first box, high enough
+% for one line of enclosed text, has its top right hand corner folded
+% down by one quarter the box height. Text is placed at the center
+% of the box, but if this is not required then it can be given as an
+% empty string (i.e., |""|).
+% \begin{macrocode}
+z302=(0,y300+mup);
+drawcardbox(302, pconl, onelineh, 1/4onelineh)("");
+
+% \end{macrocode}
+%
+% The next box is a diamond shape. Unlike the rectangular and rhomboidal
+% boxes, these are positioned
+% via the center of the box instead of the bottom left hand corner.
+% \begin{macrocode}
+z303bm=(x302tm, y302tm+mup);
+drawdiamondbox(303, pconl, 2onelineh)(btex jewel etex);
+
+% \end{macrocode}
+%
+% Now there is a double box with the top portion being 3/4 of the box
+% height. Text is put into the top half of the box using \Mpost's
+% labeling routine (see \pref{page:label}).
+% \begin{macrocode}
+z304=(0, y303tm+mup);
+drawdoublerectangle(304, pconl, 2onelineh, 3/4);
+label(btex top etex, z304ct);
+
+% \end{macrocode}
+%
+% Next comes a triple box with the bottom portion being one fifth of
+% the height, and the top portion being two fifths of the height.
+% Text is placed in the top and middle portions, but not into the bottom.
+% \begin{macrocode}
+z305=(0, y304tm+mup);
+drawtriplerectangle(305, pconl, 3onelineh, 2/5, 0.2);
+label(btex top etex, z305ct);
+label("middle", z305cm);
+
+% \end{macrocode}
+%
+% Some languages include a box that looks a little like an index card, and
+% this is shown next.
+% A small box is also drawn inside the main part of the index box,
+% just to illustrate
+% that drawings may be placed inside boxes.
+% \begin{macrocode}
+z306=(0,y305tm+mup);
+drawindexbox(306, 2pconl, 3onelineh, 3/4pconl, onelineh)(btex pack etex);
+z307=1/8[z306bl,z306tr];
+drawENT(307, 1/4pconl, onelineh)(btex E etex);
+
+% \end{macrocode}
+%
+% Another box shown here is a dotted box that covers up anything that
+% is underneath it. To demonstrate, a folded corner box is drawn first,
+% and then the
+% dashed box is drawn second. They have to be done in this order.
+% (The reason for the notation |y306P.tl| is explained under diagram 2
+% on \pref{page:dotsuffix}).
+% \begin{macrocode}
+z308=(0, y306P.tl+mup);
+z309ml=z308c;
+drawcardbox(308, pconl, 2onelineh, 1/4onelineh)(btex covered etex);
+drawdashboxover(309, pconl, onelineh);
+
+% \end{macrocode}
+%
+% An oval box comes next. The perimeter is an ellipse.
+% \begin{macrocode}
+z310bm=(x306bm,y309tm+mup);
+drawovalbox(310, 2pconl, 2onelineh)("");
+
+% \end{macrocode}
+%
+% Now we have two rounded boxes. In the first one the corner radius is
+% small and the corners are neatly rounded. The radius is large in the
+% second case, and it is automatically reduced to give semicircular ends.
+% Further, the center portion of the second of these boxes is `deleted'
+% by putting a |hiderectangle| over it.
+% \begin{macrocode}
+z311ml=(x310mr+mup, y310ml);
+drawroundedbox(311, 2pconl, 2onelineh, 1/2onelineh)("rounded");
+
+z312ml=(x311mr+mup, y311mr);
+drawroundedbox(312, 2pconl, 2onelineh, 3/2onelineh)(btex large radius etex);
+
+z314=(x312bm-1/4pconl, y312bm-1/2mup);
+hiderectangle(314, 1/2pconl, (3/2onelineh + mup));
+
+% \end{macrocode}
+%
+% The last of the simple enclosed shapes are a dashed ellipse and a dashed circle,
+% which are aligned below the partially obscured rounded box.
+% \begin{macrocode}
+z315tm=(x312bm, y312bm-mup);
+drawdashellipse(315, 2pconl, 2onelineh);
+
+z316tm=(x315bm, y315bm-mup);
+drawdashcircle(316, diam);
+
+% \end{macrocode}
+%
+% A drum box is now presented. This is centered with respect to the
+% rounded box and aligned with the bottom of the triple box. It is the
+% same nominal size as the triple box.
+% \begin{macrocode}
+z317bc=(x311bm,y304br);
+drawdrum(317, pconl, 3onelineh)(btex drum etex);
+% \end{macrocode}
+% To be a little different, I'll add a `handle' to the top of the drum. The
+% top of the handle will be above the drum at the point |z317A|, and the
+% attachement points are at the |tml| and |tmr| points on the drum. The
+% normally sharp join in the middle of the handle is smoothed off.
+% \begin{macrocode}
+z317A=(x317tc, y317tc+2onelineh);
+drawnormalthree(317tml, 317A, 317tmr);
+smooth(317tml, 317A, 317tmr);
+
+% \end{macrocode}
+%
+% Below the drum box is a stick figure. It is centered with respect to the
+% drum box and based on the bottom row.
+% \changes{v1.6}{2004/02/29}{Added stickman to example drawing}
+% \begin{macrocode}
+z320bm = (x317bm, y302);
+drawstickman(320, onelineh, 2onelineh);
+
+% \end{macrocode}
+%
+% Above the drum box there is an output box, vertically aligned with the
+% stick figure, labelled `output'.
+% \changes{v1.6}{2004/02/29}{Added output box to example drawing}
+% \begin{macrocode}
+z325bm = (x320bm, y306);
+drawoutputbox(325, pconl, 2onelineh)(btex output etex);
+
+% \end{macrocode}
+%
+% Above the output box there is a simple circled dot.
+% \changes{v1.6}{2004/02/29}{Added circled dot to example drawing}
+% \begin{macrocode}
+z330 = (x320bm, y309ml);
+drawCircledDot(330, 3/2onelineh);
+
+% \end{macrocode}
+%
+% As in the bottom half, line styles are drawn on the right side of
+% of the diagram. First, though, there is an arrowed circle symbol.
+% This is vertically aligned with the centers of the lines.
+% \begin{macrocode}
+z401bm=(1/2[x11,x111], y301+mup);
+drawcircleA(401, diam);
+
+% \end{macrocode}
+%
+% Finish off with assorted linestyles.
+% \begin{macrocode}
+z402=(xmid, y401tm+mup); z502=(x111, y402);
+drawdashA(402, 502);
+
+z403=(xmid, y402+mup); z503=(x111, y403);
+drawdashOA(403, 503);
+
+z404=(xmid, y403+mup); z504=(x111, y404);
+drawnormalOD(404, 504);
+
+z405=(xmid, y404+mup); z505=(x111, y405);
+drawnormalCD(405, 505);
+
+z406=(xmid, y405+mup); z506=(x111, y406);
+drawnormalDCA(406, 506);
+
+% \end{macrocode}
+%
+% Lines can be drawn at any angle, and the non-circular line end styles
+% remain aligned.
+%
+% A set of lines and endstyles are drawn rotating about the common
+% start point of the lines.
+% \DescribeRoutine{rotatedaround}
+% |pt1 rotatatedaround(pt2, ang)| is \Mpost{} code that rotates
+% the point |pt1| around the point |pt2| counterclockwise through the angle
+% |ang| in degrees.
+%
+% \begin{macrocode}
+numeric ang; ang = 180/7;
+z600=(xmid, y406+2mup);
+z699=(x600+len, y600);
+z601=z699 rotatedaround(z600, ang);
+z602=z699 rotatedaround(z600, 2ang);
+z603=z699 rotatedaround(z600, 3ang);
+z604=z699 rotatedaround(z600, 4ang);
+z605=z699 rotatedaround(z600, 5ang);
+z606=z699 rotatedaround(z600, 6ang);
+z607=z699 rotatedaround(z600, 7ang);
+drawnormalCA(600,601);
+drawnormalOA(600,602);
+drawnormalF(600,603);
+drawdashA(600,604);
+drawnormalOD(600,605);
+drawnormalCD(600,606);
+
+% \end{macrocode}
+%
+% This is the end of the first diagram.
+% \begin{macrocode}
+endfig; % end figure 1
+
+% \end{macrocode}
+%
+% \subsection{Diagrams 2--5: EXPRESS-G like models}
+%
+% The diagrams in this section are all drawn using the \ExpressG{}
+% specific routines. Nevertheless, they do illustrate general BLA techniques.
+%
+% \subsubsection{Diagram 2: Schema level diagram}
+%
+% In contrast to the first diagram, this one is much more like an
+% \ExpressG{} diagram. It illustrates a diagram consisting of SCHEMA
+% boxes and interconnections.
+%
+% \begin{macrocode}
+beginfig(2) % schema level model
+
+% \end{macrocode}
+%
+% First define some lengths to assist in laying out the diagram, which is
+% going to consists of three rows of boxes with varying numbers of boxes
+% in each row; the bottom row has two, the middle has four, and the top row
+% has one. We also want to align the boxes vertically in a `nice' manner.
+%
+% \begin{macrocode}
+numeric lb, hb; % length & height of boxes
+lb=20u; hb=schemah;
+numeric upshift; % vertical distance between rows
+upshift = 20u;
+numeric sideshift; % horizontal distance between boxes
+sideshift = 10u;
+
+% \end{macrocode}
+%
+% The bottom row has two boxes and the second four. The two bottom boxes
+% will be aligned vertically under the two middle boxes in the middle row.
+% Allowance must be made for a `missing' box at the start of the bottom
+% row. The second box on the bottom row is spaced from the first one.
+% \begin{macrocode}
+%%% bottom row
+
+z9=(lb+sideshift,0);
+drawSCHEMA(9, lb, hb)("nine");
+
+z11=(x9br+sideshift,y9);
+drawSCHEMA(11, lb, hb)("eleven");
+
+% \end{macrocode}
+%
+% The bottom of the boxes on the second row are all at a fixed distance
+% above the top of the boxes on the first row. We only need to specify the
+% y coordinate of the bottom of one box in the row, and use that for the
+% remainder,
+% \begin{macrocode}
+%%% middle row
+
+z1=(0,y9tl+upshift);
+drawSCHEMA(1, lb, hb)("one");
+
+z3=(x1br+sideshift, y1);
+drawSCHEMA(3, lb, hb)("three");
+
+z5=(x3br+sideshift, y1);
+drawSCHEMA(5, lb, hb)("five");
+
+z7=(x5br+sideshift, y1);
+drawSCHEMA(7, lb, hb)("seven");
+
+% \end{macrocode}
+%
+% The single box on the top row will be position centrally above the
+% two middle boxes of the middle row. Mediation is used to calculate
+% the x coordinate that is halfway between the right side of the left
+% box and the left side of the right box.
+% \begin{macrocode}
+%%% top row
+
+x50 = 1/2[x3br,x5bl];
+z31bm=(x50,y1tl+upshift);
+drawSCHEMA(31, lb, hb)("thirtyone");
+
+% \end{macrocode}
+%
+% This completes the boxes. The diagram is finished off by drawing
+% connections between the boxes. The first set of connections are just
+% straight lines between known points on boxes.
+% \begin{macrocode}
+%%% connectors
+
+drawdashOO(9tm, 3bm); % three/nine
+drawdashO(5bm, 11tm); % five/eleven
+drawdashO(3ml, 1mr); % three/one
+drawdashO(3mr, 5ml); % three/five
+drawdashOO(9mr, 11ml); % nine/eleven
+
+% \end{macrocode}
+%
+% The next connection is more complex. It goes from schema thirtyone
+% to schema nine on a three-legged route. It goes horizontally left from
+% thirtynine, then vertically down, and finally horizontally right to nine. It
+% also passes to the left of schema one.
+%
+% The route is constructed by specifying a point |z90| to the left of
+% schema nine, and the point |z31A| on the left hand of schema thirtynine.
+% The |VH| routine is then called to generate the corner point on the
+% (rotated) L shaped path between |z90| and |z31A|. The connection is then
+% drawn using these four points.
+% \begin{macrocode}
+%%% thirtyone/nine
+z90=((x1bl-sideshift), y9ml);
+z31A=3/4[z31bl,z31tl];
+VH(90, 31A);
+drawdashO(90vh, 31A);
+drawdashthreeO(90vh, 90, 9ml);
+% \end{macrocode}
+%
+% \DescribeRoutine{pickup}
+% To demonstrate another aspect of \Mpost, a dot is drawn at the location
+% of |z90|. If the drawing pen is thick enough, just drawing one point is
+% sufficient to make a noticeable dot. The code |pickup thickpen;| drops
+% the current pen and picks up
+% the thickpen for drawing. The code |pickup normalpen;| picks up the
+% normal pen, which is the one that is normally used.
+%
+% \DescribeRoutine{label}
+% \DescribeRoutine{dotlabel}
+% The last line of code here is |label.lft("z90", z90);| which puts the
+% text `z90' at the left of point |z90|.\label{page:label}
+% The label routine has two arguments,
+% the first the text and the second the point at or near which the text is
+% to be placed. The simplest form of the routine is |label("text", zk)| which
+% centers the text over the point |zk|. A
+% suffix can be used after the |label| (e.g., |.lft| in the code below) to
+% modify the placement. |.lft| positions the text at the left of the point.
+% The other modifiers are: |.rt|, |.top|, |.bot|, |.ulft|, |.urt|, |.llft| and
+% |.lrt|. There is also a |dotlabel.suffix("text", zk)| routine which draws
+% the point as well. For complicated diagrams it can be useful to label
+% some points during development, and then comment them out for the final
+% picture.
+% \begin{macrocode}
+pickup thickpen;
+draw z90;
+pickup normalpen;
+label.lft("z90", z90);
+
+% \end{macrocode}
+%
+% The next two connectors, between schemas one and eleven and between
+% thirtyone and eleven are of a similar U shape. There is, though, one tricky
+% point to remember. Up till now, all point arguments to the \Lpack{expressg}
+% routines have been of the form |3| or |4bm|;
+% that is, either a number or a number
+% followed by letter(s). For example, |VH(3,4bm)| will calculate
+% the point |z3vh|. However, if a routine adds more letters to an argument
+% that already has letters, such as |VH(4bm,3)|, the calculated point is
+% \emph{not} |z4bmvh| as might be expected, but instead
+% is |z4bm.vh|.\label{page:dotsuffix}
+% This has tripped me up on several occasions.
+% \begin{macrocode}
+%%% one/eleven
+z1A=1/3[z1bl,z1br];
+z11A=(x11bm, (y11bm-sideshift));
+VH(1A, 11A);
+drawdashthree(1A, 1A.vh, 11A); % note it is 1A.vh and not 1Avh
+drawdashO(11A, 11bm);
+dotlabel.rt("z11A", z11A);
+dotlabel.lft("z1A.vh", z1A.vh); % note it is z1A.vh and not z1Avh
+
+% \end{macrocode}
+%
+% The connector between thirtyone and eleven is the same general shape
+% as the thirtyone to nine connector. This time, I'll use the |HxH| routine
+% to calculate the turning points
+% \begin{macrocode}
+%%% thirtyone/eleven
+z31B=3/4[z31br,z31tr];
+x31BC=x7br+sideshift;
+HxH(31B, 31BC, 11mr);
+drawdashfourO(31B, 31B.hxh, 11mr.hxh, 11mr);
+
+% \end{macrocode}
+%
+% The next two connectors, between thirtyone and seven, and between
+% thirtyone and one, are simple L shapes, which are easier to produce than the
+% U shaped ones.
+% \begin{macrocode}
+%%% thirtyone/seven
+z31D=1/4[z31br,z31tr];
+VH(7tm, 31D);
+drawnormalthreeO(31D, 7tm.vh, 7tm);
+
+%%% thirtyone/one
+z31C=1/4[z31bl,z31tl];
+VH(1tm, 31C);
+drawdashO(1tm.vh, 31C);
+drawdashO(1tm.vh, 1tm);
+
+% \end{macrocode}
+%
+% The last two connectors are also simple, each consisting of vertical then
+% horizontal then vertical lines and the turning points can be calculated
+% by the |VhV| routine..
+% \begin{macrocode}
+%%% thirtyone/three
+z31E=1/4[z31bl,z31br];
+VhV(31E, 3tm);
+drawnormalfourO(31E, 31E.vhv, 3tm.vhv, 3tm);
+
+%%% thirtyone/five
+z31F=3/4[z31bl,z31br];
+VhV(31F, 5tm);
+drawnormalfourO(31F, 31F.vhv, 5tm.vhv, 5tm);
+
+% \end{macrocode}
+%
+% The last element in the diagram is a vertical closed arrowheaded line
+% with a label alongside. The arrowhead is on the top line of the connector
+% between thirtyone and eleven. Note the point mediation expression expression
+% in the |label| routine call.
+% \begin{macrocode}
+%%% labeled arrow
+z3111=1/4[z31B,z31B.hxh];
+numeric arrowsize;
+arrowsize := schemah;
+z3112=(x3111, y3111+arrowsize);
+drawnormalCA(3112, 3111);
+label.rt(btex an\_import etex, 1/2[z3111, z3112]);
+
+% \end{macrocode}
+%
+% The end of this diagram.
+% \begin{macrocode}
+endfig; % end fig 2
+
+% \end{macrocode}
+%
+%
+% \subsubsection{Diagram 3: Tree structure}
+%
+% This diagram is the first of three that are related in style. It is
+% useful at this point to define some variables, and values for some of
+% these as they will probably be used in all three diagrams.
+%
+% Values are assigned (e.g., |var := val;|) so that they can be changed
+% later if necessary (e.g., |var := newval;|). If values were equated like
+% |var = val;| then they cannot be changed afterwards\footnote{Except
+% by assignment.} as |var = newval;|
+% will then have specified two incompatible equations for |var| and \Mpost will
+% report a problem.
+% \begin{macrocode}
+
+%%%% some commonly used variables & values
+
+numeric pl, ph; % length & height of numeric page connectors
+pl:=pconl; ph:=pconh; % for eg., 9,9 (9,9)
+numeric plnamed; % length of named page connector
+numeric irh; % height of interschema boxes
+irh:=ish; % normally one line of text
+numeric sdtl, sdth; % length & height of SDT (e.g. INTEGER) boxes
+sdtl:=sdtbl; sdth:=sdtbh;
+numeric edtl, edth; % length & height of enum boxes (inset is sdtbs)
+edth:=sdtbh; % normally one text line
+numeric el, eh; % length & height of entity boxes
+eh:=enth; % normally one text line
+numeric upshift; % vertical space between rows of boxes
+numeric nextup; % vertical space between bases of rows of boxes
+% \end{macrocode}
+%
+% Now another bit of \Mpost. There is another type of variable called
+% a |picture| variable. This can hold something as trivial as a dot or
+% a text string, up to a complete diagram. References to an Index
+% type is a common element in some of the diagrams. It is useful to
+% create a shorthand for these by using picture variables.
+% \begin{macrocode}
+picture sindex, pindex;
+sindex := btex eleven.Index etex; % interschema reference text
+pindex := btex 9,9 Index etex; % page reference text
+numeric slindex, plindex;
+slindex := namespace(sindex)(nextra); % length of Index interschema
+plindex := namespace(pindex)(nextra); % length of Index page reference
+% \end{macrocode}
+%
+% Yet more new \Mpost. Array variables are supported. These are declared
+% by giving the variable name immediately followed by a pair of square
+% brackets. An element of an array can be simply accessed by suffixing the
+% variable name with the integer number denoting the desired position.
+% Actually we have been using array variables all along, as |z3| or |x7|
+% are elements of the arrays |z[]| and |x[]| respectively. We define
+% two arrays, one to be used for specifying horizontal spaces (lengths)
+% and the other for vertical (y) coordinates.
+% \begin{macrocode}
+numeric hspace[]; % horizontal spaces
+numeric lyc[]; % Y coords of box bases
+
+%%%%%%%%%%% end commonly used variables & values
+
+% \end{macrocode}
+%
+% Diagram 3 consists of type boxes. We will make these all the same length
+% and height.
+% \begin{macrocode}
+beginfig(3) % example fig 3
+%%%drawgrid;
+
+% \end{macrocode}
+%
+% The space required for the longest name is |edtl|.
+% \begin{macrocode}
+edtl := namespace(btex standard\_data\_name etex)(niextra);
+% \end{macrocode}
+%
+% There are several rows in the diagram. Specify the vertical space
+% between the rows, and the space between the bottoms of the boxes (the
+% height of a box is the normal height, |sdth|, for a type box). Also
+% specify the y coordinates for each row, counting from the bottom.
+% \begin{macrocode}
+upshift=2sdth;
+nextup=sdth+upshift;
+%%% the y coords of box bases
+lyc1:=0;
+lyc2:=lyc1+nextup;
+lyc3:=lyc2+nextup;
+lyc4:=lyc3+nextup;
+lyc5:=lyc4+nextup;
+lyc6:=lyc5+nextup;
+lyc7:=lyc6+nextup;
+lyc8:=lyc7+nextup;
+% \end{macrocode}
+% Specify two horizontal spaces.
+% \begin{macrocode}
+hspace1 := 1/3edtl; % space between data enums
+hspace2 := 2/3edtl; % initial space at start of second row
+
+% \end{macrocode}
+% Draw the 3 boxes in the first row and the 3 in the second; these are
+% staggered with respect to each other and overlap as otherwise there
+% there is not enough space to get them all onto one page.
+% I'll use a numbering scheme for
+% points so that |zCR| is a point in the Cth column and the Rth row.
+% \begin{macrocode}
+%%% bottom two rows (1 & 2)
+
+z11=(0,lyc1);
+drawENUM(11, edtl, edth)(btex coordinates etex);
+
+z22=(hspace2, lyc2);
+drawENUM(22, edtl, edth)(btex solution\_data etex);
+
+z31=(x11br+hspace1, lyc1);
+drawENUM(31, edtl, edth)(btex pressure\_loads etex);
+
+z42=(x22br+hspace1, lyc2);
+drawENUM(42, edtl, edth)(btex nondimensional etex);
+
+z51=(x31br+hspace1, lyc1);
+drawENUM(51, edtl, edth)(btex temperature etex);
+
+z62=(x42br+hspace1, lyc2);
+drawENUM(62, edtl, edth)(btex force\_loads etex);
+
+% \end{macrocode}
+%
+% The third `row' consists of a horizontal line stretching from the middle
+% of the leftmost box to the middle of the rightmost box. There are
+% connections from this line to the top middle of each of the boxes. We can
+% use the |VyV| routine for the end points of the line.
+% \begin{macrocode}
+%%% third row (horizontal line between 2 & 4 row)
+
+z13=(x11tm,lyc3);
+VyV(11tm, 13, 62tm);
+drawnormal(11tm.vyv, 62tm.vyv);
+% \end{macrocode}
+%
+% Calculate the points on this line vertically above the midpoints of
+% the boxes and draw the connections.
+% \begin{macrocode}
+z23=(x22tm,lyc3); z33=(x31tm,lyc3); z43=(x42tm,lyc3); z53=(x51tm,lyc3);
+drawnormalO(11tm.vyv,11tm);
+drawnormalO(23,22tm);
+drawnormalO(33,31tm);
+drawnormalO(43,42tm);
+drawnormalO(53,51tm);
+drawnormalO(62tm.vyv,62tm);
+
+% \end{macrocode}
+%
+% The fourth row consists of three boxes. There is a vertical line
+% from the bottom
+% of the leftmost box to the horizontal line drawn in row 4. The three
+% boxes are aligned horizontally with respect to this line.
+% \begin{macrocode}
+%%% fourth row
+
+z3224=1/3[z13,z62tm.vyv];
+z3554=2/3[z13,z62tm.vyv];
+
+%%% standard_data_name
+z24bm=(x3224,lyc4);
+drawSELECT(24, edtl, edth)(btex standard\_data\_name etex);
+drawnormal(24bm,3224);
+
+%%% adhoc_data_name
+z54bm=(x3554,lyc4);
+drawTYPE(54, edtl, edth)(btex adhoc\_data\_name etex);
+
+%%% STRING
+z64br=(x62br,lyc4);
+drawSTRING(64);
+
+% \end{macrocode}
+%
+% The fifth `row' consists of two vertical connectors to the tops of
+% the SELECT and TYPE boxes, with a horizontal line connecting the tops
+% of the connectors.
+% \begin{macrocode}
+%%% fifth row
+
+z35=(1/2[x24tm,x54tm], lyc5);
+VyV(24tm, 35, 54tm);
+drawnormalthreeO(35, 24tm.vyv, 24tm);
+drawnormalthreeO(35, 54tm.vyv, 54tm);
+
+% \end{macrocode}
+%
+% The top row consists of a SELECT box vertically aligned above the center
+% of the horizontal line from the 5th row, together with a line joining
+% these two, and also a page reference box
+% off towards the right hand side
+% \begin{macrocode}
+%%% sixth row
+
+z36bm=(x35,lyc6);
+drawSELECT(36,edtl, edth)(btex data\_name etex);
+drawnormal(36bm,35);
+
+%%% data_name
+z66=(x62,lyc6);
+drawPREF(66, sdtl, ph)(btex 3,1 (4) etex);
+
+% \end{macrocode}
+%
+% The remaining elements on the diagram are:
+% a connector on the 4th row from adhoc\_data\_name to STRING;
+% and a connector on the 6th row from the page reference to data\_name.
+% \begin{macrocode}
+%%%% rest of the connectors
+
+%%% adhoc/STRING (54, 64)
+drawnormalO(54mr,64ml);
+
+%%% PREF/data_name (36, 66)
+drawdashO(66ml,36mr);
+
+% \end{macrocode}
+%
+% The end of this diagram
+% \begin{macrocode}
+endfig; % end fig 3
+
+% \end{macrocode}
+%
+% \subsubsection{Diagram 4: Supertypes and subtypes}
+%
+% This diagram consists of a supertype entity and its four subtypes. The
+% entities have various attributes.
+%
+% \begin{macrocode}
+
+beginfig(4) % example 4
+%%%drawgrid;
+
+% \end{macrocode}
+%
+% Define some useful lengths.
+% \begin{macrocode}
+%%% length of named page reference boxes
+plnamed := namespace(btex 9,9 data\_name etex)(nextra);
+
+%%% length of entity boxes
+el := namespace(btex (ABS) Data\_t etex)(nextra);
+
+upshift := 2sdth; % vertical space between boxes
+nextup := sdth+upshift; % vertical space between bases of boxes
+hspace1 := 1/2el; % space between entity boxes
+
+%%% the y coords of box bases
+lyc1:=0;
+lyc2:=lyc1+nextup;
+lyc3:=lyc2+nextup;
+lyc4:=lyc3+nextup;
+lyc5:=lyc4+nextup;
+lyc6:=lyc5+nextup;
+lyc7:=lyc6+nextup;
+lyc8:=lyc7+nextup;
+
+% \end{macrocode}
+%
+% We'll start with the second row which consists of 4 entity (subtype)
+% boxes. The numbering scheme for point suffixes is |zCR|, where |C|
+% is the column number and |R| is the row number.
+% \begin{macrocode}
+%%%% 2nd row
+
+%%% IntArray
+z12=(0,lyc2);
+drawENT(12, el, eh)(btex IntArray etex);
+
+%%% RealArray
+z22=(x12br+hspace1, lyc2);
+drawENT(22, el, eh)(btex RealArray etex);
+
+%%% CharArray
+z42=(x22br+hspace1, lyc2);
+drawENT(42, el, eh)(btex CharArray etex);
+
+%%% BitArray
+z52=(x42br+hspace1, lyc2);
+drawENT(52, el, eh)(btex BitArray etex);
+
+% \end{macrocode}
+%
+% The first row is four simple data type boxes, aligned underneath the
+% entity boxes.
+% \begin{macrocode}
+%%%% 1st row
+
+z11bm=(x12bm,lyc1);
+drawINTEGER(11);
+
+z21bm=(x22bm,lyc1);
+drawREAL(21);
+
+z41bm=(x42bm,lyc1);
+drawSTRING(41);
+
+z51bm=(x52bm,lyc1);
+drawBINARY(51);
+
+% \end{macrocode}
+%
+% The third `row' is the thick lines connecting the subtype boxes.
+% \begin{macrocode}
+%%% 3rd row
+
+y13= y23= y43= y53=lyc3;
+x13=x12tm; x23=x22tm; x43=x42tm; x53=x52tm;
+drawthick(13,53); % horizontal line
+%%% vertical connectors
+drawthickO(13,12tm); drawthickO(23,22tm);
+drawthickO(43, 42tm); drawthickO(53, 52tm);
+
+z33=1/2[z13,z53]; % midpoint of horizontal line
+
+% \end{macrocode}
+%
+% The 4th row is an abstract supertype entity box, which is made 3 times
+% taller than the default entity box height. The entity box is centered
+% with respect to the row of subtype boxes and is connected to the
+% subtype boxes connector. The digit 1 is placed near the connection point.
+% There is also a page reference
+% and an INTEGER box at the left and right (as attributes of the supertype).
+% \begin{macrocode}
+%%% 4th row
+
+%%% Data_t
+z34bm=(x33,lyc4);
+drawENT(34, el, 3eh)(btex \twolines{(ABS)}{Data\_t} etex);
+drawthick(34bm,33);
+label.urt("1", z33); % label the connection point
+
+%%% Index
+z14=(0,lyc4);
+drawPREF(14, plindex, ph)(pindex);
+
+%%% INTEGER
+z54br=(x51br,lyc4);
+drawINTEGER(54);
+
+% \end{macrocode}
+%
+% The 5th row has page reference boxes at the left and right
+% (as attributes of the supertype).
+% \begin{macrocode}
+%%% 5th row
+
+lyc5:=y34tm-ph; % change the initial y coord value
+
+%%% Index
+z15=(0,lyc5);
+drawPREF(15, plindex, ph)(pindex);
+
+%%% DataType
+z55=(x54,lyc5);
+drawPREF(55, plnamed, ph)(btex 3,1 data\_name etex);
+
+% \end{macrocode}
+%
+% The 6th, and last, row, just consists of a page reference centered
+% above the supertype box.
+% \begin{macrocode}
+%%% 6th row
+
+%%% PREF to Data_t
+lyc6:=lyc5+nextup;
+z36bm=(x34tm,lyc6);
+drawPREF(36, pl, ph)(btex 7,5 (6) etex);
+
+% \end{macrocode}
+%
+% The rest of the diagram consists of the labelled attribute lines.
+% \begin{macrocode}
+%%%% attributes
+
+%%% Sizes Data_t/Index (34, 14)
+z3414=(x34,y14mr);
+drawnormal(3414,14mr);
+label.ulft(btex Sizes A[1:Limit] etex, z3414);
+
+%%% num Data_t/INTEGER (34, 54)
+z3454=(x34mr,y54ml);
+drawnormalO(3454,54ml);
+label.urt(btex (DER) num etex, z3454);
+
+%%% Limit Data_t/Index (34, 15)
+z3415=(x34,y15mr);
+drawnormal(3415,15mr);
+label.ulft(btex Limit etex, z3415);
+
+%%% Kind Data_t/data_name (34, 55)
+z3455=(x34mr, y55ml);
+drawnormal(3455, 55ml);
+label.urt(btex Kind etex, z3455);
+
+%%% PREF into Data_t (36, 34)
+drawdashO(36bm, 34tm);
+
+%%% Data IntArray/INTEGER (12, 11)
+drawnormalO(12bm, 11tm);
+label.lrt(btex Data A[1:num] etex, z12bm);
+
+%%% Data RealArray/REAL (22, 21)
+drawnormalO(22bm, 21tm);
+label.lrt(btex Data A[1:num] etex, z22bm);
+
+%%% Data CharArray/STRING (42, 41)
+drawnormalO(42bm, 41tm);
+label.lrt(btex Data A[1:num] etex, z42bm);
+
+%%% Data BitArray/BINARY (52, 51)
+drawnormalO(52bm, 51tm);
+label.lrt(btex Data A[1:num] etex, z52bm);
+
+% \end{macrocode}
+%
+% The end of this diagram.
+% \begin{macrocode}
+endfig; % end fig 4
+
+% \end{macrocode}
+%
+% \subsubsection{Diagram 5: Portion of larger model}
+%
+% This diagram is more complex than the previous ones. It is, nevertheless,
+% presented with virtually no commentary. It consists of three entity boxes
+% and various page reference and interschema boxes to support the
+% entities' attributes.
+%
+% \begin{macrocode}
+beginfig(5) % example 5
+%%drawgrid;
+
+% \end{macrocode}
+%
+% As usual, specify commonly used variables and values.
+% \begin{macrocode}
+plnamed := namespace(btex 7,4 Unstructured\_Donor etex)(nextra);
+
+numeric irls, irll; % length of short and long ISR boxes
+irls = namespace(btex eleven.MeshLocation etex)(nextra);
+irll = namespace(btex eleven.MeshConnectivityType etex)(nextra);
+
+upshift := irh;
+nextup := irh+upshift;
+
+numeric maxrx; % max x coordinate value of LH of right column boxes
+maxrx := maxx-irrl;
+numeric xmid; % x coord of figure center
+xmid := 1/2[irls, maxx-irll];
+
+el := namespace(btex MeshConnectivity1\_1 etex)(nextra);
+eh := irh;
+
+%%% y coords
+lyc1 := 0;
+lyc2 := lyc1+nextup;
+lyc3 := lyc2+nextup;
+lyc4 := lyc3+nextup+irh;
+lyc5 := lyc4+nextup;
+lyc6 := lyc5+nextup;
+lyc7 := lyc6+nextup;
+lyc8 := lyc7+nextup;
+lyc9 := lyc8+nextup;
+
+% \end{macrocode}
+%
+% Rows one and two have one centered box each.
+% \begin{macrocode}
+%%% Zcol/row
+%%% row 1
+
+%%% PREF for Overlapping
+z21bm=(xmid,lyc1);
+drawPREF(21, pl, ph)(btex 5,3 (8) etex)
+
+%%% row 2
+
+%%% OverlappingArea
+z22bm=(x21bm,lyc2);
+drawENT(22, el, eh)(btex OverlappingArea etex);
+
+% \end{macrocode}
+%
+% Row three has three boxes, and the middle one is centered.
+% \begin{macrocode}
+%%% row 3
+
+%%% IndexArray
+z13=(pl,lyc3);
+drawISR(13, irls, irh)(btex eleven.IndexArray etex);
+
+%%% Index
+z23bm=(x22bm,lyc3);
+drawISR(23, slindex, irh)(sindex);
+
+%%% MeshLocation
+z33br=(maxx,lyc3);
+drawISR(33, irls, irh)(btex eleven.MeshLocation etex);
+
+% \end{macrocode}
+%
+% Row four has three boxes, and the middle one is centered.
+% \begin{macrocode}
+%%% row 4
+
+%%% MeshConnectivity
+z24bm=(x23bm,lyc4);
+drawENT(24, el, eh)(btex MeshConnectivity etex);
+
+%%% PREF for MeshConnectivity
+z14ml=(pl,y24ml);
+drawPREF(14, pl, ph)(btex 5,2 (8) etex);
+
+%%% Structured_Donor
+z34br=(maxx,lyc4);
+drawPREF(34, plnamed, ph)(btex 7,5 Structured\_Donor etex);
+
+% \end{macrocode}
+%
+% Rows five and six have one box each, at the right hand side.
+% \begin{macrocode}
+%%% row 5
+
+%%% Unstructured_donor
+z35br=(maxx,lyc5);
+drawPREF(35, plnamed, ph)(btex 7,4 Unstructured\_Donor etex);
+
+%%% row 6
+
+%%% MeshConnType
+z36br=(maxx,lyc6);
+drawISR(36, irll, irh)(btex eleven.MeshConnectivityType etex);
+
+% \end{macrocode}
+%
+% Row seven has three boxes, and the middle one is centered.
+% \begin{macrocode}
+%%% row 7
+
+%%% IndexRange
+z17=(0,lyc7);
+drawISR(17, irls, irh)(btex eleven.IndexRange etex);
+
+%%% INTEGER
+x27bm=x24bm; y27ml=y17mr;
+drawINTEGER(27);
+
+%%% Zone
+z37br=(maxx,lyc7);
+drawISR(37, irls, irh)(btex seven.Zone etex);
+
+% \end{macrocode}
+%
+% Rows eight and nine have one centered box each.
+% \begin{macrocode}
+%%% row 8
+
+%%% 1to1
+z28bm=(x24bm,lyc8);
+drawENT(28, el, eh)(btex MeshConnectivity1\_1 etex);
+
+%%% row 9
+
+%%% PREF to 1to1
+z29bm=(x28bm,lyc9);
+drawPREF(29, pl, ph)(btex 5,1 (8) etex);
+
+% \end{macrocode}
+%
+% All the boxes have been drawn. The remainder is adding and labelling
+% attribute lines. First page references to subtype entities.
+% \begin{macrocode}
+%%%% attributes, etc
+
+drawthickO(21tm,22bm); % PREF to Overlap (21, 22)
+drawthickO(14mr,24ml); % PREF to MeshConn (14, 24)
+drawthickO(29bm,28tm); % PREF to 1to1 (29, 28)
+
+% \end{macrocode}
+%
+% The attributes of entity OverlappingArea (|z22|)
+% \begin{macrocode}
+%%% PointListSize (22, 23)
+drawdashO(22tm,23bm);
+label.llft(btex PointListSize etex, z23bm);
+
+%%% PointRange (22, 17)
+z22A=1/4[z22bl,z22tl]; z17A=(1/2[0,x13], y17);
+VH(17A,22A);
+drawdashthreeO(22A, 17A.vh, 17A);
+label.ulft(btex PointRange etex, z22A);
+
+%%% PointList (22, 13)
+z22B=3/4[z22bl,z22tl];
+VH(13bm,22B);
+drawdashthreeO(22B, 13bm.vh, 13bm);
+label.ulft(btex PointList etex, z22B);
+
+%%% MeshLocation (22, 33)
+z22C=1/4[z22br,z22tr];
+z33B=2/3[z33bl,z33br];
+VH(33B,22C);
+drawnormalthreeO(22C, 33B.vh, 33B);
+label.urt(btex (DER) Location etex, z22C);
+
+%%% Meshloc (22, 33)
+z22D=3/4[z22br,z22tr];
+z33A=1/3[z33bl,z33br];
+VH(33A,22D);
+drawdashthreeO(22D, 33A.vh, 33A);
+label.urt(btex Meshloc etex, z22D);
+
+% \end{macrocode}
+%
+% The attributes of entity MeshConnectivity (|z24|).
+% \begin{macrocode}
+%%% PointListSize (24, 23)
+drawnormalO(24bm, 23tm);
+label.ulft(btex PointListSize etex, z23tm);
+
+%%% StructuredDonor (24, 34)
+z24A=(x24br,y34ml);
+draw z24A--z34ml dashes;
+label.lrt(btex StructuredDonor etex, z24A);
+
+%%% UnstructuredDonor (24, 35)
+z24B=3/4[z24br,z24tr];
+HvH(24B,35ml);
+drawdashfourO(24B, 24B.hvh, 35ml.hvh, 35ml);
+label.urt(btex UnstructuredDonor etex, z24B.hvh);
+
+%%% Meshloc (24, 33)
+z24C=4/6[z24bl,z24br];
+z33C=(x33A,y33tm);
+y2433C=1/3[y33C,y24C];
+VyV(24C, 2433C, 33C);
+drawdashfourO(24C, 24C.vyv, 33C.vyv, 33C);
+label.lrt(btex Meshloc etex, z24C.vyv);
+
+%%% Location (24, 33)
+z24D=5/6[z24bl,z24br];
+z33D=(x33B,y33tm);
+y2433D=2/3[y33D,y24D];
+VyV(24D, 2433D, 33D);
+drawnormalfourO(24D, 24D.vyv, 33D.vyv, 33D);
+label.lrt(btex (DER) Location etex, z24D.vyv);
+
+%%% ConnectivityType (24, 36)
+z24H=(x24D,y24tr);
+z36H=z36bm;
+y2436H=1/2[y35tr,y36br];
+VyV(24H, 2436H, 36H);
+drawnormalfourO(24H, 24H.vyv, 36H.vyv, 36H);
+label.urt(btex (DER) ConnectivityType etex, z24H.vyv);
+
+%%% Meshcon (24, 36)
+z24G=(x24C,y24tr);
+z36G=z36ml;
+VH(24G,36G);
+drawdashthreeO(24G, 24G.vh, 36G);
+label.urt(btex Meshcon etex, z24G.vh);
+
+%%% K (24, 27)
+drawnormalO(24tm, 27bm);
+label.ulft(btex K etex, z24tm);
+
+%%% PointRange (24, 17)
+z24E=1/4[z24tl,z24tr];
+x17br-x17E = x17A-x17bl;
+y17E = y17A;
+VhV(24E,17E);
+drawdashfourO(24E, 24E.vhv, 17E.vhv, 17E);
+label.ulft(btex PointRange etex, z24E);
+
+%%% PointList (24, 13)
+z24F=1/4[z24bl,z24br];
+z13F=1/2[z13tl,z13tr];
+VhV(24F,13F);
+drawnormalfourO(24F, 24F.vhv, 13F.vhv, 13F);
+label.llft(btex PointList etex, z24F);
+
+% \end{macrocode}
+%
+% The attributes of entity MeshConnectivity1\_1 (|z28|)
+% \begin{macrocode}
+%%% N (28, 27)
+z27A=1/5[z27tl,z27tr];
+z28A=(x27A,y28bl);
+drawnormalO(28A,27A);
+label.llft(btex N etex, z28A);
+
+%%% trans (28, 27)
+z27B=1/2[z27tl,z27tr];
+z28B=(x27B,y28bl);
+drawdashO(28B,27B);
+label.lrt(btex \twolines{trans}{A[1:N]} etex, z28B);
+
+%%% Transform (28, 27)
+z27C=1/2[z27br,z27tr];
+z28C=(1/2[x27C,x28br], y28br);
+VH(28C,27C);
+drawnormalthreeO(28C,28C.vh,27C);
+label.lrt(btex (DER) Transform A[1:N] etex , z28C);
+
+%%% DonorZone (28, 37)
+z28D=1/2[z28br,z28tr];
+z37D=z37tm;
+VH(37D,28D);
+drawdashthreeO(28D,37D.vh,37D);
+label.urt(btex DonorZone etex, z28D);
+
+%%% DonorPointRange (28, 17)
+z28G=3/4[z28bl,z28tl];
+z17G=(x17A,y17tl);
+VH(17G,28G);
+drawnormalthreeO(28G,17G.vh,17G);
+label.ulft(btex DonorPointRange etex, z28G);
+
+%%% PointRange (28, 17)
+z28H=1/4[z28bl,z28tl];
+z17H=(x17E,y17G);
+VH(17H,28H);
+drawnormalthreeO(28H,17H.vh,17H);
+label.ulft(btex PointRange etex, z28H);
+
+% \end{macrocode}
+%
+% The end of this diagram.
+% \begin{macrocode}
+endfig; % end fig 5
+
+% \end{macrocode}
+%
+% \subsection{Diagrams 6--11: Car model}
+%
+% The diagrams in this section are all taken from~\cite[Chapter~2]{EBOOK}.
+% A simple information/data model of a car, car model, and car manufacturer
+% is presented in a variety of BLA languages, among which is,
+% of course, \ExpressG. In words, the model is:
+% \begin{quote} \itshape
+% A car is made by a manufacturer. Each manufacturer has a unique name.
+% A manufacturer constructs cars in several models and a car is of a
+% particular model. A manufacturer gives a serial number to each car
+% he produces and this is unique across all cars produced by that
+% manufacturer. Each model also has a name, and this is unique across
+% all models. A car has a year of production.
+% \end{quote}
+% This model is a small portion of a conceptual model developed as a common
+% specification for comparing modeling languages~\cite{TR9007}.
+%
+% The purpose of these diagrams is to
+% illustrate how the \Lpack{expressg} package supports a range of graphical
+% languages.
+%
+%
+% \subsubsection{Diagram 6: \ExpressG}
+%
+% Having already seen several examples of \ExpressG{} diagrams, this one
+% is presented with no further comments.
+% \begin{macrocode}
+
+beginfig(6) % example 6 EXPRESS-G
+%%%drawgrid;
+
+upshift := 3/2onelineh;
+nextup := onelineh+upshift;
+
+el := namespace(btex manufacturer etex)(nextra);
+eh := onelineh;
+
+hspace1 := 1/2el;
+
+%%% y coords
+lyc1 := 0;
+lyc2 := lyc1+nextup;
+lyc3 := lyc2+nextup;
+lyc4 := lyc3+nextup;
+lyc5 := lyc4+nextup;
+
+%%% Zcol/row
+
+%%% rows 4 and 5
+z14=(0,lyc4);
+drawENT(14, el, eh)(btex manufacturer etex);
+
+z25=(x14br+hspace1, lyc5);
+drawSTRING(25);
+
+z34=(x25br+hspace1, lyc4);
+drawENT(34, el, eh)(btex car\_model etex);
+
+%%% row 3
+
+z33bm=(x34bm, lyc3);
+drawENT(33, el, eh)(btex car etex);
+
+%%% row 2
+
+z22=(x25, lyc2);
+drawINTEGER(22);
+
+%%% row 1
+
+z21=(x22, lyc1);
+drawSTRING(21);
+
+%%% attributes
+
+%%% manufacturer name (14, 25)
+VH(14tm, 25ml);
+drawnormalthreeO(14tm, 14tm.vh, 25ml);
+label.urt(btex *name etex, z14tm.vh);
+
+%%% model name (34, 25)
+VH(34tm, 25mr);
+drawnormalthreeO(34tm, 34tm.vh, 25mr);
+label.ulft(btex *name etex, z34tm.vh);
+
+%%% made_by (34, 14)
+drawnormalO(34ml, 14mr);
+label.ulft(btex made\_by etex, z34ml);
+
+%%% model_type (33, 34)
+drawnormalO(33tm, 34bm);
+label.urt(btex model\_type etex, z33tm);
+
+%%% DER made_by (33, 14)
+VH(14bm, 33ml);
+drawnormalthreeO(33ml, 14bm.vh, 14bm);
+label.ulft(btex (DER) *made\_by etex, z33ml);
+
+%%% year (33, 22)
+z33A=1/3[z33bl, z33br];
+VH(33A, 22mr);
+drawnormalthreeO(33A, 33A.vh, 22mr);
+label.ulft(btex year etex, z33A.vh);
+
+%%% serial_no
+z33B=2/3[z33bl, z33br];
+VH(33B, 21mr);
+drawnormalthreeO(33B, 33B.vh, 21mr);
+label.ulft(btex *serial\_no etex, z33B.vh);
+
+% \end{macrocode}
+%
+% The end of this diagram
+% \begin{macrocode}
+endfig; % end fig 6
+
+% \end{macrocode}
+%
+%
+% \subsubsection{Diagram 7: Shlaer-Mellor}
+%
+% The Shlaer-Mellor graphical language~\cite{SHLAER88} is fairly simple,
+% consisting basically of rectangles and arrowheaded lines. However, unlike
+% \ExpressG{} each box usually has several lines of text. These are placed
+% individually at the desired positions within each box.
+%
+% Notice below that
+% I have used |drawENT| with an empty string to draw the rectangular boxes;
+% the routines for \ExpressG{} diagrams can, if suitable, be used in any
+% sort of diagram.
+%
+% \begin{macrocode}
+
+beginfig(7) % example 7
+%%%drawgrid;
+
+el := namespace(btex MANUFACTURER etex)(niextra);
+eh := onelineh;
+
+hspace1 := namespace(btex made by maker of etex)(4ndextra);
+
+hspace2 := 6onelineh; % height of CAR
+hspace3 := 5onelineh; % space between rows
+hspace4 := 3onelineh; % height of MANUFACTURER
+
+%%% y coords
+lyc1 := 0;
+lyc2 := lyc1+hspace2+hspace3;
+
+%%% Zcol/row
+
+%%% row 2
+
+z12=(0, lyc2);
+drawENT(12, el, hspace4)("");
+x121=x12+sdtbs;
+label.rt(btex MANUFACTURER etex, (x121, 2/3[y12bl, y12tl]));
+label.rt(btex * manuf-name etex, (x121, 1/3[y12bl, y12tl]));
+
+z22=(x12br+hspace1, lyc2);
+drawENT(22, el, hspace4)("");
+x221=x22+sdtbs;
+label.rt(btex CAR-MODEL etex, (x221, 2/3[y12bl, y12tl]));
+label.rt(btex * model-name etex, (x221, 1/3[y12bl, y12tl]));
+
+%%% row 1
+
+z21=(x22, lyc1);
+drawENT(21, el, hspace2)("");
+x211=x21+sdtbs;
+label.rt(btex CAR etex, (x211, 5/6[y21bl, y21tl]));
+label.rt(btex o year etex, (x211, 4/6[y21bl, y21tl]));
+label.rt(btex o model (R) etex, (x211, 3/6[y21bl, y21tl]));
+label.rt(btex * serial-no etex, (x211, 2/6[y21bl, y21tl]));
+label.rt(btex * maker (R) etex, (x211, 1/6[y21bl, y21tl]));
+
+%%%%% relationship lines
+
+% \end{macrocode}
+% In this diagram the labels on the relationship lines tend to bump
+% into the line ending symbol. \Mpost{} ignores initial and final spaces
+% within |btex...etex|. The paired braces below, each enclosing one space,
+% supply non-discarded spaces. (These could also have been written as
+% |\space|).
+% \begin{macrocode}
+%%% MANUFACTURER / CAR-MODEL (12, 22)
+drawnormalDCA(12mr, 22ml);
+drawnormalCA(22ml, 12mr);
+label.urt(btex { }{ }made by etex, z12mr);
+label.llft(btex maker of{ }{ } etex, z22ml);
+
+%%% MANUFACTURER / CAR (12, 21)
+VH(12bm, 21ml);
+drawnormalCA(12bm.vh, 12bm);
+drawnormalDCA(12bm.vh, 21ml);
+label.llft(btex { }{ }made by etex, z12bm);
+label.ulft(btex maker of{ }{ } etex, z21ml);
+
+%%% CAR-MODEL / CAR (22, 21)
+drawnormalDCA(22bm, 21tm);
+drawnormalCA(21tm, 22bm);
+label.lrt(btex { }one of etex, z22bm);
+label.ulft(btex type of{ } etex, z21tm);
+
+% \end{macrocode}
+%
+% The end of this diagram
+% \begin{macrocode}
+endfig; % end fig 7
+
+% \end{macrocode}
+%
+%
+% \subsubsection{Diagram 8: IDEF1X}
+%
+% IDEF1X is a popular language in America for representing the structure
+% of relational databases, and was developed under the auspices of the
+% US Air Force~\cite{IDEF1X}.
+%
+% The general layout of the diagram mimics the previous one. All the boxes
+% are divided horizontally into an upper and lower part.
+% The |drawdoublerectangle| is used for the rectangular boxes, but the dividing
+% line in the rounded box has to be added by hand, as it were.
+%
+% \begin{macrocode}
+
+beginfig(8) % example 8 IDEF1X
+%%%drawgrid;
+
+el := namespace(btex MANUFACTURER etex)(niextra);
+eh := onelineh;
+
+hspace1 := namespace(btex made by maker of etex)(4ndextra);
+
+hspace2 := 5onelineh; % height of CAR
+hspace3 := 5onelineh; % space between rows
+hspace4 := 3onelineh; % height of MANUFACTURER
+
+%%% y coords
+lyc1 := 0;
+lyc2 := lyc1+hspace2+hspace3;
+
+%%% Zcol/row
+
+%%% row 2
+
+z12=(0, lyc2);
+drawdoublerectangle(12, el, hspace4, 1/2);
+label.urt(btex Manufacturer etex, z12tl);
+x121=x12+sdtbs;
+label.rt(btex manuf-name etex, (x121, 3/4[y12bl, y12tl]));
+
+z22=(x12br+hspace1, lyc2);
+drawdoublerectangle(22, el, hspace4, 1/2);
+label.urt(btex Car-model etex, z22tl);
+x221=x22+sdtbs;
+label.rt(btex Model-name etex, (x221, 3/4[y12bl, y12tl]));
+label.rt(btex Manuf-name (FK) etex, (x221, 1/4[y12bl, y12tl]));
+
+%%% row 1
+
+z21=(x22, lyc1);
+drawroundedbox(21, el, hspace2, 2sdtbs)("");
+label.urt(btex Car etex, z21tl);
+draw z21ml--z21mr;
+x211=x21+sdtbs;
+label.rt(btex Serial-no etex, (x211, 5/6[y21bl, y21tl]));
+label.rt(btex Manuf-name (FK) etex, (x211, 4/6[y21bl, y21tl]));
+label.rt(btex Model-name (FK) etex, (x211, 2/6[y21bl, y21tl]));
+label.rt(btex Year etex, (x211, 1/6[y21bl, y21tl]));
+
+%%%%% relationship lines
+
+%%% MANUFACTURER / CAR-MODEL (12, 22)
+drawnormalD(12mr, 22ml);
+label.top(btex of etex, 1/2[z12mr, z22ml]);
+
+%%% MANUFACTURER / CAR (12, 21)
+VH(12bm, 21ml);
+drawnormalthreeD(12bm, 12bm.vh, 21ml);
+label.top(btex makes etex, 1/2[z12bm.vh, z21ml]);
+label.ulft(btex P{ } etex, z21ml);
+
+%%% CAR-MODEL / CAR (22, 21)
+drawnormalD(22bm, 21tm);
+label.lft(btex of etex, 1/2[z21tm,z22bm]);
+label.urt(btex { }P etex, z21tm);
+
+% \end{macrocode}
+%
+% The end of this diagram
+% \begin{macrocode}
+endfig; % end fig 8
+
+% \end{macrocode}
+%
+%
+% \subsubsection{Diagram 9: OMT}
+%
+% OMT~\cite{RUMBAUGH91} was the precursor to the currently popular UML
+% structure modeling language.
+% If you are curious as to why I believe that lexical languages are in
+% general better than BLA languages, the chapter on developing a compiler
+% for OMT highlights, probably unintentionally, some of the disadvantages
+% of BLAs.
+%
+% The general look of the OMT diagram is almost identical
+% to the IDEF1X diagram.
+%
+% \begin{macrocode}
+
+beginfig(9) % example 9 OMT
+%%%drawgrid;
+
+el := namespace(btex {\bf MANUFACTURER} etex)(niextra);
+eh := onelineh;
+
+hspace1 := namespace(btex made by maker of etex)(4ndextra);
+
+hspace2 := 4onelineh; % height of CAR
+hspace3 := 4onelineh; % space between rows
+hspace4 := 3onelineh; % height of MANUFACTURER
+
+%%% y coords
+lyc1 := 0;
+lyc2 := lyc1+hspace2+hspace3;
+
+%%% Zcol/row
+
+%%% row 2
+
+z12=(0, lyc2);
+drawdoublerectangle(12, el, hspace4, 1/2);
+x121=x12+sdtbs;
+label.rt(btex {\bf Manufacturer} etex, (x121, 3/4[y12bl, y12tl]));
+label.rt(btex name : String etex, (x121, 1/4[y12bl, y12tl]));
+
+z22=(x12br+hspace1, lyc2);
+drawdoublerectangle(22, el, hspace4, 1/2);
+x221=x22+sdtbs;
+label.rt(btex {\bf Car Model} etex, (x221, 3/4[y22bl, y22tl]));
+label.rt(btex name: String etex, (x221, 1/4[y22bl, y22tl]));
+
+%%% row 1
+
+z21=(x22, lyc1);
+drawdoublerectangle(21, el, hspace2, 1/3);
+x211=x21+sdtbs;
+label.rt(btex {\bf Car} etex, (x211, 5/6[y21bl, y21tl]));
+label.rt(btex serial-no : String etex, (x211, 4/9[y21bl, y21tl]));
+label.rt(btex year : Integer etex, (x211, 2/9[y21bl, y21tl]));
+
+%%%%% relationship lines
+
+%%% MANUFACTURER / CAR-MODEL (12, 22)
+drawnormalD(12mr, 22ml);
+label.top(btex {\it makes} etex, 1/2[z12mr, z22ml]);
+label.ulft(btex 1+{ } etex, z22ml);
+
+%%% MANUFACTURER / CAR (12, 21)
+VH(12bm, 21ml);
+drawnormalthreeD(12bm, 12bm.vh, 21ml);
+label.top(btex {\it makes} etex, 1/2[z12bm.vh, z21ml]);
+label.ulft(btex 1+{ } etex, z21ml);
+
+%%% CAR-MODEL / CAR (22, 21)
+drawnormalD(22bm, 21tm);
+label.lft(btex {\it produced as} etex, 1/2[z21tm,z22bm]);
+
+% \end{macrocode}
+%
+% The end of this diagram
+% \begin{macrocode}
+endfig; % end fig 9
+
+% \end{macrocode}
+%
+%
+% \subsubsection{Diagram 10: E-R}
+%
+% There are several flavours of Entity-Relationship modeling icons.
+% I have used a style from~\cite{ELMASRI89}.
+%
+% This example introduces some new icons and \Mpost{} modeling.
+%
+% \begin{macrocode}
+
+beginfig(10) % example 10 E-R
+%%%drawgrid;
+
+numeric diam; diam := 2onelineh;
+
+upshift := diam; % circle diameter
+nextup := diam+upshift;
+
+el := namespace(btex MANUFACTURER etex)(niextra);
+eh := onelineh;
+
+numeric dl, dh; % length and height of diamond boxes
+dl := 1/2el; dh := 2eh;
+
+numeric marg; marg := 4u; % double the seperation between parallel lines
+
+hspace1 := 1/2el;
+
+%%% y coords
+lyc1 := 0;
+lyc2 := lyc1+nextup;
+lyc3 := lyc2+nextup;
+lyc4 := lyc3+nextup;
+lyc5 := lyc4+nextup;
+
+% \end{macrocode}
+%
+% The diagram has 5 rows. Start with the 4th as it is the widest row.
+% \begin{macrocode}
+%%% Zcol/row
+%%% row 4
+
+z14=(0,lyc4);
+drawENT(14, el, eh)(btex manufacturer etex);
+
+z34ml=(x14br+hspace1, y14mr);
+drawdiamondbox(34, dl, dh)(btex has etex);
+
+z54ml=(x34mr+hspace1, y34mr);
+drawENT(54, el, eh)(btex car\_model etex);
+
+%%% row 5
+
+z15bm=(x14bm, lyc5);
+drawcirclebox(15, diam)(btex Name etex);
+
+z55bm=(x54bm, lyc5);
+drawcirclebox(55, diam)(btex Name etex);
+
+% \end{macrocode}
+%
+% The third row consists of an ordinary diamond box at the right and
+% a doubly enclosed diamond on the left. The |drawtwodiamondbox| routine
+% is used for the latter. Note that values of |marg| are
+% used to make the oustside of the double diamond larger than the single
+% diamonds.
+% \begin{macrocode}
+%%% row 3
+
+z53bm=(x54bm, lyc3);
+drawdiamondbox(53, dl, dh)(btex of etex);
+
+z13c=(x14bm, y53c);
+drawtwodiamondbox(13, dl+marg, dh+marg, 2/5marg)(btex Makes etex);
+
+% \end{macrocode}
+%
+% The second row just consists of a doubly enclosed rectangular box.
+% There is no explicit routine for drawing this, so two |drawENT| routines
+% are used for drawing smaller and larger superimposed boxes (one with
+% an empty text argument).
+% \begin{macrocode}
+%%% row 2
+
+z32bm=(x34bm, lyc2);
+drawENT(32, el, eh)(btex car etex);
+z31c=z32c;
+drawENT(31, el+marg, eh+marg)("");
+
+%%% row 1
+
+z21bm=(x32bl, lyc1);
+drawcirclebox(21, 5/4diam)(btex \twolines{Serial}{No} etex);
+
+z41bm=(x32br, lyc1);
+drawcirclebox(41, diam)(btex Year etex);
+
+%%%%%% lines
+
+%%% Name / manufacturer (15, 14)
+drawnormal(15bm, 14tm);
+
+%%% Name / model (55, 54)
+drawnormal(55bm, 54tm);
+
+%%% Mnf / has (14, 34)
+drawnormal(14mr, 34ml);
+label.top(btex 1 etex, 1/2[z14mr,z34ml]);
+
+%%% has/ model (34, 54)
+drawnormal(34mr, 54ml);
+label.top(btex N etex, 1/2[z34mr,z54ml]);
+
+%%% Mnf / makes (14, 13)
+drawnormal(14bm, 13tm);
+label.rt(btex 1 etex, 1/2[z14bm,z13tm]);
+
+%%% model / of (54, 53)
+drawnormal(54bm, 53tm);
+label.rt(btex 1 etex, 1/2[z54bm,z53tm]);
+
+% \end{macrocode}
+% In the diagrams so far, except trivially in the first,
+% the lines have all been vertical and/or
+% horizontal. Now we meet lines in arbitrary directions, and parallel
+% to boot.
+%
+% A pair of parallel lines joins the bottom of the doubly enclosed diamond
+% to the left side of the doubly enclosed rectangle. Drawing one of these is
+% simple --- just draw a straight line between the bottom middle of the
+% diamond to the middle left of the rectangle.
+% \begin{macrocode}
+%%% makes / car (13, 31)
+drawnormal(13bm, 31ml);
+% \end{macrocode}
+%
+% The point |z31A| is |1/2marg| above the point |z31ml|. This is one end
+% of the parallel line.
+% \begin{macrocode}
+z31A=(x31ml, y31ml+1/2marg);
+% \end{macrocode}
+%
+% The \Mpost{} equation |z1-z2 = frac*(z3-z4)| means that
+% (a) the line |z1--z2| is parallel to the line |z3--z4|, and (b)
+% the length of the line |z1--z2| is |frac| of the length of |z3--z4|.
+% We next specify that the line |z13U--z31A| is parallel to, and the same
+% length as, the line |z13bm--z31ml|;
+% \begin{macrocode}
+z13U-z31A = z13bm-z31ml;
+% \end{macrocode}
+%
+% The final part of the calculation is to determine the point |z13A| so
+% that the line |z31A--z13A| is parallel to our first line and starts
+% and ends at the outer perimeters of the boxes (and we already
+% know what |z31A| is).
+%
+% \DescribeVariable{whatever}
+% Remember mediation? A point, |z1234| is on the line |z1--z2| if \\
+% |z1234=frac1[z1,z2| holds. \\
+% Similarly a point |z1234| is on the line |z3--z4| if \\
+% |z1234=frac2[z3,z4]| holds.
+%
+% These two equations are linear and provided enough variables are known
+% it is easy, even if tedious and error
+% prone, to solve
+% for all the unknowns using simple mathematics. Fortunately \Mpost{} has an
+% idiom for this kind of calculation using the built-in variable
+% called |whatever|. Each time |whatever| is used it is internally given
+% a new name which saves a lot of name inventions on the part of the user.
+% The following line of code results in \Mpost{} calculating the intersection
+% point, which I call |z13A|, between the two lines |z13U,z31A|, which is
+% our parallel lines whose points are known, and the line |z13bm--z13mr|
+% which is the lower right line of the outer diamond whose points are known.
+% \begin{macrocode}
+z13A = whatever[z13U,z31A] = whatever[z13bm,z13mr];
+% \end{macrocode}
+%
+% Finally, draw the second parallel line in the desired position and length.
+% \begin{macrocode}
+draw z13A--z31A;
+label.urt(btex N etex, 1/2[z13A,z31A]);
+
+% \end{macrocode}
+%
+% Another pair of parallel lines connects the doubly bounded rectangle
+% and the singly bounded diamond, and we use a similar calculation as above.
+% \begin{macrocode}
+%%% of / car (53, 31)
+drawnormal(53bm, 31mr);
+z31B=(x31mr, y31mr+1/2marg);
+z53U - z31B = z53bm - z31mr;
+z53B = whatever[z53U,z31B] = whatever[z53bm,z53ml];
+draw z53B--z31B;
+label.ulft(btex N etex, 1/2[z53B,z31B]);
+
+% \end{macrocode}
+%
+% That's the end of the tricky bits for this diagram.
+% \begin{macrocode}
+%%% car / serial no (31, 21)
+z31C=(x21tm, y31bl);
+drawnormal(31C, 21tm);
+
+%%% car / year (31, 41)
+z31D=(x41tm, y31br);
+drawnormal(31D, 41tm);
+
+% \end{macrocode}
+%
+% The end of this diagram
+% \begin{macrocode}
+endfig; % end fig 10
+
+% \end{macrocode}
+%
+%
+% \subsubsection{Diagram 11: NIAM}
+%
+% Like IDEF1X, NIAM~\cite{NIJSSEN89} is a language for relational database
+% structures. In Europe it tends to be preferred to IDEF1X.
+%
+% Although the layout and icons of the NIAM illustration differ from
+% the prior
+% diagrams, no new techniques are used. The most obvious of the differences
+% are the use of oval and circular boxes in place of the rectangular boxes,
+% and the use of pairs of rectangular boxes in the middle of the relationship
+% lines.
+% \begin{macrocode}
+
+beginfig(11) % example 11 NIAM
+%%%drawgrid;
+
+numeric diam; diam := 2onelineh; % circle diameter
+
+upshift := diam;
+nextup := diam+upshift;
+
+numeric hel, vel; % length of horizontal and vertical box pairs
+eh := onelineh;
+hel = namespace(btex made by etex)(nextra);
+vel = namespace(btex of prod etex)(nextra);
+
+numeric del, deh; % horizontal & vertical diameters of oval boxes
+del := namespace(btex MANUFACTURER etex)(niextra);
+deh := 2eh;
+
+numeric marg; marg := 2u; % margin for doubly enclosed oval boxes
+numeric lmarg; lmarg := marg; % gap for short lines
+
+numeric dashel, dasheh; % diameters of dashed ellipses
+dashel := del+2marg;
+dasheh := deh+2marg;
+
+hspace1 := diam;
+
+%%% y coords
+lyc1 := 0;
+lyc2 := lyc1+nextup;
+lyc3 := lyc2+nextup;
+
+%%% Zcol/row
+
+%%% row 3
+
+x13ml=0; y13bm=lyc3;
+drawovalbox(13, del, deh)(btex manufacturer etex);
+z14=z13c;
+drawdashellipse(14, dashel, dasheh);
+
+z23ml=(x14mr+hspace1, y14mr);
+drawENT(23, hel, eh)(btex of etex);
+
+z33bl=z23br;
+drawENT(33, hel, eh)(btex made by etex);
+
+z44ml=(x33mr+hspace1, y33mr);
+drawdashellipse(44, dashel, dasheh);
+z43=z44c;
+drawovalbox(43, del, deh)(btex car model etex);
+
+z53ml=(x44mr+hspace1, y44mr);
+drawdashcircle(53, diam);
+label(btex year etex, z53c);
+
+%%% row 2
+
+z22c=(x23bm,lyc2);
+drawcirclebox(22, namespace(btex U etex)(2nextra))(btex U etex);
+
+x42tm=x43bm; y42ml=lyc2;
+drawdoublerectangle(42, vel, 2eh, 1/2);
+label(btex of etex, z42ct);
+label(btex is of etex, z42cb);
+
+%%z52c=(x53x,lyc2);
+x52tm=x53bm; y52ml=lyc2;
+drawdoublerectangle(52, vel, 2eh, 1/2);
+label(btex of prod etex, z52ct);
+label(btex prod in etex, z52cb);
+
+%%% row 1
+
+z11ml=(x13ml,lyc1);
+drawdashellipse(11, del, deh);
+label(btex serial no etex, z11c);
+
+z21ml=(x23ml,lyc1);
+drawENT(21, hel, eh)(btex of etex);
+
+z31bl=z21br;
+drawENT(31, hel, eh)(btex has etex);
+
+z41c=(x43c,lyc1);
+drawcirclebox(41, diam)(btex car etex);
+
+%%%%%% lines
+
+%%% manufacturer / of (14, 23)
+drawnormal(14mr, 23ml);
+
+%%% made by / car model (33, 44)
+drawnormal(33mr, 44ml);
+draw (x33tl, y33tl+lmarg)--(x33tr, y33tl+lmarg);
+draw (x33mr, y33mr+lmarg)--(x33mr+eh, y33mr+lmarg);
+
+%%% serial no / of (11, 21)
+drawnormal(11mr, 21ml);
+
+%%% of / of (23, 22, 21)
+drawnormal(23bm, 22tm); drawnormal(22bm, 21tm);
+label.rt(btex id etex, z22mr);
+
+%%% has / car (31, 41)
+drawnormal(31mr, 41ml);
+draw (x31tl, y31tl+lmarg)--(x31tr, y31tl+lmarg);
+draw (x31mr, y31mr+lmarg)--(x33mr+eh, y31mr+lmarg);
+
+%%% model / of (44, 42)
+drawnormal(43bm, 42tm);
+
+%%% is of / car (42, 41)
+drawnormal(42bm, 41tm);
+draw (x42tfr+lmarg, y42tfr)--(x42tfr+lmarg, y42br);
+draw (x42bm+lmarg, y42bm)--(x42bm+lmarg, y42bm-eh);
+
+%%% year / of prod (53, 52)
+drawnormal(53bm, 52tm);
+
+%%% prod in / car (52, 41)
+VH(52bm,41mr);
+drawnormalthree(52bm, 52bm.vh, 41mr);
+draw (x52tfr+lmarg, y52tfr)--(x52tfr+lmarg, y52br);
+draw (x52bm+lmarg, y52bm)--(x52bm+lmarg, y52bm-eh);
+
+% \end{macrocode}
+%
+% The end of this diagram
+% \begin{macrocode}
+endfig; % end fig 11
+
+% \end{macrocode}
+%
+% Note that the centers of the boxes on the bottom row are all at |y=0|,
+% and hence the bottom halves have negative y values. This does not matter
+% as \Mpost{} determines the actual space required for a diagram and does
+% not base it on the origin of the coordinate system.
+%
+%
+% The end of the \Mpost{} examples file.
+% \begin{macrocode}
+end
+
+% \end{macrocode}
+% The end of the example.
+% \begin{macrocode}
+%</eg>
+% \end{macrocode}
+%
+% \subsection{Comments}
+%
+% Everyone is likely to have a different style of diagramming. You have
+% seen how I do it but that might not be what suits you. Nevertheless,
+% the following comments may be of assistance.
+%
+% In my own work I tend to draw a lot of diagrams, using different
+% \file{.mp} files, that have similar sets of `commonly used variables
+% \& values'. Rather than repeating the list in each file, I create a
+% \Mpost{} file, called say \file{mycommons.mp}, that includes these
+% and then |input mycommons| after the |input expressg| near the start
+% of each diagram file.
+%
+% I find it a help to sketch out the diagrams using pencil and paper
+% before coding them up. I have to admit, though, that the final results
+% often look very different from my initial ideas of the layout.
+%
+% You might have noticed that I start the coding at different places
+% in the diagrams. Basically I try and plan on getting the boxes aligned
+% roughly in rows and/or columns. I then typically start with the longest
+% column, or more often with the widest row, and then fill in the rest
+% from there.
+%
+% \subsection{Running the \Mpost{} example file} \label{sec:run}
+%
+% The \file{expeg.mp} file has to be processed by \Mpost{} to obtain
+% \EPS{} (\file{eps}) files for viewing or printing.
+% Depending on your installation the command to run \Mpost{} may be
+% either: \\
+% |mpost expeg| or \\
+% |mp expeg| \\
+% or perhaps something similar. This will produce eleven files, \file{expeg.1}
+% to \file{expeg.11}, each of which is an \file{eps} file for the corresponding
+% |beginfig(N)| in \file{expeg.mp}. \Mpost{} defaults to using \TeX{} for
+% processing labels which outputs them using Computer Modern
+% fonts. Unfortunately \PS{} applications do not understand these so it
+% is necessary to get the fonts inserted. This is most simply done by
+% \LaTeX ing a document that includes the \Mpost{} output. A suitable
+% file is provided below and is configured to be processed by either
+% \LaTeX{} or \pdflatex. Run \LaTeX{} and then dvips (or what you normally
+% use to generate printable output) and you will get all eleven diagrams.
+%
+%
+% \begin{macrocode}
+%<*egt>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%%% expeg.tex display expressg.dtx MetaPost examples
+
+\documentclass[11pt]{article}
+\newif\ifpdf
+\ifx\pdfoutput\undefined
+ \pdffalse
+\else
+ \pdftrue
+\fi
+
+\ifpdf
+ \pdfoutput=1
+ \usepackage[pdftex,final]{graphicx}
+ \DeclareGraphicsRule{*}{mps}{*}{}
+\else
+ \usepackage[final]{graphicx}
+\fi
+
+%%%% page sizes for ISO document on A4 paper
+\setlength{\headheight}{11pt}
+\setlength{\headsep}{10mm}
+\setlength{\topskip}{11pt}
+\setlength{\footskip}{11mm}
+\setlength{\textwidth}{160mm}
+\setlength{\textheight}{221.5mm}
+\setlength{\columnsep}{10mm}
+\setlength{\topmargin}{0mm}
+\setlength{\oddsidemargin}{0mm}
+\setlength{\evensidemargin}{0mm}
+\setlength{\marginparwidth}{0pt}
+\setlength{\marginparsep}{0pt}
+\setlength{\marginparpush}{0pt}
+\setlength{\footnotesep}{12pt}
+ %%%% for US letterpaper need to change some margins
+\setlength{\topmargin}{-9.4mm}
+\setlength{\oddsidemargin}{1.55mm}
+\setlength{\evensidemargin}{1.55mm}
+
+\begin{document}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.1}
+\caption{Some boxes and line styles}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.2}
+\caption{Example schema level diagram}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.3}
+\caption{Example diagram of a tree structure}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.4}
+\caption{Supertypes and subtypes}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.5}
+\caption{A portion of a large model}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.6}
+\caption{Car model using EXPRESS-G}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.7}
+\caption{Car model using Shlaer-Mellor}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.8}
+\caption{Car model using IDEF1X}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.9}
+\caption{Car model using OMT}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.10}
+\caption{Car model using E-R}
+\end{figure}
+
+\begin{figure}
+\centering
+ \includegraphics{expeg.11}
+\caption{Car model using NIAM}
+\end{figure}
+
+\end{document}
+
+% \end{macrocode}
+%
+% The end of the \LaTeX{} file.
+% \begin{macrocode}
+%</egt>
+% \end{macrocode}
+%
+% \subsubsection{Using \pdflatex}
+%
+% \pdflatex{} generates a \file{.pdf} file directly from \LaTeX{} source
+% instead of a \file{.dvi} file. Unfortunately \pdflatex{} does not understand
+% \EPS{} in general, but it \emph{does} understand the restricted form
+% of \EPS{} generated by \Mpost. By default \pdflatex{} will recognise
+% files with an \file{.mps} extension as coming from \Mpost, but \Mpost{}
+% generates files with a numeric extension.
+% If you like to use both \Mpost{} and \pdflatex, then it can
+% get tedious changing all the numeric extensions to \file{.mps}. The
+% following two scripts can help with this. The first is a shell
+% script\footnote{You may well have to modify this to run on your
+% operating system.} which calls a Perl script.
+%
+% The shell script is called \file{n2mps.sh}. To get suitable versions
+% of the example \Mpost{} output files for use with \pdflatex, just do: \\
+% |n2mps.sh expeg| \\
+% after having run \Mpost{} on \file{expeg.mp}.
+%
+% \begin{macrocode}
+%<*shell>
+#! /bin/sh
+
+#####################################################################
+# Shell script n2mps.sh
+# Call as: n2mps.sh basename
+# List each file basename.* in the directory and run the Perl script
+# to copy each basename.N to basenameN.mps, where N is an integer
+#
+# Copyright 2000, Mauro S. Costa and Peter R. Wilson
+#####################################################################
+
+basename=${1:?"A file basename is required."}
+extname=N.mps
+echo Files $basename.N, where N is a number, will be copied to $basename$extname
+for file in `ls $basename.*`
+do
+ n2mpsprl.prl $file
+done
+
+####################### end shell script ###########################
+
+%</shell>
+% \end{macrocode}
+% The Perl script, which is called by the \file{n2mps} script:
+% \begin{macrocode}
+%<*perl>
+
+#!/usr/local/bin/perl -w
+
+###################################################################
+# Perl script: n2mpsprl.prl
+# Call as: n2mpsprl.prl filename
+# If filename is of the form basename.N, where N is an integer,
+# copies file basename.N to file basenameN.mps
+#
+# Copyright 2000, Mauro S. Costa and Peter R. Wilson
+##################################################################
+
+# Test for correct number of input parameters
+die "Invalid command line arguments.\nTry $0 <src> \n" if($#ARGV > 1);
+die "Invalid command line arguments.\nTry $0 <src> \n" if($#ARGV < 0);
+
+# Assign input file name to variable
+$input_file = $ARGV[0];
+
+## test if ends with a number, exit if not
+if ($input_file =~ /\w\.\d/) { ; } else { exit; }
+
+# Remove the "dot" from the string variable
+# holding the input file name
+$input_file =~ s/\.// ;
+
+# Create a list variable composed of the string variable holding
+# the concatenated input file name and the extension ".mps"
+@name_list = ($input_file,'.mps') ;
+
+# Join the string variables in the name_list variable into
+# a single string variable
+$output_file = join("",@name_list) ;
+
+# create a list variable composed to the parameters needed
+# for the system copy command excution
+@exec_list = ('cp', $ARGV[0], $output_file) ;
+
+# Execute the system copy ("cp") command
+system(@exec_list) ;
+
+############################ end perl script ##########################
+
+%</perl>
+% \end{macrocode}
+%
+% As an alternative when using \pdflatex{} and the \Lpack{graphicx} package,
+% putting \\
+% |\DeclareGraphicsRule{*}{mps}{*}{}| \\
+% will cause included graphics files with unknown extensions
+% (e.g., as generated by \Mpost) to be treated as \file{.mps} files.
+% \begin{verbatim}
+% \documentclass...
+% \usepackage{ifpdf}% you should have this
+% \ifpdf
+% \pdfoutput=1
+% \usepackage[pdftex,final]{graphicx}
+% \DeclareGraphicsRule{*}{mps}{*}{}
+% \else
+% \usepackage[final]{graphicx}
+% \fi
+% ...
+% \includegraphics{mpfig.23}
+% ...
+% \end{verbatim}
+%
+%
+% \subsection{Using \LaTeX{} instead of \TeX}
+%
+% As already noted, \Mpost{} defaults to using \TeX{} for typesetting
+% labels. If you would prefer it to use \LaTeX{} instead, then two things
+% have to be done.
+% \begin{enumerate}
+% \item \Mpost{} looks at the value of an environment variable called |TEX|
+% to see what typesetting system it should use. If the variable is
+% not set, then it uses \TeX. To get it to use \LaTeX{} the environment
+% variable has to be set to |latex|. For example, on the system I use
+% this is done by:
+% \begin{verbatim}
+% TEX=latex
+% export TEX
+% \end{verbatim}
+%
+% \item \LaTeX{} |\documentclass| and |\begin{document}| commands must
+% be put into the |verbatimtex|\ldots|etex| group at the start of
+% the diagramming file. For the example, this might look like
+% \begin{verbatim}
+% verbatimtex
+% \documentclass{article}
+% % \usepackage{...} % for any packages
+% \def\twolines#1#2{\vbox{\hbox{#1} \hbox{#2}}}
+% \begin{document}
+% etex
+% \end{verbatim}
+%
+% \end{enumerate}
+%
+% \textbf{NOTE:} Both the above are required for \LaTeX. On the other hand,
+% if |TEX| is either undefined or has a value other than |tex|,
+% then there must
+% be no \LaTeX{} code anywhere in the \file{.mp} file.
+%
+% If you need to generate individual self-contained \file{ps} files
+% for inclusion in non-\LaTeX{} documents where the font used for labels
+% is a member of the Computer Modern family,
+% then you need to use LaTeX{} and dvips on \file{*.tex} files that consist
+% of only a single diagram and no other text at all. At least on my setup
+% I have found it best to run dvips as normal but with output to a file
+% instead of a printer. Then use whatever tools are available to you to
+% convert the \file{.ps} file to an \file{.eps} one (or at least set the
+% correct bounding box values). The primary source on generating and
+% using \EPS{} in the \LaTeX{} world is~\cite{RECKDAHL97},
+% and~\cite{GOOSSENS97} also has useful information.
+%
+% \subsection{Using \PS{} fonts}
+%
+% \Mpost{} can be made to use \PS{} fonts and, providing the labels
+% don't require any special (\TeX) processing, then use of \LaTeX{} may
+% be avoided altogether. In order to do this, certain requirements have
+% to be put on the content on the \file{.mp} file.
+%
+% \begin{itemize}
+% \item \DescribeVariable{prologues} The
+% diagram file must begin with the line \\
+% |prologues:=2;| \\
+% which will add a prologue for \PS{} font to the output file.
+%
+% \item \DescribeVariable{defaultfont} The
+% |defaultfont| must be changed. What it has to be changed
+% to depends on the font you want to use. For example, to use the
+% Times Roman font, put: \\
+% |defaultfont:="ptmr8r";| \\
+% just after the |prologues| line.
+%
+% For this incantation to work, the file \file{ptmr8r.tfm} must exist
+% in a location where \Mpost{} looks for \file{.tfm} files (on the system
+% I use it is in directory \texttt{../texmf/fonts/tfm/adobe/times}). Also,
+% the file \file{psfonts.map} must include a line like \\
+% |ptmr8r Times-Roman ...| \\
+% Again, on my system \file{psfonts.map} is in directory
+% \texttt{../texmf/dvips/misc}.
+%
+% I don't know whether or not this works if you don't have a \LaTeX{}
+% distribution --- it probably doesn't. But it's unlikely that you don't
+% have one if you
+% intend to use \Mpost.
+%
+% \end{itemize}
+%
+% As a final note on changing fonts, the \Mpost{} |defaultfont| and
+% |defaultscale| values only apply to quoted text
+% (e.g., \texttt{"quoted text"}) and not to `btexed' text
+% (e.g., \texttt{btex btexed text etex}). Conversely, \TeX{} or \LaTeX{}
+% commands only apply to btexed text and not to quoted text. For more
+% details on this, see~\cite{METAFP}.
+%
+%
+%
+%
+% \section{The \Mpost{} code} \label{sec:mf}
+%
+%
+% We start by announcing what it is for.
+%
+% \begin{macrocode}
+%<*up>
+%%% EXPRESSG.MP MetaPost macros for EXPRESS-G and other BLA diagrams
+%%% version 1.5, 31 July 2003
+%%% version 1.6, 29 February 2004
+%%% version 1.61, 17 March 2004
+
+show "expressg.mp version 1.61, 2004/03/17";
+
+% \end{macrocode}
+%
+% \subsection{Variables}
+%
+% \begin{variable}{u}
+% The unit of length.
+% \begin{macrocode}
+newinternal u; numeric u;
+u := 1mm;
+
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{maxx}
+% \begin{variable}{maxy}
+% The maximum x and y coordinates for a diagram.
+% \begin{macrocode}
+newinternal maxx, maxy;
+numeric maxx, maxy;
+maxx := 159.5u; % smidgeon under 160mm for ISO
+maxy := 210u; % 210mm for ISO
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{defaultdotdiam}
+% \begin{variable}{dotdiam}
+% The default and actual diameter of circle and dot line end styles.
+% \begin{macrocode}
+newinternal defaultdotdiam, dotdiam;
+numeric defaultdotdiam, dotdiam;
+defaultdotdiam := 2u;
+dotdiam := defaultdotdiam;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{normalpensize}
+% \begin{variable}{normalpensize}
+% \begin{variable}{normalpensize}
+% The diameters of the pens for drawing normal, thick and thin lines. (The
+% size of the default \Mpost{} pen is 0.5bp).
+% \begin{macrocode}
+newinternal normalpensize, thickpensize, thinpensize;
+numeric normalpensize, thickpensize, thinpensize;
+normalpensize := 0.5bp;
+thickpensize := 1.5bp;
+thinpensize := 0.25bp;
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{dotsscale}
+% |dotsscale| is the amount the |...pensize| has to be increased so that a
+% dotted line looks as thick as a continuous or dashed line.
+% \begin{macrocode}
+newinternal dotsscale; numeric dotsscale;
+dotsscale := 2;
+
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{normalpen}
+% \begin{variable}{thickpen}
+% \begin{variable}{thinpen}
+% \begin{variable}{dotspen}
+% \begin{variable}{dotpen}
+% The pens for drawing lines, plus |dotpen| for drawing a dot line end style.
+% \begin{macrocode}
+newinternal normalpen, thickpen, thinpen, dotspen, dotpen;
+pen normalpen, thickpen, thinpen, dotspen, dotpen;
+normalpen := pencircle scaled normalpensize; % i.e. defaultpen;
+thickpen := pencircle scaled thickpensize;
+thinpen := pencircle scaled thinpensize;
+dotspen := pencircle scaled (dotsscale*normalpensize);
+dotpen := pencircle scaled dotdiam;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{defaultsmoothrad}
+% \begin{variable}{smoothrad}
+% The default and initial values for the radius of the arc used for joining
+% two lines.
+% \changes{v1.3}{2000/05/22}{Added defaultsmoothrad and smoothrad variables}
+% \begin{macrocode}
+newinternal defaultsmoothrad;
+numeric smoothrad, defaultsmoothrad;
+smoothrad := defaultsmoothrad := 2u;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{defaultdrumlid}
+% \begin{variable}{drumlid}
+% The default and initial values for the ratio of the minor to major
+% diameter of ellipses for the top and bottom of drums.
+% \changes{v1.3}{2000/05/22}{Added defaultdrumlid and drumlid variables}
+% \begin{macrocode}
+newinternal defaultdrumlid;
+numeric drumlid, defaultdrumlid;
+drumlid := defaultdrumlid := 0.2;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{defaultgal}
+% \begin{variable}{defaultgab}
+% \begin{variable}{defaultgfl}
+% \begin{variable}{defaultgfb}
+% The default values for the length and base width width of arrowheads and fanins.
+%
+% \begin{macrocode}
+%%% default length and base width for arrowheads and fanin
+newinternal defaultgal, defaultgab, defaultgfl, defaultgfb;
+numeric defaultgal, defaultgab, defaultgfl, defaultgfb;
+defaultgal := defaultgfl := defaultdotdiam;
+defaultgab := defaultgfb := defaultgal;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{gal}
+% \begin{variable}{gab}
+% \begin{variable}{gfl}
+% \begin{variable}{gfb}
+% Values of length and base width of arrowheads and fanins.
+% \begin{macrocode}
+%%% length and base width of arrowheads and fanins
+newinternal gal, gab, gfl, gfb;
+numeric gal, gab, gfl, gfb;
+gal := defaultgal;
+gab := defaultgab;
+gfl := defaultgfl;
+gfb := defaultgfb;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{onelineh}
+% The minimum height of a box that encloses a single line of text.
+%
+% \begin{macrocode}
+newinternal onelineh;
+numeric onelineh;
+onelineh := 5u;
+
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{sdtbl}
+% \begin{variable}{sdtbh}
+% \begin{variable}{sdtbs}
+% The length, height and inset for a simple data type box. The length is
+% sufficient for the name `BOOLEAN' and the height for one line of text.
+% \begin{macrocode}
+%%% length, height & inset for simple data type boxes
+newinternal sdtbl, sdtbh, sdtbs;
+numeric sdtbl, sdtbh, sdtbs;
+sdtbl := 22u;
+sdtbh := onelineh;
+sdtbs := 2u;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{sdtbel}
+% \begin{variable}{sdtbeh}
+% \begin{variable}{sdtbes}
+% The length, height and inset for a simple EXPRESSION data type box.
+% The length is
+% sufficient for the name `EXPRESSION' and the height for one line of text.
+% \begin{macrocode}
+%%% length, height & inset for EXPRESSION data type boxes
+newinternal sdtbel, sdtbeh, sdtbes;
+numeric sdtbel, sdtbeh, sdtbes;
+sdtbel := 28u;
+sdtbeh := sdtbh; sdtbes := sdtbs;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{sdtbgel}
+% \begin{variable}{sdtbgeh}
+% \begin{variable}{sdtbges}
+% The length, height and inset for a simple GENERICENT data type box.
+% The length is
+% sufficient for the name `GENERIC\_ENTITY' and the height for one line of text.
+% \changes{v1.5}{2003/07/31}{Added sdtbgel, sdtbgeh and sdtbges box lengths}
+% \begin{macrocode}
+%%% length, height & inset for GENERICENT data type boxes
+newinternal sdtbgel, sdtbgeh, sdtbges;
+numeric sdtbgel, sdtbgeh, sdtbges;
+sdtbgel := 38u;
+sdtbgeh := sdtbh; sdtbges := sdtbs;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{pconl}
+% The average length of a numeric page connector (e.g., for |9,9 (9,9)|).
+% \begin{macrocode}
+%%% average length of numeric page connector
+newinternal pconl;
+numeric pconl; % length of page connector (for e.g., 9,9 (9,9) )
+pconl:=15u;
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{pconh}
+% Height of average page connector (one line of text).
+% \begin{macrocode}
+%%% height of page connectors (one line)
+newinternal pconh;
+numeric pconh;
+pconh := onelineh;
+
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{enth}
+% \begin{variable}{typeh}
+% The height of a one line ENT(ITY) box (|enth|) and the height of a
+% one line ENUM(ERATION), SELECT or TYPE box.
+%
+% \begin{macrocode}
+%%% heights of entity, enum, select, type boxes (One text line)
+newinternal enth, typeh;
+numeric enth, typeh;
+enth := onelineh;
+typeh := onelineh;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{ish}
+% \begin{variable}{isrh}
+% The height of a normal one line interschema box (|ish|) and an
+% interschema box with one line each for the name and rename (|isrh|).
+% \begin{macrocode}
+%%% height of interschema boxes (one text line, no rename), and (name + rename)
+newinternal ish, isrh;
+numeric ish, isrh;
+ish := 2onelineh;
+isrh := 3onelineh;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{schemah}
+% Height of a one line SCHEMA box.
+% \begin{macrocode}
+%%% height of schema boxes (one text line)
+newinternal schemah;
+numeric schemah;
+schemah := 2onelineh;
+
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{eventh}
+% \begin{variable}{eventslope}
+% The height (|eventh|) of a one line (G/L)EVENT box and the slope of the
+% sides of a (G/L)EVENT box.
+% \begin{macrocode}
+%%% height and slope of event boxes
+newinternal eventh, eventslope;
+numeric eventh, eventslope;
+eventh := onelineh;
+eventslope := 0.25;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{nextra}
+% \begin{variable}{niextra}
+% Margins for namespaces in normal (|nextra|) and inset (|niextra|) boxes.
+% Inset boxes are the ENUM, SELECT and TYPE boxes.
+% \begin{macrocode}
+%%% extra namespaces for boxed names
+newinternal nextra, niextra;
+numeric nextra, niextra;
+nextra := 2u;
+niextra := nextra+sdtbs;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{ndextra}
+% Margin for namespace on a relationship line.
+% \begin{macrocode}
+%%% extra namespace for attribute names
+newinternal ndextra;
+numeric ndextra;
+ndextra := nextra+dotdiam;
+
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Utility routines}
+%
+% \begin{routine}{VH}
+% \changes{v1.1}{1999/10/30}{Added VH routine}
+% Calculates the intersection point |z$vh| between the vertical line through
+% |z$| and the horizontal line through |z$$| (see \fref{fig:vhvh}).
+% \begin{macrocode}
+%%% calculates mid-point on a path like |_ (vertical, horizontal)
+%%% final points are: z$, z$vh, z$$, where z$vh=(x$,y$$)
+def VH(suffix $, $$) =
+ z$vh=(x$,y$$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{VhV}
+% \changes{v1.1}{1999/10/30}{Added VhV routine}
+% Calculates the point |z$vhv| on the vertical line through |z$| and the
+% point |z$$vhv| on the vertical line through |z$$|, such that the line
+% |z$vhv--z$$vhv| is horizontal and centered vertically between the given
+% points (see \fref{fig:vhvh}).
+% \begin{macrocode}
+%%% Calculates mid-points on a path like |_
+%%% | (vertical, horizontal, vertical)
+%%% final points are: z$, z$vhv, z$$vhv, z$$
+def VhV(suffix $, $$) =
+ y$$vhv=1/2[y$,y$$]; x$$vhv=x$$;
+ z$vhv=(x$,y$$vhv);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{HvH}
+% \changes{v1.1}{1999/10/30}{Added HvH routine}
+% Calculates the point |z$hvh| on the horizontal line through |z$| and the
+% point |z$$hvh| on the horizontal line through |z$$|, such that the line
+% |z$hvh--z$$hvh| is vertical and centered horizontally between the given
+% points (see \fref{fig:vhvh}).
+% \begin{macrocode}
+%%% Calculates mid-points on a path like -|_ (horizontal, vertical, horizontal)
+%%% final points are: z$, z$hvh, z$$hvh, z$$
+def HvH(suffix $, $$) =
+ x$hvh=1/2[x$,x$$]; y$hvh=y$;
+ z$$hvh=(x$hvh,y$$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{VyV}
+% \changes{v1.1}{1999/10/30}{Added VyV routine}
+% A generalisation of |VhV|.
+% Calculates the point |z$vyv| on the vertical line through |z$| and the
+% horizontal line through |y@|, and the point |z$$vyv| on the vertical
+% line through |z$$| and the horizontal line through |y@| (see \fref{fig:vyxh}).
+% \begin{macrocode}
+%%% Calculates turning points on a U shaped path (vertical, horizontal, vertical)
+%%% final points are: z$, z$vyv, z$$vyv, z$$
+def VyV(suffix $, @, $$) =
+ z$$vyv=(x$$,y@);
+ z$vyv =(x$, y@);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{HxH}
+% \changes{v1.1}{1999/10/30}{Added HxH routine}
+% A generalisation of |HvH|.
+% Calculates the point |z$hxh| on the horizontal line through |z$| and the
+% vertical line through |x@|, and the
+% point |z$$hgh| on the horizontal line through |z$$| and the vertical
+% line through |x@| (see \fref{fig:vyxh}).
+% \begin{macrocode}
+%%% Calculates corner points rotated U shaped path (horizontal, vertical, horizontal)
+%%% final points are: z$, z$hxh, z$$hxh, z$$
+def HxH(suffix $, @, $$) =
+ z$$hxh=(x@,y$$);
+ z$hxh =(x@,y$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{namespace}
+% |namespace(|\meta{name}|)(|\meta{margin}|)| calculates the length of
+% the text string \meta{name} plus the \meta{margin} length. The
+% body is enclosed in parentheses\footnote{Requested by Stephan Hennig,
+% \texttt{ctt} thread \textit{[MP, expressg, latexmp] namespace and textext},
+% 16 March 2004}
+% so you can do \verb?c=2namespace...?
+% \changes{v1.61}{2004/03/17}{Added parentheses to namespace macro}
+% \begin{macrocode}
+%%% calculates length taken up by typesetting str, plus margin
+def namespace(text str)(expr margin) =
+ (xpart lrcorner(str) - xpart llcorner(str) + margin)
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{dashes}
+% Shorthand for a dashed line style. Use as: |draw ... dashes;|.
+% \begin{macrocode}
+def dashes =
+ dashed evenly
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{dots}
+% Shorthand for a dotted line style. Use as: |draw ... dots;|.
+% \begin{macrocode}
+def dots =
+ dashed withdots
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{dashedgrid}
+% |dashedgrid(|\meta{nx}, \meta{ny}, \meta{dist}|)| draws a thin dashed grid
+% with \meta{nx} and \meta{ny} divisions in the $x$ and $y$ directions,
+% with \meta{dist} between the grid lines. The grid lines are numbered.
+% \begin{macrocode}
+% draw a general dashed grid
+def dashedgrid(expr nx, ny, dist) =
+ save zg_, zg__, oldpen;
+ pair zg_[], zg__[];
+ pen oldpen; oldpen = currentpen;
+ pickup thinpen;
+ for i = 0 upto nx:
+ zg_[i] = (i*dist, 0); zg_[i+1000] = (i*dist, ny*dist);
+ draw zg_[i]--zg_[i+1000] dashes;
+ label.bot(decimal(i), zg_[i]);
+ endfor
+ for i = 0 upto ny:
+ zg__[i] = (0, i*dist); zg__[i+1000] = (nx*dist, i*dist);
+ draw zg__[i]--zg__[i+1000] dashes;
+ label.lft(decimal(i), zg__[i]);
+ endfor
+ pickup oldpen;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawgrid}
+% |drawgrid| draws a thin dashed grid filling the permitted space for an
+% ISO Standard diagram. The units are in mm and the lines are at 10mm intervals
+% with labeling in terms of mm.
+% \begin{macrocode}
+%%% draw a 1cm spaced grid of 16(x) by 21(y) cms. (units are mm)
+def drawgrid =
+ dashedgrid(16, 21, 10mm);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% The box drawing routines take as an argument the suffix (|$|) of the
+% left-hand bottom corner point of the box, and normally the length and
+% height of the box.
+% The coordinates of the box corners
+% are calculated (|z$bl|, |z$br|, |z$tr| and |z$tl|). The midpoints of
+% the sides of the box (|z$bm|, |z$mr|, |z$tm|, |z$ml|) are calculated
+% as well. The text `center' of the box is |z$c|, while the geometric
+% center of the box will be at the intersection point of the lines
+% |z$bm--z$tm| and |z$ml--z$mr|. See \fref{fig:boxpoints} for an
+% illustration.
+%
+% \begin{routine}{rectpoints}
+% \changes{v1.1}{1999/10/30}{Added rectpoints routine}
+% The routine |rectpoints($, l, h)| calculates
+% the corner and midpoints of a rectangular box with bottom left
+% at |z$|, length |l| and height |h|. Note that it does \emph{not}
+% calculate the center point (see \fref{fig:boxpoints}).
+% \begin{macrocode}
+%%% calculates corner and midpoints of a rectangle,
+%%% bottom left at $, length l, height h
+def rectpoints(suffix $)(expr l, h) =
+ z$bl = z$;
+ z$tr = (x$+l, y$+h);
+ z$br = (x$tr, y$bl);
+ z$tl = (x$bl, y$tr);
+ z$ml = 1/2[z$bl, z$tl];
+ z$mr = 1/2[z$br, z$tr];
+ z$bm = 1/2[z$bl, z$br];
+ z$tm = 1/2[z$tl, z$tr];
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{rhompoints}
+% \changes{v1.1}{1999/10/30}{Added rhompoints routine}
+% The routine |rhompoints($, l, h, s)| calculates the corner and midpoints
+% of a rhomboid length |l|, height |h|, sideslope |s|, and positioned
+% with its bottom left hand corner at |z$|. The center point is \emph{not}
+% calculated (see \fref{fig:eventpoints}).
+% \begin{macrocode}
+%%% calculate corner, midpoints and center point of a rhomboid.
+def rhompoints(suffix $)(expr l, h, s) =
+ save eshift;
+ numeric eshift; eshift = s*h;
+ z$bl = z$;
+ z$tr = (x$+l+eshift, y$+h);
+ z$br = (x$bl+l, y$bl);
+ z$tl = (x$bl+eshift, y$tr);
+ z$ml = 1/2[z$bl, z$tl];
+ z$mr = 1/2[z$br, z$tr];
+ z$bm = (1/2[x$ml,x$mr], y$bl);
+ z$tm = (x$bm, y$tr);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{circpoints}
+% \changes{v1.1}{1999/10/30}{Added circpoints routine}
+% The routine |circpoints($, d)| calculates the `corner' and `midpoints'
+% on the circumference of a circle, center |z$| and diameter |d|.
+% \begin{macrocode}
+%%% calculate circumferential points on a circle
+def circpoints(suffix $)(expr diam) =
+ save rad, sinrad, cosrad;
+ numeric rad, sinrad, cosrad;
+ rad = diam/2;
+ sinrad = rad*(sind 45);
+ cosrad = rad*(cosd 45);
+ z$c=z$;
+ z$ml=(x$c-rad, y$c);
+ z$mr=(x$c+rad, y$c);
+ z$bm=(x$c, y$c-rad);
+ z$tm=(x$c, y$c+rad);
+ z$tr=(x$c+cosrad, y$c+sinrad);
+ z$bl=(x$c-cosrad, y$c-sinrad);
+ z$br=(x$tr, y$bl);
+ z$tl=(x$bl, y$tr);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \subsection{Path routines}
+% \changes{v1.4}{2000/07/10}{Added path routines}
+%
+% \begin{routine}{~}
+% The binary operator |~| is a reimplementation of the METAFONT plain base
+% |softjoin| path connector (METAFONTbook, page 266);
+% it connects paths via a small circular arc
+% radius |smoothrad|.
+% \begin{macrocode}
+%%% circular arc join between two paths
+tertiarydef p ~ q =
+ begingroup
+ c_ := fullcircle scaled 2smoothrad shifted point 0 of q;
+ a_ := ypart(c_ intersectiontimes p);
+ b_ := ypart(c_ intersectiontimes q);
+ if a_ < 0: point 0 of p{direction 0 of p} else: subpath(0,a_) of p fi
+ ... if b_ < 0: {direction infinity of q}point infinity of q
+ else: subpath(b_,infinity) of q fi
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{sharply}
+% |sharply(zi, zj, ...zn)| creates a piecewise linear path through the
+% given points. (The code is based on the |flex| routine,
+% page 267 of the METAFONTbook).
+% \begin{macrocode}
+%%% piecewise linear path between the given points
+def sharply(text t) = % t is a list of pairs
+ hide(n_:=0; for z=t: z_[incr n_]:=z; endfor)
+ z_1 for k=2 upto n_: --z_[k] endfor
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{smoothly}
+% |smoothly(zi, zj, ...zn)| creates a piecewise linear path through the
+% given points, with the sharp corners replaced by circular arcs of radius
+% |smoothrad|.
+% page 267 of the METAFONTbook).
+% \begin{macrocode}
+%%% piecewise linear path between the given points with smooth corners
+def smoothly(text t) = % t is a list of pairs
+ hide(n_:=0; for z=t: z_[incr n_]:=z; endfor)
+ (z_1 for k=2 upto n_-1: --z_[k]) ~ (z_[k] endfor --z_[n_])
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \subsection{Line end drawing routines}
+%
+% \changes{v1.4}{2000/07/10}{Added individual line end drawing routines}
+% \begin{routine}{drawO}
+% Draw an open circle, diameter |dotdiam| at the end of the vector
+% |z$| to |z$$|. Any underlying graphic/text will be hidden.
+% All the line end drawing routines have similar code.
+% \begin{macrocode}
+%%% Draw an open circle at end of vector from $ to $$
+def drawO(suffix $, $$) =
+% \end{macrocode}
+% Keep everything inside a group and specify the local variables.
+% \begin{macrocode}
+ begingroup
+ save v_, c_, l, p;
+% \end{macrocode}
+% Specify the types of the local variables.
+% \begin{macrocode}
+ pair v_, c_;
+ numeric l;
+ path p;
+% \end{macrocode}
+% |v_| is the difference between the start and end points of the line.
+% That is, it is the vector from the end point to the start point.
+% \begin{macrocode}
+ v_ := z$-z$$;
+% \end{macrocode}
+% \DescribeRoutine{++}
+% \DescribeRoutine{xpart}
+% \DescribeRoutine{ypart}
+% Using \Mpost's Pythagorean addition operator |++|, where |a++b| means
+% $\sqrt{a^{2}+b^{2}}$, we can calculate the length |l| of the line from
+% the x and y dimension (|xpart| and |ypart|) of the vector |v_|.
+% \begin{macrocode}
+ l := (xpart v_)++(ypart v_); % length of the line
+% \end{macrocode}
+% Using mediation involving the ratio of the circle radius to the length
+% of the line, calculate |c_|, the required position of the center of
+% the circle at the end of the line.
+% \begin{macrocode}
+ c_ := (dotdiam/(2l))[z$$,z$];
+% \end{macrocode}
+% |p| is the path for drawing the circle.
+% \begin{macrocode}
+ p := fullcircle scaled dotdiam shifted c_;
+% \end{macrocode}
+% Erase anything underneath the circle.
+% \begin{macrocode}
+ unfill p;
+% \end{macrocode}
+% Now we can draw the circle (twice to make sure it shows).
+% \begin{macrocode}
+ draw p; draw p;
+% \end{macrocode}
+% Finish the local group and end.
+% \begin{macrocode}
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawD}
+% Draw a closed circle, diameter |dotdiam| at the end of the vector
+% |z$| to |z$$|. Any underlying graphic/text will be hidden.
+% \begin{macrocode}
+%%% Draw a closed circle at end of vector from $ to $$
+def drawD(suffix $, $$) =
+ begingroup
+ save v_, c_, l, p;
+ pair v_, c_;
+ numeric l;
+ path p;
+ v_ := z$-z$$;
+ l := (xpart v_)++(ypart v_); % length of the line
+ c_ := (dotdiam/(2l))[z$$,z$];
+ p := fullcircle scaled dotdiam shifted c_;
+ fill p;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawOA}
+% Draw an open arrowhead, length |gal| and base width |gab|,
+% at the end of the vector from |z$| to |z$$|.
+% The same general code pattern is used for non-circular
+% line end styles, and is described here. It is not too different
+% from drawing circular ends, except that the orientation of the line
+% has to be taken into account.
+% \begin{macrocode}
+%%% draw an open arrowhead at end of vector from $ to $$
+def drawOA(suffix $, $$) =
+ begingroup
+ save v_, c_, v_u, c_t, c_b, l, hb, p;
+ pair v_, c_, v_u, c_t, c_b;
+ numeric l, hb;
+ path p;
+ hb := gab/2;
+ v_ := z$-z$$;
+ l := (xpart v_)++(ypart v_); % length of the line
+ c_ := (gal/(l))[z$$,z$]; % base of arrowhead
+% \end{macrocode}
+% Calculate the unit vector in the direction of the line.
+% \begin{macrocode}
+ v_u := unitvector v_;
+% \end{macrocode}
+% Calculate one of the corner points on the base of the triangle by
+% shifting the midbase point in the direction of the normal to the
+% line by half the base width.
+% \begin{macrocode}
+ c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
+% \end{macrocode}
+% Specify that the other corner point is symmetrically opposite the first.
+% \begin{macrocode}
+ c_b - c_ = c_ - c_t;
+% \end{macrocode}
+% Draw the triangular arrowhead.
+% \begin{macrocode}
+ p = c_b--z$$--c_t--cycle;
+ unfill p;
+ draw p; draw p;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawCA}
+% Draw a closed (black) arrowhead, length |gal| and base width |gab|,
+% at the end of the vector from |z$| to |z$$|.
+% \begin{macrocode}
+%%% draw a closed arrowhead at end of vector from $ to $$
+def drawCA(suffix $, $$) =
+ begingroup
+ save v_, c_, v_u, c_t, c_b, l, hb, p;
+ pair v_, c_, v_u, c_t, c_b;
+ numeric l, hb;
+ path p;
+ hb := gab/2;
+ v_ := z$-z$$;
+ l := (xpart v_)++(ypart v_); % length of the line
+ c_ := (gal/(l))[z$$,z$]; % base of arrowhead
+ v_u := unitvector v_;
+ c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
+ c_b - c_ = c_ - c_t;
+ p = c_b--z$$--c_t--cycle;
+ filldraw p;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawA}
+% Draw a simple arrowhead, length |gal| and base width |gab|,
+% at the end of the vector from |z$| to |z$$|.
+% \begin{macrocode}
+%%% draw a simple arrowhead at end of vector from $ to $$
+def drawA(suffix $, $$) =
+ begingroup
+ save v_, c_, v_u, c_t, c_b, l, hb, p;
+ pair v_, c_, v_u, c_t, c_b;
+ numeric l, hb;
+ path p;
+ hb := gab/2;
+ v_ := z$-z$$;
+ l := (xpart v_)++(ypart v_); % length of the line
+ c_ := (gal/(l))[z$$,z$]; % base of arrowhead
+ v_u := unitvector v_;
+ c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
+ c_b - c_ = c_ - c_t;
+ p = c_b--z$$--c_t;
+ draw p;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawF}
+% Draw a fanin, length |gfl| and base width |gfb|,
+% at the end of the vector from |z$| to |z$$|.
+% \begin{macrocode}
+%%% draws a fanin at the end of the vector from $ to $$
+def drawF(suffix $, $$) =
+ begingroup
+ save v_, c_, v_u, c_t, c_b, l, hb, p;
+ pair v_, c_, v_u, c_t, c_b;
+ numeric l, hb;
+ path p;
+ hb := gfb/2;
+ v_ := z$-z$$;
+ l := (xpart v_)++(ypart v_); % length of the line
+ c_ := (gfl/(l))[z$$,z$]; % apex of fan
+ v_u := unitvector v_;
+ c_t := z$$ shifted (-hb*(ypart v_u), hb*(xpart v_u));
+ c_b - z$$ = z$$ - c_t;
+ p = c_b--c_--c_t;
+ draw p;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+% \subsection{Line drawing routines}
+% \changes{v1.4}{2000/07/10}{Stripped in-line line end code from line drawing routines}
+%
+% \begin{routine}{drawdots}
+% Draw a dotted line between the two points |z$| and |z$$|.
+% \begin{macrocode}
+%%% Draw a dotted line from $ to $$
+def drawdots(suffix $, $$) =
+ pickup dotspen;
+ draw z$--z$$ dots;
+ pickup normalpen;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdotsthree}
+% Draw a straight dotted line between the three points |z$|, |z@| and |z$$|.
+% \begin{macrocode}
+%%% Draws the dotted line $--@--$$
+def drawdotsthree(suffix $, @, $$) =
+ pickup dotspen;
+ draw z$--z@--z$$ dots;
+ pickup normalpen;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdotsfour}
+% Draw a straight dotted line between the four points |z$|, |z@|, |z@@| and |z$$|.
+% \begin{macrocode}
+%%% Draw the dotted line $--@--@@--$$
+def drawdotsfour(suffix $, @, @@, $$) =
+ pickup dotspen;
+ draw z$--z@--z@@--z$$ dots;
+ pickup normalpen;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdotsO}
+% Draw a dotted line between the two points |z$| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% Draw a dotted line from $ to $$ with open circle at $$
+def drawdotsO(suffix $, $$) =
+ pickup dotspen;
+ draw z$--z$$ dots;
+ pickup normalpen;
+ drawO($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdotsthreeO}
+% Draw a straight dotted line between the three points |z$|, |z@| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% Draws the dotted line $--@--$$
+def drawdotsthreeO(suffix $, @, $$) =
+ pickup dotspen;
+ draw z$--z@--z$$ dots;
+ pickup normalpen;
+ drawO(@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdotsfourO}
+% Draw a straight dotted line between the four points |z$|, |z@|, |z@@| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% Draw the dotted line $--@--@@--$$
+def drawdotsfourO(suffix $, @, @@, $$) =
+ pickup dotspen;
+ draw z$--z@--z@@--z$$ dots;
+ pickup normalpen;
+ drawO(@@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdotsOO}
+% Draw a dotted line between the two points |z$| and |z$$|,
+% ending in open circles, diameter |dotdiam|, at |z$| and |z$$|.
+% \begin{macrocode}
+%%% Draw the dotted line from $ to $$, ending in circles diameter dotdiam at $ and $$
+def drawdotsOO(suffix $, $$) =
+ pickup dotspen;
+ draw z$--z$$ dots;
+ pickup normalpen;
+ drawO($, $$); drawO($$, $);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdash}
+% Draw a dashed line between the two points |z$| and |z$$|.
+% \begin{macrocode}
+%%% draws a dashed line from $ to $$
+def drawdash(suffix $, $$) =
+ draw z$--z$$ dashes;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashthree}
+% Draw a straight dashed line between the three points |z$|, |z@| and |z$$|.
+% \begin{macrocode}
+%%% draws the dashed line $--@--$$
+def drawdashthree(suffix $, @, $$) =
+ draw z$--z@--z$$ dashes;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashfour}
+% Draw a straight dashed line between the four points |z$|, |z@|, |z@@| and |z$$|.
+% \begin{macrocode}
+%%% draws the dashed line $--@--@@--$$
+def drawdashfour(suffix $, @, @@, $$) =
+ draw z$--z@--z@@--z$$ dashes;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashO}
+% Draw a dashed line between the two points |z$| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws a dashed line from $ to $$, ending in a circle diameter dotdiam at $$
+def drawdashO(suffix $, $$) =
+ draw z$--z$$ dashes;
+ drawO($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashthreeO}
+% Draw a straight dashed line between the three points |z$|, |z@| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws the dashed line $--@--$$ with circle at $$
+def drawdashthreeO(suffix $, @, $$) =
+ draw z$--z@--z$$ dashes;
+ drawO(@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashfourO}
+% Draw a straight dashed line between the four points |z$|, |z@|, |z@@| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws the dashed line $--@--@@--$$ with circle at $$
+def drawdashfourO(suffix $, @, @@, $$) =
+ draw z$--z@--z@@--z$$ dashes;
+ drawO(@@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashOO}
+% Draw a dashed line between the two points |z$| and |z$$|,
+% ending in open circles, diameter |dotdiam|, at |z$| and |z$$|.
+% \begin{macrocode}
+% drawdashOO($, $$)
+%%% draws a dashed line from $ to $$, ending in circles diameter dotdiam at $ and $$
+def drawdashOO(suffix $, $$) =
+ draw z$--z$$ dashes;
+ drawO($, $$); drawO($$, $);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormal}
+% Draw a normal thickness line between the two points |z$| and |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$.
+def drawnormal(suffix $, $$) =
+ draw z$--z$$;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalthree}
+% Draw a straight normal thickness line between the three points |z$|, |z@| and |z$$|.
+% \begin{macrocode}
+% drawnormalthree($, @, $$)
+%%% draws the normal line $--@--$$
+def drawnormalthree(suffix $, @, $$) =
+ draw z$--z@--z$$;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalfour}
+% Draw a straight normal thickness line between the four points |z$|, |z@|, |z@@| and |z$$|.
+% \begin{macrocode}
+%%% draws the normal line $--@--@@--$$
+def drawnormalfour(suffix $, @, @@, $$) =
+ draw z$--z@--z@@--z$$;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalO}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+% drawnormalO($, $$)
+%%% draws a normal line from $ to $$, ending in a circle diameter dotdiam at $$
+def drawnormalO(suffix $, $$) =
+ draw z$--z$$;
+ drawO($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalthreeO}
+% Draw a straight normal thickness line between the three points |z$|, |z@| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws the normal line $--@--$$, ending in a circle at $$
+def drawnormalthreeO(suffix $, @, $$) =
+ draw z$--z@--z$$;
+ drawO(@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalfourO}
+% Draw a straight normal thickness line between the four points |z$|, |z@|, |z@@| and |z$$|,
+% ending in an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws the line $--@--@@--$$, ending in a circle at $$
+def drawnormalfourO(suffix $, @, @@, $$) =
+ draw z$--z@--z@@--z$$;
+ drawO(@@, $$);
+enddef;
+
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalOO}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending in open circles, diameter |dotdiam|, at |z$| and |z$$|.
+% \begin{macrocode}
+% drawnormalOO($, $$)
+%%% draws a normal line from $ to $$, ending in circles diameter dotdiam at $ and $$
+def drawnormalOO(suffix $, $$) =
+ draw z$--z$$;
+ drawO($, $$); drawO($$, $);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalD}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending in a black dot, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, ending in a dot diameter dotdiam at $$
+def drawnormalD(suffix $, $$) =
+ draw z$--z$$;
+ drawD($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalthreeD}
+% Draw a straight normal thickness line between the three points |z$|, |z@| and |z$$|,
+% ending in a black dot, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws the normal line $--@--$$, ending in a dot at $$
+def drawnormalthreeD(suffix $, @, $$) =
+ draw z$--z@--z$$;
+ drawD(@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalfourD}
+% Draw a straight normal thickness line between the four points |z$|, |z@|, |z@@| and |z$$|,
+% ending in a black dot, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws the normal line $--@--@@--$$, ending in a dot at $$
+def drawnormalfourD(suffix $, @, @@, $$) =
+ draw z$--z@--z@@--z$$;
+ drawD(@@, $$);
+enddef;
+
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalDD}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending in black dots, diameter |dotdiam|, at |z$| and |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, ending in dots diameter dotdiam at $ and $$
+def drawnormalDD(suffix $, $$) =
+ draw z$--z$$;
+ drawD($, $$); drawD($$, $);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalOA}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending with an open arrowhead, length |gal| and base width |gab|,
+% at |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, ending with an open arrowhead at $$
+def drawnormalOA(suffix $, $$) =
+ draw z$--z$$;
+ drawOA($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalCA}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending with a closed (black) arrowhead, length |gal| and base width |gab|,
+% at |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, ending with a closed arrowhead at $$
+def drawnormalCA(suffix $, $$) =
+ draw z$--z$$;
+ drawCA($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalthreeCA}
+% Draw a straight normal thickness line between the three points |z$|, |z@| and |z$$|,
+% ending in a closed arrowhead at |z$$|.
+% \begin{macrocode}
+%%% draws the normal line $--@--$$, ending in a black arrowhead at $$
+def drawnormalthreeCA(suffix $, @, $$) =
+ draw z$--z@--z$$;
+ drawCA(@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalfourCA}
+% Draw a straight normal thickness line between the four points |z$|, |z@|, |z@@| and |z$$|,
+% ending in a closed arrowhead at |z$$|.
+% \begin{macrocode}
+%%% draws the normal line $--@--@@--$$, ending in a black arrowhead at $$
+def drawnormalfourCA(suffix $, @, @@, $$) =
+ draw z$--z@--z@@--z$$;
+ drawCA(@@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalF}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending with a fanin, length |gfl| and base width |gfb|,
+% at |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, ending with a fanin at $$
+def drawnormalF(suffix $, $$) =
+ draw z$--z$$;
+ drawF($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalFO}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending with a fanin, length |gfl| and base width |gfb|,
+% at |z$| and an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, with a fanin at $ and an open circle at $$
+def drawnormalFO(suffix $, $$) =
+ draw z$--z$$;
+ drawO($, $$); drawF($$, $);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawthick}
+% Draw a straight thick line between the two points |z$| and |z$$|
+% \begin{macrocode}
+%%% draws a thick line from $ to $$.
+def drawthick(suffix $, $$) =
+ pickup thickpen;
+ draw z$--z$$;
+ pickup normalpen;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawthickO}
+% Draw a straight thick line between the two points |z$| and |z$$|,
+% ending with an open circle, diameter |dotdiam|, at |z$$|.
+% \begin{macrocode}
+%%% draws a thick line from $ to $$, ending in a circle diameter dotdiam at $$
+def drawthickO(suffix $, $$) =
+ pickup thickpen;
+ draw z$--z$$;
+ drawO($, $$);
+ pickup normalpen;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawthickOO}
+% Draw a straight thick line between the two points |z$| and |z$$|,
+% ending with open circles, diameter |dotdiam|, at |z$| and |z$$|.
+% \changes{v1.5}{2003/07/31}{Added thickpen to drawthickOO}
+% \begin{macrocode}
+%%% draws a thick line from $ to $$, ending in circles diameter dotdiam at $ and $$
+def drawthickOO(suffix $, $$) =
+ pickup thickpen;
+ draw z$--z$$;
+ drawO($, $$); drawO($$, $);
+ pickup normalpen;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{smooth}
+% Rounds the join at |z@| between the two straight lines |z$--z@--z$$|.
+% The radius of the circular arc is |smoothrad|. The code employs the
+% same technique as used for putting dots, etc., at the end of a line.
+% However, in this case we `undraw' the sharp corner before drawing the
+% arc.
+% \changes{v1.3}{2000/05/22}{Added smooth routine}
+% \begin{macrocode}
+%%% replaces the sharp corner on $--@--$$ with a circular arc radius smoothrad
+def smooth(suffix $, @, $$) =
+ begingroup
+ save v_, c_, l, p;
+ pair v_, v_', c_, c_';
+ path p;
+ v_ := z@-z$;
+ l := (xpart v_)++(ypart v_); % length of $--@
+ c_ := (smoothrad/l)[z@,z$]; % start of arc on $--@
+ v_' := z$$-z@;
+ l := (xpart v_')++(ypart v_'); % length of @--$$
+ c_' := (smoothrad/l)[z@,z$$]; % end of arc on @--$$
+ undraw c_--z@--c_'; % blank original join
+ draw c_{v_}..{v_'}c_'; % draw the arc
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{smoothtwo}
+% Rounds the joins at |z@| and |z@@| between the three straight lines
+% |z$--z@--z@@--z$$|.
+% The radius of the circular arc is |smoothrad|.
+% \changes{v1.3}{2000/05/22}{Added smoothtwo routine}
+% \begin{macrocode}
+%%% replaces the sharp corners on $--@--@@--$$ with a circular arc radius smoothrad
+def smoothtwo(suffix $, @, @@, $$) =
+ smooth($, @, @@); smooth(@, @@, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{smoothdash}
+% Rounds the join at |z@| between the two dashed straight lines |z$--z@--z$$|.
+% The radius of the circular arc is |smoothrad|.
+% \changes{v1.3}{2000/05/22}{Added smoothdash routine}
+% \begin{macrocode}
+%%% replaces the sharp corner on the dashed lines $--@--$$
+%%% with a circular arc radius smoothrad
+def smoothdash(suffix $, @, $$) =
+ begingroup
+ save v_, c_, l, p;
+ pair v_, v_', c_, c_';
+ path p;
+ v_ := z@-z$;
+ l := (xpart v_)++(ypart v_); % length of $--@
+ c_ := (smoothrad/l)[z@,z$]; % start of arc on $--@
+ v_' := z$$-z@;
+ l := (xpart v_')++(ypart v_'); % length of @--$$
+ c_' := (smoothrad/l)[z@,z$$]; % end of arc on @--$$
+ undraw c_--z@--c_'; % blank original join
+ draw c_{v_}..{v_'}c_' dashes; % draw the dashed arc
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{smoothdots}
+% Rounds the join at |z@| between the two dotted straight lines |z$--z@--z$$|.
+% The radius of the circular arc is |smoothrad|.
+% \changes{v1.3}{2000/05/22}{Added smoothdots routine}
+% \begin{macrocode}
+%%% replaces the sharp corner on the dotted line $--@--$$
+%%% with a circular arc radius smoothrad
+def smoothdots(suffix $, @, $$) =
+ begingroup
+ save oldpen;
+ pen oldpen; oldpen := currentpen;
+ save v_, c_, l, p;
+ pair v_, v_', c_, c_';
+ path p;
+ v_ := z@-z$;
+ l := (xpart v_)++(ypart v_); % length of $--@
+ c_ := (smoothrad/l)[z@,z$]; % start of arc on $--@
+ v_' := z$$-z@;
+ l := (xpart v_')++(ypart v_'); % length of @--$$
+ c_' := (smoothrad/l)[z@,z$$]; % end of arc on @--$$
+ undraw c_--z@--c_'; % blank original join
+ pickup dotspen;
+ draw c_{v_}..{v_'}c_' dots; % draw the dotted arc
+ pickup oldpen;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+% \subsection{Box drawing routines}
+%
+% The box drawing routines take as an argument the suffix (|$|) of the
+% left-hand bottom corner point of the box, and normally the length and
+% height of the box. There is normally also a text argument that gets
+% typeset at the `center' of the box. The coordinates of the box corners
+% are calculated (|z$bl|, |z$br|, |z$tr| and |z$tl|). The midpoints of
+% the sides of the box (|z$bm|, |z$mr|, |z$tm|, |z$ml|) are calculated
+% as well. The text `center' of the box is |z$c|, while the geometric
+% center of the box will be at the intersection point of the lines
+% |z$bm--z$tm| and |z$ml--z$mr|. See \fref{fig:boxpoints} for an
+% illustration.
+%
+%
+% \begin{routine}{drawSCHEMA}
+% |drawSCHEMA(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% a SCHEMA box.
+% \begin{macrocode}
+%%% draws a schema box, bottom left at $, length l, height h
+def drawSCHEMA(suffix $)(expr l, h)(text str) =
+ rectpoints($, l, h);
+ x$c = 1/2[x$ml, x$mr];
+ y$c = 1/2[y$ml, y$tl];
+ draw z$bl--z$br--z$tr--z$tl--cycle; % outer box
+ draw z$ml--z$mr; % dividing line
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawSDT}
+% |drawSDT(|\meta{suffix}|)(|\meta{name}|)| draws
+% a simple data type box of length |sdtbl| and height |sdtbh|.
+% \begin{macrocode}
+% drawSDT($)(name)
+% draw a simple data type box, bottom left at $
+def drawSDT(suffix $)(text str) =
+ rectpoints($, sdtbl, sdtbh);
+ z$ti = (x$tr-sdtbs, y$tr);
+ z$bi = (x$ti, y$br);
+ z$c = 1/2[z$bl,z$ti];
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ draw z$bi--z$ti;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawASDT}
+% |drawASDT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% a simple data type box.
+% \begin{macrocode}
+% drawASDT($, l, h)(name)
+% draw a simple data type box, bottom left at $, length l, height h
+def drawASDT(suffix $)(expr l, h)(text str) =
+ rectpoints($, l, h);
+ z$ti = (x$tr-sdtbs, y$tr);
+ z$bi = (x$ti, y$br);
+ z$c = 1/2[z$bl,z$ti];
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ draw z$bi--z$ti;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% The |drawNAME(|\meta{suffix}|)| routines draw a simple data type
+% box of the given name using the applicable lengths and heights.
+% \begin{routine}{drawBINARY}
+% \begin{routine}{drawBOOLEAN}
+% \begin{routine}{drawCOMPLEX}
+% \begin{routine}{drawEXPRESSION}
+% \begin{macrocode}
+def drawBINARY(suffix $) = drawASDT($)(sdtbl, sdtbh)("BINARY");
+ enddef;
+def drawBOOLEAN(suffix $) = drawASDT($)(sdtbl, sdtbh)("BOOLEAN");
+ enddef;
+def drawCOMPLEX(suffix $) = drawASDT($)(sdtbl, sdtbh)("COMPLEX");
+ enddef;
+def drawEXPRESSION(suffix $) = drawASDT($)(sdtbel, sdtbeh)("EXPRESSION");
+ enddef;
+% \end{macrocode}
+% \end{routine}
+% \end{routine}
+% \end{routine}
+% \end{routine}
+%
+% \begin{routine}{drawGENERIC}
+% \begin{routine}{drawINTEGER}
+% \begin{routine}{drawLOGICAL}
+% \begin{routine}{drawNUMBER}
+% \begin{macrocode}
+def drawGENERIC(suffix $) = drawASDT($)(sdtbl, sdtbh)("GENERIC");
+ enddef;
+def drawINTEGER(suffix $) = drawASDT($)(sdtbl, sdtbh)("INTEGER");
+ enddef;
+def drawLOGICAL(suffix $) = drawASDT($)(sdtbl, sdtbh)("LOGICAL");
+ enddef;
+def drawNUMBER(suffix $) = drawASDT($)(sdtbl, sdtbh)("NUMBER");
+ enddef;
+% \end{macrocode}
+% \end{routine}
+% \end{routine}
+% \end{routine}
+% \end{routine}
+%
+% \begin{routine}{drawREAL}
+% \begin{routine}{drawSTRING}
+% \begin{macrocode}
+def drawREAL(suffix $) = drawASDT($)(sdtbl, sdtbh)("REAL");
+ enddef;
+def drawSTRING(suffix $) = drawASDT($)(sdtbl, sdtbh)("STRING");
+ enddef;
+
+% \end{macrocode}
+% \end{routine}
+% \end{routine}
+%
+% \begin{routine}{drawENUM}
+% |drawENUM(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% an ENUMERATION type box.
+% \begin{macrocode}
+% drawENUM($, l, h)(name)
+%%% draw an enumeration type box, bottom left at $, length l, height h
+def drawENUM(suffix $)(expr l, h)(text str) =
+ rectpoints($, l, h);
+ z$ti = (x$tr-sdtbs, y$tr);
+ z$bi = (x$ti, y$br);
+ z$c = 1/2[z$bl,z$ti];
+ draw z$bl--z$br--z$tr--z$tl--cycle dashes;
+ draw z$bi--z$ti dashes;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawSELECT}
+% |drawSELECT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% a SELECT type box.
+% \begin{macrocode}
+% drawSELECT($, l, h)(name)
+%%% draw a select type box, bottom left at $, length l, height h
+def drawSELECT(suffix $)(expr l, h)(text str) =
+ rectpoints($, l, h);
+ z$ti = (x$tl+sdtbs, y$tl);
+ z$bi = (x$ti, y$bl);
+ z$c = 1/2[z$br,z$ti];
+ draw z$bl--z$br--z$tr--z$tl--cycle dashes;
+ draw z$bi--z$ti dashes;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawTYPE}
+% |drawTYPE(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% a user-defined TYPE type box.
+% \begin{macrocode}
+% drawTYPE($, l, h)(name)
+%%% draw a simple user defined TYPE box, bottom left at $, length l, height h
+def drawTYPE(suffix $)(expr l, h)(text str) =
+ rectpoints($, l, h);
+ z$c = 1/2[z$bl,z$tr];
+ draw z$bl--z$br--z$tr--z$tl--cycle dashes;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawENT}
+% |drawENT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% an ENTITY box.
+% \begin{macrocode}
+% drawENT($, l, h)(name)
+%%% draw an entity box, bottom left at $, length l, height h
+def drawENT(suffix $)(expr l, h)(text str) =
+ rectpoints($, l, h);
+ z$c = 1/2[z$bl,z$tr];
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawOB}
+% |drawOB(|\meta{suffix}, \meta{l}, \meta{h}|)| draws
+% a rectangular box with rounded corners (an \ExpressG{} oval box).
+% \begin{macrocode}
+% drawOB($, l, h)
+% draw an oval box, bottom left at $, length l, height h
+def drawOB(suffix $)(expr l, h) =
+ save rad;
+ numeric rad; rad := h/2;
+ rectpoints($, l, h);
+ z$cl = 1/2[z$bl, z$tl];
+ z$cr = 1/2[z$br, z$tr];
+ z$bli = (x$bl+rad, y$bl);
+ z$tli = (x$bli, y$tl);
+ z$bri = (x$br-rad, y$br);
+ z$tri = (x$bri, y$tr);
+ z$c = 1/2[z$bl,z$tr];
+ draw z$bli--z$bri..z$cr..z$tri--z$tli..z$cl..cycle;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawPREF}
+% |drawPREF(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% a page reference oval box.
+% \begin{macrocode}
+% drawPREF($, l, h)(name)
+%%% draw a page reference box oval, bottom left at $, length l, height h
+def drawPREF(suffix $)(expr l, h)(text str) =
+ drawOB($, l, h);
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+% \begin{routine}{drawISU}
+% |drawISU(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% an interschema USE box.
+% \begin{macrocode}
+% drawISU($, l, h)(name)
+%%% draw an interschema USE box, bottom left at $, length l, height h
+def drawISU(suffix $)(expr l, h)(text str) =
+ save quarter;
+ numeric quarter; quarter := h/4;
+ rectpoints($, l, h);
+ z$o = (x$, y$+quarter);
+ drawOB($o, l, 2quarter);
+ z$c = 1/2[z$bl,z$tr];
+ label(str, z$c);
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawISUR}
+% |drawISUR(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)(|\meta{rename}|)| draws
+% an interschema USE RENAME box.
+% \changes{v1.5}{2003/07/31}{Changed rnm to rname in drawISUR}
+% \begin{macrocode}
+% drawISUR($, l, h)(name)(rename)
+%%% draw an interschema USE RENAME box, bottom left at $, length l, height h
+def drawISUR(suffix $)(expr l, h)(text str, rname) =
+ save third;
+ numeric third; third := h/3;
+ rectpoints($, l, h);
+ z$o = (x$, y$+third);
+ drawOB($o, l, third);
+ z$c = 1/2[z$bl, z$tr];
+ label(str, z$c);
+ z$rnm = 1/2[z$bl,(x$br,y$br+third)];
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ label(rname, z$rnm);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawISR}
+% |drawISR(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% an interschema RERERENCE box.
+% \begin{macrocode}
+% drawISR($, l, h)(name)
+%%% draw an interschema REFERENCE box, bottom left at $, length l, height h
+def drawISR(suffix $)(expr l, h)(text str) =
+ save quarter;
+ numeric quarter; quarter := h/4;
+ rectpoints($, l, h);
+ z$o = (x$, y$+quarter);
+ drawOB($o, l, 2quarter);
+ z$c = 1/2[z$bl,z$tr];
+ label(str, z$c);
+ draw z$bl--z$br--z$tr--z$tl--cycle dashes;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawISRR}
+% |drawISRR(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)(|\meta{rename}|)| draws
+% an interschema REFERENCE RENAME box.
+% \changes{v1.5}{2003/07/31}{Changed rnm to rname in drawISSR}
+% \begin{macrocode}
+% drawISRR($, l, h)(name)(rename)
+%%% draw an interschema REFERENCE RENAME box, bottom left at $, length l, height h
+def drawISRR(suffix $)(expr l, h)(text str, rname) =
+ save third;
+ numeric third; third := h/3;
+ rectpoints($, l, h);
+ z$o = (x$, y$+third);
+ drawOB($o, l, third);
+ z$c = 1/2[z$bl,z$tr];
+ label(str, z$c);
+ z$rnm = 1/2[z$bl,(x$br,y$br+third)];
+ draw z$bl--z$br--z$tr--z$tl--cycle dashes;
+ label(rname, z$rnm);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+% \begin{routine}{drawLEVENT}
+% |drawLEVENT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% a Local EVENT box, with side slope |eventslope|.
+% \begin{macrocode}
+% drawLEVENT($, l, h)(name)
+%%% draw a Local EVENT box, bottom left at $, length l, height h
+def drawLEVENT(suffix $)(expr l, h)(text str) =
+ rhompoints($, l, h, eventslope);
+ z$c = 1/2[z$ml,z$mr];
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawGEVENT}
+% |drawGEVENT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
+% a Global EVENT box, with side slope |eventslope|.
+% \begin{macrocode}
+% drawGEVENT($, l, h)(name)
+%%% draw a Global EVENT box, bottom left at $, length l, height h
+def drawGEVENT(suffix $)(expr l, h)(text str) =
+ rhompoints($, l, h, eventslope);
+ z$c = 1/2[z$ml,z$mr];
+ pickup thickpen;
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ pickup normalpen;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+%
+% \begin{routine}{drawcirclebox}
+% |drawcirclebox(|\meta{suffix}, \meta{diam}|)(|\meta{name}|)| draws
+% a circle, center |zsuffix| and diameter \meta{diam}, around \meta{name}.
+% \begin{macrocode}
+% drawcirclebox($, diam)(name)
+%%% draw a circled name, diameter diam centered at $
+def drawcirclebox(suffix $)(expr diam)(text str) =
+ circpoints($, diam);
+ draw z$bl..z$bm..z$br..z$mr..z$tr..z$tm..z$tl..z$ml..cycle;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \subsection{Extra BLA variables and routines}
+%
+% Some extra facilities are provided for assistance in drawing
+% non-\ExpressG{} BLA diagrams, such as flow charts, IDEF diagrams
+% or UML structure diagrams.
+%
+% \begin{variable}{gdl}
+% \begin{variable}{gdb}
+% |gdl| is the length of a diamond line end style and |gdb| is the base
+% width.
+% \begin{macrocode}
+%%% length and base width of diamond line end styles
+newinternal gdl, gdb;
+numeric gdl, gdb;
+gdl := 2defaultgal;
+gdb := 0.75defaultgab;
+
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{routine}{ellipsepoints}
+% \changes{v1.2}{1999/11/15}{Added ellipsepoints routine}
+% Calculates the points on an ellipse, center at |z$| with horizontal
+% diameter |l| and vertical diameter |h|. It does \emph{not} calculate
+% the center point.
+% \begin{macrocode}
+def ellipsepoints(suffix $)(expr l, h) =
+ save epp, move;
+ path epp;
+ pair move;
+ z$ml=(x$-l/2, y$); z$mr=(x$ml+l,y$);
+ z$tm=(x$, y$+h/2); z$bm=(x$, y$tm-h);
+ move = 1/2[z$ml,z$mr];
+ epp = fullcircle scaled h xscaled (l/h) shifted move;
+ z$tr = point 1.2 of epp;
+ z$tl = point 2.8 of epp;
+ z$bl = point 5.2 of epp;
+ z$br = point 6.8 of epp;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawDCA}
+% Draw double closed arrowheads, each length |gal| and base
+% width |gab|, at end of vector from |z$| to |z$$|.
+% \changes{v1.4}{2000/07/10}{Added drawDCA}
+% \begin{macrocode}
+%%% draws double closed arrowheads at end of vector from $ to $$
+def drawDCA(suffix $, $$) =
+ begingroup
+ save v_, c_, v_u, c_t, c_b, l, hb, p;
+ pair v_, c_, v_u, c_t, c_b;
+ path p[];
+ numeric l, hb;
+ hb := gab/2;
+ v_ := z$-z$$;
+ l := (xpart v_)++(ypart v_); % length of the line
+ c_ := (gal/(l))[z$$,z$]; % base of arrowhead
+ v_u := unitvector v_;
+ c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
+ c_b - c_ = c_ - c_t;
+ p1 := c_b--z$$--c_t--cycle;
+ filldraw p1;
+ p2 := p1 shifted ((xpart c_ - x$$), (ypart c_ - y$$));
+ filldraw p2;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawOD}
+% Draw an open diamond, length |gdl| and base width |gdb|,
+% at end of vector from |z$| to |z$$|.
+% \begin{macrocode}
+%%% draws an open diamond at end of vector from $ to $$
+def drawOD(suffix $, $$) =
+ begingroup
+ save v_, c_, c__, v_u, c_t, c_b, l, hb, p;
+ pair v_, c_, c__, v_u, c_t, c_b;
+ numeric l, hb;
+ path p;
+ hb := gdb/2;
+ v_ := z$-z$$;
+ l := (xpart v_)++(ypart v_); % length of the line
+ c_ := (gdl/(2l))[z$$,z$]; % base of diamond
+ c__ := (gdl/(l))[z$$,z$]; % interior tip of diamond
+ v_u := unitvector v_;
+ c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
+ c_b - c_ = c_ - c_t;
+ p = c_b--z$$--c_t--c__--cycle;
+ unfill p;
+ draw p; draw p;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawCD}
+% Draw a closed diamond, length |gdl| and base width |gdb|,
+% at end of vector from |z$| to |z$$|.
+% \begin{macrocode}
+%%% draws a closed diamond at end of vector from $ to $$
+def drawCD(suffix $, $$) =
+ begingroup
+ save v_, c_, c__, v_u, c_t, c_b, l, hb, p;
+ pair v_, c_, c__, v_u, c_t, c_b;
+ numeric l, hb;
+ path p;
+ hb := gdb/2;
+ v_ := z$-z$$;
+ l := (xpart v_)++(ypart v_); % length of the line
+ c_ := (gdl/(2l))[z$$,z$]; % base of diamond
+ c__ := (gdl/(l))[z$$,z$]; % interior tip of diamond
+ v_u := unitvector v_;
+ c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
+ c_b - c_ = c_ - c_t;
+ p = c_b--z$$--c_t--c__--cycle;
+ filldraw p;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+% \begin{routine}{drawdashA}
+% Draw a straight dashed line between the two points |z$| and |z$$|,
+% ending with an arrowhead, length |gal| and base width |gab|,
+% at |z$$|.
+% \begin{macrocode}
+%%% draws a dashed line from $ to $$, ending with an arrowhead at $$
+def drawdashA(suffix $, $$) =
+ draw z$--z$$ dashes;
+ drawA($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashOA}
+% Draw a straight dashed line between the two points |z$| and |z$$|,
+% ending with an open arrowhead, length |gal| and base width |gab|,
+% at |z$$|.
+% \begin{macrocode}
+%%% draws a dashed line from $ to $$, ending with an open arrowhead at $$
+def drawdashOA(suffix $, $$) =
+ draw z$--z$$ dashes;
+ drawOA($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalDCA}
+% Draw a straight normal line between the two points |z$| and |z$$|,
+% ending with double closed arrowheads, each length |gal| and base
+% width |gab|, at |z$$|.
+% \changes{v1.2}{1999/11/15}{Added drawnormalDCA}
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, ending with double closed arrowheads at $$
+def drawnormalDCA(suffix $, $$) =
+ draw z$--z$$;
+ drawDCA($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalOD}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending with an open diamond, length |gdl| and base width |gdb|,
+% at |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, ending with an open diamond at $$
+def drawnormalOD(suffix $, $$) =
+ draw z$--z$$;
+ drawOD($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawnormalCD}
+% Draw a straight normal thickness line between the two points |z$| and |z$$|,
+% ending with a closed diamond, length |gdl| and base width |gdb|,
+% at |z$$|.
+% \begin{macrocode}
+%%% draws a normal line from $ to $$, ending with a closed diamond at $$
+def drawnormalCD(suffix $, $$) =
+ draw z$--z$$;
+ drawCD($, $$);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashcircle}
+% \changes{v1.2}{1999/11/15}{Added drawdashcircle}
+% Draw a normal thickness dashed open circle, center |z$|, diameter |diam|.
+% \begin{macrocode}
+%%% draws an open dashed circle, center z$, diameter diam
+def drawdashcircle(suffix $)(expr diam) =
+ circpoints($, diam);
+ draw z$bl..z$bm..z$br..z$mr..z$tr..z$tm..z$tl..z$ml..cycle dashes;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawcircleA}
+% \changes{v1.1}{1999/10/30}{Added drawcircleA routine}
+% Draw a normal thickness open circle, center |z$|, diameter |diam|, and with
+% a counterclockwise pointing arrow at the topmost point. The arrow has
+% length |gal| and base width |gab|.
+% \begin{macrocode}
+%%% draws an open circle, center z$, diameter diam, with an arrow at the top
+def drawcircleA(suffix $)(expr diam) =
+ circpoints($, diam);
+ begingroup
+ save c_, c_t, c_b, hb;
+ pair c_, c_t, c_b;
+ numeric hb;
+ hb := gab/2;
+ c_ := z$tm shifted (gal*right); % base of arrowhead
+ c_t := c_ shifted (hb*up);
+ c_b := c_ shifted (hb*down);
+ draw z$bl..z$bm..z$br..z$mr..z$tr..z$tm..z$tl..z$ml..cycle;
+ draw c_t--z$tm--c_b;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawDot}
+% Draw a black dot, center |z$|, diameter |diam|.
+% \changes{v1.6}{2004/02/29}{Added drawDot}
+% \begin{macrocode}
+%%% draws black dot, center z$, diameter diam
+def drawDot(suffix $)(expr diam) =
+ begingroup
+ save p;
+ path p;
+ p := fullcircle scaled diam shifted z$;
+ filldraw p;
+ endgroup
+enddef;
+
+% \nd{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawCircledDot}
+% Draw a black dot, center |z$|, surrounded by a circle, overall
+% diameter |diam|.
+% \changes{v1.6}{2004/02/29}{Added drawCircledDot}
+% \begin{macrocode}
+%%% draws black dot surrounded by a circle, center z$, diameter diam
+def drawCircledDot(suffix $)(expr diam) =
+ begingroup
+ save l_, p;
+ numeric l_;
+ path p[];
+ l_ := 5/7diam;
+ p1 := fullcircle scaled diam shifted z$;
+ unfill p1;
+ draw p1;
+ p2 := fullcircle scaled l_ shifted z$;
+ filldraw p2;
+ endgroup
+enddef;
+
+% \nd{macrocode}
+% \end{routine}
+%
+%
+% \begin{routine}{drawcardbox}
+% \changes{v1.1}{1999/10/30}{Added drawcardbox routine}
+% Draw a rectangular box that has its top righthand corner folded down.
+% |m| is the height/length of the fold.
+% \begin{macrocode}
+def drawcardbox(suffix $)(expr l, h, m)(text str) =
+ rectpoints($, l, h);
+ begingroup
+ save c;
+ pair c[];
+ c1 = (x$tr-m, y$tr);
+ c3 = (x$tr, y$tr-m);
+ c2 = (xpart c1, ypart c3);
+ draw z$bl--z$br--c3--c1--z$tl--cycle;
+ draw c1--c2--c3;
+ endgroup;
+ z$c = 1/2[z$ml,z$mr];
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdiamondbox}
+% Draw a diamond shaped box. Like circles, the box is located at its
+% center point and
+% not at the bottom left corner (see \fref{fig:diamondpoints}).
+%
+% \begin{macrocode}
+def drawdiamondbox(suffix $)(expr l, h)(text str) =
+ z$ml=(x$-l/2, y$); z$tm=(x$, y$+h/2);
+ z$mr=(x$ml+l, y$); z$bm=(x$, y$tm-h);
+ z$bl=1/2[z$ml,z$bm];
+ z$br=1/2[z$bm,z$mr];
+ z$tr=1/2[z$mr,z$tm];
+ z$tl=1/2[z$tm,z$ml];
+ z$c=z$;
+ draw z$ml--z$bm--z$mr--z$tm--cycle;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawtwodiamondbox}
+% \changes{v1.2}{1999/11/15}{Added drawtwodiamondbox routine}
+% Draw a diamond shaped box with a smaller diamond inside.
+%
+% \begin{macrocode}
+def drawtwodiamondbox(suffix $)(expr l, h, mrg)(text str) =
+ z$ml=(x$-l/2, y$); z$tm=(x$, y$+h/2);
+ z$mr=(x$ml+l, y$); z$bm=(x$, y$tm-h);
+ z$bl=1/2[z$ml,z$bm];
+ z$br=1/2[z$bm,z$mr];
+ z$tr=1/2[z$mr,z$tm];
+ z$tl=1/2[z$tm,z$ml];
+ z$c=z$;
+ begingroup
+ save v_, p, tl, sf;
+ pair v_;
+ numeric tl, sf;
+ path p[];
+ p1 = z$ml--z$bm--z$mr--z$tm--cycle;
+ draw p1;
+ v_ := z$c-z$tr;
+ tl := (xpart v_)++(ypart v_);
+ sf = 1.0 - mrg/tl;
+ p2 = p1 shifted -z$c scaled sf shifted z$c;
+ draw p2;
+ endgroup;
+ label(str, z$c);
+
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdoublerectangle}
+% Draw a double box where |tf| is the fraction of the height of the
+% top portion. The ends of the dividing line are |z$tfl| and |z$tfr|.
+% The text centers are |z$ct| and |z$cb| for the top and bottom portions.
+% \begin{macrocode}
+def drawdoublerectangle(suffix $)(expr l, h, tf) =
+ rectpoints($, l, h);
+ z$tfl=tf[z$tl,z$bl]; z$tfr=tf[z$tr,z$br];
+ z$cb=1/2[z$bl,z$tfr];
+ z$ct=1/2[z$tfl,z$tr];
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ draw z$tfl--z$tfr;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+%
+% \begin{routine}{drawtriplerectangle}
+% \changes{v1.1}{1999/10/30}{Added drawtriplerectangle routine}
+% Draws a triple box, where |tf| is the fraction of the height for the
+% top portion and |bf| is the fraction of the height for the bottom
+% portion. Text centers for the three portions are |z$ct|, |z$cm| and |z$cb|
+% for the top, middle and bottom portions. The points at the ends of the
+% dividing lines are |z$tfl| and |z$tfr| for the top portion
+% and |z$bfl| and |z$bfr| for the bottom.
+%
+% \begin{macrocode}
+def drawtriplerectangle(suffix $)(expr l, h, tf, bf) =
+ rectpoints($, l, h);
+ z$tfl=tf[z$tl,z$bl]; z$tfr=tf[z$tr,z$br];
+ z$bfl=bf[z$bl,z$tl]; z$bfr=bf[z$br,z$tr];
+ z$cb=1/2[z$bl,z$bfr];
+ z$cm=1/2[z$bfl,z$tfr];
+ z$ct=1/2[z$tfl,z$tr];
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ draw z$bfl--z$bfr;
+ draw z$tfl--z$tfr;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{hiderectangle}
+% Draws an invisible rectangular box of the usual dimensions that
+% covers up anything underneath it.
+% \begin{macrocode}
+def hiderectangle(suffix $)(expr l, h) =
+ begingroup
+ save c;
+ pair c[];
+ c1=(x$,y$);
+ c2=c1+(l,0);
+ c3=c1+(l,h);
+ c4=c1+(0,h);
+ unfilldraw c1--c2--c3--c4--cycle;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashboxover}
+% Draws a dashed box that covers up anything underneath it.
+% \begin{macrocode}
+def drawdashboxover(suffix $)(expr l, h) =
+ rectpoints($, l, h);
+ hiderectangle($, l, h);
+ z$c = 1/2[z$bl,z$tr];
+ draw z$bl--z$br--z$tr--z$tl--cycle dashes;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawindexbox}
+% Draws an index box. The main box is |l| by |h| and the small box
+% at the top left is |lp| by |hp|. The main box points are the usual
+% |z$bl| etc, but the top box points are |z$P.bl| etc. The |str|
+% is put at the center (|z$P.c|) of the small box.
+% \begin{macrocode}
+def drawindexbox(suffix $)(expr l, h, lp, hp)(text str) =
+ rectpoints($, l, h);
+ z$c = 1/2[z$bl,z$tr];
+ z$P = z$tl;
+ rectpoints($P, lp, hp);
+ z$P.c = 1/2[z$P.bl, z$P.tr];
+ draw z$bl--z$br--z$tr--z$tl--cycle;
+ draw z$P.bl--z$P.br--z$P.tr--z$P.tl--cycle;
+ label(str, z$P.c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawroundedbox}
+% Draws a rectangular box with rounded corners (like the \LaTeX{} |\oval|).
+% The box is |l| by |h| and located by the bottom left corner. The
+% corners are rounded with a radius of |r|. If the radius is too large for
+% the box it is reduced so that at least two opposite sides are semi-circular.
+% The |str| is put at the center (|z$c|) of the box.
+% \begin{macrocode}
+def drawroundedbox(suffix $)(expr l, h, r)(text str) =
+ rectpoints($, l, h);
+ begingroup
+ save rad;
+ numeric rad; rad := r;
+ if rad > l/2:
+ rad := l/2;
+ fi
+ if rad > h/2:
+ rad := h/2;
+ fi
+ draw (x$br-rad, y$br){right}..{up}(x$br, y$br+rad)--
+ (x$tr, y$tr-rad){up}..{left}(x$tr-rad, y$tr)--
+ (x$tl+rad, y$tl){left}..{down}(x$tl, y$tl-rad)--
+ (x$bl, y$bl+rad){down}..{right}(x$bl+rad, y$bl)--cycle;
+ endgroup;
+ z$c = 1/2[z$bl,z$tr];
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawovalbox}
+% \changes{v1.1}{1999/10/30}{Added drawovalbox routine}
+% Draws an elliptical box with horizontal diameter |l| and vertical diameter
+% |h|. The box is located by the center point.
+% \begin{macrocode}
+def drawovalbox(suffix $)(expr l, h)(text str) =
+ ellipsepoints($, l, h);
+ z$c = 1/2[z$ml,z$mr];
+ begingroup
+ save p;
+ path p;
+ p = fullcircle scaled h xscaled (l/h) shifted z$c;
+ draw p;
+ endgroup;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdashellipse}
+% \changes{v1.2}{1999/11/15}{Added drawdashellipse routine}
+% Draws a dashed elliptical box with horizontal diameter |l| and vertical diameter
+% |h|. The ellipse is located by the center point.
+% \begin{macrocode}
+def drawdashellipse(suffix $)(expr l, h) =
+ ellipsepoints($, l, h);
+ z$c = 1/2[z$ml,z$mr];
+ begingroup
+ save p;
+ path p;
+ p = fullcircle scaled h xscaled (l/h) shifted z$c;
+ draw p dashes;
+ endgroup
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawdrum}
+% \changes{v1.3}{2000/05/22}{Added drawdrum routine}
+% Draws a drum box with length |l| and height |h|. The top and bottom
+% ellipse minor/major diamter ratio id |drumlid|. The text is put at the
+% (curved) center of the drum.
+% \begin{macrocode}
+def drawdrum(suffix $)(expr l, h)(text str) =
+ save vdia; numeric vdia;
+ vdia := drumlid*l; % ellipse vertical diameter
+ save pf, ph; path pf, ph; % full & half ellipse paths
+
+ % points on the basic rectangle
+ z$bl = z$;
+ z$tr = (x$+l, y$+h);
+ z$br = (x$tr, y$);
+ z$tl = (x$, y$tr);
+ z$ml = 1/2[z$bl,z$tl];
+ z$mr = 1/2[z$br,z$tr];
+ z$tc = 1/2[z$tl,z$tr]; % center of top rectangle line
+ z$bc = 1/2[z$bl,z$br];
+ % draw box sides
+ draw z$tl--z$bl; draw z$tr--z$br;
+
+ % points on top ellipse
+ z$T''' = z$tc; % ellipse center
+ ellipsepoints($T''', l, vdia);
+ z$tm = z$T'''.tm;
+ z$tml = z$T'''.tl;
+ z$tmr = z$T'''.tr;
+
+ % points on bottom ellipse
+ z$B''' = z$bc;
+ ellipsepoints($B''', l, vdia);
+ z$bm = z$B'''.bm;
+ z$bml = z$B'''.bl;
+ z$bmr = z$B'''.br;
+
+ % box center point
+ z$c = 1/2[z$T'''.bm, z$B'''.bm];
+
+ % draw top ellipse
+ pf = fullcircle scaled vdia xscaled (l/vdia) shifted z$T''';
+ draw pf;
+ % draw bottom half ellipse
+ ph = (halfcircle rotated 180) scaled vdia xscaled (l/vdia) shifted z$B''';
+ draw ph;
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+% \begin{routine}{drawoutputbox}
+% Draws an output box. The box is |l| by |h| and the |str|
+% is put at the center. The bottom of the box is a wavy line.
+%
+% This code was supplied by Guy Worthington (see \texttt{comp.text.tex}
+% newsgroup thread \textit{Trial, ignore}, January 2004, and in
+% particuar Guy's message of 2004/01/27).
+% \changes{v1.6}{2004/02/29}{Added drawoutputbox}
+% \begin{macrocode}
+def drawoutputbox(suffix $)(expr l, h)(text str) =
+ rectpoints($, l, h);
+ begingroup
+ save c;
+ pair c[];
+ c1 = (x$br, y$br+1/8h); % right side of box is shorter
+ c2 = (x$bm, y$bm+1/16h);
+ % draw the tear
+ draw z$bl..c2{dir 45}..c1{dir -15}--z$tr--z$tl--cycle;
+ endgroup;
+ z$c = (x$bm, 1/2(y$bm+y$tm));
+ label(str, z$c);
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+% \begin{routine}{drawstickman}
+% Draws a full frontal genderless stick figure, inside a rectangle
+% |l| by |h|.
+% \changes{v1.6}{2004/02/29}{Added drawstickman}
+% \begin{macrocode}
+\def drawstickman(suffix $)(expr l, h) =
+ rectpoints($,l,h);
+ begingroup
+ save c;
+ pair c[];
+ c1 = 8/24[z$bm,z$tm];
+ c2 = 15/24[z$bm,z$tm];
+ c3 = 18/24[z$bm,z$tm];
+ c4 = 1/2[c3,z$tm];
+ c6 = (x$bl, ypart(c2));
+ c7 = (x$br, ypart(c2));
+ draw z$bl--c1--z$br; % legs
+ draw c1--c3; % body
+ draw c6--c7; % arms
+ draw c3{right}..z$tm{left}..cycle; % head
+ endgroup;
+enddef;
+
+% \end{macrocode}
+% \end{routine}
+%
+%
+%
+%
+% The end of the package
+%
+% \begin{macrocode}
+%</up>
+% \end{macrocode}
+%
+%
+% \bibliographystyle{alpha}
+% \begin{thebibliography}{RBP+91}
+%
+% \bibitem[EN89]{ELMASRI89}
+% R.~Elmasri and S.~B.~Navathe.
+% \newblock \emph{Fundamentals of Database Systems}.
+% \newblock Benjamin Cummings Publishing Co. Inc., 1989.
+%
+% \bibitem[GMS94]{GOOSSENS94}
+% Michel Goossens, Frank Mittelbach, and Alexander Samarin.
+% \newblock \emph{The LaTeX Companion}.
+% \newblock Addison-Wesley Publishing Company, 1994.
+%
+% \bibitem[GRM97]{GOOSSENS97}
+% Michel Goossens, Sebastian Rahtz, and Frank Mittelbach.
+% \newblock \emph{The LaTeX Graphics Companion}.
+% \newblock Addison-Wesley Publishing Company, 1997.
+%
+% \bibitem[Hob92]{MPOST}
+% John D.~Hobby.
+% \newblock \emph{A user's manual for MetaPost}.
+% \newblock Computing Science Technical Report no. 162,
+% AT\&T Bell Laboratories, Murray Hill, NJ, April 1992.
+% (Available from CTAN with the MetaPost distribution
+% in \texttt{.../graphics/metapost}).
+%
+% \bibitem[Hoe98]{HOENIG98}
+% Alan Hoenig.
+% \newblock \emph{TeX Unbound}.
+% \newblock Oxford University Press, 1998.
+%
+% \bibitem[IDE85]{IDEF1X}
+% AFWAL/MLTC, Wright-Patterson AFB, OH.
+% \newblock \emph{Integrated Informatiuon Support Systems (IISS), Vol.~V:
+% Common Data Model Subsystem, Part 4: Information Modeling Manual
+% --- IDEF1X}.
+% \newblock Report Number: AFWAL--TR--86--4006, Volume~V, 1985.
+%
+% \bibitem[ISO87]{TR9007}
+% ISO TR9007.
+% \newblock \emph{Information processing systems ---
+% Concepts and terminology for the conceptual schema and
+% the information base}, 1987.
+%
+% \bibitem[ISO94]{STEP11}
+% ISO 10303-11:1994.
+% \newblock \emph{Industrial automation systems and integration ---
+% Product data representation and exchange ---
+% Part~11: Description methods: The EXPRESS language reference manual},
+% 1994.
+%
+% \bibitem[Knu86]{MFONT}
+% Donald E~Knuth.
+% \newblock \emph{The METAFONTbook}.
+% \newblock Addison-Wesley Publishing Company, 1986.
+%
+% \bibitem[Lam94]{LATEX}
+% Leslie Lamport.
+% \newblock \emph{\LaTeX: A Document Preperation System}.
+% \newblock Second edition. Addison-Wesley Publishing Company, 1994.
+%
+% \bibitem[NH89]{NIJSSEN89}
+% G.~M.~Nijssen and T.~A.~Halpin.
+% \newblock \emph{Conceptual Schema and Relational Database Design}.
+% \newblock Prentice Hall, 1989.
+%
+% \bibitem[Rec97]{RECKDAHL97}
+% Keith Reckdahl.
+% \newblock \emph{Using EPS Graphics in LaTeX2e Documents}.
+% \newblock February 1997.
+% (Available from CTAN as \texttt{../info/epslatex.ps}).
+%
+%
+% \bibitem[RBP+91]{RUMBAUGH91}
+% J.~Rumbaugh, M.~Blaha, W.~Premerlani, F.~Eddy and W.~Lorensen.
+% \newblock \emph{Object-Oriented Modeling and Design }
+% \newblock Prentice Hall, 1991.
+%
+% \bibitem[SW94]{EBOOK}
+% Douglas A.~Schenck and Peter R.~Wilson.
+% \newblock \emph{Information Modeling the EXPRESS Way}.
+% \newblock Oxford University Press, 1994.
+% (ISBN 0-19-508714-3)
+%
+% \bibitem[SM88]{SHLAER88}
+% S.~Shlaer and S.~J.~Mellor.
+% \newblock \emph{Object-Oriented System Analysis}.
+% \newblock Yourdon Press, 1988.
+%
+% \bibitem[Wil99]{METAFP}
+% Peter Wilson.
+% \newblock \emph{Some Experiences in Running METAFONT and MetaPost}.
+% \newblock November, 1999.
+% (Available from CTAN as \texttt{../info/metafp.ps}).
+%
+% \end{thebibliography}
+%
+% \textbf{Note:} See \texttt{http://www.tug.org} for information on accessing
+% CTAN --- the Comprehensive \TeX{} Archive Network.
+%
+%
+% \Finale
+% \PrintIndex
+%
+\endinput
+
+%% \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 \~}
+
+
diff --git a/Master/texmf-dist/source/metapost/expressg/expressg.ins b/Master/texmf-dist/source/metapost/expressg/expressg.ins
new file mode 100644
index 00000000000..7d467b833e8
--- /dev/null
+++ b/Master/texmf-dist/source/metapost/expressg/expressg.ins
@@ -0,0 +1,114 @@
+%% expressg.ins
+%% Author: Peter Wilson (CUA) now at peter.r.wilson@boeing.com until June 2004
+%% (or: pandgwilson at earthlink dot net)
+%% Copyright 1996, 2003, 2004 Peter R. Wilson
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3 of this license or (at your option) any
+%% later version.
+%% The latest version of the license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of
+%% LaTeX version 2003/06/01 or later.
+%%
+%% This work has the LPPL maintenance status "author-maintained".
+%%
+%% This work consists of the files listed in the README file.
+%%
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this work when run through
+%% LaTeX.
+%%
+%%
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\batchfile{expressg.ins}
+\input docstrip.tex
+\preamble
+
+ Author: Peter Wilson (CUA) now at peter.r.wilson@boeing.com until June 2004
+ (or pandgwilson@earthlink.net)
+ Copyright 1996, 2003 Peter R. Wilson
+
+ v1.0 1996/05/09 (first release)
+ v1.2 1999/11/15
+ v1.3 2000/05/22
+ v1.4 2000/07/10
+ v1.5 2003/07/31
+ v1.6 2004/02/29
+ v1.61 2004/03/17
+
+ This work may be distributed and/or modified under the
+ conditions of the LaTeX Project Public License, either
+ version 1.3 of this license or (at your option) any
+ later version.
+ The latest version of the license is in
+ http://www.latex-project.org/lppl.txt
+ and version 1.3 or later is part of all distributions of
+ LaTeX version 2003/06/01 or later.
+
+ This work has the LPPL maintenance status "author-maintained".
+
+ This work consists of the files listed in the README file.
+ This program is provided under the terms of the
+ LaTeX Project Public License distributed from CTAN
+ archives in directory macros/latex/base/lppl.txt.
+
+\endpreamble
+
+\keepsilent
+
+%%% \Msg{*** Generating the driver file ***}
+%%% \generateFile{expressg.drv}{t}{\from{expressg.dtx}{driver}}
+
+\Msg{*** Generating the Metapost files ***}
+
+\usepostamble\empty
+\generateFile{expressg.mp}{t}{\from{expressg.dtx}{up}}
+\generateFile{expeg.mp}{t}{\from{expressg.dtx}{eg}}
+
+
+\Msg{*** Generating the LaTeX files ***}
+\usepostamble\defaultpostamble
+
+\generateFile{expeg.tex}{t}{\from{expressg.dtx}{egt}}
+
+\Msg{*** Generating the script files ***}
+
+\usepreamble\empty
+\usepostamble\empty
+\generateFile{n2mps.sh}{t}{\from{expressg.dtx}{shell}}
+\generateFile{n2mpsprl.prl}{t}{\from{expressg.dtx}{perl}}
+
+\Msg{***********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into directories searched by Metapost:}
+\Msg{*}
+\Msg{* \space\space expressg.mp}
+\Msg{*}
+\Msg{* To run the examples move the following files into a}
+\Msg{* working directory:}
+\Msg{* \space\space expeg.mp}
+\Msg{* \space\space expeg.tex}
+\Msg{* Then run MetaPost on expeg.mp and (pdf)LaTeX on expeg.tex.}
+\Msg{*}
+\Msg{* To run the scripts, make the following files executable:}
+\Msg{* \space\space n2mps.sh}
+\Msg{* \space\space n2mpsprl.prl}
+\Msg{*}
+\Msg{*}
+\Msg{* To produce the documentation run the files ending with}
+\Msg{* `.dtx' through LaTeX.}
+\Msg{* Process any name.idx file by:}
+\Msg{* \space\space\space\space makeindex -s gind.ist name}
+\Msg{* Process any name.glo file by:}
+\Msg{* \space\space\space\space makeindex -s gglo.ist -o name.gls name.glo}
+\Msg{*}
+\Msg{* Happy TeXing}
+\Msg{***********************************************************}
+
+\endinput