@Section
   @Title { Putting it all together }
@Begin
@PP
In this section we consider the problem of linking individual shapes
together to form complex diagrams like this one:
@ID @Fig {
@Frame { 10c @Wide 6c @High }
// X**0.1 ++ Y**0.4 @BaseOf A:: @Square { @I A }
// X**0.4 ++ Y**0.7 @BaseOf B:: @Square { @I B }
// X**0.6 ++ Y**0.1 @BaseOf C:: @Square { @I C }
// X**0.8 ++ Y**0.6 @BaseOf D:: @Square { @I D }
// A @JoinFigures arrow { forward } B
// A @JoinFigures arrow { forward } C
// B @JoinFigures arrow { forward } C
// B @JoinFigures arrow { forward } D
// C @JoinFigures arrow { forward } D
}
We already have several aids to hand:  the standard Lout symbols,
especially horizontal and vertical concatenation, rotation and scaling;
the ability to nest text, equations, and other figures (in fact
arbitrary Lout objects) within our shapes; and the standard Lout
definition mechanism.
@PP
The default values of the various options -- @Code "solid" for
{@Code linestyle}, @Code noarrow for {@Code arrow}, and so on -- may be
changed by giving options to the @Code "@Fig" symbol:
@ID {
@Code {
"@Fig"
"   linestyle { noline }"
"   paint { black }"
"{"
"   @Circle |1c @Square"
"   /1c @Diamond | @Polygon"
"}"
}
||7ct
@Fig
   linestyle { noline }
   paint { black }
{
    @Circle |1c @Square
   /1c
   @Diamond | @Polygon
}
}
A complete list of options is given in the next section.
@PP
Fig provides an additional aid: the symbols {@Code "@BaseOf"} and
{@Code "@MarkOf"}.  The right parameter of {@Code "@BaseOf"} is an
arbitrary object, and its left parameter is a point.  As far as Lout
is concerned, the result of @Code "@BaseOf" is always an empty object;
but the right parameter will appear on the page with the bottom left-hand
corner of its base at the point denoted by the left parameter.  We stress
that Lout has no idea that this is happening, and so cannot prevent the
shifted object from writing over other objects or even going off the edge
of the page.  Of course, this lack of discipline is just what is needed
very often in diagrams.
@PP
The @Code "@MarkOf" symbol works in a similar way, except that the point
where the object's marks cross (rather than its bottom left-hand corner)
will appear on the page at the point denoted by the left parameter.
@PP
We can set up a coordinate system for a figure:
@ID @Code {
"@Figure shape { xsize 0 @Label X  0 ysize @Label Y }"
"{ 10c @Wide 6c @High }"
}
In fact, Fig contains this shape under the name {@Code "@Frame"}, so we
need only write
@ID @Code "@Frame { 10c @Wide 6c @High }"
Of course, the right parameter may contain an arbitrary Lout object.
@PP
Once the frame is set up, we can specify points by their @Code X and
@Code Y coordinates, as fractions of the total width and height:
@ID @Code "X ** 0.5  ++  Y ** 0.8"
To place the squares in the diagram above, we can use
@ID @Code {
"//  X**0.1 ++ Y**0.4  @BaseOf  A:: @Square { @I A }"
"//  X**0.4 ++ Y**0.7  @BaseOf  B:: @Square { @I B }"
"//  X**0.6 ++ Y**0.1  @BaseOf  C:: @Square { @I C }"
"//  X**0.8 ++ Y**0.6  @BaseOf  D:: @Square { @I D }"
}
The symbols' precedences are chosen so that this very common situation
requires no braces.  The result of this is
@ID @Fig {
@Box margin { 0c } @Frame { 10c @Wide 6c @High }
// X**0.1 ++ Y**0.4 @BaseOf A:: @Square { @I A }
// X**0.4 ++ Y**0.7 @BaseOf B:: @Square { @I B }
// X**0.6 ++ Y**0.1 @BaseOf C:: @Square { @I C }
// X**0.8 ++ Y**0.6 @BaseOf D:: @Square { @I D }
}
{@PageMark sumpoints} where we have drawn a box with margin 0 around the
frame to make its extent clear.
@PP
Now the arrow from @I A to @I B starts on the boundary of @I A at the
angle of a line drawn between the centres of @I A and {@I B}:
@ID @Code "A@CTR ++ { {A@CTR @Angle B@CTR} A@CIRCUM }"
and a similar expression will yield the endpoint of the arrow.  Such
expressions should be placed into definitions if they are to be used often:
@ID @Code {
"import @Fig"
"def @JoinFigures"
"   left A"
"   named linestyle { solid }"
"   named dashlength { 0.15 cm }"
"   named arrow { noarrow }"
"   named linewidth { 0.5 pt }"
"   right B"
"{  @Arrow"
"      from { A\"@CTR\" ++ {{A\"@CTR\" @Angle B\"@CTR\"} A\"@CIRCUM\"} }"
"      to   { B\"@CTR\" ++ {{B\"@CTR\" @Angle A\"@CTR\"} B\"@CIRCUM\"} }"
"      linestyle { linestyle }"
"      dashlength { dashlength }"
"      arrow { arrow }"
"      linewidth { linewidth }"
"   {}"
"}"
}
Definitions preceded by @Code "import @Fig" may use the symbols of
Fig within them; they may themselves be used only within
@Code "@Fig { ... }".  Now, to the figure above we can add
@ID @Code {
"// A @JoinFigures arrow { forward } B"
"// A @JoinFigures arrow { forward } C"
"// B @JoinFigures arrow { forward } C"
"// B @JoinFigures arrow { forward } D"
"// C @JoinFigures arrow { forward } D"
}
to obtain the diagram as it appears at the beginning of this
section.  Definitions are the best means of managing complexity in
diagrams, and serious users maintain a file of definitions which is
included automatically by an @Code "@Include" command.
@End @Section
