summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/generic/xypic/xy.doc
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/generic/xypic/xy.doc')
-rw-r--r--Master/texmf-dist/source/generic/xypic/xy.doc8324
1 files changed, 8324 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/generic/xypic/xy.doc b/Master/texmf-dist/source/generic/xypic/xy.doc
new file mode 100644
index 00000000000..54ac9fca7d0
--- /dev/null
+++ b/Master/texmf-dist/source/generic/xypic/xy.doc
@@ -0,0 +1,8324 @@
+%% $Id: xy.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
+%%
+%% Basic Xy-pictures: Xy-pic bootstrap and kernel macros.
+%% Copyright (c) 1991-1999 Kristoffer H. Rose <krisrose@ens-lyon.fr>
+%%
+%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
+%% Copyright (c) 1991-1999 Kristoffer H. Rose <krisrose@ens-lyon.fr>
+%%
+%% The Xy-pic package is free software; you can redistribute it and/or modify
+%% it under the terms of the GNU General Public License as published by the
+%% Free Software Foundation; either version 2 of the License, or (at your
+%% option) any later version.
+%%
+%% The Xy-pic package is distributed in the hope that it will be useful, but
+%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+%% for more details.
+%%
+%% You should have received a copy of the GNU General Public License along
+%% with this package; if not, write to the Free Software Foundation, Inc.,
+%% 675 Mass Ave, Cambridge, MA 02139, USA.
+%%
+\ifx\xyloaded\undefined\else\message{not reloaded}\endinput\fi
+\let\xyloaded=\relax
+
+% NOTE: Apart from the actual macros (as also found in xy.tex), this file
+% contains both the Xy-pic kernel reference manual and TeXnical documentation.
+% See xyrefer.man and xysource.man for how to typeset this information.
+
+\message{Bootstrap\string'ing\string:}
+
+{\catcode96 12\catcode`\#6\catcode`\.12\catcode`\:12\catcode`\'12\catcode`\@11
+\ifx\xywarnifdefined\undefined\else \immediate\write16{}%
+ \immediate\write16{Xy-pic Warning: \string\xywarnifdefined\space redefined.}%
+ \immediate\write16{}\fi
+\gdef\xywarnifdefined#1{\ifx#1\undefined\else \immediate\write16{}%
+ \immediate\write16{Xy-pic Warning: `\string#1' redefined.}%
+ \immediate\write16{}\fi}
+\xywarnifdefined\xydef@ \gdef\xydef@#1{\xywarnifdefined#1\gdef#1}
+\xywarnifdefined\xylet@ \gdef\xylet@#1{\xywarnifdefined#1\global\let#1}
+\xywarnifdefined\xynew@
+ \gdef\xynew@#1#2{\xywarnifdefined#2\csname new#1\endcsname#2}}
+
+\message{catcodes\string,}
+
+\xywarnifdefined\xyuncatcodes
+\xywarnifdefined\xyreuncatcodes \def\xyreuncatcodes{\edef\xyuncatcodes{%
+ \catcode92 0 \catcode123 1 \catcode125 2 \catcode37 14
+ \catcode 9 \the\catcode 9 \catcode10 \the\catcode10 \catcode12 \the\catcode12
+ \catcode35 \the\catcode35 \catcode36 \the\catcode36 \catcode38 \the\catcode38
+ \catcode43 \the\catcode43 \catcode45 \the\catcode45 \catcode46 \the\catcode46
+ \catcode47 \the\catcode47
+ \catcode60 \the\catcode60 \catcode61 \the\catcode61 \catcode62 \the\catcode62
+ \catcode64 \the\catcode64 \catcode96 \the\catcode96
+ \newlinechar \the\newlinechar \endlinechar \the\endlinechar }}
+\xyreuncatcodes
+
+\xywarnifdefined\xycatcodes \def\xycatcodes{%
+ \catcode 9 10
+ \catcode 35 6 \catcode 36 3 \catcode 38 4
+ \catcode 43 12 \catcode 45 12 \catcode 46 12 \catcode 47 12
+ \catcode 60 12 \catcode 61 12 \catcode 62 12
+ \catcode 64 11 \catcode 96 12 }
+
+\xycatcodes
+
+\message{docmode,}
+
+{\catcode`\|0 \xywarnifdefined|DOCMODE
+\gdef|DOCMODE#1{\ifx(#1\relax \xycatcodes \expandafter\ignorespaces
+ \else \skipspecials@ \expandafter\docm@\fi}%
+
+\xywarnifdefined\skipspecials@
+\gdef\skipspecials@{%
+ \catcode`\\12 \catcode`\{12 \catcode`\}12 \catcode`\#12 \catcode`\%12
+ \catcode`\^^L12 \endlinechar`\^^J }%
+
+\catcode`\/=12 \lccode`\/`\\%
+\lccode`\D`\D \lccode`\O`\O \lccode`\C`\C \lccode`\M`\M \lccode`\E`\E
+\lowercase{%
+\xywarnifdefined\docm@ \gdef\docm@{\docm@i}%
+\xywarnifdefined\docm@i \gdef\docm@i#1^^J{\docm@ii#1/DOCMODE\docm@iii}%
+\xywarnifdefined\docm@ii
+ \gdef\docm@ii#1/DOCMODE{\def\next@{#1}\futurelet\next\docm@iii}%
+\xywarnifdefined\docm@iii \gdef\docm@iii#1\docm@iii{%
+ \ifx\next\docm@iii \let\next\next@ \docecho@ \let\next@\docm@
+ \else\ifx\next@\empty \let\next@\docfinish@
+ \else \edef\next@{\noexpand\docm@iv\next@/DOCMODE#1\noexpand\docm@iv}%
+ \fi\fi \next@}%
+\xywarnifdefined\docm@iv
+ \gdef\docm@iv#1/DOCMODE\docm@iv{\def\next{#1}\docecho@ \docm@}}%
+
+\xywarnifdefined\docecho@ \global\let\docecho@\relax
+\xywarnifdefined\docfinish@ \gdef\docfinish@{\xyuncatcodes|DOCMODE\next}}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ After giving an overview of the \Xy-pic environment in \S??[env],
+ this \FILE\ document the basic concepts of \Xy-picture construction
+ in \S??[basics], including the maintained `graphic state'. The
+ following sections give the precise syntax rules of the main \Xy-pic
+ constructions: the position language in~\S??[pos], the object
+ constructions in~\S??[object], and the picture `decorations'
+ in~\S??[decor]. \S??[objectlib] presents the kernel repertoire of
+ objects for use in pictures; \S??[option] documents the interface to
+ \Xy-pic options like the standard `feature' and `extension' options.
+
+\DOCMODE1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ Details of the implementation are not discussed here but in the
+ complete \TeX\-nical documentation~\cite{RM95:Xy-picCSTC}.
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ Section \S??[algo] documents the more complicated algorithms used to
+ compute directions, edges, and connections.
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section{The \Xy-pic implementation}
+??=[env]
+
+ This section briefly discusses the various aspects of the present
+ \Xy-pic kernel implementation of which the user should be aware.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Loading \Xy-pic}
+??=[env.loading]??w[loading]
+
+ \Xy-pic is careful to set up its own environment in order to function
+ with a large variety of formats. For most formats a single line with
+ the command
+$$
+ ??c![\input xy]
+$$
+ in the preamble of a document file should load the kernel (see
+ `integration with standard formats' below for variations possible
+ with certain formats, in particular \LaTeX~\cite{L94:LaTeX}).
+
+ The rest of this section describes things you must consider if you
+ need to use \Xy-pic together with other macro packages, style
+ options, or formats. The less your environment deviates from plain
+ \TeX\ the easier it should be.
+\DOCMODE1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ Consult the \TeX\-nical documentation~\cite{RM95:Xy-picCSTC} for the
+ exact requirements for other definitions to coexist with \Xy-pic.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{File header:}
+??w[file header]
+
+ Here is what actually happens in the header of |xy.doc|. It contains
+ the copyright message, protection against ??w![loading] the file more
+ than once, and then bootstrap code to handle category codes and the
+ ??c![DOCMODE] format---we explain each separately below:
+
+\DOCHEADER
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Privacy:}
+??w[privacy]
+
+ \Xy-pic will warn about control sequences it redefines---thus you can
+ be sure that there are no conflicts between \Xy-pic-defined control
+ sequences, those of your format, and other macros, provided you
+ load??w[loading] \Xy-pic last and get no ??w![warning
+ messages] like
+$$
+ |Xy-pic Warning: `|\dots|' redefined.|??w[redefined]
+$$
+ In general the \Xy-pic kernel will check all control sequences it
+ redefines "except" that (1)~generic temporaries like ??c![\next] are
+ not checked, (2)~predefined font identifiers (see~\S??[env.fonts])
+ are assumed intentionally preloaded, and (3)~some of the more exotic
+ control sequence names used internally (like |@{-}|) are only
+ checked to be different from ??c![\relax].
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ This is handled by ??c![\xywarnifdefined]---after we have ensured
+ that it is unique itself\footnote{This may seem paranoid but in fact
+ many inconvieniences in the \TeX\ world stem from the fact that
+ somebody copied somebody elses definition of, say,
+ {\tt\string\xywarnifdefined}, modified it, and then used it in
+ something that somehow got distributed! The `flat name space'
+ problem remains \TeX\ largest problem as a programming language in
+ this \TeX\ hackers opinion.}. ??c![\xydef@], ??c![\xylet@], and
+ |\xynew@{|<type>|}|??c[\xynew@] are abbreviations used to this end
+ throughout \Xy-pic instead of ??c![\let], ??c![\def], and the
+ |\new|<type> commands.
+
+ Next some auxilliaries: |\xydefcsname@| is similar to |\xydef@|
+ except that it builds the control sequence with ??c![\csname] \dots\
+ ??c![\endcsname] which means that it is |\relax| when undefined---there
+ is thus no way to prevent redefinition of control sequences bound to
+ ??c![\relax]~\frowny.
+
+\DOCMODE(
+\xydef@\xydefcsname@#1{\DN@{#1}\DNii@##1{%
+ \ifx ##1\relax\else \xywarning@{\string`\string##1\string' redefined}\fi
+ \def##1}%
+ \expandafter\nextii@\csname\codeof\next@\endcsname}
+\DOCMODE)
+
+ |\xyletcsnamecsname@| is to ??c![\let] one weird control sequence
+ be the same as another using several |\expandafter|s:
+
+\DOCMODE(
+\xydef@\xyletcsnamecsname@#1#2{\def\1{#1}\def\2{#2}\DN@##1##2{%
+ \ifx ##1\relax\else \xywarning@{`\string##1\string' redefined}\fi
+ \let##1=##2}%
+ \expandafter\expandafter\expandafter\next@
+ \expandafter\csname\expandafter\codeof\expandafter\1\expandafter\endcsname
+ \csname\codeof\2\endcsname}
+\DOCMODE)
+
+ Finally ??c![\codeof]: a useful hack used to allow any characters in
+ control sequences: ??c![\codeof]<cs> expands to the characters of the
+ control sequence <cs> as a string of `other' characters, \ie, all of
+ category 12 and with a \verb*/ /$_{12}$ after every control sequence.
+ The <cs> must be a macro or it blows up.
+
+\DOCMODE(
+\xywarnifdefined\codeof
+\xywarnifdefined\codeof@
+{\catcode`\:=12 % to ensure that all of :-> and <-: are other :-)
+ \gdef\codeof#1{\expandafter\codeof@\meaning#1<-:}
+ \gdef\codeof@#1:->#2<-:{#2}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Category codes:\ }
+
+ The situation is complicated by the flexibility of
+ \TeX's input format. The culprit is the `??w![category code]'
+ concept of \TeX\ (\cf~\cite[p.37]{K84:TeXbook}): when loaded \Xy-pic
+ requires the characters {\tt\char32}|\{}%| (the first is a space) to
+ have their standard meaning and all other printable characters to
+ have the "same category as when \Xy-pic will be used"---in particular
+ this means that (1)~you should surround the ??w![loading] of \Xy-pic
+ with ??c![\makeatother] \dots\ ??c![\makeatletter] when loading it
+ from within a \LaTeX\ package, and that (2)~\Xy-pic should be loaded
+ after files that change category codes like the ??c![german.sty] that
+ makes |"| active??w[active characters]. Some styles require that you
+ reset the catcodes for every diagram, \eg, with ??c![french.sty] you
+ should use the command |\english| before every |\xymatrix|.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ We define ??c![\xyuncatcodes] to restore the current catcodes, and
+ ??c![\xycatcodes] to install our own.
+
+ Here is an exact list of the category codes which \Xy-pic requires
+ (all standard in plain \TeX):
+$$
+\vcenter{\tabskip=.5em plus1fil \halign to\displaywidth{#\hfil&&\hfil#\hfil\cr
+ character(s) &|\| &|{| &|}| &CR &TAB SP&|A|--|Z| |a|--|z| &|0|--|9| &|%| \cr
+ category code & 0 & 1 & 2 & 5 & 10 & 11 & 12 & 14 \cr}
+}$$
+ Furthermore none of the remaining printable ASCII characters
+$$
+ |!"#$&'()*,/:;?@[]^_`||~|
+$$
+ may be of category 0, 1, 2, 9, 14, or 15, because all should be
+ tokens allowed in the replacement text of a |\def|---this also means
+ that they may not be active characters defined to be ``|\outer|''!
+
+ All other catcodes needed are established using ??c![\xycatcodes]
+ defined above---this is the reason the macros must be loaded at a
+ time where the category codes are stable (otherwise it will make them
+ stable!).
+
+ Internally \Xy-pic enforces the following category codes:
+$$
+\vcenter{\tabskip=.5em plus1fil \halign to\displaywidth{#\hfil&&\hfil#\hfil\cr
+ character &|#|&|$|&|&|&|'|&|+|&|-|&|.|&|<|&|=|&|>|&|@|&|`|\cr
+ ASCII code & 35& 36& 38& 39& 43& 45& 46& 60& 61& 62& 64& 96\cr
+ category code& 6 & 3 & 4 & 12& 12& 12& 12& 12& 12& 12& 11& 12\cr
+ abbreviation&|HASH|&|DOLL|&|AND|&|RQ|&|PLUS|&|DASH|&|DOT|
+ &|LT|&|EQ|&|GT|&|AT|&|LQ|\cr}
+}$$
+ with special control sequences named |\add|<abbreviation>|@| that
+ take an argument and expand to it followed by the original character
+ token, \ie, many tests throughout the program look like |\addDOT@|
+ |\ifx| |\next| \dots
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\DOCMODE(
+\xywarnifdefined\addAT@
+\xywarnifdefined\addHASH@
+\xywarnifdefined\addDOLL@
+\xywarnifdefined\addAND@
+\xywarnifdefined\addRQ@
+\xywarnifdefined\addPLUS@
+\xywarnifdefined\addDASH@
+\xywarnifdefined\addDOT@
+\xywarnifdefined\addLT@
+\xywarnifdefined\addEQ@
+\xywarnifdefined\addGT@
+\xywarnifdefined\addLQ@
+
+\xydef@\xymakeADD@#1#2 #3 {\ifnum\catcode#3=6 \def#1##1{##1#2#2}%
+ \else \def#1##1{##1#2}\fi}
+
+\xydef@\xyrecat@{\xymakeADD@\addAT@}
+\xydef@\xyrecat{\xyrecat@}
+\xydef@\xyresetcatcodes{\def\xyrecat{\xyrecat@}\xyreuncatcodes
+ \input xyrecat \relax \xyuncatcodes}
+
+\xyuncatcodes \xyresetcatcodes \xycatcodes
+
+\xydef@\testAND@{{\aftergroup\ifx
+ \addAND@\ifx\next\addFalse@\else\addTrue@\fi}}
+\xydef@\addFalse@{\aftergroup\iffalse}
+\xydef@\addTrue@{\aftergroup\iftrue}
+\DOCMODE)
+
+\inputdoc!{xyrecat.doc}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The last block of the \Xy-pic header bootstraps the ``??c![DOCMODE]
+ format'' used in |.doc| variants of \Xy-pic macro files in order to
+ keep documentation and macros together in a literal programming style
+ (this is redundant in the |xy.tex| macro file where all instances of
+ |DOCMODE| have been eliminated (see chapter \S??g[:Makefile] for how
+ this is accomplished) but it is included anyway since users may load
+ options still in |DOCMODE| format). The details of |DOCMODE| are
+ described in |xydoc.sty|, a special \LaTeX\ package used to typeset
+ \Xy-pic documentation; please read it if you intend to write \Xy-pic
+ options.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Integration with standard formats}
+??w[formats]
+%
+ This is handled by the |xyidioms.tex| file and the integration as a
+ \LaTeX~\cite{L94:LaTeX} package by |xy.sty|.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ We input |xyidioms.tex| from the kernel:
+
+\DOCMODE(
+\input xyidioms
+\DOCMODE)
+
+\DOCMODE1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\paragraph*{xyidioms.tex:}
+??c[xyidioms.tex]%
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\paragraph*{xyidioms.doc:}
+??c[xyidioms.doc]%
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\inputdoc!{xyidioms.doc}
+
+\paragraph{xy.sty:}
+??c[xy.sty]%
+%%
+ If you use ??w![\LaTeX] then this file makes it possible to
+ load??w[loading] \Xy-pic as a `??w![package]' using the
+ ??w![\LaTeXe]~\cite{L94:LaTeX} ??c![\usepackage] command:
+%
+\begin{defs1}
+??c![\usepackage] |[|<option>|,|\dots|]| |{xy}|
+\end{defs1}
+\noindent\unskip
+%
+ where the <option>s will be interpreted as if passed to
+ ??c![\xyoption] (\cf~\S??[option]).
+
+ The only exceptions to this are the options having the same names as
+ those driver package options of \GROUP~??g[:drivers], which appear in
+ \cf~\cite[table 11.2, p.317]{GMS94:LaTeXC} or the \LaTeXe\ |graphics|
+ bundle. These will automatically invoke any backend extension
+ required to best emulate the \LaTeXe\ behaviour. (This means that,
+ \eg, ??C![dvips] and ??C![textures] can be used as options to the
+ ??c![\documentclass] command, with the normal effect.)
+
+ The file also works as a \LaTeX~2.09~\cite{L86:LaTeX} `??w![style
+ option]' although you will then have to load options with the
+ |\xyoption| mechanism described in \S??[option].
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Here is the raw source of |xy.sty|.
+
+\inputdoc0{xy.sty}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Logo, version, and messages}
+??=[env.logo]
+
+ Loading \Xy-pic prints a ??w![banner] containing the version and
+ author of the kernel; small progress ??w![messages] are printed when
+ each major division of the kernel has been loaded. Any options
+ loaded will announce themself in a similar fashion.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Of these, ??c![\stripRCS] is a very useful hack for extracting the
+ first component of an RCS |$|\dots|$| keyword value.
+
+\DOCMODE(
+\xydef@\stripRCS$#1${\stripRCS@#1: @@ @@@}
+\xydef@\stripRCS@#1: #2@ #3@@@{%
+ \ifx @#2\string?\else\ifx :#2\else\stripRCS@@#2\fi\fi}
+\xydef@\stripRCS@@#1 #2: @{#1}
+
+\edef\next{\stripRCS$Revision: 3.7 $}
+\xylet@\xyversion=\next
+
+\edef\next{\stripRCS$Date: 1999/02/16 15:12:50 $}
+\xylet@\xydate=\next
+
+\xydef@\Xygreet@{%
+ \W@{}%
+ \W@{ Xy-pic version \xyversion\space<\xydate>}%
+ \W@{ Copyright (c) 1991-1998 by Kristoffer H. Rose <krisrose@ens-lyon.fr>}%
+ \W@{ Xy-pic is free software: see the User\string's Guide for details.}%
+ \W@{}}
+\Xygreet@
+\expandafter\everyjob\expandafter{\the\everyjob\Xygreet@}
+
+\message{Loading kernel:}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ If you refer to \Xy-pic in your written text (please do~\smiley~)
+ then you can use the command ??c![\Xy]|-pic| to typeset the
+ ``??w![\Xy-pic]'' ??w![logo]. The ??w![version] of the kernel is
+ typeset by ??c![\xyversion] and the release date by ??c![\xydate] (as
+ found in the banner). By the way, the \Xy-pic "name"\footnote{No
+ description of a \TeX\ program is complete without an explanation of
+ its name.} originates from the fact that the first version was
+ little more than support for $(x,y)$ coordinates in a configurable
+ coordinate system where the main idea was that "all" operations could
+ be specified in a manner independent of the orientation of the
+ coordinates. This property has been maintained except that now the
+ package allows explicit absolute orientation as well.
+
+\DOCMODE(
+\xydef@\Xy{\leavevmode
+ \hbox{\kern-.1em X\kern-.3em\lower.4ex\hbox{Y\kern-.15em}}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Messages that start with ``|Xy-pic| ??c![Warning]'' are indications
+ that something needs your attention; an ``|Xy-pic| ??c![Error]'' will
+ stop \TeX\ because \Xy-pic does not know how to proceed.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ We use the input line number if available and rudimentary help in the
+ form of a reference to the manual if no specific help string is
+ given. ??c![\newlinechar] is set locally to |^^J| while writing such
+ that messages of several lines can be written.
+
+\DOCMODE(
+\message{messages;}
+
+\xywarnifdefined\thelineno@
+\ifx\inputlineno\undefined \edef\thelineno@{\string?}
+\else \def\thelineno@{\the\inputlineno}\fi
+\xydef@\xytracelineno@{ \string[\jobname:\thelineno@\string]}
+
+\xydef@\xywarning@#1{{\newlinechar=10 %
+ \W@{}\W@{Xy-pic Warning: #1\xytracelineno@.}\W@{}}}
+
+\xydef@\xyerror@#1#2{\if\inxy@\xy@{ERROR #1}{}\fi
+ {\def\2{#2}\newlinechar=10 %
+ \ifx\2\empty \errhelp{See the Xy-pic manual for further information.}%
+ \else \errhelp{#2}\fi
+ \errmessage{Xy-pic error: #1}}}
+\DOCMODE)
+
+ Finally one that I hope will never get expanded~\frowny
+
+\DOCMODE(
+\xydef@\xybug@#1{{\newlinechar=10 %
+ \errhelp{This is a bug in Xy-pic and should not happen!^^J%
+If it did then please send a bug report with the offending Xy-pic code^^J%
+to the author of Xy-pic, krisrose@ens-lyon.fr.}%
+ \errmessage{Xy-pic BUG: #1 -- notify krisrose@ens-lyon.fr.}}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Fonts}
+??=[env.fonts]
+
+ The \Xy-pic kernel implementation makes its drawings using five
+ specially designed ??w![fonts]:%
+%
+??w[dashes]??w[tips]??w[circles]??w[hooks]??w[squiggles]
+$$
+\begin{array}{\otherbar c\otherbar c\otherbar l\otherbar}
+\hline
+ \hbox{Font} & \hbox{Characters} & \hbox{Default}\\
+\hline
+ ??c![\xydashfont]& \hbox{dashes} & ??c![xydash10]\\
+ ??c![\xyatipfont]& \hbox{arrow tips, upper half} & ??c![xyatip10]\\
+ ??c![\xybtipfont]& \hbox{arrow tips, lower half} & ??c![xybtip10]\\
+ ??c![\xybsqlfont]& \hbox{quarter circles for\qquad} & ??c![xybsql10]\\
+ & \hbox{\qquad hooks and squiggles} &\\
+ ??c![\xycircfont]& \hbox{$1/8$ circle segments} & ??c![xycirc10]\\
+\hline
+\end{array}
+$$
+ The first four contain variations of characters in a large number of
+ directions, the last contains 1/8 circle segments.
+
+\paragraph*{Note:}
+ The default fonts are not part of the \Xy-pic kernel "specification":
+ they just set a standard for what drawing capabilities should at
+ least be required by an \Xy-pic implementation. Implementations
+ exploiting capabilitites of particular output devices are in use.
+ Hence the fonts are only loaded by \Xy-pic if the control sequence
+ names are undefined---this is used to preload them at different sizes
+ or prevent them from being loaded at all.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ To be more precise, \Xy-pic requires ??c![\xydashfont] to be a
+ "??w![semidirectional]" font as \MF\ will generate with the driver
+ file ??c![xyd2.mf]---this is very important because the "??w![italic
+ corrections]" of the characters in this particular font are used to
+ approximate trigonometric computations, so if you replace
+ ??c![\xydashfont] be sure to replace it with another semidirectional
+ font! Similarly, the three fonts ??c![\xyatipfont],
+ ??c![\xybtipfont], and ??c![\xybsqlfont] should be
+ "??w![directional]" as \MF\ will generate with the driver file
+ ??c![xyd.mf].
+
+ Finally, ??c![\xycircfont] should contain $1/8$ circle segments of
+ various radii as described in |xycirc10.mf|.
+
+ The following code loads the fonts "unless it was already loaded" and
+ defines some associated dimensions for ??c![\xydashfont] and
+ ??c![\xybsqlfont]: for each of these $f$ we define $f_\ell$ as the
+ length of a unit in the current direction (used when juxtaposing for
+ connections), $f_h$ as the height of the unit (used for several
+ parallel connections), and $f_w$ as the `line width' of the unit (to
+ know how to interface to rules).
+
+\DOCMODE(
+\message{fonts;}
+
+\xydef@\xyfont@#1{\ifx#1\undefined \DN@{\global\font#1}\expandafter\next@
+ \else \xywarning@{Using previously loaded \string#1\space font}\fi}
+
+\xyfont@\xydashfont=xydash10
+\xydef@\xydashl@{\fontdimen6\xydashfont}
+\xydef@\xydashh@{\fontdimen5\xydashfont}
+\xydef@\xydashw@{\fontdimen8\xydashfont}
+
+\xyfont@\xyatipfont=xyatip10
+\xyfont@\xybtipfont=xybtip10
+
+\xyfont@\xybsqlfont=xybsql10
+\xydef@\xybsqll@{\fontdimen6\xybsqlfont}
+\xydef@\xybsqlh@{\fontdimen5\xybsqlfont}
+\xydef@\xybsqlw@{\fontdimen8\xybsqlfont}
+
+\xyfont@\xycircfont=xycirc10
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Allocations}
+??=[env.alloc]??w[allocation]
+
+ One final thing that you must be aware of is that \Xy-pic allocates a
+ significant number of dimension registers and some counters, token
+ registers, and box registers, in order to represent the state and do
+ computations. The current kernel allocates 4~counters,
+ 28~dimensions, 2~box registers,4~token registers, 1~read channel, and
+ 1~write channel (when running under \LaTeX; some other formats use
+ slightly more because standard generic temporaries are used).
+ Options may allocate further registers (currently loading
+ "everything" loads 6~dimen-, 3~toks-, 1~box-, and 9~count-registers
+ in addition to the kernel ones).
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\DOCMODE(
+\message{allocations:}
+\DOCMODE)
+
+ See \S??[env.loading] for scratch register allocations.
+
+\paragraph*{Picture state:}
+
+ These realise the picture state as described in \S??[basics.state]:
+ $c$, $p$, the "base", and the picture size:
+
+\DOCMODE(
+\message{state,}
+
+\xynew@{dimen}\X@c
+\xynew@{dimen}\Y@c
+\xynew@{dimen}\U@c
+\xynew@{dimen}\D@c
+\xynew@{dimen}\L@c
+\xynew@{dimen}\R@c
+\xynew@{toks}\Edge@c
+
+\xynew@{dimen}\X@p
+\xynew@{dimen}\Y@p
+\xynew@{dimen}\U@p
+\xynew@{dimen}\D@p
+\xynew@{dimen}\L@p
+\xynew@{dimen}\R@p
+\xynew@{toks}\Edge@p
+
+\xynew@{dimen}\X@origin \X@origin=\z@
+\xynew@{dimen}\Y@origin \X@origin=\z@
+\xynew@{dimen}\X@xbase \X@xbase=1mm
+\xynew@{dimen}\Y@xbase \Y@xbase=\z@
+\xynew@{dimen}\X@ybase \X@ybase=\z@
+\xynew@{dimen}\Y@ybase \Y@ybase=1mm
+
+\xynew@{dimen}\X@min
+\xynew@{dimen}\Y@min
+\xynew@{dimen}\X@max
+\xynew@{dimen}\Y@max
+\DOCMODE)
+
+\paragraph*{Drop and connect:}
+
+ |\lastobjectbox@| stores the most recently dropped
+ object.??c[\lastobject]
+
+\DOCMODE(
+\xynew@{box}\lastobjectbox@
+\DOCMODE)
+
+ |\zerodotbox@|??c[\zerodot] is of zero size with a `dot' in the form
+ of a rule the width and height as the line width of the line font;
+ ??c![\zz@] is `almost-zero-check'.
+
+\DOCMODE(
+\xynew@{box}\zerodotbox@
+\setbox\zerodotbox@=\hbox{\dimen@=.5\xydashw@
+ \kern-\dimen@ \vrule width\xydashw@ height\dimen@ depth\dimen@}
+\wd\zerodotbox@=\z@ \ht\zerodotbox@=\z@ \dp\zerodotbox@=\z@
+
+\xynew@{dimen}\almostz@ \almostz@=50sp
+\xydef@\zz@#1{\ifdim#1<\z@-\fi#1<\almostz@\relax}
+
+\xynew@{if}\iftmp@
+\DOCMODE)
+
+\paragraph*{Direction state:}
+
+ The ??w![direction] state is rather complicated and described in
+ detail in~\S??[algo.direction].
+
+\DOCMODE(
+\message{direction,}
+
+\xynew@{dimen}\d@X
+\xynew@{dimen}\d@Y
+\xydef@\sd@X{}
+\xydef@\sd@Y{}
+
+\xynew@{count}\K@ \K@=1024
+\xynew@{count}\KK@ \KK@=32
+
+\xynew@{count}\Direction
+\xynew@{dimen}\K@dXdY
+\xynew@{dimen}\K@dYdX
+
+\xydef@\cosDirection{}
+\xydef@\sinDirection{}
+
+\xywarnifdefined\DirectionChar
+\xywarnifdefined\SemiDirectionChar
+\DOCMODE)
+
+\paragraph*{Miscellaneous:}
+
+ Finally some generic allocations used in the following:
+
+\DOCMODE(
+\xynew@{read}\xyread@ % for `safe input'
+\xynew@{write}\xywrite@ % for `saving' to .xyc file
+
+\xynew@{count}\csp@ % for `control stack pointer'
+\xynew@{dimen}\quotPTK@ % for `fractions'
+\DOCMODE)
+
+ The required temporaries are defined by |xyidioms.tex|.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Utility macros}
+??=[env.util]
+
+ Finally we define some utility macros.
+
+\DOCMODE(
+\message{utility macros;}
+\DOCMODE)
+
+\paragraph*{Simple queue:}
+??w[queue]
+
+ Just appending to the ??c![\toks@] list.
+
+\DOCMODE(
+\xydef@\addtotoks@#1{\toks@=\expandafter{\the\toks@#1}}
+\DOCMODE)
+
+\paragraph*{Safe input:}
+
+ Check that file is available before input. Tries the alternate
+ extension |.doc| in case the |.tex| file is not there. The second is
+ the lowest level function used when the desired files cannot be
+ preloaded and do not exist in |.doc| form.
+
+\DOCMODE(
+\xydef@\xyinputorelse@#1#2{%
+ \expandafter\let\expandafter\next@\csname#1loaded\endcsname
+ \ifx\next@\empty \else
+ \DN@{\xyinputorelse@@{#1}{\xyinputorelse@@{#1.doc}{#2}}}%
+ \fi \next@}
+
+\xydef@\xyinputorelse@@#1#2{\openin\xyread@=#1 %
+ \ifeof\xyread@ \DN@{#2}\else \DN@{\closein\xyread@\input#1 }\fi \next@}
+\DOCMODE)
+
+\paragraph*{Continuation stack:}
+
+ This is used to `??w![enter]' a new ??w![context] and `??w![leave]'
+ to the previous context. It works as a stack defining a control
+ sequence for each level, thus using a counter as the stack pointer.
+ Defines the following
+%
+\begin{defs}
+ |\csp@| & `Continuation Stack Pointer' \cr
+ |\enter@{|<code>|}| & Enter new block with <code> expanded as continuation\cr
+ |\nter@{|<code>|}| & Enter new block with<code> as continuation\cr
+ |\dontleave@| & Execute continuation without leaving block\cr
+ |\unenter@| & Leave block without executing its continuation\cr
+ |\leave@| & Leave block (execute its continuation)\cr
+\end{defs}
+
+ So |\enter@{}\leave@| is a noop and |\leave@| is the same as
+ |\dontleave@\unenter@|.
+
+\DOCMODE(
+\global\csp@=\z@
+
+\xydef@\enter@#1{\global\advance\csp@\@ne
+ \expandafter\xdef\csname cs@\number\csp@\endcsname{#1}\ignorespaces}
+
+\xydef@\nter@#1{\global\advance\csp@\@ne
+ \expandafter\gdef\csname cs@\number\csp@\endcsname{#1}\ignorespaces}
+
+\xydef@\dontleave@{\csname cs@\number\csp@\endcsname}
+
+\xydef@\unenter@{\global\advance\csp@\m@ne}
+
+\xydef@\leave@{\expandafter\unenter@\csname cs@\number\csp@\endcsname}
+\DOCMODE)
+
+\paragraph*{Fractions:}
+??w[fraction computation]
+
+ Below we often use a factor on the form of a quotient $A/B$. Here is
+ a hack to get it; it is not very precise but suffices for our needs.
+%
+\begin{defs}
+ |\quotient@| <cs> |{|$A$|}| |{|$B$|}| &
+ Defines <cs> to expand (immediately) to the factor corresponding to
+ $A/B$; $A$, $B$ must be dimensions where $\abs{A}\lt|\maxdimen|/|KK|$
+ and $\abs{B}\gt|KK|$
+\cr
+ |\quotient@@| <cs> |{|$A$|}| |{|$B$|}| &
+ Same, but uses $8|KK|$ for |KK|.
+\cr
+\end{defs}
+%
+ "Notes": (1) If |\c| is a count register, then |{1\c}| is a legal
+ dimension. (2) Really computes
+$$
+ \left((A*\abs{|KK|}) / (B/\abs{|KK|})\right) * \left(|1pt|/\abs{|K|}\right)
+$$
+ and then defines <cs> to expand to the resulting |pt| value. This
+ means that results are only reasonable for
+ $\abs{A}\ll|\maxdimen|/|KK|$ and $\abs{B}\gg|KK|$.
+
+\DOCMODE(
+\quotPTK@=\p@ \divide\quotPTK@\K@
+\xylet@\quotsign@@=\empty
+\xywarnifdefined\removePT@
+{\catcode`p=12 \catcode`t=12 \gdef\removePT@#1pt{#1}}
+
+\xydef@\quotient@#1#2#3{\A@=#2\relax \B@=#3\relax
+ \ifdim\A@<\z@\def\quotsign@@{-}\else\def\quotsign@@{+}\fi
+ \ifdim\quotsign@@\A@<15pt \multiply\A@\K@
+ \else\ifdim\quotsign@@\A@<511pt \multiply\A@\KK@
+ \advance\B@\ifdim\B@<\z@-\fi 16sp \divide\B@\KK@
+ \else
+ \advance\B@\ifdim\B@<\z@-\fi 512sp \divide\B@\K@
+ \fi\fi
+ \ifdim\ifdim\B@<\z@-\fi\B@<\quotPTK@ \xywarning@{division overflow}%
+ \else \advance\A@.5\B@ \divide\A@\B@ \fi
+ \multiply\A@\quotPTK@ \edef#1{\expandafter\removePT@\the\A@}}
+
+\xydef@\quotient@@#1#2#3{\A@=#2\relax \B@=#3\relax \multiply\A@\KK@
+ \advance\B@\ifdim\B@<\z@-\fi 128sp \divide\B@\KK@ \divide\B@ 8 %
+ \ifdim\B@=\z@\else \advance\A@.5\B@ \divide\A@\B@ \fi
+ \B@=.125\quotPTK@ \multiply\A@\B@ \edef#1{\expandafter\removePT@\the\A@}}
+\DOCMODE)
+
+\paragraph*{Loops:}
+
+ \Xy-pic uses its own |\loop@| to avoid interference with plain
+ ??c![\loop].
+
+\DOCMODE(
+\xydef@\loop@#1\repeat@{\def\body@{#1}\iterate@}\xylet@\repeat@=\fi
+\xydef@\iterate@{\body@\expandafter\iterate@\else\fi}
+\DOCMODE)
+
+\paragraph*{Execution:}
+
+ All ??w![execution] of \Xy-commands should be `indirect', \ie,
+ execute
+$$
+ |\xy@{|<source>|}{|<internal commands>|}|
+$$
+ where the <internal commands> directly do the desired operation(s).
+ This is used for tracing and can be used to separate parsing and
+ execution by changing |\xy@|; |\oxy@| is kept stable such that
+ |\let\xy@=\oxy@| will reestablish a sane state; it should only be
+ changed with |\change@oxy@| to make this easy to verify.
+
+\DOCMODE(
+\xydef@\xyinitial@#1#2{\DN@{#1}%
+ \xyerror@{command used out of context: \codeof\next@}{}}
+
+\xylet@\xy@=\xyinitial@
+\xylet@\oxy@=\xy@
+
+\xydef@\change@oxy@#1{\let\oxy@=#1\relax
+% \W@{*OXY@:=\meaning\oxy@}%
+}
+\DOCMODE)
+
+ This is also used to check whether an \Xy-picture is already
+ active; use as |\if\inxy@|\dots|\else|\dots|\fi|:
+
+\DOCMODE(
+\xydef@\inxy@{T\ifx\xy@\xyinitial@ F\else T\fi}
+\DOCMODE)
+
+ The final execution command is a trick used to put bits of the user's
+ input inside the |\next@| scratch macro "with the user's catcodes
+ intact": |\xy@@ix@{|\dots|}| is the same as
+ |\xy@@{\global\toks9={|\dots|}}| except for the category codes used
+ for the \dots.
+
+\DOCMODE(
+\xydef@\xyxy@@ix@{\begingroup
+ \xyuncatcodes\afterassignment\endgroup\global\toks9=}
+\DOCMODE)
+
+ This to save some tokens -- maybe not worth it:
+
+\DOCMODE(
+\xydef@\xy@@{\xy@{}}
+\DOCMODE)
+
+ Finally this to establish a sane state -- only use within a group!
+
+\DOCMODE(
+\xydef@\plainxy@{\let\xy@=\xyxy@ \change@oxy@\xy@ \let\xy@@ix@=\xyxy@@ix@}
+\DOCMODE)
+
+ \TODO: Clean up all uses of these such that <source> is always that
+ and only that. Define a method for `inner' \aka\ `implied' <source>
+ that doesn't really count in that it is a consequence of some other
+ source\dots
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section{Picture basics}
+??=[basics]
+
+ The basic concepts involved when constructing \Xy-pictures are
+ positions and objects, and how they combine to form the state used by
+ the graphic engine.
+
+ The general structure of an \Xy-picture is as follows:
+%
+\begin{defs1}
+%
+ ??c![\xy] <pos> <decor> ??c![\endxy] \cr
+%
+\end{defs1}
+\noindent\unskip
+%
+ builds a box with an \Xy-picture (\LaTeX\ users may substitute
+ |\begin{xy}| \dots\ |\end{xy}| if they prefer).
+
+ <pos> and <decor> are components of the special `graphic language'
+ which \Xy-pictures are specified in. We explain the language
+ components in general terms in this \S\ and in more depth in the
+ following \S\S.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The code for the |\xy|\dots|\endxy| command is presented last in this
+ section.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Positions}
+??=[basics.pos]
+
+ All "??w![positions]" may be written |<|$X$|,|$Y$|>| where ??w![$X$]
+ is the \TeX\ dimension distance "right" and ??w![$Y$] the distance
+ "up" from the "??w![zero position]" ??c![0] of the \Xy-picture (|0|
+ has coordinates |<0mm,0mm>|, of course). The zero position of the
+ \Xy-picture determines the box produced by the
+ ??c![\xy]\dots??c![\endxy] command together with the four parameters
+ ??w![$X_{\min}$], ??w![$X_{\max}$], ??w![$Y_{\min}$], and
+ ??w![$Y_{\max}$] set such that all the objects in the picture are
+ `contained' in the following rectangle:
+$$
+\xy.(-13,-12).(25,15)="b"*\frm{-}*@{o},
+ "b"+<2pc,-.8pc>*{|0|};"b"*{}**@{.},
+ "b"+L+<-2pc,-.8pc>*!UR\txt{\TeX\ reference point};"b"+L*@{*}**@{.},
+ "b"+0;
+ "b"+L **@{-} ?>*@{>} ?*++!U{X_{\min}},
+ "b"+R **@{-} ?>*@{>} ?(.7)*++!U{X_{\max}},
+ "b"+D **@{-} ?>*@{>} ?(.7)*++!L{Y_{\min}},
+ "b"+U **@{-} ?>*@{>} ?*++!L{Y_{\max}}
+\endxy
+$$
+ where the distances follow the ``up and right~$\gt0$'' principle,
+ \eg, the indicated \TeX\ reference point has coordinates
+ |<|$X_{\min}$|,0pt>| within the \Xy-picture. The zero position does
+ not have to be contained in the picture, but $X_{\min} \le X_{\max}
+ \land Y_{\min} \le Y_{\max}$ always holds. The possible positions
+ are described in detail in~\S??[pos].
+
+ When an \Xy-picture is entered in "??w![math mode]" then the
+ reference point becomes the ``vcenter'' instead, \ie, we use the
+ point |<|$X_{\min}$|,-\the\fontdimen22>| as reference point.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Objects}
+??=[basics.object]
+
+ The simplest form of putting things into the picture is to `drop' an
+ "??w![object]" at a position. An object is like a \TeX\ box except
+ that it has a general "??w![Edge]" around its reference point---in
+ particular this has the "??w![extents]" (\ie, it is always contained
+ within) the dimensions ??w![$L$], ??w![$R$], ??w![$U$], and ??w![$D$]
+ away from the reference point in each of the four directions left,
+ right, up, and down. Objects are encoded in \TeX\ boxes using the
+ convention that the ??w![\TeX\ reference point] of an object is at
+ its left edge, thus shifted |<|${-}L$|,0pt>| from the center---so a
+ \TeX\ box may be said to be a rectangular object with $L=|0pt|$.
+ Here is an example:
+$$
+ \let\objectstyle=\scriptstyle
+ \xy(0,0).(-10,-5).(15,8)*\frm{-}="box"*@{o}+0;
+ "box"+L*{}**@{.}?*{L},
+ "box"+R*{}**@{.}?*{R},
+ "box"+D*{}**@{.}?*{D},
+ "box"+U*{}**@{.}?*{U},
+ "box"+L+<-2pc,-.8pc>*!UR\hbox{\TeX\ reference point};
+ "box"+L*{\bullet}*{}**@{.},
+ \endxy
+$$
+ The object shown has a rectangle edge but others are available even
+ though the kernel only supports rectangle and circle edges. It is
+ also possible to use entire \Xy-pictures as objects with a rectangle
+ edge, |0| as the reference point, $L={-X_{\min}}$, $R={X_{\max}}$,
+ $D={-Y_{\min}}$, and $U={Y_{\max}}$. The commands for objects are
+ described in~\S??[object].
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Connections}
+??=[basics.connect]
+
+ Besides having the ability to be dropped at a position in a picture,
+ all objects may be used to "??w![connect]" the two current objects of
+ the state, \ie, $p$ and $c$. For most objects this is done by
+ `filling' the straight line between the centers with as many copies
+ as will fit between the objects:
+$$
+ \let\objectstyle=\scriptscriptstyle
+ \xy*=<12pt>[o]{p}="P"*\cir{} ; (60,15)*=<18pt,8pt>{c}="C"*\frm{-}**@{--}
+%
+ **\xybox{(0,0).(-3,-2).(2,3)*\frm{.}="box"*@{o}+0;
+ "box"+L**@{.}?*{L},
+ "box"+R**@{.}?*{R},
+ "box"+D**@{.}?*{D},
+ "box"+U**@{.}?*{U}},
+ \endxy
+$$
+ The ways the various objects connect are described along with the
+ objects.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Decorations}
+??=[basics.decor]
+
+ When the ??c![\xy] command reaches something that can not be
+ interpreted as a continuation of the position being read, then it is
+ expected to be a "??w![decoration]", \ie, in a restricted set of
+ \TeX\ commands which add to pictures. Most such commands are
+ provided by the various "user options" (\cf~\S??[option])---only a
+ few are provided within the kernel to facilitate programming of such
+ options (and user macros) as described in~\S??[decor].
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{The \Xy-pic state}
+??=[basics.state]
+
+ Finally we summarise the user-accessible parts of the
+ ??w![\Xy-picture state] of two positions together with the
+ last object associated with each: the "previous", ??w![$p$], is the
+ position |<|??w![$X_p$]|,| ??w![$Y_p$]|>| with the object
+ ??w![$L_p$], ??w![$R_p$], ??w![$D_p$], ??w![$U_p$], ??w!["Edge$_p$"],
+ and the "current", ??w![$c$], is the position |<|??w![$X_c$]|,|
+ ??w![$Y_c$]|>| with the object ??w![$L_c$], ??w![$R_c$], ??w![$D_c$],
+ ??w![$U_c$], ??w!["Edge$_c$"].
+
+ Furthermore, \Xy-pic has a configurable "??w![cartesian coordinate
+ system]" described by an "origin" position
+ |<|??w![$X_"origin"$]|,|??w![$Y_"origin"$]|>|
+ and two "base vectors" |<|??w![$X_"xbase"$]|,|??w![$Y_"xbase"$]|>|
+ and~|<|??w![$X_"ybase"$]|,|??w![$Y_"ybase"$]|>|
+ accessed by the usual notation using parentheses:
+$$
+\arraycolsep=.25em \begin{array}{rclll}
+ |(|x|,|y|)| & = & |<| & X_"origin" + x*X_"xbase" + y*X_"ybase" & |,| \\
+ & & & Y_"origin" + x*Y_"xbase" + y*Y_"ybase" & |>| \\
+\end{array}
+$$
+ This is explained in full when we show how to set the base in
+ note~??[base] of \S??[pos].
+
+ Finally typesetting a connection will setup a ``??w![placement
+ state]'' for referring to positions on the connection that is
+ accessed through a special |?| position construction; this is also
+ discussed in detail in \S??[pos].
+
+ The \Xy-pic "??w![state]" consists of all these parameters
+ together. They are initialised to zero except for
+ $X_"xbase"=Y_"ybase"=|1mm|$.
+
+\DOCMODE1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ The edges are not directly available but points on the edges may be
+ found using the different <corner> forms described in \S??[pos].
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ The edges are are available to the programmer as token lists; see
+ \S??[algo.edge] for details.
+
+\subparagraph*{Procedure:}
+
+ ??c![\xy]\ \dots\ ??c![\endxy] builds an object from an \Xy-pic <pos>
+ <decor> sequence as follows: (??_[xy1])~|\xy| starts the |\hbox| to
+ contain the \Xy-picture, (??_[xy2])~starts an inner box to be resized
+ appropriately later, sets |\xy@| to just execute immediately, and
+ makes a fresh scope for global internal names, and
+ (??_[xy3])~initialises the \Xy-pic state (setting the size to a
+ ridiculously large negative value), and finally passes control to
+ the <pos> parser.
+
+ Some care is taken to `lift' the diagram a bit to `vcenter' it when
+ in math mode, and ??c![\mathsurround] is set to zero to make changes
+ into math mode safe.
+
+\DOCMODE(
+\message{pictures: \string\xy,}
+
+\xydef@\xy{\ifmmode\expandafter\xymath@\else\expandafter\xynomath@\fi}
+\xydef@\xymath@{\hbox\bgroup \dimen@=\the\fontdimen22\textfont\tw@ \xyinside@}
+\xydef@\xynomath@{\hbox\bgroup \dimen@=\z@ \xyinside@}
+
+\xydef@\xyinside@{%
+ \saveXyStyle@ \aftergroup\xycheck@end %?*[xy1]
+ \setboxz@h\bgroup %?*[xy2]
+ \plainxy@
+ \X@c=\z@ \Y@c=\z@ \czeroEdge@ %?*[xy3]
+ \X@p=\z@ \Y@p=\z@ \U@p=\z@ \D@p=\z@ \L@p=\z@ \R@p=\z@ \Edge@p={\zeroEdge}%
+ \X@min=\hsize \X@max=-\hsize \Y@min=\hsize \Y@max=-\hsize
+ \mathsurround=\z@
+ \expandafter\POS\everyxy@@}
+
+\xydef@\czeroEdge@{\U@c=\z@ \D@c=\U@c \L@c=\U@c \R@c=\U@c \Edge@c={\zeroEdge}}
+
+\xydef@\xyxy@#1#2{#2}
+
+\xywarnifdefined\everyxy
+\expandafter\def\addEQ@\everyxy#1{\def\everyxy@@{#1}\ignorespaces}
+
+\xylet@\everyxy@@=\empty
+\DOCMODE)
+
+ When finished |\endxy| does a |\relax| to disable any parser still
+ active and (??_[endxy1])~resets the size of the generated box to zero
+ if no (unhidden) objects were inserted, and (??_[endxy2])~defines a
+ command to end both the temporary and the `proper' box and set its
+ size correctly---this uses ??c![\edef] to expand the required
+ dimensions used within the temporary box before leaving the two
+ groups (namely the temporary box and the `proper' box).
+
+\DOCMODE(
+\xydef@\endxy{\if\inxy@\else\xyerror@{Unexpected \string\endxy}{}\fi
+ \relax
+ \dimen@=\Y@max \advance\dimen@-\Y@min %?*[endxy1]
+ \ifdim\dimen@<\z@ \dimen@=\z@ \Y@min=\z@ \Y@max=\z@ \fi
+ \dimen@=\X@max \advance\dimen@-\X@min
+ \ifdim\dimen@<\z@ \dimen@=\z@ \X@min=\z@ \X@max=\z@ \fi
+ \edef\tmp@{\egroup %?*[endxy2]
+ \setboxz@h{\kern-\the\X@min\boxz@}%
+ \ht\z@=\the\Y@max \dp\z@=-\the\Y@min \wdz@=\the\dimen@
+ \noexpand\maybeunraise@ \raise\dimen@\boxz@
+ \noexpand\recoverXyStyle@ \egroup \noexpand\xy@end
+ \U@c=\the\Y@max \D@c=-\the\Y@min \L@c=-\the\X@min \R@c=\the\X@max}\tmp@}
+
+\xydef@\maybeunraise@{\if\inxy@\else \dimen@ii=\dp\z@
+ \ifdim\dimen@ii<\z@ \advance\dimen@\dimen@ii \fi\fi}
+\DOCMODE)
+
+ If an |\xy| is not properly closed by an |\endxy| then the error
+ message is produced. This happens if (a)~too many |\xy|s or (b)~too
+ many |\endxy|s or (c)~if there is the correct number of each but the
+ grouping becomes unbalanced due to a misplaced |}| or |\egroup|.
+
+\DOCMODE(
+\xydef@\xycheck@end{\xyFN@\xycheck@end@}
+\xydef@\xycheck@end@{\ifx\next\xy@end\DN@\xy@end{}\else\DN@{\xy@end}\fi\next@}
+\xydef@\xy@end{%
+ \xyerror@{An \string\xy\space environment is not closed correctly.}%
+ {I expected \string\endxy. You probably have an umatched {} grouping.}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ It is possible to insert an `initial' piece of <pos> <decor> at the
+ start of every \Xy-picture with the declaration
+%
+\begin{defs1}
+|\everyxy={| <text> |}|
+\end{defs1}
+\noindent\unskip
+%
+ This will act as if the <text> was typed literally right after each
+ ??c![\xy] command, parsing the actual contents as if it follows this
+ -- thus it is recommended that <text> has the form <pos>|,| such that
+ users can continue with <pos> <decor>.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section{Positions}
+??=[pos]
+
+\DOCMODE(
+\message{positions,}
+\DOCMODE)
+
+ A <pos>ition is a way of specifying locations as well as dropping
+ objects at them and decorating them---in fact any aspect of the
+ \Xy-pic state can be changed by a <pos> but most will just change the
+ coordinates and/or shape of~$c$.
+
+\begin{figure*}[tp]\SQUEEZE
+\vss
+\begin{syntax}
+ ??w![<pos>]
+ &\iss & <coord>
+ & $c\from<coord>$
+\cr
+ &\orr & <pos> ??c![+] <coord>
+ & $c \from <pos> + <coord>$??^[arithmetic]
+\cr
+ &\orr & <pos> ??c![-] <coord>
+ & $c \from <pos> - <coord>$??^[arithmetic]
+\cr
+ &\orr & <pos> ??c![!] <coord>
+ & $c\from<pos>$ then ??!^[skew] $c$ by <coord>
+\cr
+ &\orr & <pos> ??c![.] <coord>
+ & $c\from<pos>$ but also ??!^[covering] $<coord>$
+\cr
+ &\orr & <pos> ??c![,] <coord>
+ & $c\from<pos>$ then $c\from<coord>$
+\cr
+ &\orr & <pos> ??c![;] <coord>
+ & $c\from<pos>$, swap $p$ and $c$, $c\from<coord>$
+\cr
+ &\orr & <pos> ??c![:] <coord>
+ & $c\from<pos>$, set ??!^[base], $c\from<coord>$
+\cr
+ &\orr & <pos> ??c![::] <coord>
+ & $c\from<pos>$, $"ybase"\from c-"origin"$, $c\from<coord>$
+\cr
+ &\orr & <pos> ??c![*] <object>
+ & $c\from<pos>$, ??!^[drop] <object>
+\cr
+ &\orr & <pos> ??c![**] <object>
+ & $c\from<pos>$, ??!^[connect] using <object>
+\cr
+ &\orr & <pos> ??c![?] <place>
+ & $c\from<pos>$, $c\from\hbox{??!^[<place>]}$
+\cr
+ &\orr & <pos> ??c![@] <stacking>
+ & $c\from<pos>$, do <stacking>??^[stack]
+\cr
+ &\orr & <pos> ??c![=] <saving>
+ & $c\from<pos>$, do <saving>??^[save]
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<coord>]
+ &\iss & <vector>
+ & <pos> is <vector> with zero size
+\cr
+ &\orr & <empty> \orr\ ??c![c]
+ & reuse last $c$ (do nothing)
+\cr
+ &\orr & ??c![p]
+ & $p$
+\cr
+ &\orr & ??c![x] \orr\ ??c![y]
+ & ??!^[axis intersection] with $\overline{pc}$
+\cr
+ &\orr & ??c![s]<digit> \orr\ |s{|<number>|}|
+ & ??!^[stack] position <digit> or <number> below the top
+\cr
+ &\orr & |"|<id>|"|
+ & restore what was ??!^[saved] as <id> earlier
+\cr
+ &\orr & |{| <pos> <decor> |}|
+ & the $c$ resulting from interpreting the ??!^[group]
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<vector>]
+ &\iss & ??c![0]
+ & zero
+\cr
+ &\orr & |<| <dimen> |,| <dimen> |>|
+ & absolute??c[<>]
+\cr
+ &\orr & |<| <dimen> |>|
+ & absolute with equal dimensions
+\cr
+ &\orr & |(| <factor> |,| <factor> |)|
+ & in current ??!^[base]??c[()]
+\cr
+ &\orr & ??c![a] |(| <number> |)|
+ & ??!^[angle in current base]
+\cr
+ &\orr & <corner>
+ & from reference point to <corner> of $c$
+\cr
+ &\orr & <corner> |(| <factor> |)|
+ & The <corner> multiplied with <factor>
+\cr
+ &\orr & |/| <direction> <dimen> |/|
+ & vector <dimen> ??!^[in <direction>]??c[//]
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<corner>]
+ &\iss & ??c![L]\orr??c![R]\orr??c![D]\orr??c![U]
+ & ??!^[offset] to left, right, down, up side
+\cr
+ &\orr & ??c![CL]\orr??c![CR]\orr??c![CD]\orr??c![CU]\orr??c![C]
+ & ??!^[offset] to center of side, true center
+\cr
+ &\orr & ??c![LD]\orr??c![RD]\orr??c![LU]\orr??c![RU]
+ & ??!^[offset] to actual left/down, \dots\ corner
+\cr
+ &\orr & ??c![E]\orr??c![P]
+ & ??!^[offset] to nearest/proportional edge point to $p$
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<place>]
+ &\iss & ??c![<] <place> \orr\ ??c![>] <place>
+ & ??!^[shave] ??c![(0)]/??c![(1)] to edge of $p$/$c$, $f \from |0|/|1|$
+\cr
+ &\orr & |(| <factor> |)| <place>
+ & $f \from <factor>$
+\cr
+ &\orr & <slide>
+ & ??!^[pick place] and apply <slide>
+\cr
+ &\orr & ??c![!] |{|<pos>|}| <slide>
+ & ??!^[intercept] with line setup by <pos> and apply <slide>
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<slide>]
+ &\iss & |/| <dimen> |/|
+ & ??!^[slide] <dimen> further along connection
+\cr
+ &\orr & <empty>
+ & no slide
+\cr
+\end{syntax}
+\unskip\vskip-1em
+\caption{\protect<pos>itions.}??=[f.pos]
+\vfill
+\end{figure*}
+
+ All possible positions are shown in figure~??[f.pos] with explanatory
+ notes below.
+
+\begin{exercise}
+ Which of the positions |0|, |<0pt,0pt>|, |<0pt>|, |(0,0)|, and
+ |/0pt/| is different from the others?
+\answertext{In the default setup they are all denote the reference point of
+ the \Xy-picture but the cartesian coordinate <pos> ??c![(0,0)]
+ denotes the point "origo" that may be changed to something else using
+ the |:| operator.}
+\end{exercise}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Parsing:}
+
+ First the ??c![\POS] and ??c![\afterPOS] <decor>ations, and similar
+ ??c![\afterCOORD] and ??c![\afterVECTORorEMPTY] ones. They handle
+ parsing of <pos>, <coord>, and <vector>; parsing of <corner> and
+ <place> is presented along with note~??[corner] and~??[<place>]
+ explaining them.
+
+\DOCMODE(
+\xydef@\POS{\afterPOS{}}
+
+\xydef@\afterPOS#1{%
+ \DN@##1{\def\afterPOS@{\def\afterPOS@{##1}#1}}%
+ \expandafter\next@\expandafter{\afterPOS@}%
+ \afterCOORD{\xyFN@\POS@}}
+
+\xylet@\afterPOS@=\empty
+
+\xydef@\afterCOORD#1{%
+ \DN@##1{\def\afterCOORD@{\def\afterCOORD@{##1}#1}}%
+ \expandafter\next@\expandafter{\afterCOORD@}%
+ \afterVECTORorEMPTY{\xy@@\czeroEdge@ \afterCOORD@}{\xyFN@\COORD@}}
+
+\xylet@\afterCOORD@=\empty
+
+\xydef@\afterVECTORorEMPTY#1#2{%
+ \DN@##1{\def\afterVECTOR@{\def\afterVECTOR@{##1}%
+ \ifVECTORempty@\DN@{#2}\else\DN@{#1}\fi \next@}}%
+ \expandafter\next@\expandafter{\afterVECTOR@}%
+ \xyFN@\VECTOR@}
+
+\xynew@{if}\ifVECTORempty@
+\xylet@\afterVECTOR@=\empty
+\DOCMODE)
+
+ The ??c![\afterVECTORorEMPTY] command is special in that it takes two
+ arguments: the `continuation' if a <vector> was found and the
+ continuation if <empty> was found (this is not applicable to the
+ other two since <empty> is a legal <coord> and thus also a legal
+ <pos>).
+
+ Next we proceed with the actual parsing primitives: |\COORD@|,
+ |\POS@|, and |\VECTOR@|. These are bound to |\xyCOORD@|, |\xyPOS@|,
+ and |\xyVECTOR@| in order to be extendable, \eg, the |matrix| option
+ extends <coord> to support the |[|"row"|,| "column"|]| format by
+ redefining |\COORD@| to first test for this new format and then call
+ |\xyCOORD@|.
+
+ The parsing commands above are set up such that they all first call
+ the |\VECTOR@| command. <coord> and <pos> parsing then proceeds with
+ calling the |\COORD@| if there was no <vector>. <pos> parsing then
+ calls |\POS@| to continue the <pos> (in both cases).
+
+ First <vector>s:
+
+\DOCMODE(
+\xydef@\xyVECTOR@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\VECTOR@}%gobble spaces
+ \else \ifcat A\noexpand\next \let\next@=\VECTOR@letter
+ \else \let\next@=\VECTOR@other \fi\fi \next@}
+
+\xylet@\VECTOR@=\xyVECTOR@
+\DOCMODE)
+
+ All letters used for <vector>s are uppercase <corner>s except for |a|
+ used for angles (where the main code is in note~??[angle in current
+ base]); this is also where we introduce the auxiliary
+ |\notrelaxorelse@| that takes two control sequences and expands the
+ first unless it is relax in which case it expands the second:
+
+\DOCMODE(
+\def\notrelaxorelse@#1#2{\ifx#1\relax \expandafter#2\else\expandafter#1\fi}
+
+\xydef@\VECTOR@letter{%
+ \ifx a\next \expandafter\VECTOR@a \else \expandafter\CORNER@ \fi}
+
+\xydef@\VECTOR@a a(#1){\xy@{a(#1)}{\vfromcartesianangle@{#1}}%
+ \VECTORempty@false \afterVECTOR@}
+\DOCMODE)
+
+ The <corner> trick is to do nothing when there is nothing and
+ initialise both $X$ and $Y$ in all other cases.
+
+\DOCMODE(
+\xydef@\CORNER@{%
+ \xy@{}{\A@=-.5\L@c \advance\A@.5\R@c \B@=-.5\D@c \advance\B@.5\U@c
+ \let\nextii@=\zeroit@}%
+ \VECTORempty@true\CORNER@i}
+
+\xydef@\zeroit@#1{#1=\z@}
+
+\xydef@\CORNER@i{%
+ \ifx D\next \DN@ D{\xy@{D}{\Y@c=-\D@c \nextii@\X@c \B@=\Y@c}\CORNER@ii}%
+ \else\ifx U\next \DN@ U{\xy@{U}{\Y@c= \U@c \nextii@\X@c \B@=\Y@c}\CORNER@ii}%
+ \else\ifx L\next \DN@ L{\xy@{L}{\X@c=-\L@c \nextii@\Y@c \A@=\X@c}\CORNER@ii}%
+ \else\ifx R\next \DN@ R{\xy@{R}{\X@c= \R@c \nextii@\Y@c \A@=\X@c}\CORNER@ii}%
+ \else\ifx C\next \DN@ C{\xy@{C}{\X@c= \A@ \Y@c= \B@}\CORNER@ii}%
+ \else\ifx E\next \DN@ E{\xy@{E}{%
+ \A@=\X@c \B@=\Y@c \the\Edge@c\z@ \advance\X@c-\A@ \advance\Y@c-\B@}%
+ \CORNER@ii}%
+ \else\ifx P\next \DN@ P{\xy@{P}{%
+ \A@=\X@c \B@=\Y@c \the\Edge@c\thr@@ \advance\X@c-\A@ \advance\Y@c-\B@}%
+ \CORNER@ii}%
+ \else\ifx (\next %)
+ \DN@(##1){\xy@{(##1)}{\X@c=##1\X@c \Y@c=##1\Y@c}\afterVECTOR@}%
+ \else \let\next@=\afterVECTOR@
+ \fi\fi\fi\fi\fi\fi\fi\fi \next@}
+
+\xydef@\CORNER@ii{\xy@@{\let\nextii@=\eat@}%
+ \VECTORempty@false \xyFN@\CORNER@i}
+\DOCMODE)
+
+ |\CORNER@i| recognises the |(|<factor>|)| also; this does no harm as
+ it was never called if the first character was a |(|.
+
+ The remaining <vector> forms just set $X$ and $Y$.
+
+\DOCMODE(
+\xydef@\VECTOR@other{%
+ \addLT@\ifx \next
+ \addGT@{\addLT@\DN@##1}{\xy@{<##1>}{\vfromabsolute@{##1}}%
+ \VECTORempty@false\afterVECTOR@}%
+ \else\ifx (\next %)
+ \DN@({\xyFN@\VECTOR@other@open}%)
+ \else\ifx /\next %/
+ \DN@/##1/{\xy@@ix@{{##1}}%
+ \xy@{/##1/}{\expandafter\vfromslide@\the\toks9 }%
+ \VECTORempty@false\afterVECTOR@}%
+ \else\ifx 0\next
+ \DN@ 0{\xy@{0}{\X@c=\z@ \Y@c=\z@}\VECTORempty@false\afterVECTOR@}%
+ \else
+ \DN@{\VECTORempty@true\afterVECTOR@}%
+ \fi\fi\fi\fi \next@}
+\DOCMODE)
+
+ \HACK: escape out in case of the special |(*| introducer\dots picked
+ up by the <coord> parser, then.
+
+\DOCMODE(
+\xydef@\VECTOR@other@open{%
+ \ifx *\next \DN@{\VECTORempty@true \xyFN@\afterVECTOR@(}%)
+ \else
+ \DN@##1){\xy@{(##1)}{\vfromcartesian@{##1}}\VECTORempty@false\afterVECTOR@}%
+ \fi \next@}
+\DOCMODE)
+
+ Next <coord>inates that are not <vector>s:
+
+\DOCMODE(
+\xydef@\xyCOORD@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\COORD@}%gobble spaces
+ \else \ifcat A\noexpand\next \let\next@=\xyCOORD@letter
+ \else \let\next@=\xyCOORD@other \fi\fi \next@}
+
+\xylet@\COORD@=\xyCOORD@
+
+\xydef@\xyCOORD@letter{%
+ \ifx c\next
+ \DN@ c{\xy@{c}{}\afterCOORD@}%
+ \else\ifx p\next
+ \DN@ p{\xy@{p}\cfromp@ \afterCOORD@}%
+ \else\ifx x\next
+ \DN@ x{\xy@{x}{\R@c=\X@xbase \U@c=\Y@xbase \intersect@}\afterCOORD@}%
+ \else\ifx y\next
+ \DN@ y{\xy@{y}{\R@c=\X@ybase \U@c=\Y@ybase \intersect@}\afterCOORD@}%
+ \else\ifx s\next
+ \DN@ s##1{\xy@{s{##1}}{\cfroms@{##1}}\afterCOORD@}%
+ \else \let\next@=\afterCOORD@ \fi\fi\fi\fi\fi \next@}
+
+\xydef@\xyCOORD@other{%
+ \ifx "\next %"
+ \DN@"##1"{\xy@{"##1"}{\cfromid@{##1}}\afterCOORD@}%
+ \else\ifx \bgroup\next
+ \DN@##1{\xy@{{##1}}{\enter@{\pfromthep@\basefromthebase@}}%
+ \silencexy@ \POS##1\relax \unsilencexy@ \xy@@\leave@ \afterCOORD@}%
+ \else\ifx (\next %)
+ \DN@({\xyFN@\xyCOORD@other@open}%)
+ \else \let\next@=\afterCOORD@ \fi\fi\fi \next@}
+
+\xynew@{if}\ifsilentxy@
+
+\xydef@\silencexy@{%
+ \ifsilentxy@ \nter@{}%
+ \else \nter@{\silentxy@false \let\xy@=\unsilent@@xy@}
+ \silentxy@true \let\unsilent@@xy@=\xy@ \def\xy@##1##2{\unsilent@@xy@{}{##2}}%
+ \fi}
+
+\xydef@\unsilencexy@{\leave@}
+
+\xydef@\xyCOORD@other@open{%
+ \ifx *\next
+ \DN@*##1*){\xy@{(*}{\enter@{\pfromthep@\basefromthebase@}}%
+ \POS##1\relax \xy@{*)}\leave@ \afterCOORD@}%
+ \else \DN@{\xyFN@\afterCOORD@(}%)
+ \fi \next@}
+\DOCMODE)
+
+ Finally <pos> parsing after <coord> (possibly <vector>) is
+ interpreted:
+
+\DOCMODE(
+\xydef@\xyPOS@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\POS@}%gobble spaces
+ \else\addPLUS@\ifx \next
+ \addPLUS@\DN@{\xy@+{\enter@\cplusthec@}%
+ \afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
+ \else\addDASH@\ifx \next
+ \addDASH@\DN@{\xy@-{\enter@\cplusthec@}%
+ \afterCOORD{\xy@@{\X@c=-\X@c \Y@c=-\Y@c\leave@}\xyFN@\POS@}}%
+ \else\ifx !\next
+ \DN@ !{\xy@!{\enter@\cskewthec@}\afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
+ \else\addDOT@\ifx \next
+ \addDOT@\DN@{\xy@.{\enter@\cmergethec@}%
+ \afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
+ \else\ifx ,\next
+ \DN@ ,{\xy@,{\comma@@}\afterCOORD{\xyFN@\POS@}}%
+ \else\ifx ;\next
+ \DN@ ;{\xy@;{\swap@}\afterCOORD{\xyFN@\POS@}}%
+ \else\ifx :\next
+ \DN@ :{\xyFN@\POS@colon}%
+ \else\addEQ@\ifx \next
+ \addEQ@\DN@{\xyFN@\saveid@}%
+ \else\ifx *\next
+ \DN@ *{\xyFN@\POS@star}%
+ \else \ifx ?\next
+ \DN@?{\xy@?{}\afterPLACE{\xyFN@\POS@}}%
+ \else \addAT@\ifx \next
+ \addAT@\DN@{\xyFN@\STACK@}%
+ \else
+ \let\next@=\afterPOS@
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
+
+\xylet@\comma@@=\relax
+
+\xylet@\POS@=\xyPOS@
+\DOCMODE)
+
+ |\comma@@| is a hook used to change the operation of |,|, \eg, when
+ reading a stack setup where it means `push'.
+
+ The final functions serve only to distinguish between the single
+ character |:|/|*| and dual character |::|/|**| operators:
+
+\DOCMODE(
+\xydef@\POS@colon{\DNii@{\afterCOORD{\xyFN@\POS@}}%
+ \ifx :\next \xy@{::}{\setbase@@\X@c\Y@c}\DN@:{\nextii@}%
+ \else \xy@:{\setbase@\X@p\Y@p\X@c\Y@c}\let\next@=\nextii@ \fi
+ \next@}
+
+\xydef@\POS@star{%
+ \ifx *\next
+ \DN@*##1##{\nextii@{##1}}%
+ \DNii@##1##2{\xy@@ix@{{##1}{##2}}%
+ \xy@{**##1{##2}}{\expandafter\connect@\the\toks9 }\xyFN@\POS@}%
+ \else
+ \DN@##1##{\nextii@{##1}}%
+ \DNii@##1##2{\xy@@ix@{{##1}{##2}}%
+ \xy@{*##1{##2}}{\expandafter\drop@\the\toks9 }\xyFN@\POS@}%
+ \fi
+ \next@}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Simple actions:}
+
+ Next follow the simplest actions; the complicated ones are explained
+ along with their notes below.
+
+\DOCMODE(
+\xydef@\cfromp@{\X@c=\X@p \Y@c=\Y@p \U@c=\U@p \D@c=\D@p \L@c=\L@p \R@c=\R@p
+ \Edge@c=\expandafter{\the\Edge@p}}
+
+\xydef@\pfromc@{\X@p=\X@c \Y@p=\Y@c \U@p=\U@c \D@p=\D@c \L@p=\L@c \R@p=\R@c
+ \Edge@p=\expandafter{\the\Edge@c}}
+
+\xydef@\swapdimen@#1#2{\dimen@=#1\relax #1=#2\relax #2=\dimen@}
+
+\xynew@{toks}\swaptoks@@
+
+\xydef@\swap@{\swapdimen@\X@c\X@p \swapdimen@\Y@c\Y@p
+ \swapdimen@\U@c\U@p\swapdimen@\D@c\D@p \swapdimen@\L@c\L@p\swapdimen@\R@c\R@p
+ \swaptoks@@=\Edge@c \Edge@c=\Edge@p \Edge@p=\swaptoks@@}
+\DOCMODE)
+
+ Next the parsing of coordinate pairs in |<>|:
+
+\DOCMODE(
+\xydef@\vfromabsolute@#1{\vfromabsolute@@#1,@}
+
+\xydef@\vfromabsolute@@#1,#2@{\X@c=#1\relax
+ \DN@{#2}\ifx\next@\empty \Y@c=\X@c
+ \else \DN@##1,{\Y@c=##1}\next@#2\relax \fi
+% \advance\X@c 1sp \advance\Y@c 1sp %HACK
+}
+\DOCMODE)
+
+ The next group of commands are used to store on the control stack
+ with the |\enter@| command, so they "expand" to something useful:
+
+\DOCMODE(
+\xydef@\cfromthec@{\X@c=\the\X@c \Y@c=\the\Y@c
+ \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
+ \Edge@c={\expandafter\noexpand\the\Edge@c}}
+
+\xydef@\cfromthep@{\X@c=\the\X@p \Y@c=\the\Y@p
+ \U@c=\the\U@p \D@c=\the\D@p \L@c=\the\L@p \R@c=\the\R@p
+ \Edge@c={\expandafter\noexpand\the\Edge@p}}
+
+\xydef@\pfromthep@{\X@p=\the\X@p \Y@p=\the\Y@p
+ \U@p=\the\U@p \D@p=\the\D@p \L@p=\the\L@p \R@p=\the\R@p
+ \Edge@p={\expandafter\noexpand\the\Edge@p}}
+
+\xydef@\pfromthec@{\X@p=\the\X@c \Y@p=\the\Y@c
+ \U@p=\the\U@c \D@p=\the\D@c \L@p=\the\L@c \R@p=\the\R@c
+ \Edge@p={\expandafter\noexpand\the\Edge@c}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{notes}
+
+\note??=[arithmetic]
+%
+ When doing arithmetic with |+| and |-| then the resulting current
+ object inherits the size of the <coord>, \ie, the right
+ argument---this will be zero if the <coord> is a <vector>.
+
+\begin{exercise}
+ How do you set $c$ to an object the same size as the saved object
+ |"ob"| but moved |<|$X$|,|$Y$|>|?
+\answertext{Use the <pos>ition |<|$X$|,|$Y$|>+"ob"|.}
+\end{exercise}
+
+\DOCMODE(
+\xydef@\cplusthec@{\advance\X@c\the\X@c \advance\Y@c\the\Y@c}
+\DOCMODE)
+
+\note??=[skew]
+%
+ "Skewing" using |!| just means that the reference point of $c$ is
+ moved with as little change to the shape of the object as possible,
+ \ie, the edge of~$c$ will remain in the same location except that it
+ will grow larger to avoid moving the reference point outside~$c$.
+%
+\begin{exercise}
+ What does the <pos> \dots|!R-L| do?
+\answertext{It first sets $c$ according to ``\dots''. Then it changes $c$ to
+ the point right of $c$ at the same distance from the right edge of
+ $c$ as its width, $w$, \ie,
+$$
+\xy
+ *+\hbox{The \dots}="it" *\frm{_\}}!D-U*{w}
+ ,{"it"+RD}.{"it"+RU}.{"it"!R-L*{\times}+0}!C *\frm{_\}}!D-U*{w}
+\endxy
+$$}
+\end{exercise}
+%
+ \BUG: The result of |!| is always a rectangle currently.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Procedure:}
+
+ |!| moves the center of $c$ by a temporarily read $c'$ and then
+ readjusts the extents:
+$$
+\begin{array}{rclcl}
+ D_c &:=& Y'+Y_c - \min(Y'-D', Y'+Y_c) &=& \max(Y_c+D',0)\\
+ U_c &:=& \max(Y'+U', Y'+Y_c) - (Y'+Y_c) &=& \max(U'-Y_c,0)\\
+ Y_c &:=& Y'+Y_c\\
+ L_c &:=& X'+X_c - \min(X'-L', X'+X_c) &=& \max(X_c+L',0)\\
+ R_c &:=& \max(X'+R', X'+X_c) - (X'+X_c) &=& \max(R'-X_c,0)\\
+ X_c &:=& X'+X_c\\
+\end{array}
+$$
+
+\DOCMODE(
+\xydef@\cskewthec@{%
+ \noexpand\cskew@{\the\Y@c}{\the\X@c}{\the\D@c}{\the\U@c}{\the\L@c}{\the\R@c}}
+
+\xydef@\cskew@#1#2#3#4#5#6{%
+ \D@c=#3\advance\D@c \Y@c \ifdim\D@c<\z@ \D@c=\z@ \fi
+ \U@c=#4\advance\U@c-\Y@c \ifdim\U@c<\z@ \U@c=\z@ \fi
+ \advance\Y@c#1%
+ \L@c=#5\advance\L@c \X@c \ifdim\L@c<\z@ \L@c=\z@ \fi
+ \R@c=#6\advance\R@c-\X@c \ifdim\R@c<\z@ \R@c=\z@ \fi
+ \advance\X@c#2%
+ \Edge@c={\rectangleEdge}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[covering]
+%
+ A <pos> "covers" another if it is a rectangle with size sufficiently
+ large that the other is ``underneath''. The |.| operation
+ ``extends'' a <pos> to cover an additional one---the reference point
+ of $c$ is not moved but the shape is changed to a rectangle such that
+ the entire $p$ object is covered.
+
+ \BUG: non-rectangular objects are first ``translated'' into a
+ rectangle by using a diagonal through the object as the diagonal of
+ the rectangle.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Procedure:}
+
+ |.| takes a temporary object $c'$ and adjusts the extents of $c$ such
+ that it is covered.
+$$
+\begin{array}{rclcl}
+ L_c &:=& X' - \min(X'-L_c, X-L) &=& \max(L_c, A+L)\\
+ R_c &:=& \max(X'+R_c, X+R) - X' &=& \max(R_c, -A+R)\\
+ D_c &:=& Y' - \min(Y'-D_c, Y-D) &=& \max(D_c, B+D)\\
+ U_c &:=& \max(Y'+U_c, Y+U) - Y' &=& \max(U_c, -B+U)\\
+\end{array}
+$$
+ with $|<|A|,|B|>| = |<|X'-X|,|Y'-Y|>|$. First method~2 of the object
+ is used to convert it into a rectangle.
+
+\DOCMODE(
+\xydef@\cmergethec@{%
+ \noexpand\cmerge@{\the\Y@c}{\the\X@c}{\the\D@c}{\the\U@c}{\the\L@c}{\the\R@c}}
+
+\xydef@\cmerge@#1#2#3#4#5#6{\the\Edge@c4%
+ \A@=#2\advance\A@-\X@c \B@=#1\advance\B@-\Y@c
+ \dimen@=#5\advance\L@c \A@ \ifdim\L@c<\dimen@ \L@c=\dimen@ \fi
+ \dimen@=#6\advance\R@c-\A@ \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
+ \dimen@=#3\advance\D@c \B@ \ifdim\D@c<\dimen@ \D@c=\dimen@ \fi
+ \dimen@=#4\advance\U@c-\B@ \ifdim\U@c<\dimen@ \U@c=\dimen@ \fi
+ \advance\X@c\A@ \advance\Y@c\B@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[base]
+%
+ The operations |:| and |::| set the "base" used for <coord>inates
+ having the form $|(|x|,|y|)|$. The |:| operation will set
+ |<|$X_"origin"$|,| $Y_"origin"$|>| to~$p$, |<|$X_"xbase"$|,|
+ $Y_"xbase"$|>| to $c-"origin"$, and~|<|$X_"ybase"$|,| $Y_"ybase"$|>|
+ to |<|${-}Y_"xbase"$|,| $X_"xbase"$|>| (this ensures that it is a
+ usual square coordinate system). The |::| operation may then be used
+ afterwards to make nonsqare bases by just setting "ybase" to
+ $c-"origin"$. Here are two examples: firstly |0;<1cm,0cm>:| sets the
+ coordinate system
+$$
+\xy
+ <0cm,0cm>*@{o};<1cm,0cm>:
+ (0,0);{(1,0)**@{-}?>*@{>}},{(0,1)**@{-}?>*@{>}},
+ (0,0)*+!UR\hbox{\small"origin"},
+ (1,0)*+!LC\hbox{\small"xbase"},
+ (0,1)*!D\hbox{\small"ybase"},
+ (1,1)*{*}*++!CL{|(1,1)|}+0;(0,1)**@{.},(1,0)**@{.}
+\endxy
+$$
+ while~|<1cm,.5cm>;<2cm,1.5cm>:<1cm,1cm>::|\hfil defines
+$$
+\xy
+ <0cm,0cm>*@{o}, <1cm,.5cm>;<2cm,1.5cm>:
+%
+ (0,0);{(0,1)**@{--}?(1)*@{>}},
+ (0,1)*+!R\txt\small{"ybase"\\before\\{\tt::}},
+%
+ <1cm,1cm>::
+ (0,0);{(1,0)**@{-}?(1)*@{>}},{(0,1)**@{-}?(1)*@{>}},
+ (0,0)*+!LU\txt\small{"origin"},
+ (1,0)*+!LC\txt\small{"xbase"},
+ (0,1)*!D\txt\small{"ybase"},
+ (1,1)*{*}*++!CL{|(1,1)|}+0;(0,1)**@{.},(1,0)**@{.}
+\endxy
+$$
+ where in each case the $\circ$ is at |0|, the base vectors have been
+ drawn and the $\times$ is at |(1,1)|.
+
+ When working with cartesian coordinates these three special <factor>s
+ are particularly useful:
+%
+\begin{defs}
+ ??c![\halfroottwo] & $0.70710678\approx{1\over2}\sqrt2$ \cr
+ ??c![\partroottwo] & $0.29289322\approx 1-{1\over2}\sqrt2$ \cr
+ ??c![\halfrootthree] & $0.86602540\approx{1\over2}\sqrt3$ \cr
+\end{defs}
+\noindent\unskip
+%
+ More can be defined using |\def| (or |\newcommand| in \LaTeX).
+
+\DOCMODE(
+\xydef@\halfroottwo{.70710678}
+\xydef@\partroottwo{.29289322}
+\xydef@\halfrootthree{.8660254}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Procedure:}
+
+ The code chosen by the parsing is very simple; the only tricky bit is
+ to ensure that |\basefromthebase@| always expands to set the current
+ base.
+
+\DOCMODE(
+\xydef@\vfromcartesian@#1{\vfromcartesian@@#1@}
+
+\xydef@\vfromcartesian@@#1,#2@{%
+ \X@c=\X@origin \advance\X@c#1\X@xbase \advance\X@c#2\X@ybase
+ \Y@c=\Y@origin \advance\Y@c#1\Y@xbase \advance\Y@c#2\Y@ybase}
+
+\xydef@\setbase@#1#2#3#4{%
+ \X@origin=#1\relax \Y@origin=#2\relax
+ \X@xbase=#3\relax \advance\X@xbase-\X@origin
+ \Y@xbase=#4\relax \advance\Y@xbase-\Y@origin
+ \X@ybase=-\Y@xbase \Y@ybase=\X@xbase}
+
+\xydef@\setbase@@#1#2{%
+ \X@ybase=#1\relax \advance\X@ybase-\X@origin
+ \Y@ybase=#2\relax \advance\Y@ybase-\Y@origin}
+
+\xydef@\basefromthebase@{\X@origin=\the\X@origin \Y@origin=\the\Y@origin
+ \X@xbase=\the\X@xbase \Y@xbase=\the\Y@xbase
+ \X@ybase=\the\X@ybase \Y@ybase=\the\Y@ybase}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[angle in current base]
+%
+ An "angle" $\alpha$ in \Xy-pic is the same as the coordinate pair
+ $|(|\cos\alpha|,|\sin\alpha|)|$ where $\alpha$ must be an integer
+ interpreted as a number of degrees. Thus the <vector> |a(0)| is the
+ same as |(1,0)| and |a(90)| as |(0,1)|, etc.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The translation involves several steps: (??_[ang1])~Normalise the
+ argument to be within $[0^\circ:360^\circ[$. (??_[ang2])~Flip angle
+ around $x$-axis and then $y$-axis to ensure it is in the first
+ quadrant, \ie, within $[0^\circ:90^\circ[$. (??_[ang3])~Flip around
+ diagonal to ensure angle within $[0^\circ:45^\circ[$.
+ (??_[ang4])~Find values $\phi\le\alpha\lt\psi$ from the table in
+ figure~??[f.angles] (using recursive table lookup -- at most 3 tests
+ needed). (??_[ang5])~build vector $(x,y)$ interpolated between the
+ sin/cos values for $\phi$ and $\psi$ using the formula
+$$
+ \left(\cos\phi + k(\cos\psi-\cos\phi) ,
+ \sin\phi + k(\sin\psi-\sin\phi) \right) ~,
+ \quad\hbox{where}~k = \frac{\alpha-\phi}{\psi-\phi}
+$$
+ (??_[angx])~build the chosen vector.
+
+\begin{figure*}[tp]
+ \noindent Vectors for angles in $[0^\circ:45^\circ]$: contains all
+ angles required to typeset fractions up to $\frac{n}{12}\times2\pi$,
+ $\frac1{16}\times2\pi$, and $\frac1{24}\times2\pi$ exactly, and two
+ extra low ones to ensure that all gaps are less than $5^\circ$ and
+ the precision of all sine/cosines better than $\frac1{1000}$.
+ $$
+ \small
+ \def"{\vphantom{\frac()}\frac}
+ \begin{array}{\otherbar l\otherbar r@{~}l\otherbar c\otherbar c\otherbar}
+ \hline
+ ~\alpha & (\cos\alpha, & \sin\alpha) & \hbox{fractions of $2\pi$} &
+ \hbox{flipped fractions of $2\pi$} \\
+ \hline
+ ~0&(1,&0) & "0{n}
+ & "12,"14,"24,"28,"34,"36,"3{12},"48,"5{10},"68,"6{12},"9{12} \\
+ ~4.090909 & (.99677570, & .08023846) & - & - \\
+ ~6 & (.99452190, & .10452846) & - & - \\
+ ~8.181818 & (.98982144, & .14231484) & "3{11} & "8{11} \\
+ 10 & (.98480775, & .17364818) & "79 & "29 \\
+ 12.857143 & (.97492791, & .22252093) & "27 & "57 \\
+ 15 & (.96592583, & .25881905) & "1{24} & \\
+ 16.363636 & (.95949297, & .28173256) & "6{11} & "5{11} \\
+ 18 & (.95105652, & .30901699) & "3{10},"45,"8{10} & "15,"2{10},"7{10} \\
+ 20 & (.93969262, & .34202014) & "59 & "49 \\
+ 22.5 & (.92387953, & .38268343) & "1{16} & \\
+ 24.545455 & (.90963200, & .41541501) & "9{11} & "2{11} \\
+ 25.714286 & (.90096887, & .43388374) & "47 & "37 \\
+ 30 & (.86602540, & .5) & "13,"1{12},"26,"39,"4{12},"56,"7{12},"{10}{12}
+ & "16,"23,"2{12},"46,"5{12},"69,"8{12},"{11}{12} \\
+ 32.727273 & (.84125353, & .54064082) & "1{11} & "{10}{11} \\
+ 36 & (.80901699, & .58778525) & "1{10},"35,"6{10} & "25,"4{10},"9{10} \\
+ 38.571429 & (.78183148, & .62348980) & "67 & "17 \\
+ 40 & (.76604444, & .64278761) & "19 & "89 \\
+ 40.909091 & (.75574957, & .65486073) & "4{11} & "7{11} \\
+ 45 & (.70710678, & .70710678) & "18,"38,"58,"78 & - \\
+ \hline
+ \end{array}
+ $$
+ \caption{Computing angle vectors}
+ ??=[f.angles]
+\end{figure*}
+
+\DOCMODE(
+\xydef@\vfromcartesianangle@#1{\enter@\basefromthebase@ \R@=#1\p@
+ \B@=360\p@ %?*[ang1]
+ \loop@ \ifdim\R@<\z@ \advance\R@\B@ \repeat@
+ \loop@ \ifdim\R@>\B@ \advance\R@-\B@ \repeat@
+ \ifdim\R@<.5\B@\else \R@=-\R@ \advance\R@\B@ %?*[ang2]
+ \X@ybase=-\X@ybase \Y@ybase=-\Y@ybase \fi
+ \B@=180\p@
+ \ifdim\R@<.5\B@\else \R@=-\R@ \advance\R@\B@
+ \X@xbase=-\X@xbase \Y@xbase=-\Y@xbase \fi
+ \B@=90\p@ %?*[ang3]
+ \ifdim\R@<.5\B@ \let\nextiii@=\literal@
+ \else \R@=-\R@ \advance\R@\B@ \def\nextiii@##1,##2@{##2,##1@}\fi
+ \dimen@=\z@ \DN@{1,0@}% %?*[ang4]
+ \dimen@ii=45\p@ \DNii@{.70710678,.70710678@}%
+ \chooseangleinterval@
+ {\chooseangleinterval@
+ {\chooseangleinterval@
+ {\chooseangleinterval@
+ {\chooseangleinterval@
+ {}%
+ {4.090909}{.99677570,.08023846@}%
+ {}}%
+ {6}{.99452190,.10452846@}%
+ {\chooseangleinterval@
+ {}%
+ {8.181818}{.98982144,.14231484@}%
+ {}}}%
+ {10}{.98480775,.17364818@}%
+ {\chooseangleinterval@
+ {}%
+ {12.857143}{.97492791,.22252093@}%
+ {}}}%
+ {15}{.96592583,.25881905@}%
+ {\chooseangleinterval@
+ {\chooseangleinterval@
+ {}%
+ {16.363636}{.95949297,.28173256@}%
+ {}}%
+ {18}{.95105652,.30901699@}%
+ {\chooseangleinterval@
+ {}%
+ {20}{.93969262,.34202014@}%
+ {}}}}%
+ {22.5}{.92387953,.38268343@}%
+ {\chooseangleinterval@
+ {\chooseangleinterval@
+ {\chooseangleinterval@
+ {}%
+ {24.545455}{.90963200,.41541501@}%
+ {}}%
+ {25.714286}{.90096887,.43388374@}%
+ {}}%
+ {30}{.86602540,.5@}%
+ {\chooseangleinterval@
+ {\chooseangleinterval@
+ {}%
+ {32.727273}{.84125353,.54064082@}%
+ {}}%
+ {36}{.80901699,.58778525@}%
+ {\chooseangleinterval@
+ {\chooseangleinterval@
+ {}%
+ {38.571429}{.78183148,.62348980@}%
+ {}}%
+ {40.909091}{.75574957,.65486073@}%
+ {\chooseangleinterval@
+ {}%
+ {40}{.76604444,.64278761@}%
+ {}}}}}%
+ \A@=\R@ \advance\A@-\dimen@ %?*[ang5]
+ \ifdim\ifdim\A@<\z@-\fi\A@<.01\p@ \edef\next@{\expandafter\nextiii@\next@}%
+ \else \B@=\dimen@ii \advance\B@-\R@
+ \ifdim\A@<\B@ \dimen@=\toradians@\A@
+ \edef\next@{\next@ \expandafter\removePT@\the\dimen@ @}%
+ \else \dimen@=-\toradians@\B@
+ \edef\next@{\nextii@ \expandafter\removePT@\the\dimen@ @}%
+ \fi
+ \expandafter\interpolatepoint@\next@
+ \edef\next@{\expandafter\nextiii@\next@}%
+ \fi
+ \expandafter\vfromcartesian@@\next@ %?*[angx]
+ \leave@}
+
+\xydef@\chooseangleinterval@#1#2#3#4{%
+ \B@=#2\p@ \def\next{#3}%
+ \ifdim\R@<\B@ \dimen@ii=\B@ \let\nextii@=\next #1%
+ \else \dimen@=\B@ \let\next@=\next \ifdim\B@<\R@ #4\fi\fi}
+
+\xydef@\interpolateinterval@#1,#2@#3,#4@{%
+ \A@=#1\p@ \dimen@=#3\p@ \advance\dimen@-\A@ \advance\A@\next\dimen@
+ \B@=#2\p@ \dimen@=#4\p@ \advance\dimen@-\B@ \advance\B@\next\dimen@
+ \edef\next@{\expandafter\removePT@\the\A@,\expandafter\removePT@\the\B@ @}}
+
+\xydef@\toradians@{0.01745329}
+
+\xydef@\interpolatepoint@#1,#2@#3@{%
+ \A@=#1\p@ \dimen@ii=#3\A@ \dimen@ii=-.5\dimen@ii \advance\A@#3\dimen@ii
+ \dimen@=-#2\p@ \advance\A@#3\dimen@
+ \B@=#2\p@ \dimen@ii=#3\B@ \dimen@ii=-.5\dimen@ii \advance\B@#3\dimen@ii
+ \dimen@=#1\p@ \advance\B@#3\dimen@
+ \edef\next@{\expandafter\removePT@\the\A@,\expandafter\removePT@\the\B@ @}}
+\DOCMODE)
+
+ Figure~\ref{f.alldirections} shows all directions.
+
+\begin{figure}[ht]
+\begin{center}\leavevmode
+\def\a#1(#2){\save"o";a(#2)**@{-}*+__!P{\scriptscriptstyle#1#2}\restore}
+\def\ad(#1){\save"o",a(#1)*{\cdot}\restore}
+%
+\newcount\n \newcount\m
+\xy (50,0):0*{\kern.7pt\scriptstyle\ddot\smile}*[o]\cir<4pt>{}="o"\relax
+\n=0 %
+\loop
+ \expandafter\a\expandafter(\the\n)%
+ \advance\n1 \expandafter\ad\expandafter(\the\n)%
+ \advance\n1 \expandafter\ad\expandafter(\the\n)%
+ \advance\n1 \expandafter\ad\expandafter(\the\n)%
+ \advance\n1 \expandafter\ad\expandafter(\the\n)%
+ \advance\n1 \ifnum360>\n\relax \repeat
+\a~, (360)%
+\endxy
+\end{center}
+\caption{All directions.}\label{f.alldirections}
+\end{figure}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[drop]
+%
+ To "drop" an <object> at $c$ with |*| means to actually physically
+ typeset it in the picture with reference position at $c$---how this
+ is done depends on the <object> in question and is described in
+ detail in~\S??[object]. The intuition with a drop is that it
+ typesets something at $|<|X_c|,|Y_c|>|$ and sets the edge of $c$
+ accordingly.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subparagraph*{Procedure:}
+
+ (??_[drop1])~sets up the direction to allow for directionals and
+ builds the requested <object> in the (global) |\lastobjectbox@| box,
+ (??_[drop2])~adjust the picture size unless it is a hidden object,
+ setting $|\dimen@| = X_c-L_c$, and (??_[drop3])~drop the object in
+ the picture at the right point by setting |box0| and using the
+ |\Drop@@| method.
+
+\DOCMODE(
+\xydef@\drop@#1#2{%*[drop1]
+ \global\setbox\lastobjectbox@=\object#1{#2}%
+ \ifHidden@ \dimen@=\X@c \advance\dimen@-\L@c \else %?*[drop2]
+ \dimen@=\Y@c \advance\dimen@ \U@c \ifdim\Y@max<\dimen@ \Y@max=\dimen@ \fi
+ \dimen@=\Y@c \advance\dimen@-\D@c \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi
+ \dimen@=\X@c \advance\dimen@ \R@c \ifdim\X@max<\dimen@ \X@max=\dimen@ \fi
+ \dimen@=\X@c \advance\dimen@-\L@c \ifdim\dimen@<\X@min \X@min=\dimen@ \fi
+ \fi
+ \ifInvisible@\else %?*[drop3]
+ \setboxz@h{\kern\dimen@ \raise\Y@c\box\lastobjectbox@}%
+ \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ {\Drop@@}\fi}
+\DOCMODE)
+
+ \NOTE: All typesetting into a picture should use or emulate |\drop@|!
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[connect]
+%
+ The "connect" operation |**| will first compute a number of internal
+ parameters describing the direction from~$p$ to~$c$ and then typesets
+ a connection filled with copies of the <object> as illustrated
+ in~\S??[basics.connect]. The exact details of the connection depend
+ on the actual <object> and are described in general in~\S??[object].
+ The intuition with a connection is that it typesets something
+ connecting $p$ and $c$ and sets the |?| <pos> operator up accordingly.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subparagraph*{Procedure:}
+
+ Set up the direction to allow for directional objects, then save
+ $c$, build the <object> in |\lastobjectbox@|, restore $c$, and perform
+ the |\Connect@@| method to connect using |\lastobjectbox@|.
+
+\DOCMODE(
+\xydef@\connect@#1#2{\setupDirection@ \enter@{\cfromthec@}%
+ \global\setbox\lastobjectbox@=\object#1{#2}\leave@
+ \Connect@@}
+
+\xydef@\preconnect@#1#2{\setupDirection@ \enter@{\cfromthec@}%
+ \global\setbox\lastobjectbox@=\object#1{#2}\leave@ \connectStore@
+ \ifInvisible@ \Connect@@ \else \Invisible@true\Connect@@\Invisible@false \fi}
+\DOCMODE)
+
+ The |\preconnect| command is for internal use by arrow \dots\ it
+ makes use of the following:
+
+\DOCMODE(
+\xynew@{box}\connectobjectbox@@
+\xylet@\connectDrop@@=\empty
+\xylet@\connectpreXY@style@=\empty
+\xylet@\connectpostXY@style@=\empty
+
+\xylet@\connectRest@@=\empty
+
+\xydef@\connectStore@{%
+ \global\setbox\connectobjectbox@@=\copy\lastobjectbox@
+ \let\connectDrop@@=\Drop@@
+ \let\connectpreXY@style@ =\preXY@style@
+ \let\connectpostXY@style@=\postXY@style@
+ \xdef\connectRest@@{%
+ \def\noexpand\Upness@{\Upness@}%
+ \def\noexpand\Leftness@{\Leftness@}%
+ \ifInvisible@ \noexpand\Invisible@true \else \noexpand\Invisible@false \fi
+ \ifHidden@ \noexpand\Hidden@true \else \noexpand\Hidden@false \fi}}
+
+\xydef@\connectRestore@{%
+ \ifvbox\connectobjectbox@@
+ \setbox\lastobjectbox@=\copy\voidb@x
+ \else
+ \global\setbox\lastobjectbox@=\copy\connectobjectbox@@
+ \fi
+ \let\Drop@@=\connectDrop@@
+ \global\let\preXY@style@ =\connectpreXY@style@
+ \global\let\postXY@style@=\connectpostXY@style@
+ \connectRest@@}
+\DOCMODE)
+
+ See note `??w![define <shape>]' for the use of |\preXY@style@| and
+ |\postXY@style@| to apply special <style>s, specified via
+ <object-modifier>s; being saved here by |\connectStore@| as
+ |\connectpreXY@style@| and |\connectpostXY@style@| to be reset by
+ |\connectRestore@|.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[shave]??=[pick place]??=[<place>]
+%
+ Using |?| will ``pick a place'' along the most recent connection
+ typeset with |**|. What exactly this means is determined by the
+ object that was used for the connection and by the modifiers
+ described in general terms here.
+
+ The ``shave'' modifiers in a <place>, |<| and |>|, change the default
+ <factor>, $f$, and how it is used, by `moving' the positions that
+ correspond to |(0)| and |(1)| (respectively): These are initially set
+ equal to~$p$ and~$c$, but shaving will move them to the point on the
+ edge of $p$ and $c$ where the connection ``leaves/enters'' them, and
+ change the default $f$ as indicated. When one end has already been
+ shaved thus then subsequent shaves will correspond to sliding the
+ appropriate position(s) a \TeX\ ??c![\jot] (usually equal to |3pt|)
+ further towards the other end of the connection (and past it).
+ Finally the "pick" action will pick the position located the fraction
+ $f$ of the way from |(0)| to |(1)| where $f=|0.5|$ if it was not set
+ (by |<|, |>|, or explicitly).
+
+ All this is probably best illustrated with some examples: each
+ $\otimes$ in figure~??[f.places] is typeset by a sequence of the form
+ $p$|;| $c$ |**@{.}| |?|<place> |*{\oplus}| where we indicate the
+ |?|<place> in each case. (We also give examples of <slide>s.)
+
+\begin{figure*}[tb]
+$$
+ \def\[#1]#2{\def\2{#2}%
+ \POS "p";"c"**{}
+ #2*+=[o]{\oplus}="x"*=<5em,3em>{}-#1*!#1\hbox{{\tt\codeof\2}};
+ "x"**@{-}?>*@{>}\ignorespaces}%
+ %
+\xy
+ <0pt,110pt>*[o]=<20pt>{}="p"*\frm{oo}+L*!RC\hbox{$p$ is circular:~},
+ <270pt,0pt>*=<4em>\txt<4em>{$c$ is a square text!}="c"*\frm{-,},
+ "p";"c"**@{--}\relax
+ %
+ \[UR]{?(0)}
+ \[UR]{?(1)}
+ \[UR]{?}
+ \[UR]{?(.7)}
+ %
+ \[D]{?<>(.5)}
+ \[DL]{?<>(.2)(.5)}
+ \[DL]{?<}
+ \[UR]{?<<<}
+ \[UR]{?<<</1cm/}
+ \[D]{?<(0)}
+ \[DL]{?>}
+ \[D]{?>>>>}
+ %
+ \[DL]{?<>(.7)}
+ \[D]{?>(.7)}
+\endxy
+$$
+\caption{Example \protect<place>s}??=[f.places]
+\end{figure*}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Procedure:}
+
+ The code for parsing <place> is the following. To get first |<>| to
+ move to edge and the remaining to move a ??c![\jot] we have both
+ initial and continuing versions for each, the idea being that the
+ second and following go to the edge of a small temporary object with
+ radius |\jot|.
+
+ \NOTE: This parser tests the "new parsing principle" that |\xy@|
+ should always be called as |\xy@{| "source" |}{| "target" |}|!
+
+% \HACK: `Helps' the `arrow' feature: in the procedure for path
+% sub-segments, it is necessary to know the value of |\PLACEf@| both at
+% the (possibly delayed) time when the sub-segments are being typeset
+% and also at the time when the subsegments are being processed (and
+% packaged to be delayed by the |\xy@@|). Thus it is necessary for any
+% changes to the value of |\PLACEf@| to be both immediate and
+% delayed. The reason is that |\bstartPLACE@| and |\bendPLACE@| read
+% values from |\PLACEf@| and are themselves delayed by calls to |\xy@@|
+% -- these delayed calls need to know what |\PLACEf@| will be when they
+% are used.
+
+\DOCMODE(
+\xydef@\afterPLACE#1{%
+ \DN@##1{\def\afterPLACE@{\xy@@\leave@ \def\afterPLACE@{##1}#1}}%
+ \expandafter\next@\expandafter{\afterPLACE@}%
+ \def\PLACEf@{{.5}}%
+ \xy@@{\enter@{\pfromthep@}%
+ \Creset@@ \def\PLACEf@{{.5}}%
+ \let\PLACEedgep@@=\PLACEedgep@ \let\PLACEedgec@@=\PLACEedgec@}%
+ \xyFN@\PLACE@}
+
+\xydef@\PLACEf@{}
+
+\xydef@\PLACEedgep@@{}
+\xydef@\PLACEedgec@@{}
+
+\xydef@\PLACEedgep@{\Cshavep@@ \def\PLACEedgep@@{\Cslidep@@\jot}}
+\xydef@\PLACEedgec@{\Cshavec@@ \def\PLACEedgec@@{\Cslidec@@{-\jot}}}
+
+\xylet@\afterPLACE@=\empty
+
+\xydef@\PLACE@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@}%gobble spaces
+ \else\addLT@\ifx \next
+ \addLT@\DN@{\addLT@\xy@{\def\PLACEf@{{0}}\PLACEedgep@@}\xyFN@\PLACE@}%
+ \else\addGT@\ifx \next
+ \addGT@\DN@{\addGT@\xy@{\def\PLACEf@{{1}}\PLACEedgec@@}\xyFN@\PLACE@}%
+ \else\ifx (\next %)
+ \DN@(##1){\def\PLACEf@{{##1}}\xy@{(##1)}{\def\PLACEf@{{##1}}}\xyFN@\PLACE@}%
+ \else\ifx !\next
+ \DN@!{\xyFN@\PLACE@intercept}%
+ \else
+ \DN@{\xy@@{\expandafter\Calong@@\PLACEf@ \czeroEdge@}\PLACE@@}%
+ \fi\fi\fi\fi\fi \next@}
+
+\xydef@\PLACE@intercept{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@intercept}%gobble spaces
+ \else\ifx \bgroup\next
+ \DN@##1{\xy@{!{##1}}{}\PLACE@intercept@{##1}}%
+ \else\ifx (\next %)
+ \DN@(*##1*){\xy@{!(*##1*)}{}\PLACE@intercept@{##1}}%
+ \else \DN@{\xyerror@{{<pos>} expected after ! in <place>}{}}%
+ \fi\fi\fi \next@}
+
+\xydef@\PLACE@intercept@#1{%
+ \xy@@{\enter@{\pfromthep@\basefromthebase@}\begingroup}%
+ \xy@@ix@{#1}\xy@@{\plainxy@ \expandafter\POS\the\toks9\relax
+ \edef\next@{\endgroup
+ \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p}%
+ \next@ \Cintercept@@ \leave@}%
+ \PLACE@@}
+
+\xydef@\PLACE@@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@@}%gobble spaces
+ \else\ifx /\next \DN@/##1/{\xy@{/##1/}{\Cslidec@@{##1}}\afterPLACE@}%
+ \else \let\next@=\afterPLACE@
+ \fi\fi \next@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[slide]
+%
+ A <slide> will move the position a dimension further along the
+ connection at the picked position. For straight connections (the
+ only ones kernel \Xy-pic provides) this is the same as adding a
+ vector in the tangent direction, \ie, $|?|\dots|/|A|/|$ is the same
+ as $|?|\dots|+/|A|/|$.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[intercept]
+%
+ This special <place> finds the point where the last connection
+ intercepts with the line from $p$ to $c$ as setup by the <pos>, thus
+ usually this will have the form |!{|<coord>|;|<coord>|}|\footnote{The
+ braces can be replaced by |(*|\dots|*)| "once", \ie, there can be no
+ other braces nested inside it.}, for example,
+ \BUG: Only works for straight arrows at present.
+%
+\begin{code}
+\xy <1cm,0cm>:
+ (0,0)*=0{+}="+" ;
+ (2,1)*=0{\times}="*" **@{.} ,
+ (1,0)*+{A} ; (2,2)*+{B} **@{-}
+ ?!{"+";"*"} *{\bullet}
+\endxy
+\end{code}
+\displaycode\noindent
+%
+ will typeset
+%
+$$\docode$$
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[axis intersection]
+%
+ The positions denoted by the "axis intersection"
+ <coord>inates~??c![x] and~??c![y] are the points where the line
+ through $p$ and $c$ intersects with each axis. The following figure
+ illustrates this:
+$$
+ \xy;<1cm,.5cm>:<-.5cm,.5cm>::
+ (0,0)*+!UR{"origin"};
+ (1,0)*+!DR{"xbase"}**@{-}?>*@{>},
+ (0,0);(0,1)*+!DR{"ybase"}**@{-}?>*@{>},
+ (0.5,-1)="p"*@{o}*!LU\hbox{~$p$};
+ p+<.25cm,.5cm>="c"*@{o}*!LU\hbox{~$c$}*{}?(1),
+ %
+ "p";"c",x*+!LD{|x|}*@{*}*{}**@{.};(1,0)**@{.},
+ "p";"c",y*!U{\strut|y|}*@{*}*{}**@{.};(0,0)**@{.},
+ \endxy
+$$
+
+\begin{exercise}
+%
+ Given predefined points $A$, $B$, $C$, and $D$ (stored as objects
+ |"A"|, |"B"|, |"C"|, and |"D"|), write a <coord> specification that
+ will return the point where the lines $\overline{AB}$ and
+ $\overline{CD}$ cross (the point marked with a large circle here):
+%
+\begin{code}
+\xy
+ %
+ % set up and mark A, B, C, and D:
+ (0,0)="A" *\cir<1pt>{}*+!DR{A},
+ (7,10)="B" *\cir<1pt>{}*+!DR{B},
+ (13,8)="C" *\cir<1pt>{}*+!DL{C},
+ (15,4)="D" *\cir<1pt>{}*+!DL{D},
+ %
+ % goto intersection and name+circle it:
+ {"A";"B":"C";"D",x} ="I" *\cir<3pt>{},
+ %
+ % make dotted lines:
+ "I";"A"**{} +/1pc/;-/1pc/ **@{..},
+ "I";"D"**{} +/1pc/;-/1pc/ **@{..}
+ %
+\endxy
+\end{code}
+$$\docode$$
+%
+\answertext{The <coord> ``|{"A";"B":| |"C";"D",| |x}|'' returns the cross
+ point. Here is how the author typeset the diagram in the exercise:}
+\answercode
+\answertext{\displaycode\noindent A |?!|\dots\ <place> could also have been
+ used.}
+\end{exercise}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Procedure:}
+
+ We solve the following equation in $a,b$:
+$$
+ "origin" + a*|<|R_c|,|U_c|>| = c - b*(c-p)
+$$
+ and then set
+$$
+ |<|X_c|,|Y_c|>| := |<|X_c|,|Y_c|>| - b*(c-p)
+ \quad\textrm{with zero size}\quad
+ D_c,U_c,L_c,R_c := 0,0,0,0.
+$$
+ The code uses $c=(X_c,Y_c,D_c,U_c,L_c,R_c)$ and $A,B$ as temporaries
+ and computes:
+$$
+\begin{array}{rcl}
+ |<|dX|,|dY|>| &:=& |<|X_c|,|Y_c|>| - |<|X_p,Y_p|>| \\[1pt]
+ |<|A|,|B|>| &:=& |<|X_c|,|Y_c|>| - |<|X_"origin"|,|Y_"origin"|>| \\[1pt]
+ |<|D_c|,|L_c|>| &:=& |<| \Det{R& dX\\U&dY} |,|
+ \Det{R&A\\U&B} |>| \\[1pt]
+ |<|X_c|,|Y_c|>| &:=& |<|X_c|,|Y_c|>| - (L_c/D_c)*|<|dX|,|dY|>|
+\end{array}
+$$
+ where we really do $D := (R/|pt|)dY - (U/|pt|)dX$ and similarly for
+ $L$.
+
+\DOCMODE(
+\xydef@\intersect@{%?*[intersect@]
+ \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
+ \A@=\X@c \advance\A@-\X@origin \B@=\Y@c \advance\B@-\Y@origin
+ \edef\next@{\expandafter\removePT@\the\R@c}%
+ \edef\nextii@{\expandafter\removePT@\the\U@c}%
+ \D@c=\next@\d@Y \advance\D@c-\nextii@\d@X \divide\D@c\KK@
+ \L@c=\next@\B@ \advance\L@c-\nextii@\A@ \divide\L@c\KK@
+ \ifdim\D@c=\z@\zeroDivide@\else \quotient@\next@\L@c\D@c \fi
+ \advance\X@c-\next@\d@X \advance\Y@c-\next@\d@Y
+ \czeroEdge@}
+\DOCMODE)
+
+ When there is no intersection point a wrong answer is returned,
+ accompanied by a warning message. This behaviour can be altered by
+ assigning a different value to the hook: |\zeroDivide@|. This macro
+ must store a number in |\next@|.
+
+\DOCMODE(
+\xydef@\zeroDivide@@{\zeroDivide@message{\intersect@}{treated as 0}\DN@{0}}
+\xydef@\zeroDivide@message#1#2{\xywarning@{division by 0 in \string#1, #2}}
+\xylet@\zeroDivide@=\zeroDivide@@
+
+\xydef@\zeroDivideLimit@@{\ifdim\L@c=\z@ \DN@{0}%
+ \else\ifdim\L@c<\z@\DN@{-\zeroDivide@Limit}%
+ \else\DN@{\zeroDivide@Limit}\fi\fi
+ \zeroDivide@message{\intersect@}{replaced by \zeroDivide@Limit}}
+\xydef@\zeroDivideLimit@#1{\edef\zeroDivide@Limit{#1}%
+ \let\zeroDivide@=\zeroDivideLimit@@}
+\xylet@\zeroDivideLimit=\zeroDivideLimit@
+\DOCMODE)
+
+ By specifying |\zeroDivideLimit{|<num>|}| the user can locally
+ establish that ${x\over0} = \sgn(x)$<num>, whenever such a division
+ by zero would otherwise occur in an intersection calculation.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[group]
+%
+ A <pos> <decor> "grouped" in |{}|-braces\footnote{One can use
+ |(*|\dots|*)| instead also here.} is interpreted in a local scope in
+ the sense that any $p$ and "base" built within it are forgotten
+ afterwards, leaving only the $c$ as the result of the <coord>.
+ \NOTE: Only $p$ and "base" are restored -- it is not a \TeX\ group.
+
+\begin{exercise}
+ What effect is achieved by using the <coord>inate ``|{;}|''?
+\answertext{To copy the $p$ value to $c$, \ie, equivalent to ``|p|''.}
+\end{exercise}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The code is inside |\POS@|.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[in <direction>]
+%
+ The vector $|/|Z|/|$, where $Z$ is a <dimen>sion, is the same as the
+ vector $|<|Z\cos\alpha|,|Z\sin\alpha|>|$ where $\alpha$ is the angle
+ of the last direction set by a connection (\ie, with |**|) or
+ subsequent placement (|?|) position.
+
+\DOCMODE(
+\xydef@\vfromslide@#1{\enter@\DirectionfromtheDirection@ \begingroup
+ \plainxy@\afterDIRECTIONorEMPTY\vfromslide@i\vfromslide@i#1@}
+
+\xydef@\vfromslide@i#1@{\DN@{#1}%
+ \edef\next{\endgroup
+ \ifx\next@\empty \dimen@=.5pc \else \dimen@=#1\relax \fi
+ \X@c=\cosDirection\dimen@ \Y@c=\sinDirection\dimen@}\next
+ \leave@}
+\DOCMODE)
+
+ It is possible to give a <direction> as described in the next section
+ (figure~??[f.object], note~??[direction] in particular) that will
+ then be used to set the value of $\alpha$. It is also possible to
+ omit the <dimen> in which case it is set to a default value of
+ |.5pc|.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[offset]??=[corner]
+%
+ A <corner> is an offset from the current $|<|X_c|,|Y_c|>|$ position
+ to a specific position on the edge of the $c$ object (the two-letter
+ ones may be given in any combination):
+$$
+\def\[#1]{\POS"box"+#1="x";"box"
+ **{} ?</-2em/*+\hbox{\tt#1};"x",**@{-}?>*@{>}}
+%
+\xy.(-5,-4).(15,9)*\frm{-}="box"*{c}="c";
+ "box"+L**@{.}, "box"+R**@{.}, "box"+D**@{.}, "box"+U**@{.}
+%
+ \[L] \[R] \[D] \[U]
+ \[LD]\[RD]\[LU]\[RU]
+ \[CL]\[CR]\[DC]\[UC] \[C] \[P]
+ \POS"box"+(-20,-8)*{p}="p";"c"**@{.},"box"**{}\[E]
+\endxy
+$$
+ The `edge point' |E| lies on the edge along the line from $p$ to the
+ centre of the object, in contrast to the `proportional' point |P|
+ which is also a point on the edge but computed in such a way that the
+ object looks as much `away from $p$' as possible.
+
+ Finally, a following $|(|f|)|$ suffix will multiply the offset vector
+ by the <factor> $f$.
+
+\begin{exercise}
+ What is the difference between the <pos>itions |c?<| and |c+E|?
+\answertext{When using the kernel connections that are all straight there is
+ no difference, \eg, |**{}?<| and |**{}+E| denote exactly the same
+ position. However, for other connections it is not necessarily the
+ case that the point where the connection enters the current object,
+ denoted by |?<|, and the point where the straight line from $p$
+ enters the object, denoted by |+E|, coincide.}
+\end{exercise}
+
+\begin{exercise}
+\begin{code}
+\xy *=<3cm,1cm>\txt{Box}*\frm{-}
+ !U!R(.5) *\frm{..}*{\bullet} \endxy
+\end{code}
+%
+ What does this typeset?
+%
+\displaycode
+\noindent
+ "Hint": ??c![\frm] is defined by the frame extension and just
+ typesets a frame of the kind indicated by the argument.
+%
+\answercode
+\answertext{The code typesets the picture $$\docode$$}
+\end{exercise}
+
+ \BUG: Currently only the single-letter corners (??c![L], ??c![R],
+ ??c![D], ??c![U], ??c![C], ??c![E], and ??c![P]) will work for any
+ shape---the others silently assume that the shape is rectangular.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[stack]??=[<stack op>eration]
+%
+ The "stack" is a special construction useful for storing a sequence
+ of <pos>itions that are accessible using the special
+ <coord>inates~|s|$n$, where $n$~is either a single digit or a
+ positive integer in |{}|s: |s0| is always the `top' element of the
+ stack and if the stack has depth $d$ then the `bottom' element of the
+ stack has number |s{|$d-1$|}|. The stack is said to be `empty' when
+ the depth is~$0$ and then it is an error to access any of the |s|$n$
+ or `pop' which means remove the top element, shifting what is in |s1|
+ to |s0|, |s2| to |s1|, etc. Similarly, `push~$c$' means to shift
+ |s0| to |s1|, etc., and then insert the $c$ as the new |s0|.
+
+ The stack is manipulated as follows:
+%
+\begin{defs}
+ |@|<stacking> & Action \cr
+\noalign{\nobreak\smallskip\nobreak\hrule\nobreak\smallskip\nobreak}%
+ ??c![@+]<coord> & push $<coord>$ \cr
+ ??c![@-]<coord> & $c\from<coord>$ then pop \cr
+ ??c![@=]<coord> & load stack with <coord> \cr
+ ??c![@@]<coord> & do $<coord>$ for $c\from$ stack \cr
+ ??c![@i] & initialise \cr
+ ??c![@(] & enter new frame \cr
+ ??c![@)] & leave current frame \cr
+\end{defs}
+\noindent\unskip
+%
+ To `load stack', means to load the entire stack with the positions
+ set by <coord> within which |,| means `push $c$'.
+
+ To `do <coord> for all stack elements' means to set $c$ to each
+ element of the stack in turn, from the bottom and up, and for each
+ interpret the <coord>. Thus the first interpretation has $c$ set to
+ the bottom element of the stack and the last has $c$ set to~|s0|. If
+ the stack is empty, the <coord> is not interpreted at all.
+
+ These two operations can be combined to repeat a particular <coord>
+ for several points, like this:
+%
+\begin{code}
+\xy
+ @={(0,-10),(10,3),(20,-5)} @@{*{P}}
+\endxy
+\end{code}
+\displaycode\noindent
+%
+ will typeset
+%
+$$\docode$$
+
+ Finally, the stack can be forcibly cleared using |@i|, however, this
+ is rarely needed because of |@(|, which saves the stack as it is, and
+ then clears it, such when it has been used (and is empty), and |@)|
+ is issued, then it is restored as it was at the time of the~|@(|.
+
+\begin{exercise}
+ How would you change the example above to connect the points as shown
+ below?
+%
+\begin{code}
+\xy
+ @={(0,-10),(10,3),(20,-5)},
+ s0="prev" @@{;"prev";**@{-}="prev"}
+\endxy
+\end{code}
+%
+$$\docode$$
+%
+\answercode
+\answertext{This does the job, saving each point to make the previous point
+ available for the next piece:\displaycode\noindent Notice how we
+ close the line by first saving |s0|, the last point visited, such
+ that the first point will be connected to it.}
+%
+\end{exercise}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ First the stack top and bottom, both initially~$-1$:
+
+\DOCMODE(
+\xydef@\s@bot{-1}
+\xydef@\s@top{-1}
+\DOCMODE)
+
+ Next the function to set $c\from|s|n$, \ie, test that $"bot"\lt
+ n+"bot"\lt "top"$ and then run the associated stack element.
+
+\DOCMODE(
+\xydef@\cfroms@#1{\tests@{#1}\runs@\outofranges@}
+
+\xydef@\tests@#1#2#3{\DN@{#3}%
+ \count@=\s@top \advance\count@-#1\relax
+ \ifnum\count@>\s@bot\relax \ifnum\count@>\s@top\else\DN@{#2}\fi\fi
+ \next@}
+
+\xydef@\runs@{\csname S@\the\count@\endcsname}
+
+\xydef@\outofranges@{\count@=\s@top \advance\count@-\s@bot
+ \xyerror@{stack index out of range (should be 0..\the\count@)}{}}
+\DOCMODE)
+
+ Finally the actual code to do the stack operations: it depends on the
+ `code' passed after |@|; spaces are not allowed:
+
+\DOCMODE(
+\xydef@\STACK@{%
+ \addPLUS@\ifx\next
+ \addPLUS@\DN@{\xy@{@+}{}\afterCOORD{\xy@@\spushc@ \xyFN@\POS@}}%
+ \else\addDASH@\ifx\next
+ \addDASH@\DN@{\xy@{@-}{}\afterCOORD{\xy@@\spop@ \xyFN@\POS@}}%
+ \else \ifx i\next \DN@ i{\xy@{@i}\sinit@ \xyFN@\POS@}%
+ \else \ifx (\next \DN@ ({\xy@{@(}\senter@ \xyFN@\POS@}%
+ \else \ifx )\next \DN@ ){\xy@{@)}\sleave@ \xyFN@\POS@}%
+ \else\addEQ@\ifx\next \addEQ@\DN@{\STACK@load}%
+ \else\addAT@\ifx\next \addAT@\DN@{\xy@{@@}{}\smap@}%
+ \else \DN@##1{\xyerror@{illegal stack command ##1}{}\afterCOORD{\xyFN@\POS@}}%
+ \fi\fi\fi\fi\fi\fi\fi \next@}
+
+\xydef@\STACK@load{\xy@{@=}{%
+ \if\sempty@\else \xywarning@{loading on top of non-empty stack}\sinit@ \fi
+ \let\comma@@=\spushc@}%
+ \afterCOORD{\xy@@{\spushc@ \let\comma@@=\relax}\xyFN@\POS@}}
+
+\xydef@\spushc@{%
+ \count@=\s@top \advance\count@\@ne \edef\s@top{\the\count@}%
+ \expandafter\edef\csname S@\s@top\endcsname{\cfromthec@}}
+
+\xydef@\spushid@#1{\DNii@{#1}\edef\nextii@{\codeof\nextii@}%
+ \expandafter\let\expandafter\next@\csname Q@\nextii@\endcsname
+ \ifx\next@\relax \xyerror@{<pos> \string"\nextii@\string" not defined}{}%
+ \else
+ \count@=\s@top \advance\count@\@ne \edef\s@top{\the\count@}%
+ \DNii@##1{\expandafter\def\csname S@\s@top\endcsname{##1}}%
+ \expandafter\nextii@\expandafter{\next@}%
+ \fi}
+
+\xydef@\idfroms@#1#2{%
+ \tests@{#2}{\DN@{\idfromxy@{#1}}%
+ \expandafter\expandafter\expandafter\next@
+ \expandafter\expandafter\expandafter{\csname S@\the\count@\endcsname}%
+ }\outofranges@}
+
+\xydef@\spop@{\count@=\s@top
+ \ifnum\count@>\s@bot \advance\count@\m@ne \edef\s@top{\the\count@}%
+ \else \xyerror@{nothing to pop from stack}{}\fi}
+
+\xydef@\sinit@{\edef\s@top{\s@bot}}
+
+\xydef@\senter@{%
+ \count@=\s@top \advance\count@\@ne
+ \expandafter\edef\csname S@\the\count@\endcsname{\s@bot}%
+ \edef\s@bot{\the\count@}\edef\s@top{\the\count@}}
+
+\xydef@\sleave@{%
+ \ifnum\s@bot=\s@top\else \xywarning@{leaving non-empty stack}\sinit@ \fi
+ \ifnum\s@bot>\m@ne \edef\s@bot{\csname S@\s@top\endcsname}%
+ \count@=\s@top \advance\count@\m@ne \edef\s@top{\the\count@}%
+ \edef\sbot{\the\count@}\fi}
+
+\xydef@\sempty@{\ifnum\s@top=\s@bot TT\else TF\fi}
+\DOCMODE)
+
+ |\smap@| maps a <coord> over a stack:
+
+\DOCMODE(
+\xydef@\xytotoks@#1#2{\addtotoks@{#2}}
+\xydef@\xytotoks@@toksix@#1{\addtotoks@{\toks9={#1}}}
+
+\xydef@\smap@{%
+ \begingroup \toks@={}\let\xy@=\xytotoks@ \change@oxy@\xy@
+ \let\xy@@ix@=\xytotoks@@toksix@
+ \afterCOORD{\expandafter\endgroup
+ \expandafter\smapxy@@\expandafter{\the\toks@}\xyFN@\POS@}}
+
+\xydef@\smapxy@@#1{\xy@@{\edef\smapp@@{\s@bot}\smapxy@i{#1}}}
+
+\xylet@\smapp@@=\empty
+
+\xydef@\smapxy@i#1{%
+ \ifnum\smapp@@<\s@top
+ \count@=\smapp@@ \advance\count@\@ne \edef\smapp@@{\the\count@}%
+ \DN@{\csname S@\smapp@@\endcsname #1\relax \smapxy@i{#1}}%
+ \else \let\next@=\relax
+ \fi \next@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[save]??=[saved]
+%
+ It is possible to define new <coord>inates on the form |"|<id>|"| by
+ "saving" the current $c$ using the \dots|="|<id>|"| <pos>ition form.
+ Subsequent uses of |"|<id>|"| will then reestablish the $c$ at the
+ time of the saving.
+
+ Using a |"|<id>|"| that was never defined is an error, however,
+ saving into a name that was previously defined just replaces the
+ definition without warning, \ie, |"|<id>|"| always refers to the last
+ thing saved with that <id>.
+
+ However, many other things can be `saved': in general |@|<saving> has
+ either of the forms
+%
+\begin{defs}
+ |@:"|<id>|"| & |"|<id>|"| restores current "base" \cr
+ |@|<coord>|"|<id>|"| & |"|<id>|"| reinterprets <coord> \cr
+ |@@"|<id>|"| & |@="|<id>|"| reloads this stack \cr
+\end{defs}
+\noindent\unskip
+%
+ The first form defines |"|<id>|"| to be a macro that restores the
+ current "base".
+
+ The second does not depend on the state at the time of definition at
+ all; it is a macro definition. You can pass parameters to such a
+ macro by letting it use coordinates named |"1"|, |"2"|, etc., and
+ then use |="1"|, |="2"|, etc., just before every use of it to set the
+ actual values of these. \NOTE: it is not possible to use a <coord>
+ of the form |"|<id>|"| directly: write it as |{"|<id>|"}|.
+%
+\begin{exercise}
+ Write a macro |"dbl"| to double the size of the current~$c$ object,
+ \eg, changing it from the dotted to the dashed outline in this
+ figure:
+%
+\begin{code}
+\xy ={.{+DL(2)}.{+UR(2)}}"dbl",
+ *+<3pc,2pc>{+}*\frm{.}, "dbl"*\frm{--}
+\endxy
+\end{code}
+$$
+\docode
+$$
+\answercode
+\answertext{The author used \displaycode\noindent to typeset the figure in
+ the exercise.}
+\end{exercise}
+
+ The final form defines a special kind of macro that should only be
+ used after the |@=| stack operation: the entire current stack is
+ saved such that the stack operation |@="|<id>|"| will reload it.
+
+ \NOTE: There is no distinction between the `name spaces' of <id>s
+ used for saved coordinates and other things.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ This parser distinguishes between the cases:
+
+\DOCMODE(
+\xydef@\saveid@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\saveid@}%gobble spaces
+ \else \ifx "\next\DN@"##1"{\xy@{="##1"}{\idfromc@{##1}}\xyFN@\POS@}%
+ \else \ifx :\next\DN@:##1"##2"{\xy@{=:"##2"}{\idfrombase@{##2}}\xyFN@\POS@}%
+ \else\addAT@\ifx\next
+ \addAT@\DN@"##1"{\xy@{=@"##1"}{\idfromstack@{##1}}\xyFN@\POS@}%
+ \else \ifx s\next
+ \DN@ s##1"##2"{\xy@{=s##1"##2"}{\idfroms@{##2}{##1}}\xyFN@\POS@}%
+ \else\addEQ@\ifx\next \let\saveid@COORD@@=\saveid@COORDii
+ \addEQ@\DN@{\xyFN@\saveid@COORD}%
+ \else \let\saveid@COORD@@=\saveid@COORDi \let\next@=\saveid@COORD
+ \fi\fi\fi\fi\fi\fi \next@}
+
+\xylet@\saveid@COORD@@=\relax
+\DOCMODE)
+
+ Here is the code for saving/restoring a position and a base.
+
+\DOCMODE(
+\xydef@\idfromc@#1{\DN@{#1}%
+ \expandafter\edef\csname Q@\codeof\next@\endcsname{\cfromthec@}}
+
+\xydef@\idfrombase@#1{\DN@{#1}%
+ \expandafter\edef\csname Q@\codeof\next@\endcsname{\basefromthebase@}}
+
+\xydef@\idfromstack@#1{%
+ \toks@={\if\sempty@\else
+ \xywarning@{loading on top of non-empty stack}\sinit@ \fi}%
+ \count@=\s@bot \advance\count@\@ne
+ \ifnum\count@>\s@top\else
+ \loop@
+ \expandafter\let\expandafter\next@\csname S@\the\count@\endcsname
+ \expandafter\addtotoks@\expandafter{\next@}%
+ \ifnum\count@<\s@top \advance\count@\@ne \addtotoks@{\spushc@}\repeat@
+ \fi
+ \DN@{#1}\edef\next@##1{%
+ \def\expandafter\noexpand\csname Q@\codeof\next@\endcsname{##1}}%
+ \expandafter\next@\expandafter{\the\toks@}}
+
+\xydef@\saveid@COORD{%
+ \begingroup \toks@={}\let\xy@=\xytotoks@ \change@oxy@\xy@
+ \let\xy@@ix@=\xytotoks@@toksix@
+ \afterCOORD{\expandafter\saveid@COORDi\expandafter{\the\toks@}}}
+
+\xydef@\saveid@COORDi#1#2"#3"{\endgroup \xy@@{\idfromxy@{#3}{#1}}\xyFN@\POS@}
+\xydef@\saveid@COORDii#1#2"#3"{\endgroup \xy@@{\idfromcxy@{#3}{#1}}\xyFN@\POS@}
+
+\xydef@\idfromxy@#1#2{\DN@{#1}%
+ \expandafter\def\csname Q@\codeof\next@\endcsname{#2}}
+
+\xydef@\idfromcxy@#1#2{\DN@{#1}%
+ \expandafter\edef\csname Q@\codeof\next@\endcsname{\cfromthec@#2}}
+
+\xydef@\cfromid@#1{\DNii@{#1}\edef\nextii@{\codeof\nextii@}%
+ \expandafter\let\expandafter\next@\csname Q@\nextii@\endcsname
+ \ifx\next@\relax \xyerror@{<pos> \string"\nextii@\string" not defined}{}%
+ \else \expandafter\next@\fi}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{notes}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section{Objects}
+??=[object]
+
+\DOCMODE(
+\message{objects,}
+\DOCMODE)
+
+ Objects are the entities that are manipulated with the |*| and |**|
+ <pos> operations above to actually get some output in \Xy-pictures.
+ As for <pos>itions the operations are interpreted strictly from left
+ to right, however, the actual object is built "before" all the
+ <modifier>s take effect. The syntax of objects is given in
+ figure~??[f.object] with references to the notes below. \REMARK: It
+ is "never" allowed to include braces |{}| inside <modifier>s! In
+ case you wish to do something that requires |{|\dots|}| then check in
+ this manual whether you can use |(*|\dots|*)| instead. If not then
+ you will have to use a different construction!
+
+\begin{figure*}[tp]
+\begin{syntax}
+%
+ ??w![<object>]
+ &\iss & <modifier> <object>
+ & apply <modifier> to <object>
+\cr
+ &\orr & <objectbox>
+ & build <objectbox> then apply its <modifier>s
+\cr
+\noalign{\smallbreak}
+%
+\cr
+ ??w![<objectbox>]
+ &\iss & |{| <text> |}|
+ & ??!^[build default] object
+\cr
+ &\orr & <library object> \orr\ |@|<dir>
+ & use <library object> or <dir>ectional (see~\S??[objectlib])
+\cr
+ &\orr & <\TeX\ box> |{| <text> |}|
+ & ??!^[build box] object with <text> using the given <\TeX\ box>
+ command, \eg, ??c![\hbox]
+\cr
+ &\orr & ??c![\object] <object>
+ & wrap up the <object> as a ??!^[finished object box]
+\cr
+ &\orr & ??c![\composite] |{| <composite> |}|
+ & build ??!^[composite object box]
+\cr
+ &\orr & ??c![\xybox] |{| <pos> <decor> |}|
+ & package ??!^[entire \Xy-picture as object]
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<modifier>]
+ &\iss & |!| <vector>
+ & <object> has its reference point ??!^[shifted] by <vector>
+\cr
+ &\orr & |!|
+ & <object> has the original reference point reinstated
+\cr
+ &\orr & <add op> <size>
+ & change ??!^[<object> size]
+\cr
+ &\orr & ??c![h] \orr\ ??c![i]
+ & <object> is ??!^[hidden], ??!^[invisible]
+\cr
+ &\orr & |[| <shape> |]|
+ & <object> is given the specified ??!^[<shape>]
+\cr
+ &\orr & ??c![[=] <shape> |]|
+ & ??!^[define <shape>] to reestablish ??w![current object style]
+\cr
+ &\orr & <direction>
+ & set current direction for this <object>
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<add op>]
+ &\iss & |+| \orr\ |-| \orr\ |=| \orr\ |+=| \orr\ |-=|
+ & grow, shrink, set, grow to, shrink to
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<size>]
+ &\iss & <empty>
+ & ??!^[default size]
+\cr
+ &\orr & <vector>
+ & size as sides of rectangle covering the <vector>
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<direction>]
+ &\iss & <diag>
+ & <diag>onal ??!^[direction]
+\cr
+ &\orr & ??c![v] <vector>
+ & ??!^[direction] of <vector>
+\cr
+ &\orr & ??c![q]|{| <pos> <decor> |}|
+ & ??!^[direction] from $p$ to $c$ after <pos> <decor>
+\cr
+ &\orr & <direction> ??c![:] <vector>
+ & vector relative ??!^[to <direction>]
+\cr
+ &\orr & <direction> |_| \orr\ <direction> |^|
+ & $90^\circ$ clockwise/anticlockwise ??!^[to <direction>]
+\cr
+%
+ ??w![<diag>]
+ &\iss & <empty>
+ & last used direction (not necessarily ??!^[diagonal])
+\cr
+ &\orr & |l|\orr|r|\orr|d|\orr|u|
+ & left, right, down, up ??!^[diagonal]
+\cr
+ &\orr & |ld|\orr|rd|\orr|lu|\orr|ru|
+ & left/down, \dots\ ??!^[diagonal]
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<composite>]
+ &\iss & <object>
+ & first object is required
+\cr
+ &\orr & <composite> |*| <object>
+ & add <object> to ??!^[composite object box]
+%
+\end{syntax}
+\caption{\protect<object>s.}
+??=[f.object]
+\end{figure*}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ We first discuss the parser and then summarise the required methods.
+ The entry point to use of objects is ??c![\object] described in note
+ ??[finished object box]. This should always be used because it
+ initialises the token list and redefines |\xy@| to be |\addtotoks@|
+ such that we can use <pos> parser routines within the <object>!
+
+\paragraph*{Parsing:}
+
+ The <object> parser |\OBJECT@| will first parse the <modifier>s,
+ storing the action of each in sequence on the |\toks@| token list.
+ When there are no more modifiers we insert ??c![\objectbox] if we have
+ reached the |{| otherwise we just assume that the rest of the
+ <object> is some kind of box construction.
+
+ "Note": The <modifier> actions doing shifts are implemented by having
+ an independent vector for the shift: $|<|R_p|,|U_p|>|$ always
+ contains the vector from the current to the original \TeX\ reference
+ point; furthermore the initial $L_c$ is saved as $L_p$ such that we
+ can retrieve the original (\Xy-pic) reference point again. Modifying
+ the $p$ values is safe because all actual changes are done in a local
+ scope after the entire <object> is parsed and we have built the
+ object box (in |\OBJECT@@|).
+
+ The <modifier>s changing the direction are executed while parsing to
+ make sure that the direction used when building the <object> is
+ right, and restored in the right sequence while evaluating the
+ <modifier>s afterwards.
+
+\DOCMODE(
+\xydef@\OBJECT@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\OBJECT@}%gobble spaces
+ \else\ifcat A\noexpand\next \let\next@=\OBJECT@letter
+ \else \let\next@=\OBJECT@other \fi\fi \next@}
+
+\xydef@\OBJECT@letter{%
+ \ifx i\next \DN@ i{\addtotoks@\Invisible@true \xyFN@\OBJECT@}%
+ \else\ifx h\next\DN@ h{\addtotoks@\Hidden@true \xyFN@\OBJECT@}%
+ \else\ifx o\next\DN@ o{\xywarning@{Obsolete o modifier used}\OBJECT@shape{o}}%
+ \else\ifx x\next\DN@ x{\xywarning@{Obsolete x modifier used}\OBJECT@shape{}}%
+ \else\ifx @\next\DN@ @##1##{%
+%
+\xywarning@{Impossible @ (letter) should not be here!!}
+%
+ \OBJECT@@{\dir##1}}%
+ \else \let\next@=\OBJECT@direction
+ \fi\fi\fi\fi\fi \next@}
+
+\xydef@\OBJECT@other{%
+ \ifx !\next \DN@!{\OBJECT@shift}%
+ \else\addPLUS@\ifx \next \DN@{\OBJECT@change}%
+ \else\addDASH@\ifx \next \DN@{\OBJECT@change}%
+ \else\addEQ@\ifx \next \DN@{\OBJECT@set}%
+ \else\ifx [\next %]
+ \DN@[##1]{\xy@{[##1]}{\OBJECT@shape{##1}}}%
+ \else\ifx ^\next \let\next@=\OBJECT@direction
+ \else\ifx _\next \let\next@=\OBJECT@direction
+ \else\ifx :\next \let\next@=\OBJECT@direction
+ \else\ifx ?\next
+ \DN@ ?{\xywarning@{\string? modifier used}\xyFN@\OBJECT@direction}%
+ \else\ifx (\next %)
+ \let\next@=\OBJECT@direction
+ \else\addAT@\ifx\next \addAT@\DN@##1##{\OBJECT@@{\dir##1}}%
+ \else \DN@##1##{\OBJECT@@{##1}}%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
+\DOCMODE)
+
+ |\OBJECT@@| is where we actually build the box by first
+ ??_[OBJ0]~saving the previous edge in case it is needed, then
+ ??_[OBJ1]~setting the defaults (including temporarily resetting
+ |\xy@| to execute in case any |\xy@|s are used internally),
+ ??_[OBJ2]~building the object box (which might change them) using
+ ??c![\objectbox] if no other command specified and setting the
+ $D,U,L,R$ dimensions ad required using the |\Leftness@| and
+ |\Upness@| methods, and finally ??_[OBJ3]~setting up the $R_p,U_p$
+ dimensions (as discussed above) and applying the <modifier>s stored
+ in |\toks@| and dumping the modified box.
+
+\DOCMODE(
+\xydef@\prevEdge@@{\zeroEdge}
+
+\xydef@\OBJECT@@#1#2{%
+ \expandafter\def\expandafter\prevEdge@@\expandafter{\the\Edge@c}%?*[OBJ0]
+ \expandafter\Edge@c\expandafter{\objectEdge}%?*[OBJ1]
+ \Invisible@false\Hidden@false
+ \def\Leftness@{.5}\def\Upness@{.5}%
+ \gdef\preXY@style@{}\gdef\postXY@style@{}%
+ \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\relax}%
+ \DN@{#1}\ifx\next@\empty \DNii@{#2}%?*[OBJ2]
+ \ifx\nextii@\empty \DN@{\hbox\bgroup\no@}\else \let\next@=\objectbox \fi\fi
+ \setbox\z@=\next@{#2}\L@c=\Leftness@\wdz@ \R@c=\wdz@ \advance\R@c-\L@c
+ \D@c=\dp\z@ \advance\D@c\ht\z@ \U@c=\Upness@\D@c \advance\D@c-\U@c
+ \R@p=\z@ \L@p=\L@c \U@p=\U@c \advance\U@p-\ht\z@ \D@p=-\U@p %?*[OBJ3]
+ \the\toks@\toks@={}\setboxz@h{\kern\R@p \raise\U@p\boxz@}%
+ \checkZeroEdge@
+ \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@ \ht\z@=\U@c \dp\z@=\D@c \boxz@
+ \OBJECT@x}
+
+\xydef@\adjustLR@{%
+ \ifdim\zz@\wdz@ \L@c=\z@ \R@c=\z@ \dimen@=\Leftness@\p@
+ \ifdim\dimen@<\z@ \L@c=\dimen@ \R@c=-\L@c
+ \else\ifdim\dimen@>\p@ \L@c=\dimen@ \advance\L@c-\p@ \R@c=-\L@c \fi\fi
+ \else \L@c=\Leftness@\wdz@ \R@c=\wdz@ \advance\R@c-\L@c \fi}
+
+\xydef@\adjustUD@{\dimen@=\ht\z@ \advance\dimen@\dp\z@
+ \ifdim\zz@\dimen@ \U@c=\z@ \D@c=\z@ \dimen@=\Upness@\p@
+ \ifdim\dimen@<\z@ \U@c=\dimen@ \D@c=-\L@c
+ \else\ifdim\dimen@>\p@ \U@c=\dimen@ \advance\U@c-\p@ \D@c=-\L@c \fi\fi
+ \else \D@c=\dimen@ \U@c=\Upness@\dimen@ \advance\D@c-\U@c \fi}
+
+\def\checkZeroEdge@{%
+ \DN@{}%
+ \ifdim\zz@\L@c \ifdim\zz@\R@c \ifdim\zz@\U@c \ifdim\zz@\D@c
+ \DN@{\Edge@c={\zeroEdge}}\fi\fi\fi\fi
+ \next@}
+\DOCMODE)
+
+ As an optimisation |\OBJECT@@| sets the edge type of all zero-sized
+ objects to ??c![\zeroEdge].
+
+ |\OBJECT@x| cleans up the object by ensuring that it defines all the
+ required methods: Essentially it terminates the box with the sequence
+ ``|}| |\def\Drop@@{|\dots|}| |\def\Connect@@{|\dots|}| |\D@c=|\dots\
+ |\U@c=|\dots\ |\L@c=|\dots\ |\R@c=|\dots\ | \Invisible@|\dots
+ |\Hidden@|\dots\ |\def\Leftness@{|\dots|}| |\def\Upness@{|\dots|}|''
+ where each \dots\ is set to the method defined within the object
+ creation environment (started with |\hbox{| in |\OBJECT@@| or
+ possibly elsewhere). We use rather heavy expansion hacking with
+ |\toks@| to create the sequence so please look the other
+ way\dots\smiley
+
+\DOCMODE(
+\xydef@\OBJECT@x{\toks@={\egroup\def\Drop@@}%
+ \expandafter\addtotoks@\expandafter{\expandafter{\Drop@@}\def\Connect@@}%
+ \expandafter\addtotoks@\expandafter{\expandafter{\Connect@@}}%
+ \edef\tmp@{\D@c=\the\D@c \U@c=\the\U@c \L@c=\the\L@c \R@c=\the\R@c
+ \Edge@c={\expandafter\noexpand\the\Edge@c}%
+ \ifInvisible@\noexpand\Invisible@true\else\noexpand\Invisible@false\fi
+ \ifHidden@\noexpand\Hidden@true\else\noexpand\Hidden@false\fi
+ \def\noexpand\Leftness@{\Leftness@}\def\noexpand\Upness@{\Upness@}}%
+ \expandafter\addtotoks@\expandafter{\tmp@}\the\toks@}
+\DOCMODE)
+
+\paragraph*{Methods:}
+??w[object methods]
+
+ In addition to the ``current object properties'' for $c$
+ (\cf~??[basics.state]) the following methods are set up by all
+ objects:
+
+\begin{defs}
+ |\Invisible@true| or |\Invisible@false| & whether object is ??!^[invisible]\cr
+ |\Hidden@true| or |\Hidden@false| & whether object is ??!^[hidden]\cr
+ |\def\Leftness@{|<factor>|}| & the desired $L/(L+R)$\cr
+ |\def\Upness@{|<factor>|}| & the desired $U/(D+U)$\cr
+ |\def\Drop@@{|\dots|}| & code that outputs the object, assuming |\boxz@| is
+ of zero size and has the object displaced $|<|X|,|Y|>|$
+ inside---usually just |\def|'d to |\styledboxz@|\cr
+ |\def\Connect@@{|\dots|}| & code that builds a connection from $p$ to $c$,
+ assuming |\last|\-|object|\-|box@| contains the object\cr
+\end{defs}
+
+ It is important to |\def| and not |\let| the last four methods since
+ the \TeX\-nique used in |\OBJECT@x| (and elsewhere) of passing them
+ to surrounding scopes depends on it. The |\Connect@@| method should
+ in turn setup several submethods as described in detail in
+ ??[algo.connection].
+
+ Suitable defaults are set up by |\OBJECT@@| above which is why any
+ box generating command can be used to construct objects as explained
+ in note ??[build default] below.
+
+ Here are the declarations:
+
+\DOCMODE(
+\xynew@{if}\ifInvisible@
+\xynew@{if}\ifHidden@
+
+\xydef@\Leftness@{}
+\xydef@\Upness@{}
+
+\xydef@\Drop@@{\styledboxz@}
+\xydef@\Connect@@{}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{notes}
+%
+\note??=[build default]
+%
+ An <object> is built using |\object|\-|box|??c[\objectbox]
+ |{|<text>|}|. |\object|\-|box| is initially defined as
+%
+\begin{code}
+\def\objectbox#1{%
+ \hbox{$\objectstyle{#1}$}}
+\let\objectstyle=\displaystyle
+\end{code}
+\displaycode
+%
+ but may be redefined by options or the user. The <text> should thus
+ be in the mode required by the ??c![\objectbox] command---with the
+ default |\objectbox| shown above it should be in math mode.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ Actually it is
+
+\DOCMODE(
+\xydef@\objectbox#1{\hbox{$\m@th\objectstyle{#1}$}}
+
+\xylet@\objectstyle=\textstyle
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[build box]
+%
+ An <object> built from a \TeX\ box with dimensions $w*(h+d)$ will
+ have $L_c=R_c=w/2$, $U_c=D_c=(h+d)/2$, thus initially be equipped
+ with the adjustment |!C| (see note~??[shifted]). In particular: in
+ order to get the reference point on the (center of) the base line of
+ the original <\TeX~box> then you should use the <modifier> |!|; to
+ get the reference point identical to the \TeX\ reference point use
+ the modifier |!!L|.
+
+ \TeX\-nical remark: Any macro that expands to something that starts
+ with a <box> may be used as a <\TeX~box> here.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ This is done by the parsing above.
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[finished object box]
+%
+ Takes an object and constructs it, building a box; it is then
+ processed according to the preceeding modifiers. This form makes it
+ possible to use any <object> as a \TeX\ box (even outside of
+ \Xy-pictures) because a finished object is always also a box.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ This macro is the main entry point to the <object> parser. It
+ furthermore initialises the modifier list and the previous object
+ edge.
+
+\DOCMODE(
+%\xydef@\object{\hbox\bgroup\object@}
+\xydef@\object{\hbox\bgroup\resetStyle@\object@}
+
+\xydef@\object@{%
+ \edef\next@{={\DirectionfromtheDirection@}}\expandafter\toks@\next@
+% \resetStyle@\plainxy@ \xyFN@\OBJECT@}
+ \plainxy@ \xyFN@\OBJECT@}
+\DOCMODE)
+
+ The initial value of |\toks@| <modifier> list is explained in
+ note~??[direction] below.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[composite object box]
+%
+ Several <object>s can be combined into a single object using the
+ special command ??c![\composite] with a list of the desired objects
+ separated with |*|s as the argument. The resulting box (and object)
+ is the least rectangle enclosing all the included objects.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ First we collect all the objects smash on top of each other in box0
+ while we maintain the maximal extents in $(DULR)_p$. Then we reset
+ box0 to contain the same but with the right spacing around.
+
+\DOCMODE(
+\xydef@\composite#1#{\hbox\bgroup\composite@{#1}}
+
+\xydef@\composite@#1#2{%
+ \DN@{#1}\ifx\next@\empty\else\xywarning@{no variants of
+ \string\composite\space allowed}\fi
+ \global\setbox9=\hbox\bgroup
+ \D@p=-\maxdimen \U@p=-\maxdimen \L@p=-\maxdimen \R@p=-\maxdimen
+ \xyFN@\composite@i#2@}
+
+\xydef@\composite@i{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\composite@i}%gobble spaces
+ \else\ifx *\next \DN@ *{\xyFN@\composite@i}%
+ \else\ifx @\next \DN@ @{\composite@x}%
+ \xyerror@{<composite> object expected}{}\czeroEdge@
+ \else \DN@{\composite@ii}\fi\fi\fi \next@}
+
+\xydef@\composite@ii#1#{\composite@iii{#1}}
+
+\xydef@\composite@iii#1#2{%
+ \setbox\z@=\object#1{#2}%
+ \ifInvisible@ \setboxz@h{}\else
+ \setboxz@h{\kern-\L@c \boxz@}\ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ {\Drop@@}\fi
+ \ifHidden@\else
+ \ifdim\U@p<\U@c \U@p=\U@c \fi \ifdim\D@p<\D@c \D@p=\D@c \fi
+ \ifdim\R@p<\R@c \R@p=\R@c \fi \ifdim\L@p<\L@c \L@p=\L@c \fi
+ \fi
+ \xyFN@\composite@iv}
+
+\xydef@\composite@iv{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\composite@iv}%gobble spaces
+ \else \ifx @\next \DN@ @{\composite@x}%
+ \else \let\next@=\composite@i \fi\fi \next@}
+
+\xydef@\composite@x{%
+ \edef\tmp@{\egroup
+ \D@c=\the\D@p \U@c=\the\U@p \L@c=\the\L@p \R@c=\the\R@p}\tmp@
+ \setboxz@h{\kern\L@c\box9}\ht\z@=\U@c \dp\z@=\D@c
+ \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@
+ \Edge@c={\rectangleEdge}\computeLeftUpness@ \boxz@
+ \OBJECT@x}
+
+\xydef@\computeLeftUpness@{%
+ \dimen@=\L@c \advance\dimen@\R@c
+ \ifdim\zz@\dimen@ \def\Connect@@{\straight@{\dottedSpread@\jot}}%
+ \ifdim\zz@\L@c\else
+ \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edge@c}%
+ \ifx\next@\nextii@\Edge@c={\rectangleEdge}\fi\fi
+ \else \quotient@\Leftness@\L@c\dimen@ \fi
+ \dimen@=\U@c \advance\dimen@\D@c
+ \ifdim\zz@\dimen@ \def\Connect@@{\straight@{\dottedSpread@\jot}}%
+ \ifdim\zz@\U@c\else
+ \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edge@c}%
+ \ifx\next@\nextii@\Edge@c={\rectangleEdge}\fi\fi
+ \else \quotient@\Upness@\U@c\dimen@ \fi}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note ??=[entire \Xy-picture as object]
+%
+ Take an entire \Xy-picture and wrap it up as a box as described
+ in~\S??[basics.pos]. Makes nesting of \Xy-pictures possible: the
+ inner picture will have its own zero point which will be its
+ reference point "in" the outer picture when it is placed there.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ This is simple exploiting the fact that |\endxy| actually sets up the
+ extents of the `object':
+
+\DOCMODE(
+\xydef@\xybox#1{\xy#1\endxy \Edge@c={\rectangleEdge}\computeLeftUpness@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[shifted]
+%
+ An object is "shifted" a <vector> by moving the point inside it which
+ will be used as the reference point. This effectively pushes the
+ object the same amount in the opposite direction.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Shifting uses the special value of $R_p$ and $U_p$ used while
+ evalutaing the <modifier>s. The fact that shifts like |!C| refer to
+ the initial object's size means that we should parse the <vector>
+ such that its actions happen at modification time\dots hence
+ |\xytotoks@| is used to delay execution.
+
+\DOCMODE(
+\xydef@\OBJECT@shift{%
+ \let\xy@=\xytotoks@ \afterVECTORorEMPTY
+ {\OBJECT@shift@}%
+ {\addtotoks@{\X@c=-\L@c \advance\X@c\R@p \advance\X@c\L@p \Y@c=\U@p}%
+ \OBJECT@shift@}}
+
+\xydef@\OBJECT@shift@{%
+ \addtotoks@{\advance\U@p-\Y@c
+ \advance\L@c\X@c \advance\R@c-\X@c \advance\D@c\Y@c \advance\U@c-\Y@c
+ \computeLeftUpness@}%
+ \let\xy@=\oxy@ \xyFN@\OBJECT@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{exercise}
+ What is the difference between the <pos>itions |0*{a}!DR| and
+ |0*!DR{a}|?
+\answertext{The first typesets ``$a$'' centered around |0| and then moves $c$
+ to the lower right corner, the second typesets ``$a$'' above the |0|
+ point and does not change $c$. With a ``$+$'' at |0| they look like
+ this: $\vcenter{\xy*{+}*{a}!DR\endxy}$ and
+ $\vcenter{\xy*{+}*!DR{a}\endxy}$.}%
+\end{exercise}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[<object> size]??=[change size]??=[<size>]??=[default size]
+%
+ A <size> is a pair $|<|W|,|H|>|$ of the width and height of a
+ rectangle. When given as a <vector> these are just the vector
+ coordinates, \ie, the <vector> starts in the lower left corner and
+ ends in the upper right corner. The possible <add op>erations that
+ can be performed are described in the following table.
+$$
+\begin{array}{\otherbar c\otherbar l\otherbar}
+\hline
+ \hbox{<add op>} & \hbox{description} \\
+\hline
+ |+| & \hbox{grow} \\
+ |-| & \hbox{shrink} \\
+ |=| & \hbox{set to} \\
+ |+=| & \hbox{grow to at least} \\
+ |-=| & \hbox{shrink to at most} \\
+\hline
+\end{array}
+$$
+ In each case the <vector> may be omitted which invokes the ``default
+ size'' for the particular <add op>:
+$$
+\begin{array}{\otherbar c\otherbar l\otherbar}
+\hline
+ \hbox{<add op>} & \hbox{default}\\
+\hline
+ |+| & |+<|2*"objectmargin"|>| \\
+ |-| & |-<|2*"objectmargin"|>| \\
+ |=| & |=<|"objectwidth"|,|"objectheight"|>| \\
+ |+=| & |+=<|\max(L_c+R_c,D_c+U_c)|>| \\
+ |-=| & |-=<|\min(L_c+R_c,D_c+U_c)|>| \\
+\hline
+\end{array}
+$$
+ The defaults for the first three are set with the commands
+%
+\begin{defs1}
+ ??c![\objectmargin] <add op> |{|<dimen>|}| \cr
+ ??c![\objectwidth] <add op> |{|<dimen>|}| \cr
+ ??c![\objectheight] <add op> |{|<dimen>|}| \cr
+\end{defs1}
+\noindent\unskip
+%
+ where <add op> is interpreted in the same way as above.
+
+\DOCMODE(
+\xylet@\objectmargin@=\jot
+\xylet@\objectwidth@=\z@
+\xylet@\objectheight@=\z@
+
+\xydef@\objectmargin{\afterADDOP{\Addop@@\objectmargin@}}
+\xydef@\objectwidth{\afterADDOP{\Addop@@\objectwidth@}}
+\xydef@\objectheight{\afterADDOP{\Addop@@\objectheight@}}
+\DOCMODE)
+
+ The defaults for |+=|/|-=| are such that the resulting object will be
+ the smallest containing/largest contained square.
+
+\begin{exercise}
+ How are the objects typeset by the <pos>itions ``|*+UR{\sum}|'' and
+ ``|*+DL{\sum}|'' enlarged?
+\answertext{They have the outlines
+ $$\xy*+UR{\sum}*\frm{-}*{+}\endxy
+ \quad\textrm{and}\quad
+ \xy*+DL{\sum}*\frm{-}*{+}\endxy$$
+ because the first is enlarged by the positive offset to the upper
+ right corner and the second by the negative offset to the lower left
+ corner.}
+\end{exercise}
+
+ \BUG: Currently changing the size of a circular object is buggy---it
+ is changed as if it is a rectangle and then the change to the $R$
+ parameter affects the circle. This should be fixed probably by a
+ generalisation of the |o| shape to be ovals or ellipses with
+ horizontal/vertical axes.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The three cases distinguished by the parsing above are handled
+ similarly: they insert the parsed/default vector into $X,Y$ in the
+ modifications and then perform the operation at that time using the
+ |\xytotoks@| trick described in note~??[shifted]:
+
+\DOCMODE(
+\xydef@\OBJECT@change{%
+ \afterADDOP{%
+ \addEQ@\ifx \next
+ \addtotoks@{\X@c=\D@c \advance\X@c\U@c \Y@c=\L@c \advance\Y@c\R@c}%
+ \else
+ \addtotoks@{\X@c=\objectmargin@ \advance\X@c\X@c \Y@c=\X@c}%
+ \fi
+ \let\xy@=\xytotoks@
+ \afterVECTORorEMPTY\OBJECT@change@\OBJECT@change@}}
+
+\xydef@\OBJECT@set{%
+ \afterADDOP{%
+ \let\xy@=\xytotoks@ \afterVECTORorEMPTY\OBJECT@change@
+ {\addtotoks@{\X@c=\objectwidth@ \Y@c=\objectheight@}\OBJECT@change@}}}
+\DOCMODE)
+
+ The real work is done by the following command: a hack using
+ expansion tricks to make use of the |\Addop@@| known now on the
+ values in $X,Y$ at modification time.
+
+\DOCMODE(
+\xydef@\OBJECT@change@{%
+ \addtotoks@{\advance\R@c\L@c \advance\R@p-\L@c \let\tmp@=\R@c}%
+ \expandafter\addtotoks@\expandafter{\Addop@@\tmp@\X@c\R@c=\tmp@
+ \L@c=\Leftness@\R@c \advance\R@p\L@c \advance\R@c-\L@c}%
+ \addtotoks@{\advance\D@c\U@c \let\tmp@=\D@c}%
+ \expandafter\addtotoks@\expandafter{\Addop@@\tmp@\Y@c\D@c=\tmp@
+ \U@c=\Upness@\D@c \advance\D@c-\U@c}%
+ \let\xy@=\oxy@ \xyFN@\OBJECT@}
+\DOCMODE)
+
+ It is clearly crucial that |\Addop@@| expands to its action
+ immediately! Also note that enlarging changes the initial box offset
+ in the horizontal direction only, \ie, $R_p$.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Finally the code to interpret an <add op> used above: This
+ simply parses it and creates a macro |\Addop@@| that takes a
+ control sequence and a parameter <dimen> as arguments, and
+ expands directly to commands that perform the <add op> of the
+ <dimen> on the control sequence:
+$$
+\begin{array}{\otherbar c\otherbar l\otherbar}
+\hline
+ \hbox{<add op>} & \hbox{effect of |\Addop@@| "cs" $D$} \\
+\hline
+ |+| & "cs" \from "cs"+D \\
+ |-| & "cs" \from "cs"-D \\
+ |=| & "cs" \from D \\
+ |+=| & "cs" \from \left\{
+ \begin{array}{cc} D & \hbox{if $D\le"cs"$} \\
+ "cs" & \hbox{if $D\gt"cs"$} \end{array}\right.
+ \\[1pt]
+ |-=| & "cs" \from \left\{
+ \begin{array}{cc} D & \hbox{if $D\ge"cs"$} \\
+ "cs" & \hbox{if $D\lt"cs"$} \end{array}\right.
+ \\[1pt]
+\hline
+\end{array}
+$$
+ Furthermore ??c![\afterADDOP] leaves the |\next| token set to |=| in
+ the last three cases only (this is used to determine the right
+ default value in the size changes above).
+
+ The ??c![\afterADDOP] macro is relatively simple because <add op>s
+ don't nest:
+
+\DOCMODE(
+\xydef@\afterADDOP#1{\def\afterADDOP@{#1}\xyFN@\ADDOP@}
+
+\xylet@\afterADDOP@=\empty
+
+\xydef@\ADDOP@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\ADDOP@}%gobble spaces
+ \else\addPLUS@\ifx \next \addPLUS@\DN@{\xyFN@\ADDOP@plus}%
+ \else\addDASH@\ifx \next \addDASH@\DN@{\xyFN@\ADDOP@minus}%
+ \else\addEQ@\ifx \next
+ \addEQ@\DN@{\def\Addop@@{\Addop@0+=}\afterADDOP@}%
+ \else
+ \DN@{\def\Addop@@{\Addop@0+=}\afterADDOP@}%
+ \fi\fi\fi\fi \next@}
+
+\xydef@\ADDOP@plus{%
+ \addEQ@\ifx \next
+ \addEQ@\DN@{\def\Addop@@{\Addop@0+<}\afterADDOP@}%
+ \else
+ \DN@{\def\Addop@@{\Addop@1+=}\afterADDOP@}%
+ \fi \next@}
+
+\xydef@\ADDOP@minus{%
+ \addEQ@\ifx \next
+ \addEQ@\DN@{\def\Addop@@{\Addop@0+>}\afterADDOP@}%
+ \else
+ \DN@{\def\Addop@@{\Addop@1-=}\afterADDOP@}%
+ \fi \next@}
+\DOCMODE)
+
+ The work is done by the general |\Addop@| |{|$f$|}| |{|$\pm$|}|
+ |{|$\bowtie$|}| |{|"cs"|}| $D$ that defines
+$$
+"cs" \equiv \left\{
+ \begin{array}{ll}
+ f*"cs"~{\pm}~D & \hbox{if $\lnot ((f*"cs"~{\pm}~D)~{\bowtie}~D)$} \\
+ "cs" & \hbox{otherwise} \end{array}\right.
+$$
+ and also leaves the dimension in |\dimen@|.
+
+\DOCMODE(
+\xydef@\Addop@#1#2#3#4#5{%
+ \dimen@=#4\relax \edef#4{\the\dimen@}%
+ \dimen@=#1\dimen@ \advance\dimen@#2#5\relax %\advance\dimen@ 1sp %HACK
+ \ifdim\dimen@#3#4\else \edef#4{\the\dimen@}\fi
+ \ifx\xy@\xyinitial@\else \DN@##1{\xy@@{\edef#4{##1}\checkZeroEdge@}}%
+ \expandafter\next@\expandafter{#4}\fi}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[hidden]
+%
+ A "hidden" object will be typeset but hidden from \Xy-pic in that it
+ won't affect the size of the entire picture as discussed
+ in~\S??[basics.pos].
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ This is handled by the |\ifHidden@| conditional allocated with the
+ methods.
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[invisible]
+%
+ An "invisible" object will be treated completely normal except that
+ it won't be typeset, \ie, \Xy-pic will behave as if it was.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ This is handled by the |\ifInvisible@| conditional allocated with the
+ methods.
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[<shape>]
+%
+ Setting the "shape" of an object forces the shape of its edge to be
+ as indicated. The kernel provides three shapes that change the edge,
+ namely ??C![.], ??C![], and ??C![o], corresponding to the outlines
+$$
+\let\objectstyle=\scriptstyle
+\xy*{*}\endxy
+\quad
+\textrm{,}
+\quad
+\xy(0,0).(-10,-4).(15,7)*\frm{-}="box"*{*}+0;
+ "box"+L*{}**@{.}?*{L},
+ "box"+R*{}**@{.}?*{R},
+ "box"+D*{}**@{.}?*{D},
+ "box"+U*{}**@{.}?*{U}
+\endxy
+\quad
+\textrm{, and}
+\quad
+\xy*[o]=<40pt>{*}="box"*\cir{}+0;
+ "box"+L*{}**@{.}?*{L},
+ "box"+R*{}**@{.}?*{R},
+ "box"+D*{}**@{.}?*{D},
+ "box"+U*{}**@{.}?*{U}
+\endxy
+$$
+ where the $*$ denotes the point of the reference position in the
+ object (the first is a point). Extensions can provide more shapes,
+ however, all shapes set the extent dimensions $L$, $R$, $D$,
+ and $U$.
+
+ The default shape for objects is ??C![] and for plain coordinates it
+ is ??C![.].
+
+\DOCMODE(
+\xydef@\objectEdge{\rectangleEdge}
+\DOCMODE)
+
+ Furthermore the <shape>s ??C![r], ??C![l], ??C![u], and ??C![d], are
+ defined for convenience to adjust the object to the indicated side by
+ setting the reference point such that the reference point is the same
+ distance from the opposite of the indicated edge and the two
+ neighbour edges but never closer to the indicated side than the
+ opposite edge, \eg, the object |[r]\hbox{Wide text}| has reference
+ point at the $*$ in $\xy*[r]\hbox{Wide text}*\frm{-}*{*}\endxy$ but
+ the object |[d]\hbox{Wide text}| has reference
+ point at the $*$ in $\xy*[d]\hbox{Wide text}*\frm{-}*{*}\endxy$.
+ Finally, ??C![c] puts the reference point at the center.
+
+\DOCMODE(
+\xydefcsname@{shape [r]}{\advance\U@p\D@c \centerobject@
+ \ifdim\L@c>\D@c
+ \advance\R@c\L@c \L@c=.5\U@c \advance\L@c.5\D@c \advance\R@c-\L@c \fi
+ \advance\U@p-\D@c}
+\xydefcsname@{shape [l]}{\advance\U@p\D@c \centerobject@
+ \ifdim\L@c>\D@c
+ \advance\L@c\R@c \R@c=.5\U@c \advance\R@c.5\D@c \advance\L@c-\R@c \fi
+ \advance\U@p-\D@c}
+\xydefcsname@{shape [u]}{\advance\U@p\D@c \centerobject@
+ \ifdim\D@c>\L@c
+ \advance\U@c\D@c \D@c=.5\L@c \advance\D@c.5\R@c \advance\U@c-\D@c \fi
+ \advance\U@p-\D@c}
+\xydefcsname@{shape [d]}{\advance\U@p\D@c \centerobject@
+ \ifdim\D@c>\L@c
+ \advance\D@c\U@c \U@c=.5\L@c \advance\U@c.5\R@c \advance\D@c-\U@c \fi
+ \advance\U@p-\D@c}
+\xydefcsname@{shape [c]}{\advance\U@p\D@c \centerobject@ \advance\U@p-\D@c}
+
+\xydef@\centerobject@{%
+ \advance\D@c\U@c \D@c=.5\D@c \U@c=\D@c \advance\L@c\R@c \L@c=.5\L@c \R@c=\L@c}
+\DOCMODE)
+
+ \NOTE: Extensions can add new <shape> object <modifier>s which are
+ then called <style>s. These will always be either of the form
+ |[|<keyword>|]| or |[|<character> <argument>|]|. Some of these
+ <style>s do other things than set the edge of the object.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ A ``simple shape'' is just a control sequence |\shape [|<shape>|]|
+ setting the appropriate edge. When such a |[|<shape>|]| modifier is
+ encountered then we expand this control sequence onto the modifier
+ queue, unless a control sequence |\style [|<shape>|]| exists: then
+ that is expected to do it (and whatever else is required).
+
+\DOCMODE(
+\xydef@\OBJECT@shape#1{\DN@{shape [#1]}%
+ \expandafter\let\expandafter\nextii@\csname\codeof\next@\endcsname
+ \ifx\nextii@\relax\DN@{style [#1]}%
+ \expandafter\let\expandafter\nextii@\csname\codeof\next@\endcsname
+ \ifx\nextii@\relax \DN@{\OBJECT@shapei[#1]}%
+ \else\DN@{\nextii@\xyFN@\OBJECT@}\fi
+ \else \expandafter\addtotoks@\expandafter{\nextii@}%
+ \DN@{\xyFN@\OBJECT@}%
+ \fi \next@}
+
+\xydefcsname@{shape []}{\the\Edge@c5\relax}%
+\xydefcsname@{shape [Outer]}{\the\Edge@c5\relax}%
+\xydefcsname@{shape [Inner]}{\the\Edge@c4\relax}%
+\xydefcsname@{shape [o]}{\Edge@c={\circleEdge}\the\Edge@c5\relax
+ \Edge@c={\circleEdge}\def\prevEdge@@{\circleEdge}}
+\xydefcsname@{shape [.]}{\czeroEdge@}
+\DOCMODE)
+
+ Add more simple shapes by defining more commands like these and
+ proceed with coding the |\|\dots|Edge| command as described
+ in~\S??[algo.edge].
+
+ Alternatively it is a ``complex shape'' of which none are defined in
+ the kernel but some options like more variation\dots It is
+ characterised by its first token and the rest of the contents of the
+ ??C![]s is the argument (remember: no |{}[]| characters!); it is
+ searched for as control sequence |\[|<shape>|...]| overridden
+ in the same way by |\*stylechar@|<shape>|@|.
+
+\DOCMODE(
+\def\OBJECT@shapei[#1#2]{\DN@{shape [#1...]}%
+ \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
+ \ifx\next\relax\DN@{*stylechar@#1@}%
+ \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
+ \ifx\next\relax\DNii@{shape [#1#2]}%
+ \xywarning@{illegal [<shape>] ignored: \codeof\nextii@\space not defined}%
+ \DN@{\xyFN@\OBJECT@}%
+ \else% Delete this: \expandafter\addtotoks@\expandafter{\next{#2}}%
+ \DN@{\next{#2}\xyFN@\OBJECT@}%
+ \fi
+ \else
+
+\expandafter\addtotoks@\expandafter{\next{#2}}\DN@{\next{#2}\xyFN@\OBJECT@}%
+ \fi \next@}
+\DOCMODE)
+
+ \BUG: The above is messy!
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[define <shape>]
+%
+ While typesetting an object, some of the properties are considered
+ part of the `??w![current object style]??w[style]'. Initially this
+ means nothing but some of the <style>s defined by extensions have
+ this status, \eg, colours |[red]|, |[blue]| say, using the |xycolor|
+ extension, or varying the width of lines using |xyline|. Such styles
+ are processed "left-to-right"; for example,
+$$
+|*[red][green][=NEW][blue]{A}|
+$$
+ will typeset a blue |A| and define |[NEW]| to set the colour to green
+ (all provided that |xycolor| has been loaded, of course).
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The method of requesting a special effect is via the <shape>
+ modifiers. However the code required for implementation is quite
+ different. In particular it must allow for the different ways in
+ which the <driver> may implement the |\special|s required to
+ activate, and turn off, the effect. Another difficulty is that the
+ <style> applies also to nested sub-parts of any <object>. This means
+ that the code cannot be wholly delayed until after the <object> has
+ been constructed.
+
+ Usually some value has to be stored, so as to be accessible to
+ sub-parts, though the |\special| commands cannot be fully constructed
+ until the <object> is completely known and ready to be |\Drop@@| or
+ |\Connect@@|'ed.
+
+ Finally, the overhead in using |\special| commands can be quite high
+ with some |dvi|-drivers. Thus it is not best that every <style>
+ request generate a |\special| command; indeed {\it two} |\special|
+ commands, since each style-change also requires a command to revert
+ to the previous style, after the change is no longer applicable.
+
+ Thus, as with <shape>s, all the style-change requests are stored
+ until the <object> is ready to be |\Drop@@|'ed. This also helps with
+ getting the sequencing correct when later requests compound on, or
+ override, earlier requests.
+
+ When the <style> requests are processed, after the <object> has been
+ constructed, information of the form <control-word>|{|<data>|}| is
+ added to a global list called |\preXY@style@|. Similar information is
+ added to another global list |\postXY@style@|, for the purpose of
+ reverting the style parameters, within the <driver>-file, to their
+ previous values prior to the current <object>.
+
+ Both lists are initially <empty> at the start of an <object>. The
+ contents of these lists are processed when the macros
+ |\xypre@Style@@| and |\xypost@Style@@| are encountered in the
+ expansion of |\styledboxz@|.
+
+\DOCMODE(
+\xydef@\preXY@style@{}
+\xydef@\postXY@style@{}
+
+\xydef@\resetStyle@{\gdef\preXY@style@{}\gdef\postXY@style@{}}
+\DOCMODE)
+
+ The <data> contains the code needed to implement the requested
+ style-change, with the particular <driver> being used.
+
+ The <control-word> is a macro whose expansion could be fixed, or
+ could depend upon what other style-change requests are made for this
+ <object>. Its purpose is to decide whether or not the <data> is
+ actually required. If so, it is added to the token-list
+ |\styletoks@| for later use.
+
+ Whether the <control-word>|{|<data>|}| tokens are prepended or
+ appended to the global lists depends upon the nature of the
+ style-change requested. For example, with |*[red][green]|<object>
+ the information |\|<set-color>|{|<green>|}| could be appended to
+ |\preXY@style@|, with |\|<revert-to-color>|{|<red>|}| prepended to
+ |\postXY@style@|. Then the dvi-output would set the color to <red>
+ then <green> and restore it first to <red> then <black>.
+
+ \TODO: A more sophisticated implementation could instead prepend
+ |\|<set-color>|{|<green>|}| to |\preXY@style@| and append
+ |\|<revert-to-color>|{|<red>|}| to |\postXY@style@|. Now the first
+ |\|<set-color> encountered adds its <data> to |\styletoks@| then
+ rebinds |\|<set-color> to |\eat@|, to ignore subsequent occurrences.
+ Similarly |\|<revert-to-color> is rebound so that only the is
+ restoration to <black> is retained.
+
+ This latter strategy is preferred when the overhead for a |\special|
+ command is high, within the <driver>'s output. Indeed the \PS\
+ back-end is even more efficient. Since \PS\ is itself a programming
+ language, the <data> can be just the \PS\ code. A single |\special|
+ command is sufficient to accommodate {\it all\/} the style-changes
+ for an individual <object>. This is achieved by rebinding
+ |\xydoprestyles@@| and |\xydopoststyles@@| to include the <data>
+ within an appropriately prepared |\special| command.
+
+\DOCMODE(
+\xynew@{toks}{\styletoks@}
+\xydef@\addtostyletoks@#1{%
+ \expandafter\styletoks@\expandafter{\the\styletoks@#1}}
+\DOCMODE)
+
+ The <data> to be used is collected in the token-list |\styletoks@|.
+ If this is <empty> for an <object> then the style processing is
+ skipped completely. For safety, in case multiple occurences of
+ |\xypre@Style@| have somehow slipped into the token stream, these and
+ |\xypost@Style@@| are bound to |\relax| until the <object> is
+ finished. Indeed |\xypost@Style@@| is always bound to |\relax| unless
+ |\styletoks@| is non-empty.
+
+\DOCMODE(
+\xydef@\styledboxz@{%
+%
+%\W@{STYLED BOX:}%
+%\W@{: PRE={\meaning\xypre@Style@@}}%
+%
+ \xypre@Style@@
+%
+%{\expandafter\DN@\expandafter{\the\styletoks@}\W@{: STYLTOKS={\codeof\next@}}}%
+%
+ \boxz@
+%
+%\W@{: POST={\meaning\xypost@Style@@}}%
+%
+ \xypost@Style@@}
+
+\xydef@\xypre@Style@{\styletoks@={}\saveXyStyle@\preXY@style@
+ \expandafter\DN@\expandafter{\the\styletoks@}%
+ \ifx\next@\empty \DN@{\let\xypre@Style@@=\relax
+ \let\xypost@Style@@=\relax \xypre@skipStyle@}%
+ \else
+ \let\xypre@Style@@=\relax \let\xypost@Style@@=\xypost@Style@
+ \DN@{\expandafter\xydoprestyles@\expandafter{\the\styletoks@}}%
+ \fi \next@ }
+
+\xydef@\xypost@Style@{\styletoks@={}\postXY@style@
+ \expandafter\xydopoststyles@\expandafter{\the\styletoks@}%
+ \let\xypost@Style@@=\relax \let\xypre@Style@@=\xypre@Style@ }
+
+\xydef@\xypre@skipStyle@#1\xypost@Style@@{#1\relax
+ \let\xypre@Style@@=\xypre@Style@ }
+
+\xydef@\xydoprestyles@@{\literal@}
+\xydef@\xydopoststyles@@{\literal@}
+\xylet@\xydoprestyles@=\xydoprestyles@@
+\xylet@\xydopoststyles@=\xydopoststyles@@
+\DOCMODE)
+
+ Some extensions use the following macros to add style <data> to the
+ global macros. Here code is added sequentially to |\preXY@style@| so
+ that it is acted upon in the order of occurrence (FIFO) of the
+ <shape> modifiers. Code is added to |\postXY@style@| in reverse order
+ (LIFO), so that each addition to |\preXY@style@| can be closed off,
+ if necessary, in correctly nested sequence.
+
+\DOCMODE(
+\xydef@\modXYstyle@{%
+ \ifx\xy@style@\empty\resetStyle@\fi \checkXyStyle@
+ \expandafter\expandafter\expandafter\DN@
+ \expandafter\expandafter\expandafter{\preXYstyle@@}%
+ \ifx\next@\empty\else\DN@{\modXYstyle@@}\fi \next@ }
+
+\xydef@\modXYstyle@@{%
+ \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
+ \expandafter\next@\expandafter{\preStyle@@}%
+ \DN@##1{\expandafter\gdef\expandafter\preXY@style@\expandafter{%
+ \preXY@style@ ##1}}\expandafter\next@\expandafter{\tmp@}%
+ \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
+ \expandafter\next@\expandafter{\postStyle@@}%
+ \DN@##1{\expandafter\gdef\expandafter\postXY@style@\expandafter{%
+ \tmp@ ##1}}\expandafter\next@\expandafter{\postXY@style@}}
+
+\xydef@\xy@style@{}
+\xydef@\checkXyStyle@{\ifx\xy@style@\empty\resetStyle@\fi
+ \let\xy@style@=\relax}
+\DOCMODE)
+
+ The |\preStyle@| and |\postStyle@| temporarily hold style <data>.
+ The macro |\preXYstyle@@| is used to check whether there is any
+ <data> to process. Normally this is just an alias for |\preStyle@@|,
+ but some back-ends may use the two control-names differently.
+
+\DOCMODE(
+\xydef@\preStyle@@{}
+\xydef@\postStyle@@{}
+\xydef@\preXYstyle@@{\relax}
+
+\xydef@\loadxystyle@{%
+ \let\xypre@Style@@=\xypre@Style@ \def\preXYstyle@@{\preStyle@@}}
+
+\loadxystyle@
+\DOCMODE)
+
+ Initially styles are activated but can be suppressed using
+ |\Unloadstyle@|.
+
+\DOCMODE(
+\xydef@\Unloadstyle@{%
+ \let\xypre@Style@@=\relax \let\xypost@Style@@=\relax
+ \def\preXYstyle@@{\relax}}
+\DOCMODE)
+
+ Global macros are used, so that the same styles can be reused by
+ successive objects without having to re-interpret <shape> modifiers,
+ as described next.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Saving styles:\ }
+
+ Once specified for an <object>, the collection of <style>s can be
+ assigned a name, using ??c![[=]<word>|]|. Then |[|<word>|]| becomes a
+ new <style>, suitable for use with the same or other <objects>s. Use
+ a single <word> built from ordinary letters. If |[|<word>|]| already
+ had meaning the new definition will still be imposed, but the
+ following type of warning will be issued:
+$$
+|Xy-pic Warning: Redefining style [|<word>|]|
+$$
+ The latter warning will appear if the definition occurs within an
+ ??c![\xymatrix]. This is perfectly normal, being a consequence of the
+ way that the matrix code is handled. Similarly the message may appear
+ several times if the style definition is made within an ??c![\ar].
+
+\begin{code}
+ \setbox0=\hbox{%
+ \xy\drop[OrangeRed][=A]{}\endxy}
+\end{code}
+
+\noindent
+ The following illustrates how to avoid these messages by defining the
+ style without typesetting anything.
+
+\displaycode
+
+ \NOTE{~1:} The current colour is regarded as part of the style for
+ this purpose.
+
+ \NOTE{~2:} Such namings are global in scope. They are intended to
+ allow a consistent style to be easily maintained between various
+ pictures and diagrams within the same document.
+
+\DOCMODE(
+\xydefcsname@{shape [=...]}#1{\checkXyStyle@ \addtotoks@{\xynamestyle@{#1}}}
+
+\xydef@\xynamestyle@#1{\checkXyStyle@
+ \expandafter\DNii@\expandafter{\csname shape [#1]\endcsname}%
+ \expandafter\ifx\nextii@\relax %%\xywarning@{Defining new style [#1]}%
+ \else\xywarning@{Redefining style [#1]}\fi
+ \expandafter\xynamestyle@@\csname shape [#1]\endcsname }
+
+\xydef@\xynamestyle@@#1{%
+ \expandafter\def\expandafter\tmp@\expandafter{\preXY@style@}%
+ \DN@##1{\def\tmp@{\checkXyStyle@\gdef\preXY@style@{##1}}}%
+ \expandafter\next@\expandafter{\preXY@style@}%
+ \DN@##1{\expandafter\gdef\expandafter#1\expandafter{\tmp@
+ \gdef\postXY@style@{##1}}}%
+ \expandafter\next@\expandafter{\postXY@style@}\DN@{}}
+\DOCMODE)
+
+ If the same <style> is intended for several <object>s occurring
+ in succession, the |[||*]| <modifier> can be used on the later
+ <object>s. This only works when |[||*]| precedes any other <style>
+ modifiers; it is local in scope, recovering the last <style>s used
+ at the same level of \TeX\ grouping.
+
+\DOCMODE(
+\xydef@\prevXypreStyle@@{}
+\xydef@\prevXypostStyle@@{}
+
+\xydef@\saveXyStyle@{\expandafter
+ \def\expandafter\prevXypreStyle@@\expandafter{\preXY@style@}%
+ \expandafter\def\expandafter\prevXypostStyle@@\expandafter{%
+ \postXY@style@}}
+
+\xydef@\recoverXyStyle@{\expandafter
+ \gdef\expandafter\preXY@style@\expandafter{\prevXypreStyle@@}%
+ \expandafter\gdef\expandafter\postXY@style@\expandafter{%
+ \prevXypostStyle@@}}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Defining new effects}
+
+ Allow new effects to be declared and a default action provided. The
+ name is constructed from |#1| and the action to be taken is passed as
+ |#2|. If |#3| is non-empty then overwrite any existing definition for
+ a control sequence of the same name.
+
+\DOCMODE(
+\xydef@\newxystyle#1#2#3{%
+ \DN@{#3}\ifx\next@\empty
+ \xydefcsname@{shape [#1]}{\csname xyshape@#1@\endcsname}%
+ \else \expandafter\def\csname shape [#1]\endcsname{%
+ \csname xyshape@#1@\endcsname}\fi
+ \DN@{#2}\ifx\next@\empty
+ \expandafter\def\csname xyshape@#1@\endcsname{%
+ \xyundefinedStyle@{#1}{}@@}%
+ \else \expandafter\def\csname xyshape@#1@\endcsname{#2}\fi}
+
+\xydef@\xyundefinedStyle@#1#2@@{%
+ \xywarning@{style #1 not defined, nothing to apply}}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Support for a new <style> takes the following form, in which
+ |\thestyle@| expands to the current value of the <style> information
+ to be maintained. If this is kept in a <count> or <dimen> register,
+ named |\xystyle@| say, then replace |\thestyle@| by
+ |\the\style@|. (However due to the large number of <dimen>s already
+ allocated, it is preferable to keep a text form of the value in
+ |\thestyle@|.)
+
+\begin{code}
+\xyshape@stylechange@{\modifystyle@{<how>}}
+\xydef@\modifystyle@#1{\checkXyStyle@
+ \edef\prevstyle@{\thestyle@}\modifystyle@@{#1}%
+ \let\prestyle@=\prestyle@@ \let\poststyle@=\poststyle@@
+ \applystyle@\prestyle@{\thestyle@}\poststyle@{\prevstyle@}}
+\xydef@\resetstyle@@#1{\def\thestyle@{#1}\outputstyle@{#1}}
+\xydef@\outputstyle@#1{\transformstyle@{#1}%
+ \expandafter\stylespecial@\expandafter{\next@}}
+\xylet@\transformstyle@@=\DN@
+\xylet@\transformstyle@=\transformstyle@@
+\end{code}
+\displaycode
+
+ In the above the macros |\modifystyle@@| and |\stylespecial@| are
+ adapted to the particular <style> information, see below. Typically
+ <how> is actual \TeX\ code and |\modifystyle@@| is simply |\literal@|
+ to execute this code. Typesetting is done by |\stylespecial@#1|
+ which is typically of the form |\special{|<key> |#1}|.
+
+ The |\transformstyle@| is required in case a dvi-<driver> needs
+ information in a form that is different to how \Xy-pic maintains it
+ in |\thestyle@|. A <driver> file should define |\|<driver>|@style@@|
+ to perform the transformation and place its result in |\next@|.
+ Install this macro using |\let\transformstyle@=\|<driver>|@style@@|
+ within the <driver> installation macro.
+
+\medskip
+
+ Next we discuss |\applystyle@|; which uses |\prestyle@|,
+ |\prestyle@@|, |\poststyle@| and |\poststyle@@|. There are two
+ strategies here, affecting how much information is placed into the
+ dvi-file, indicated by the alternative expansions given above. The
+ appropriateness for a given style must be decided by the author of
+ the style-option.
+
+ Suppose several modifications are made to a particular style
+ parameter. We must build a list of commands |\prestyle@{|<value>|}|,
+ to be executed later, which will recover the required value. Also we
+ build a list of commands |\poststyle@{|<value>|}| to reset to the
+ previous value.
+
+ In most cases it is only the result of the modifications that need be
+ placed into the dvi-file. Since we do not know how many, if any, more
+ modifications follow we could store each new result {\em after} the
+ previous, so that its effect will override the previous value. This
+ is building a FIFO list for the |\prestyle@| commands, with a FILO
+ list for the |\poststyle@| commands:
+
+\DOCMODE(
+\xydef@\applyFIFOstyle@#1#2#3#4{\bgroup
+ \styletoks@={\egroup\gdef\preXY@style@}%
+ \expandafter\toks@\expandafter{\preXY@style@}%
+ \expandafter\addtotoks@\expandafter{\expandafter#1\expandafter{#2}}%
+ \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}%
+ \gdef\postXY@style@}%
+ \expandafter\toks@\expandafter{\expandafter#3\expandafter{#4}}%
+ \expandafter\addtotoks@\expandafter{\postXY@style@}%
+ \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}}%
+ \the\styletoks@ }
+\DOCMODE)
+%
+\noindent
+ Use this via:
+ |\applyLIFOstyle@\prestyle@{\thestyle@}\poststyle@{\prevstyle@}|.
+ \newline With this method each modification places two entries into
+ the dvi-file; there is no need for separate |\prestyle@| and
+ |\prestyle@@| macros.
+
+ Perhaps a more efficient strategy is to build a LIFO list for the
+ |\prestyle@| commands. This way the required value is encountered
+ first. This first instance should then cancel all subsequent
+ instances of |\prestyle@|. This is where the need comes for a
+ |\prestyle@@|. Accompanying this is a FIFO list for the
+ |\poststyle@| commands, with a corresponding |\poststyle@@| to kill
+ subsequent instances:
+
+\DOCMODE(
+\xydef@\applyLIFOstyle@#1#2#3#4{\bgroup
+ \styletoks@={\egroup\gdef\preXY@style@}%
+ \expandafter\toks@\expandafter{\expandafter#1\expandafter{#2}}%
+ \expandafter\addtotoks@\expandafter{\preXY@style@}%
+ \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}%
+ \gdef\postXY@style@}%
+ \expandafter\toks@\expandafter{\postXY@style@}%
+ \expandafter\addtotoks@\expandafter{\expandafter#3\expandafter{#4}}%
+ \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}}%
+ \the\styletoks@ }
+\DOCMODE)
+
+\noindent
+ Use this via:
+ |\applyLIFOstyle@\prestyle@{\thestyle@}\poststyle@{\prevstyle@}|.
+ \newline The advantage here is that only two pieces of data need be
+ output to the dvi-file, no matter how many modifications are
+ requested.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[diagonal]??=[direction]??=[<direction>]
+%
+ Setting the current direction is simply pretending for the
+ typesetting of the object (and the following <modifier>s) that some
+ connection set it -- the <empty> case just inherits the previous
+ direction.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The code just calls the general <direction> parser below:
+
+\DOCMODE(
+\xydef@\OBJECT@direction{\afterDIRECTIONorEMPTY{%
+ \edef\next@{{\DirectionfromtheDirection@}}\expandafter\addtotoks@\next@
+ \xyFN@\OBJECT@}%
+ {\xyFN@\OBJECT@}}
+\DOCMODE)
+
+ Here is the <direction> parser: first the parts parsing the <diag>
+ part then the parts parsing the <trailer> part:
+
+\DOCMODE(
+\xydef@\afterDIRECTIONorEMPTY#1#2{%
+ \DN@##1{\def\afterDIRECTION@{\def\afterDIRECTION@{##1}%
+ \ifDIRECTIONempty@\DN@{#2}\else\DN@{#1}\fi \next@}}%
+ \expandafter\next@\expandafter{\afterDIRECTION@}%
+ \xyFN@\DIRECTION@}
+
+\xylet@\afterDIRECTION@=\empty
+\xynew@{if}\ifDIRECTIONempty@
+
+\xydef@\DIRECTION@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\DIRECTION@}%gobble spaces
+ \else\ifx v\next \DN@ v{\DIRECTION@v}%
+ \else\ifx \bgroup\next \let\next@=\DIRECTION@group
+ \else\ifx (\next \DN@({\xyFN@\DIRECTION@open}%))
+ \else
+ \DN@{\count@=8 %
+ \afterDIAG{\ifnum\count@=8 \DN@{\DIRECTIONempty@true \xyFN@\DIRECTION@i}%
+ \else \DN@{\xy@@{\dimen@=\xydashl@}\Directionfromdiag@}\fi \next@}}%
+ \fi\fi\fi\fi \next@}
+
+\xydef@\DIRECTION@open{%
+ \ifx *\next \DN@*##1*){\DIRECTION@group{##1}}%
+ \else \DN@{\xyerror@{(* <pos> *) expected}{} \xyFN@\DIRECTION@i}%
+ \fi \next@}
+\DOCMODE)
+
+\paragraph*{Diagonal directions.}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ It is particularly easy to set <diag>onal directions:
+$$
+\xy *[o]\cir<1pc>{}="c",
+ "c"; (-1,-1)**{},p+/4pc/ *+{|dl|=|ld|} **@{-}?>*@{>},
+ "c"; ( 0,-1)**{},p+/4pc/ *+{|d|} **@{-}?>*@{>},
+ "c"; ( 1,-1)**{},p+/4pc/ *+{|dr|=|rd|} **@{-}?>*@{>},
+ "c"; ( 1, 0)**{},p+/4pc/ *+{|r|} **@{-}?>*@{>},
+ "c"; ( 1, 1)**{},p+/4pc/ *+{|ur|=|ru|} **@{-}?>*@{>},
+ "c"; ( 0, 1)**{},p+/4pc/ *+{|u|} **@{-}?>*@{>},
+ "c"; (-1, 1)**{},p+/4pc/ *+{|ul|=|lu|} **@{-}?>*@{>},
+ "c"; (-1, 0)**{},p+/4pc/ *+{|l|} **@{-}?>*@{>},
+\endxy
+$$
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ More to the point, <diag>onals are stored internally as
+$$
+\xy *\cir<1pc>{}="c",
+ "c"; (-1,-1)**{},p+/3pc/ *+{|0|} **@{-}?>*@{>},
+ "c"; ( 0,-1)**{},p+/3pc/ *+{|1|} **@{-}?>*@{>},
+ "c"; ( 1,-1)**{},p+/3pc/ *+{|2|} **@{-}?>*@{>},
+ "c"; ( 1, 0)**{},p+/3pc/ *+{|3|} **@{-}?>*@{>},
+ "c"; ( 1, 1)**{},p+/3pc/ *+{|4|} **@{-}?>*@{>},
+ "c"; ( 0, 1)**{},p+/3pc/ *+{|5|} **@{-}?>*@{>},
+ "c"; (-1, 1)**{},p+/3pc/ *+{|6|} **@{-}?>*@{>},
+ "c"; (-1, 0)**{},p+/3pc/ *+{|7|} **@{-}?>*@{>},
+\endxy
+$$
+ Expanding |\afterDIAG{|<stuff>|}|<diag> will result in |\count@|
+ being set to the <diag> code (not changed in case the <diag> is
+ <empty>) before expanding <stuff>.
+
+\DOCMODE(
+\def\afterDIAG#1{\def\afterDIAG@{#1}\xyFN@\DIAG@}
+
+\xydef@\DIAG@{%
+ \ifx d\next \DN@ d{\count@=1 \xyFN@\DIAG@@}%
+ \else\ifx r\next \DN@ r{\count@=3 \xyFN@\DIAG@@}%
+ \else\ifx u\next \DN@ u{\count@=5 \xyFN@\DIAG@@}%
+ \else\ifx l\next \DN@ l{\count@=7 \xyFN@\DIAG@@}%
+ \else \let\next@=\afterDIAG@
+ \fi\fi\fi\fi \next@}
+
+\xydef@\DIAG@@{\ifcase\count@ \or
+%\count@=1 3 5 7
+ \DIAG@@@ l0r2\or\or \DIAG@@@ d2u4\or\or \DIAG@@@ r4l6\or\or \DIAG@@@ u6d0%
+ \else\xybug@{impossible <diag> number}\fi
+ \next@}
+
+\xydef@\DIAG@@@#1#2#3#4{%
+ \ifx #1\next \count@=#2\DN@#1{\afterDIAG@}%
+ \else \ifx #3\next \count@=#4\DN@#3{\afterDIAG@}%
+ \else \let\next@=\afterDIAG@ \fi\fi}
+\DOCMODE)
+
+ The action in case of a <diag> is simply to pick the right direction
+ setup routine according to the encoding, getting the <diag> from
+ |\count@| and the length of the $d$ vector from |\dimen@|:
+
+\DOCMODE(
+\xydef@\Directionfromdiag@{\ifcase\count@
+ \xy@@{\dlDirection@\dimen@}%
+ \or \xy@@{\dDirection@\dimen@}%
+ \or \xy@@{\drDirection@\dimen@}%
+ \or \xy@@{\rDirection@\dimen@}%
+ \or \xy@@{\urDirection@\dimen@}%
+ \or \xy@@{\uDirection@\dimen@}%
+ \or \xy@@{\ulDirection@\dimen@}%
+ \or \xy@@{\lDirection@\dimen@}%
+ \or % 8 is legal and means change nothing
+ \else\xybug@{impossible <diag>}\fi
+ \DIRECTIONempty@false \xyFN@\DIRECTION@i}
+\DOCMODE)
+
+\paragraph*{Vector directions.}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Alternatively |v|<vector> sets the direction as if the connection
+ from |0| to the <vector> had been typeset except that the "origin" is
+ assumed zero such that directions $|v(|x|,|y|)|$ mean the natural
+ thing, \ie, is the direction of the connection from |(0,0)| to
+ $|(|x|,|y|)|$.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The action for a |v| reads a <vector> and sets the direction
+ accordingly using some expansion hackery to propagate it out. The
+ "origin" is cleared locally to make |v(|$x$|,|$y$|)| behave as it
+ should.
+
+\DOCMODE(
+\xydef@\DIRECTION@v{%
+ \xy@{v}{\enter@{\cfromthec@ \X@origin=\the\X@origin \Y@origin=\the\Y@origin
+ \X@p=\the\X@p \Y@p=\the\Y@p}%
+ \X@origin=\z@ \Y@origin=\z@}%
+ \afterVECTORorEMPTY
+ {\xy@@{\X@p=\z@ \Y@p=\z@ \setupDirection@ \leave@}%
+ \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
+ {\xy@@\leave@ \xyerror@{<vector> expected after v}{}%
+ \DIRECTIONempty@false \xyFN@\DIRECTION@i}}
+\DOCMODE)
+
+\paragraph*{Complex direction.}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ In case the direction is not as simple, you can construct
+ |{| <pos> <decor> |}| that sets up $p$ and $c$ such that
+ $\overline{pc}$ has the desired direction. \NOTE: that you must use
+ the |(*|\dots|*)| form if this is to appear in an object <modifier>!
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The code for this is rather like the one for <vector>s.
+
+\DOCMODE(
+\xydef@\DIRECTION@group#1{%
+ \xy@@{\begingroup}\xy@@ix@{#1}\xy@@{\plainxy@\expandafter\POS\the\toks9\relax
+ \setupDirection@\edef\next@{\endgroup \DirectionfromtheDirection@}\next@}%
+ \DIRECTIONempty@false \xyFN@\DIRECTION@i}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{exercise}
+ What effect is achieved by using <modifier>s |v/1pc/| and |v/-1pc/|?
+\answertext{The first has no effect since the direction is set to be that of
+ a vector in the current direction, however, the second reverses the
+ current direction.}
+\end{exercise}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[to <direction>]
+%
+ Once the initial direction is established as either the last one or
+ an absolute one then the remainder of the <direction> is interpreted.
+
+ Adding a single |^| or |_| denotes the result of rotating the default
+ direction a right angle in the positive and negative direction, \ie,
+ anti-/clockwise, respectively. \NOTE: Do \emph{not} use |^|\relax|^|
+ but only |__| to reverse the direction!
+
+ A trailing |:|<vector> is like |v|<vector> but uses the
+ <direction> to set up a standard square base such that |:(0,1)| and
+ |:(0,-1)| mean the same as |:a(90)| and |:a(-90)| and as |^| and |_|,
+ respectively.
+
+\DOCMODE(
+\xydef@\DIRECTION@i{%
+ \ifx ^\next \DN@ ^{\xy@^{\aboveDirection@\xydashl@}%
+ \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
+ \else\ifx _\next \DN@ _{\xy@_{\belowDirection@\xydashl@}%
+ \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
+ \else\ifx :\next \DN@ :{%
+ \xy@{:}{\enter@{\cfromthec@ \basefromthebase@ \X@p=\the\X@p \Y@p=\the\Y@p}%
+ \X@origin=\z@ \Y@origin=\z@
+ \X@xbase=\cosDirection\xydashl@ \Y@xbase=\sinDirection\xydashl@
+ \X@ybase=-\Y@xbase \Y@ybase=\X@xbase}%
+ \afterVECTORorEMPTY
+ {\xy@@{\X@p=\z@ \Y@p=\z@ \setupDirection@ \leave@}%
+ \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
+ {\xy@@\leave@ \xyerror@{<vector> expected after :}{}%
+ \DIRECTIONempty@false \xyFN@\DIRECTION@i}}%
+ \else
+ \let\next@=\afterDIRECTION@
+ \fi\fi\fi \next@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{exercise}
+ What effect is achieved by using <modifier>s |v/1pc/:(1,0)| and
+ |v/-1pc/__|?
+\answertext{None in both cases.}
+\end{exercise}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{notes}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section{Decorations}
+??=[decor]
+
+\DOCMODE(
+\message{decorations;}
+\DOCMODE)
+
+ <Decor>ations are actual \TeX\ macros that decorate the current
+ picture in manners that depend on the state. They are allowed "after"
+ the <pos>ition either of the outer ??c![\xy]\dots??c![\endxy] or inside
+ |{|\dots|}|. The possibilities are given in figure~??[f.decor] with
+ notes below.
+
+\begin{figure*}[tp]
+\vss
+\begin{syntax}
+ ??w![<decor>]
+ &\iss & <command> <decor>
+ & either there is a command\dots
+\cr
+ &\orr & <empty>
+ & \dots or there isn't.
+\cr
+ ??w![<command>]
+ &\iss & ??c![\save] <pos>
+ & save ??!^[state], then do <pos>
+\cr
+ &\orr & ??c![\restore]
+ & restore ??!^[state] saved by matcing |\save|
+\cr
+ &\orr & ??c![\POS] <pos>
+ & interpret <pos>
+\cr
+ &\orr & ??c![\afterPOS] |{| <decor> |}| <pos>
+ & interpret <pos> and then perform <decor>
+\cr
+ &\orr & ??c![\drop] <object>
+ & drop <object> as the <pos> |*| operation
+\cr
+ &\orr & ??c![\connect] <object>
+ & connect with <object> as the <pos> |**| operation
+\cr
+ &\orr & ??c![\relax]
+ & do nothing
+\cr
+ &\orr & <\TeX\ commands>
+ & any ??!^[\TeX\ commands] and user-defined macros \hfil\break
+ that neither generates output (watch out for stray
+ \hfil\break spaces!), nor changes the grouping, may be used
+\cr
+ &\orr & ??c![\xyverbose]\orr??c![\xytracing]\orr??c![\xyquiet]\kern-1pc
+ &\kern1pc ??!^[tracing] commands
+\cr
+ &\orr & ??c![\xyignore] |{|<pos> <decor>|}|
+ & ??!^[ignore] \Xy-code
+\cr
+ &\orr & ??c![\xycompile] |{|<pos> <decor>|}|
+ & ??!^[compile] to file <prefix><no>|.xyc|
+\cr
+ &\orr & ??c![\xycompileto]|{|<name>|}{|<pos><decor>|}|\kern-1pc
+ &\kern1pc ??!^[compile] to file <name>|.xyc|
+\cr
+\end{syntax}
+\caption{\protect<decor>ations.}
+??=[f.decor]
+\vfill
+\end{figure*}
+
+ Most options add to the available <decor>, in particular the |v2|
+ option loads many more since \Xy-pic versions prior to 2.7 provided
+ most features as <decor>.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Simple decorations:}
+
+ ??c![\POS] and ??c![\afterPOS] have already been defined; the
+ following are just simple applications of previously defined
+ commands:
+
+\DOCMODE(
+\xydef@\drop#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
+ \xy@{\drop#1{##1}}{\expandafter\drop@\the\toks9 }\ignorespaces}\next@}
+
+\xydef@\connect#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
+ \xy@{\connect#1{##1}}{\expandafter\connect@\the\toks9 }\ignorespaces}\next@}
+
+\xydef@\preconnect#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
+ \xy@{\connect#1{##1}}{\expandafter\preconnect@\the\toks9 }\ignorespaces}\next@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{notes}
+%
+\note??=[state]
+%
+ Saving and restoring allows `excursions' where lots of things are
+ added to the picture without affecting the resulting \Xy-pic state,
+ \ie, $c$, $p$, and "base", and without requiring matching |{}|s. The
+ independence of |{}| is particularly useful in conjunction with the
+ ??c![\afterPOS] command, for example, the definition
+
+\begin{code}
+\def\ToPOS{\save\afterPOS{%
+ \POS**{}?>*@2{>}**@{-}\restore};p,}
+\end{code}
+\gdocode
+\displaycode
+
+ will cause the code |\ToPOS|<pos> to construct a double-shafted arrow
+ from the current object to the <pos> (computed relative to it) such
+ that
+%
+\begin{code}
+\xy *{A} \ToPOS +<10mm,2mm> \endxy
+\end{code}
+%
+ \thecode\ will typeset the picture \docode.
+
+\paragraph*{Note:}
+ Saving this way in fact uses the same state as the |{}| `grouping',
+ so the code $p_1$|,| |{|$p_2$|\save},| \dots\ |{\restore}| will have
+ $c=p_1$ both at the \dots\ and at the end!
+
+\DOCMODE(
+\xydef@\save{\relax\saveC}
+\xydef@\saveC{\xy@\save\save@ \POS}
+
+\xydef@\save@{\enter@{\cfromthec@ \pfromthep@ \basefromthebase@}}
+
+\xydef@\restore{\xy@\restore\leave@ \ignorespaces}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[\TeX\ commands]
+%
+ One very tempting kind of \TeX\ commands to perform as <decor> is
+ arithmetic operations on the \Xy-pic state. This will work in simple
+ \Xy-pictures as described here but be warned: "it is not portable"
+ because all \Xy-pic execution is indirect, and this is used by
+ several options in nontrivial ways. Check the \TeX-nical
+ documentation~\cite{RM95:Xy-picCSTC} for details about this!
+
+ Macros that expand to <decor> will always do the same, though.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ \TeX\ hackers like the author may enjoy changing the \Xy-pic state
+ directly using <decor> of the form |\xy@{|<id>|}{|<code>|}|\dots
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[tracing]
+%
+ ??c![\xyecho] will turn on echoing of all interpreted \Xy-pic <pos>
+ characters. \BUG: Not completely implemented yet. ??c![\xyverbose]
+ will switch on a tracing of all \Xy-pic commands executed, with line
+ numbers. ??c![\xytracing] traces even more: the entire \Xy-pic state
+ is printed after each modification. ??c![\xyquiet] restores default
+ quiet operation.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The trick is to replace the |\xy@| command such that it calls the
+ `normal' one between writing out a trace message and the state.
+
+\DOCMODE(
+\xydef@\xyecho{%
+ \xy@\xyecho{\let\xy@=\xyecho@ \message{\string\xyecho}}\POS}
+
+\xydef@\xyecho@#1#2{{\def\1{#1}\ifx\1\empty\else\message{\codeof\1}\fi}%
+ \oxy@{#1}{#2}}
+
+\xydef@\xyverbose{%
+ \xy@\xyverbose{\let\xy@=\xyverbose@
+ \W@{Xy: \string\xyverbose\xytracelineno@}}\POS}
+
+\xydef@\xyverbose@#1#2{%
+ {\def\1{#1}\ifx\1\empty\else\W@{Xy: \codeof\1\xytracelineno@}\fi}%
+ \oxy@{#1}{#2}}
+
+\xydef@\xytracing{%
+ \xy@\xytracing{\let\xy@=\xytracing@
+ \W@{Xy TRACE: \string\xytracing\xytracelineno@}\xystatus@:}\POS}
+
+\xydef@\xytracing@#1#2{{\def\1{#1}\def\2{#2}%
+ \W@{Xy TRACE: \codeof\1 {\codeof\2}\xytracelineno@}}\oxy@{#1}{#2}\xystatus@:}
+
+\xydef@\xystatus@#1{\xystatus@cp{#1}%
+ \W@{#1 d=<\the\d@X,\the\d@Y>
+ Direction=\the\Direction=\string(\cosDirection,\sinDirection\string)}%
+ \W@{#1 base=<\the\X@origin,\the\Y@origin>+%
+ <\the\X@xbase,\the\Y@xbase>x+<\the\X@ybase,\the\Y@ybase>y}%
+ \W@{#1 min/max=<\the\X@min,\the\Y@min>/<\the\X@max,\the\Y@max>
+ S=\the\csp@}}
+
+\xydef@\xystatus@cp#1{%
+ \W@{#1 c=<\the\X@c,\the\Y@c> \expandafter\string\the\Edge@c
+ \string[\the\L@c+\the\R@c,\the\D@c+\the\U@c\string]
+ \ifInvisible@ I\fi\ifHidden@ H\fi}%
+ \W@{#1 p=<\the\X@p,\the\Y@p> \expandafter\string\the\Edge@p
+ \string[\the\L@p+\the\R@p,\the\D@p+\the\U@p\string]}}
+
+\xydef@\xystatus@c#1{%
+ \W@{#1<\the\X@c,\the\Y@c> \expandafter\string\the\Edge@c
+ \string[\the\L@c+\the\R@c,\the\D@c+\the\U@c\string]}}
+
+\xydef@\xyquiet{\xy@\xyquiet{\let\xy@=\oxy@}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[ignore]
+%
+ Ignoring means that the <pos> <decor> is still parsed the usual way
+ but nothing is typeset and the \Xy-pic state is not changed.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ We ignore in a group to ensure that nothing done inside `leaks' to
+ the outside.
+
+\DOCMODE(
+\xydef@\xyignore#1{\xy@\xyignore{\xyignore@{#1}}\ignorespaces}
+
+\xydef@\xyignore@#1{{\let\xy@=\xyeat@ \change@oxy@\xy@ \POS#1\relax}}
+
+\xydef@\xyeat@#1#2{}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[compile]
+%
+ It is possible to save an intermediate form of commands that generate
+ parts of an \Xy-picture to a file such that subsequent typesetting of
+ those parts is significantly faster: this is called
+ "??w![compiling]". The produced file contains code to check that the
+ compiled code still corresponds to the same <pos><decor> as well as
+ efficient \Xy-code to redo it; if the <pos><decor> has changed then
+ the compilation is redone.
+
+ There are two ways to use this. The direct is to invent a <name> for
+ each diagram and then embrace it in
+ |\xycompileto{|<name>|}||{|\dots|}| -- this dumps the compiled code
+ into the file <name>|.xyc|.
+
+ When many diagrams are compiled then it is easier to add
+ ??c![\xycompile]|{|\dots|}| around the <pos><decor> to be compiled.
+ This will assign file names numbered consecutively with a <prefix>
+ which is initially the expansion of |\jobname-| but may be set with
+%
+\begin{defs1}
+??c![\CompilePrefix]|{|<prefix>|}|
+\end{defs1}
+\noindent\unskip
+%
+ This has the disadvantage, however, that if additional compiled
+ \Xy-pictures are inserted then all subsequent pictures will have to
+ be recompiled. One particular situation is provided, though: when
+ used within constructions that typeset their contents more than once
+ (such as most ??w![\AMS-\LaTeX] equation constructs) then the
+ declaration
+%
+\begin{defs1}
+??c![\CompileFixPoint]|{|<id>|}|
+\end{defs1}
+\noindent\unskip
+%
+ can be used inside the environment to fix the counter to have the
+ same value at every passage.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ It is done by just writing all |\xy@|-commands to the file. The file
+ establishes the correct input mode through use of the appropriate
+ commands itself.
+
+\DOCMODE(
+\xydef@\xycompile@@{\jobname-}
+\xydef@\xycompileno@@{0}
+
+\xydef@\CompilePrefix#1{%
+ \def\xycompile@@{#1}\xdef\xycompile@@{\codeof\xycompile@@}%
+ \xdef\xycompileno@@{0}}
+
+\xydef@\xycompile{%
+ \count@=\xycompileno@@ \advance\count@\@ne
+ \xdef\xycompileno@@{\ifnum10>\count@ 0\fi \the\count@}%
+ \edef\next{\noexpand\xycompileto{\xycompile@@\xycompileno@@}}\next}
+
+\xylet@\compilename@@=\empty
+\xylet@\xyrecompile@@=\relax
+
+\xydef@\xycompileto#1#2{%
+ \if\inxy@ \DN@{\xy@@{\nter@{}}}%
+ \else \DN@{\xy \xy@@{\nter@{\endxy}}}\fi \next@
+ \ifxysaving@ \xyerror@{Compilations can not be nested}{}\fi
+ \DN@{#1}\edef\compilename@@{\codeof\next@}\DNii@{#2}%
+ \def\xyrecompile@@{recompiling TRUNCATED}%
+ \expandafter\xyinputorelse@@\expandafter{\compilename@@.xyc}%
+ {\def\xyrecompile@@{compiling to}}%
+ \ifx\xyrecompile@@\relax \else \expandafter\xyrecompile@ \fi
+ \xy@@\leave@ \ignorespaces}
+\DOCMODE)
+
+ Recompilation is done by just writing all |\xy@|-commands to the
+ file. The file establishes the correct input mode and terminates
+ itself; after it has been finished it is simply reread to actually
+ get the drawing done in the document.
+
+\DOCMODE(
+\xydef@\xyrecompile@{%
+ \message{(\xyrecompile@@\space\string`\compilename@@.xyc\string'}%
+ \DN@{\immediate\openout\xywrite@=}\expandafter\next@\compilename@@.xyc
+ \immediate\write\xywrite@{%
+ \string\xycompiled{\compilename@@}%
+ {\the\year/\the\month/\the\day\string:\the\time\xytracelineno@}%
+ {Xy-pic \xyversion}\xycomment@}%
+ \immediate\write\xywrite@{{\codeof\nextii@}\relax}%
+ {\xysaving@ \expandafter\POS\nextii@ \relax}%
+ \immediate\write\xywrite@{\string\xyendcompiled}%
+ \immediate\closeout\xywrite@ \message{done)}%
+ \expandafter\input\compilename@@.xyc
+ \outlines@@\writeoutline@\writeoutline@}
+
+\xydef@\xysaving@{\let\xy@=\xysave@ \change@oxy@\xy@
+ \let\xy@@ix@=\xysave@@toksix@ \xysaving@true}
+
+\xynew@{if}\ifxysaving@ \xysaving@false
+
+\xydef@\xysave@#1#2{{\DN@{{#1}{#2}}%
+ \immediate\write\xywrite@{\string\xy@\codeof\next@\xycomment@}}}
+
+\xydef@\xysave@@toksix@#1{{\DN@{{#1}}%
+ \immediate\write\xywrite@{\string\xy@@ix@\codeof\next@\relax}}}
+
+\xywarnifdefined\xycomment@
+{\catcode`\%=12 \catcode`\(=1 \catcode`\)=2 \gdef\xycomment@(%)}
+\DOCMODE)
+
+ \HACK{1:} The |\ifxysaving@| can never be locally switched off!
+ Anyway it is used to allow a gross hack avoiding building a queue in
+ the matrix option that will generate too long lines!!
+
+ \HACK{2:} |\xysave@@toksix@| is not doing the catcode jive because it
+ can never be invoked while loading a file (knock, knock~\smiley~).
+
+ The initial command in all |.xyc| files check that this is the right
+ file and that neither the version of \Xy-pic nor the user's code has
+ changed:
+
+\DOCMODE(
+\xydef@\xycompiled#1#2#3#4{\DN@{#1}\edef\next@{\codeof\next@}%
+ \ifx\next@\compilename@@\else
+ \xywarning@{This file does not contain the result of
+ \string\xycompileto{\compilename@@}{...}^^J%
+ but of \string\xycompileto{\next@}}\fi
+ \edef\next{Xy-pic \xyversion}\DN@{#3}\ifx\next\next@
+ \DN@{#4}\ifx\next@\nextii@ \xycatcodes \outlines@@\relax\readoutline@
+ \else \def\xyrecompile@@{recompiling to}\endinput \fi
+ \else \def\xyrecompile@@{Xy-pic version change - recompiling}\endinput \fi}
+
+\xydef@\xyendcompiled{\let\xyrecompile@@=\relax \xyuncatcodes\endinput}
+\DOCMODE)
+
+ Finally the fix-point thing.
+
+\DOCMODE(
+\xydef@\CompileFixPoint#1{%
+ \expandafter\ifx\csname#1FIX@@\endcsname\relax
+ \expandafter\xdef\csname#1FIX@@\endcsname{\xycompileno@@}%
+ \else
+ \xdef\xycompileno@@{\csname#1FIX@@\endcsname}\fi}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Finally, when many `administrative typesetting runs' are needed, \eg,
+ readjusting \LaTeX\ cross references and such, then it may be an
+ advantage to not typeset any \Xy-pictures at all during the
+ intermediate runs. This is supported by the following declarations
+ which for each compilation creates a special file with the extension
+ ??c![.xyd] containing just the size of the picture:
+%
+\begin{defs1}
+??c![\MakeOutlines]\cr
+??c![\OnlyOutlines]\cr
+??c![\ShowOutlines]\cr
+??c![\NoOutlines]\cr
+\end{defs1}
+\noindent\unskip
+%
+ The first does no more. The second uses the file to typesets a
+ dotted frame of the appropriate size instead of the picture (unless
+ the picture has changed and is recompiled, then it is typeset as
+ always and the |.xyd| file is recreated for subsequent runs). The
+ third shows the outlines as dotted rectangles. The last switches
+ outline processing completely off.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The implementation is all handled by |\outlines@@| which is called at
+ strategic places in the compilation macros above. It just expands to
+ nothing when the state is `No', the first argument when it is `Make',
+ and the second when it is `Only'.
+
+\DOCMODE(
+
+\xydef@\outlines@no#1#2{}
+\xydef@\outlines@make#1#2{#1}
+\xydef@\outlines@only#1#2{#2}
+
+\xylet@\outlines@@=\outlines@no
+\xylet@\writeoutline@@=\relax
+\xylet@\readoutline@@=\relax
+
+\xydef@\MakeOutlines{\let\outlines@@=\outlines@make}
+
+\xydef@\OnlyOutlines{\xywarning@{Compiled pictures only shown as outlines}%
+ \let\outlines@@=\outlines@only}
+
+\xydef@\ShowOutlines{\let\readoutline@@=\typesetoutline@}
+
+\xydef@\NoOutlines{\let\outlines@@=\outlines@no}
+
+\xydef@\writeoutline@{%
+ \DN@{\immediate\openout\xywrite@=}\expandafter\next@\compilename@@.xyd
+ \immediate\write\xywrite@{\xycomment@\space\compilename@@.xyd}
+ \immediate\write\xywrite@{%
+ \string\X@min=\the\X@min \string\X@max=\the\X@max
+ \string\Y@min=\the\Y@min \string\Y@max=\the\Y@max \string\relax}%
+ \writeoutline@@
+ \immediate\closeout\xywrite@}
+
+\xynew@{if}\ifoutlineread@
+
+\xydef@\readoutline@{\outlineread@true
+ \expandafter\xyinputorelse@@\expandafter{\compilename@@.xyd}%
+ {\def\xyrecompile@@{outline missing - recompiling to}\outlineread@false}%
+ \ifoutlineread@ \readoutline@@
+ \writeoutline@\expandafter\xyendcompiled\fi}
+
+\xydef@\typesetoutline@{%
+ \xy@@{\czeroEdge@ \U@p=\z@ \D@p=\z@ \L@p=\z@ \R@p=\z@ \Edge@p={\zeroEdge}%
+ \X@p=\X@min \Y@p=\Y@min \X@c=\X@min \Y@c=\Y@max \connect@\dir{.}%
+ \X@p=\X@c \Y@p=\Y@c \X@c=\X@max \Y@c=\Y@max \connect@\dir{.}%
+ \X@p=\X@c \Y@p=\Y@c \X@c=\X@max \Y@c=\Y@min \connect@\dir{.}%
+ \X@p=\X@c \Y@p=\Y@c \X@c=\X@min \Y@c=\Y@min \connect@\dir{.}}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{notes}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section{Kernel object library}
+??=[objectlib]
+
+\DOCMODE(
+\message{kernel objects:}
+\DOCMODE)
+
+ In this section we present the "library objects" provided with the
+ kernel language---several options add more library objects. They fall
+ into three types: Most of the kernel objects (including all those
+ usually used with |**| to build connections) are "directionals",
+ described in \S??[objectlib.directionals]. The remaining kernel
+ library objects are "circles" of \S??[objectlib.circles] and "text"
+ of \S??[objectlib.text].
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Directionals}
+??=[objectlib.directionals]
+
+\DOCMODE(
+\message{directionals,}
+\DOCMODE)
+
+ The kernel provides a selection of "directionals": objects that
+ depend on the current direction. They all take the form
+%
+\begin{defs1}
+%
+ ??c![\dir]<dir> \cr
+%
+\end{defs1}
+\noindent\unskip
+%
+ to typeset a particular <dir>ectional object. All have the structure
+%
+\begin{defs1}
+%
+ <dir> \iss\ <variant>|{|<main>|}| \cr
+%
+\end{defs1}
+\noindent\unskip
+%
+ with <variant> being <empty> or one of the characters |^_23| and
+ <main> some mnemonic code.
+
+ We will classify the directionals primarily intended for building
+ connections as "connectors" and those primarily intended for
+ placement at connection ends or as markers as "tips".
+
+\begin{figure*}[tp]
+ %
+ \def\Dx#1#2{\hbox{\def\1{#1{#2}}\enspace\tt\string\dir\codeof\1}}
+ %
+ \def\DC#1#{\DCx{#1}}
+ \def\DCx#1#2{ \Dx{#1}{#2} & \vcenter{\xy
+ 0*\cir<5pt>{} ; (16,5)*=<10.1pt>{}*\frm{-} **\dir#1{.} **h\dir#1{#2}
+ \endxy}}
+ %
+ \def\DT#1#{\DTx{#1}}
+ \def\DTx#1#2{\Dx{#1}{#2} & \vcenter{\xy
+ -(4,2.5)*{} ; (4,0)*{} **{} ?>*\dir#1{#2} **\dir#1{.}
+ \endxy}}
+ %
+ \def\Darray#1#2{{\let\\=\cr \tabskip=0pt plus 1fil %
+ \halign to\hsize{&\hfil$##$&$##$\hfil\\
+ \noalign{\hbox to\hsize{\hss#1\hss}\smallskip}#2\crcr}\bigskip}}
+%
+\Darray{??!^[Dummy]}{\hbox{\tt\string\dir\string{\string}}}
+%
+\Darray{??!^[Plain connectors]}{%
+ \DC{-} &\DC2{-} &\DC3{-} \\
+ \DC{.} &\DC2{.} &\DC3{.} \\
+ \DC{~} &\DC2{~} &\DC3{~} \\
+ \DC{--} &\DC2{--} &\DC3{--} \\
+ \DC{~~} &\DC2{~~} &\DC3{~~} \\
+}
+\bigskip
+\Darray{??!^[Plain tips]}{%
+ \DT{>} &\DT^{>} &\DT_{>} &\DT2{>} &\DT3{>} \\
+ \DT{<} &\DT^{<} &\DT_{<} &\DT2{<} &\DT3{<} \\
+ \DT{|} &\DT^{|} &\DT_{|} &\DT2{|} &\DT3{|} \\
+ \DT{(} &\DT^{(} &\DT_{(} \\
+ \DT{)} &\DT^{)} &\DT_{)} \\
+ & &\DT^{`} &\DT_{`} \\
+ & &\DT^{'} &\DT_{'}
+}
+\bigskip
+\Darray{??!^[Constructed tips]}{%
+ \DT{>>} &\DT^{>>} &\DT_{>>} &\DT2{>>} &\DT3{>>} \\
+ \DT{<<} &\DT^{<<} &\DT_{<<} &\DT2{<<} &\DT3{<<} \\
+ \DT{||} &\DT^{||} &\DT_{||} &\DT2{||} &\DT3{||} \\
+ \DT{|-} &\DT^{|-} &\DT_{|-} &\DT2{|-} &\DT3{|-} \\
+ \DT{>|} &\DT{>>|} &\DT{|<} &\DT{|<<} &\DT{*} \\
+ \DT{+} &\DT{x} &\DT{/} &\DT{//} &\DT{o}
+}
+\caption{Kernel library \protect<dir>ectionals}??=[f.dir]
+\end{figure*}
+
+ Figure~??[f.dir] shows all the <dir>ectionals defined by the kernel
+ with notes below; each <main> type has a line showing the available
+ <variant>s. Notice that only some variants exist for each
+ <dir>---when a nonexisting variant of a <dir> is requested then the
+ <empty> variant is used silently. Each is shown in either of the two
+ forms available in each direction as applicable: connecting a
+ $\bigcirc$ to a $\Box$ (typeset by |**\dir|<dir>) and as a tip at the
+ end of a dotted connection of the same variant (\ie, typeset by the
+ <pos> |**\dir|<variant>|{.}| |?>| |*\dir|<dir>).
+
+ As a special case an entire <object> is allowed as a <dir> by
+ starting it with a |*|: |\dir*| is equivalent to ??c![\object].
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Setup:}
+
+ ??c![\dir] starts an <object> and passes control to a `finisher' named
+ |\dir|<variant>|{|<main>|}| otherwise to the one corresponding to an
+ <empty> <variant>. The kernel ones described here have in common
+ that they make use of the generic |\straight@| defined
+ in~\S??[algo.connection].
+
+\DOCMODE(
+\xydef@\dir{\hbox\bgroup\xyFN@\dir@i}
+
+\xydef@\dir@i{\ifx *\next \DN@*{\resetStyle@\object@}%
+ \else \let\next@=\dir@ii \fi \next@}
+
+\xydef@\dir@ii#1#{\dir@{#1}}
+
+\xydef@\dir@#1#2{\DN@{dir#1{#2}}%
+ \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
+ \ifx\next\relax \DN@{dir{#2}}%
+ \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
+ \ifx\next\relax \DN@{\dir#1{#2}}%
+ \xyerror@{illegal <dir>: \codeof\next@\space not defined}{}%
+ \let\next=\no@ \fi\fi \next}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{notes}
+
+\note??=[Dummy]
+
+ You may use |\dir{}| for a ``dummy'' directional object (in fact this
+ is used automatically by |**{}|). This is useful for a uniform
+ treatment of connections, \eg, making the |?| <pos> able to find a
+ point on the straight line from $p$ to $c$ without actually
+ typesetting anything.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Uses an empty droppping, the |\no@@| connection. All the variants
+ are defined for optimisation reasons and it is also named |\dir{ }|
+ to allow spurious spaces:
+
+\DOCMODE(
+\xydefcsname@{dir{}}{\no@}
+
+\xyletcsnamecsname@{dir0{}}{dir{}}
+\xyletcsnamecsname@{dir1{}}{dir{}}
+\xyletcsnamecsname@{dir^{}}{dir{}}
+\xyletcsnamecsname@{dir_{}}{dir{}}
+\xyletcsnamecsname@{dir2{}}{dir{}}
+\xyletcsnamecsname@{dir3{}}{dir{}}
+
+\xyletcsnamecsname@{dir{ }}{dir{}}
+
+\xydef@\no@{\egroup \czeroEdge@ %\Invisible@false \Hidden@false %%%%HACK?
+ \def\Leftness@{.5}\def\Upness@{.5}%
+ \def\Drop@@{\setbox\z@=\copy\voidb@x}\def\Connect@@{\no@@}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[Plain connectors]
+
+ The "plain connectors" group contains basic directionals that lend
+ themself to simple connections.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The bulk of the code is in fact in the description of these. First
+ each of the three types---lines, dots, and squiggles---then the code
+ for doubling and tripling.
+
+\paragraph*{Lines:}
+
+ A single |\dir{-}| object is a dash in the current direction: build
+ box with character $C$ of the semidirectional ??c![\xydashfont]; use
+ the characters natural width $w$ and construct a height/depth from $d
+ = \abs{\sin(|\Direction|)}|em|$ (where |1em| is the dash length,
+ \cf~|xydash10.mf|) as follows:
+$$
+\begin{array}{cccccc}
+ C & L & R & D & U & "flip if" \\
+ 0\ldots30 & 0 & w & 0 & d & dY \lt 0 \\
+ 31\ldots63 & 0 & w & d & 0 & dY \gt 0 \\
+ 64\ldots95 & 0 & w & d & 0 & dX \lt 0 \\
+ 96\ldots127 & 0 & w & 0 & d & dX \lt 0 \\
+\end{array}
+$$
+ where "flip" means shift the box opposite vertically and
+ horizontally, \ie, $(L,R,D,U) := (R,L,U,D)$, and then lower the box
+ $D-U$.
+
+ "Procedure": (??_[line1])~Compute $d$, (??_[line2])~set $D,U$, and
+ flip condition, (??_[line3])~build box to get $w,L,R$,
+ (??_[line4])~dump box that is flipped if condition holds, and
+ (??_[line5])~finally setup the required parameters properly.
+
+\DOCMODE(
+\xydefcsname@{dir1{-}}{\line@}
+\xydefcsname@{dir2{-}}{\line@ \double@\xydashh@}
+\xydefcsname@{dir3{-}}{\line@ \triple@\xydashh@}
+\xyletcsnamecsname@{dir0{-}}{dir{}}
+\xyletcsnamecsname@{dir{-}}{dir1{-}}
+\xyletcsnamecsname@{dir{=}}{dir2{-}}
+
+\xydef@\line@{\dimen@=\sd@Y\sinDirection\xydashl@ %?*[line1]
+ \ifnum\SemiDirectionChar<31 \D@c=\z@ \U@c=\dimen@ \DN@{\d@Y<\z@}% %?*[line2]
+ \else\ifnum\SemiDirectionChar<64 \D@c=\dimen@ \U@c=\z@ \DN@{\z@<\d@Y}%
+ \else\ifnum\SemiDirectionChar<96 \D@c=\dimen@ \U@c=\z@ \DN@{\d@X<\z@}%
+ \else \D@c=\z@ \U@c=\dimen@ \DN@{\d@X<\z@}\fi\fi\fi
+ \setboxz@h{\line@@}\ht\z@=\U@c \dp\z@=\D@c %?*[line3]
+ \L@c=\z@ \R@c=\wdz@
+ \ifdim\next@ \dimen@=\R@c \R@c=\L@c \L@c=\dimen@ %?*[line4]
+ \dimen@=\U@c \U@c=\D@c \D@c=\dimen@ \advance\dimen@-\U@c
+ \lower\dimen@\boxz@
+ \else \boxz@ \fi
+%
+%\ifnum\SemiDirectionChar=31\relax
+% \W@{LINE@(\the\SemiDirectionChar): WH=<\the\L@c+\the\R@c,\the\D@c+\the\U@c>;
+% d=<\the\d@X,\the\d@Y>}\fi
+%
+ \edef\tmp@{\egroup \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c}% %?*[line5]
+ \tmp@
+ \Edge@c={\rectangleEdge}%%%%%\Invisible@false\Hidden@false
+ \ifdim\z@<\U@c \def\Upness@{1}\else \def\Upness@{0}\fi
+ \ifdim\z@<\L@c \def\Leftness@{1}\else \def\Leftness@{0}\fi
+ \def\Drop@@{\styledboxz@}\def\Connect@@{\solid@}}
+
+\xydef@\line@@{{\xydashfont\SemiDirectionChar\/}}
+\DOCMODE)
+
+ \BUG: |\line@| should allow the size of the object to be changed
+ after typesetting---this should make |\Connect@@| do dashing. Hm.
+
+ As mentioned above a dash will `Connect' to make lines by using rules
+ when strictly horizontal or vertical. This is controlled by enabling
+ or disabling the test |\ifjusthvtest@| discussed below.
+
+\DOCMODE(
+\xydef@\solid@{%
+%
+%\W@{SOLID}\xystatus@:%
+%
+ \checkXy@rules@\solidhrule@\solidvrule@{\straight@\solidSpread@}}
+
+\xydef@\checkXy@rules@#1#2#3{%
+ \dimen@=\Y@c \advance\dimen@-\Y@p
+ \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{#1}%
+ \else \dimen@=\X@c \advance\dimen@-\X@p
+ \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{#2}%
+ \else \DN@{#3}\fi\fi \next@}
+\DOCMODE)
+
+ Finally, we give the algorithm for `spreading' the dashes along a
+ solid line: just add an extra dash so they always overlap
+ (see~\S??[algo.connection] for a proper defintion of the requirements
+ to spreading).
+
+\DOCMODE(
+\xydef@\solidSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ By default \Xy-pic will typeset horizontal and vertical |\dir{-}|
+ connections using \TeX\ rules. Unfortunately rules is the feature of
+ the DVI format most commonly handled wrong by DVI drivers. Therefore
+ \Xy-pic provides the <decor>ations
+%
+\begin{defs1}
+%
+ ??c![\NoRules] \cr
+ ??c![\UseRules] \cr
+%
+\end{defs1}
+\noindent\unskip
+%
+ that will switch the use of such off and on.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ They simply redefine the conditional used to select typesetting
+ with rules in |\solid@| above:
+
+\DOCMODE(
+\xylet@\ifjusthvtest@=\ifdim
+
+\xydef@\NoRules{\let\ifjusthvtest@=\iffalse}
+\xydef@\UseRules{\let\ifjusthvtest@=\ifdim}
+\DOCMODE)
+
+ The actual typesetting essentially means calling |\drop@| to box with
+ a rule of the appropriate length and with line width set to that of
+ ??c![\xydashfont] (as stored in |\xydashw@|).
+
+\DOCMODE(
+\xydef@\solidvrule@{\no@@ \solidvrule@typeset \ifHidden@\else\noinsert@\fi
+ \solidvrule@pre}
+
+\xydef@\solidvrule@pre{%
+%
+%\W@{VRULE SETUP}%
+%
+ \def\Cbreak@@{%
+%
+%\W@{VRULE Cbreak}%
+%
+ \connectRestore@ \swap@\lastbreak@@\swap@
+ \solidvrule@typeset \edef\lastbreak@@{\cfromthec@}\Creset@@}%
+ \def\Clast@@{%
+%
+%\W@{VRULE Clast}%
+%\let\Clast@@=\undefined
+%
+ \connectRestore@ \Creset@@\swap@\lastbreak@@\swap@
+ \solidvrule@typeset \Creset@@ \edef\lastbreak@@{\cfromthep@}}%
+}
+
+\xydef@\solidvrule@typeset{%
+%
+%\W@{VRULE TYPESET}\xystatus@cp:%
+%
+ \ifInvisible@ \let\next@=\relax \else \let\next@=\solidvrule@typeset@ \fi
+ \checkoverlap@@ \next@}
+
+\xydef@\solidvrule@typeset@{{%
+%
+ \advance\X@c\X@p \X@c=.5\X@c \X@p=\X@c
+ \advance\X@c-.5\xydashw@ \advance\X@p.5\xydashw@
+%
+ \ifdim\Y@c<\Y@p \advance\Y@c\U@c \advance\Y@p-\D@p
+ \else \swapdimen@\Y@c\Y@p \advance\Y@c\U@p \advance\Y@p-\D@c \fi
+%
+ \Droprule@}}
+
+\xydef@\solidhrule@{\no@@ \solidhrule@typeset \ifHidden@\else\noinsert@\fi
+ \solidhrule@pre}
+
+\xydef@\solidhrule@pre{%
+%
+%\W@{HRULE SETUP}%
+%
+ \def\Cbreak@@{%
+%
+%\W@{HRULE Cbreak}%
+%
+ \connectRestore@ \swap@\lastbreak@@\swap@
+ \solidhrule@typeset \edef\lastbreak@@{\cfromthec@}\Creset@@}%
+ \def\Clast@@{%
+%
+%\W@{HRULE Clast}%
+%\let\Clast@@=\undefined
+%
+ \connectRestore@ \Creset@@\swap@\lastbreak@@\swap@
+ \solidhrule@typeset \Creset@@ \edef\lastbreak@@{\cfromthep@}}%
+}
+
+\xydef@\solidhrule@typeset{%
+%
+%\W@{HRULE TYPESET}\xystatus@cp:%
+%
+ \ifInvisible@ \let\next@=\relax \else \let\next@=\solidhrule@typeset@ \fi
+ \checkoverlap@@ \next@}
+
+\xydef@\solidhrule@typeset@{{%
+ \ifdim\X@c<\X@p \advance\X@c\R@c \advance\X@p-\L@p
+ \else \swapdimen@\X@c\X@p \advance\X@c\R@p \advance\X@p-\L@c \fi
+ \advance\Y@c\Y@p \Y@c=.5\Y@c \Y@p=\Y@c
+ \advance\Y@c-.5\xydashw@ \advance\Y@p.5\xydashw@
+ \Droprule@}}
+\DOCMODE)
+
+ |\Droprule@| puts the actual ink on the page: with lower left corner
+ at $c$ and upper right corner at~$p$.
+
+\DOCMODE(
+\xydef@\Droprule@{\advance\X@p-\X@c
+%
+%\W@{: kern\the\X@c\space width\the\X@p\space depth-\the\Y@c\space
+% height\the\Y@p}%
+%
+ \setboxz@h{\kern\X@c \vrule width\X@p depth-\Y@c height\Y@p}%
+ \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ \Drop@@}
+\DOCMODE)
+
+\paragraph*{Dots:}
+
+ |\dir{.}| creates a very boring dot when used as an <object>, but
+ interesting dotted lines when used to connect. ??c![\zerodot] should
+ expand to a zero-sized box with a dot (initialised to use
+ |\zero|\-|dotbox@|); the <object> is built using |\pointlike@| <text>
+ <spread-dimen> that we will use again later.
+
+\DOCMODE(
+\xydef@\zerodot{\copy\zerodotbox@}
+
+\xydefcsname@{dir1{.}}{\point@}
+\xydefcsname@{dir2{.}}{\point@ \double@\xydashh@}
+\xydefcsname@{dir3{.}}{\point@ \triple@\xydashh@}
+\xyletcsnamecsname@{dir0{.}}{dir{}}
+\xyletcsnamecsname@{dir{.}}{dir1{.}}
+\xyletcsnamecsname@{dir{:}}{dir2{.}}
+
+\xydef@\point@{\pointlike@\zerodot\p@}
+
+\xydef@\pointlike@#1#2{%
+ \setboxz@h{#1}\wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@\egroup
+% \Invisible@false \Hidden@false
+ \def\Leftness@{.5}\def\Upness@{.5}\ctipEdge@
+ \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@{#2}}}}
+\DOCMODE)
+
+ This is reflected by the rather complicated spreading routine:
+ `Dotting' is the art of putting zero-sized objects together with
+ equal distance independent of the chosen direction. So we must
+ recompute the number of segments $N$ (likely to be very big or
+ ${-}1$) with trigonometry; using "radius" for the individual dots
+ this becomes
+$$
+\begin{array}{lc}
+ ??_[dottedspread]
+ & A := \abs{\cos{|\Direction|}}*"radius"\\
+ & B := \abs{\sin{|\Direction|}}*"radius"\\
+ ??_[dottedspread1]
+ & "if"~A+B \gt \abs{|\d@X|}+\abs{|\d@Y|}~"then"~N=0~"and exit" \\
+ ??_[dottedspread2]
+ & |<|A|,|B|>| := 2*|<|A|,|B|>|\\
+ & "Filler" := <box with the original filler centered...>\\
+ ??_[dottedspread3]
+ & |<\d@X,\d@Y>| := |<\d@X,\d@Y>| + |<\sd@X|*A|,\sd@Y|*B|>|\\
+ & |<|X|,|Y|>| := |<|X|,|Y|>| + |<\sd@X|*A/2|,\sd@Y|*B/2|>|\\
+ ??_[dottedspread4]
+ & N := \floor{"if"~\abs{|\d@X|}\gt\abs{|\d@Y|}
+ ~"then" \abs{|\d@X|}/A else \abs{|\d@Y|}/B} + 1
+\end{array}
+$$
+ as realised below:
+
+\DOCMODE(
+\xydef@\dottedSpread@#1{%\setupDirection@ %?*[dottedspread]
+ \dimen@=#1\relax \DN@{\A@=2\A@ \B@=2\B@ \dottedSpread@i}%
+ \A@=\sd@X\cosDirection\dimen@ \B@=\sd@Y\sinDirection\dimen@
+ \dimen@=\A@ \advance\dimen@\B@ %?*[dottedspread1]
+ \dimen@ii=\sd@X\d@X \advance\dimen@ii\sd@Y\d@Y
+ \ifdim\dimen@>\dimen@ii \DN@{\count@@=\z@}\fi
+ \next@}
+
+\xydef@\dottedSpread@i{%\setupDirection@ %?*[dottedspread2]
+ \global\setbox8=\hbox to\A@{\hss
+ \kern.5\A@\box\lastobjectbox@\kern.5\A@\hss}\dp8=.5\B@ \ht8=.5\B@
+ \advance\d@X\sd@X\A@ \advance\d@Y\sd@Y\B@ %?*[dottedspread3]
+ \advance\X@c\sd@X.5\A@ \advance\Y@c\sd@Y.5\B@
+ \ifdim\sd@Y\d@Y<\sd@X\d@X \dimen@=\sd@X\d@X %?*[dottedspread4]
+ \ifdim\zz@\A@\else \divide\dimen@\A@ \fi \count@@=\dimen@
+ \else \dimen@=\sd@Y\d@Y
+ \ifdim\zz@\B@\else \divide\dimen@\B@ \fi \count@@=\dimen@
+ \fi \advance\count@@\@ne}
+\DOCMODE)
+%
+\noindent
+ A particular aspect of this is that we have to enlarge and recenter
+ the actual box used for the typesetting (|\lastobjectbox@|).
+
+\paragraph*{Squiggles:}
+
+ These are just a lot of box maneuvering using the directional
+ characters of ??c![\xybsqlfont] (see~|xybsql10.mf| for details):
+
+\DOCMODE(
+\xydefcsname@{dir1{~}}{\squiggle@}
+\xydefcsname@{dir2{~}}{\squiggle@ \double@\xybsqlh@}
+\xydefcsname@{dir3{~}}{\squiggle@ \triple@\xybsqlh@}
+\xyletcsnamecsname@{dir0{~}}{dir{}}
+\xyletcsnamecsname@{dir{~}}{dir1{~}}
+
+\xydef@\squiggle@{\xybsqlfont
+ \dimen@=\sd@X\cosDirection\xybsqll@ \advance\dimen@.1\p@
+ \dimen@ii=\sd@Y\sinDirection\xybsqll@
+ \kern\dimen@\squiggle@@
+ \edef\tmp@{\egroup \U@c=\the\dimen@ii \L@c=\the\dimen@}\tmp@
+ \wdz@=2\L@c \R@c=\L@c \ht\z@=\U@c \D@c=\U@c \dp\z@=\U@c
+ \Edge@c={\rectangleEdge}%
+% \Invisible@false \Hidden@false
+ \def\Leftness@{.5}\def\Upness@{.5}%
+ \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\squiggledSpread@}}
+
+\xydef@\squiggle@@{\DirectionChar \count@=\DirectionChar
+ \advance\count@-64 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}
+\DOCMODE)
+
+ The interesting bit is that they spread by not spreading, \ie, by
+ centering between the endpoints---this means
+$$
+\begin{array}{ll}
+ X := X - d/2, dX := dX - d
+ &\hbox{where}~ d = |\sd@X|(\abs{dX} - N*A + |.1pt|)\\
+ Y := Y - d/2, dY := dY - d
+ &\hbox{where}~ d = |\sd@Y|(\abs{dY} - N*B + |.1pt|)\\
+\end{array}
+$$
+
+\DOCMODE(
+\xydef@\squiggledSpread@{%
+ \dimen@=\d@X \advance\dimen@-\sd@X\count@@\A@ \advance\dimen@\sd@X.3\p@
+ \advance\X@c-.5\dimen@ \advance\d@X-\dimen@
+ \dimen@=\d@Y \advance\dimen@-\sd@Y\count@@\B@ \advance\dimen@\sd@Y.3\p@
+ \advance\Y@c-.5\dimen@ \advance\d@Y-\dimen@}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Double and triple directionals:}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ As can be seen by the last two columns, these (and most of the other
+ connectors) also exist in double and triple versions with a |2| or a
+ |3| prepended to the name. For convenience |\dir{=}| and |\dir{:}|
+ are synonyms for |\dir2{-}| and |\dir2{.}|, respectively; similarly
+ |\dir{==}| is a synonym for |\dir2{--}|.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ This is very simple, really: |\double@| and |\triple@| do the work by
+ redefining the |\Drop@@| method to do its job twice and thrice.
+ \TODO: should probably extend any already defined |\Drop@@| method?
+
+\DOCMODE(
+%\xydef@\double@#1{\edef\Drop@@{\dimen@=#1\relax
+% \dimen@=.5\dimen@ \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
+% \setbox2=\hbox{\kern\A@\raise\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
+% \setbox2=\hbox{\kern-\A@\raise-\B@\boxz@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 }}
+
+%\xydef@\triple@#1{\edef\Drop@@{\dimen@=#1\relax
+% \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
+% \setbox2=\hbox{\kern\A@\raise\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
+% \setbox2=\hbox{\kern-\A@\raise-\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2
+% \dp\z@=\z@ \ht\z@=\z@ \wdz@=\z@ \boxz@}}
+
+\xydef@\double@#1{\edef\Drop@@{\dimen@=#1\relax
+ \dimen@=.5\dimen@ \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
+ \setboxz@h{\setbox2=\hbox{\kern\A@\raise\B@\copy\z@}%
+ \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
+ \setbox2=\hbox{\kern-\A@\raise-\B@ \noexpand\boxz@}%
+ \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 }%
+ \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \noexpand\styledboxz@}}
+
+\xydef@\triple@#1{\edef\Drop@@{\dimen@=#1\relax
+ \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
+ \setboxz@h{\setbox2=\hbox{\kern\A@\raise\B@\copy\z@}%
+ \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
+ \setbox2=\hbox{\kern-\A@\raise-\B@\copy\z@}%
+ \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
+ \dp\z@=\z@ \ht\z@=\z@ \wdz@=\z@ \noexpand\boxz@}%
+ \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \noexpand\styledboxz@}}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Dashing directionals:}
+
+ First traditional dashing:
+
+\DOCMODE(
+\xydefcsname@{dir1{--}}{\dash@}
+\xydefcsname@{dir2{--}}{\dash@ \double@\xydashh@}
+\xydefcsname@{dir3{--}}{\dash@ \triple@\xydashh@}
+\xyletcsnamecsname@{dir0{--}}{dir{}}
+\xyletcsnamecsname@{dir{--}}{dir1{--}}
+\xyletcsnamecsname@{dir{==}}{dir2{--}}
+
+\xydef@\dash@{\line@ \wdz@=2\wdz@ \ht\z@=2\ht\z@ \dp\z@=2\dp\z@
+ \multiply\D@c\tw@ \multiply\U@c\tw@ \multiply\L@c\tw@ \multiply\R@c\tw@
+ \def\Connect@@{\straight@\dashedSpread@}}
+\DOCMODE)
+
+ Since the dashes should reach the endpoints we do this:
+$$
+\begin{array}{l}
+ "if"~ N\gt 0 ~"then"~ N := N+1\\
+ dX := dX + d/2 ~"where"~ d = |\sd@X|A\\
+ dY := dY + d/2 ~"where"~ d = |\sd@Y|B\\
+ "if"~ dX\gt 0 ~"then"~ X := X + A/2\\
+ Y := Y + |\sd@Y|A/2\\
+\end{array}
+$$
+\DOCMODE(
+\xydef@\dashedSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi
+ \advance\d@X\sd@X.5\A@ \advance\d@Y\sd@Y.5\B@
+ \ifdim\z@<\d@X \advance\X@c.5\A@ \fi \advance\Y@c\sd@Y.5\B@}
+\DOCMODE)
+
+ Dashed dashing of squiggled lines are simpler since squiggles are
+ symmetric:
+
+\DOCMODE(
+\xydefcsname@{dir1{~~}}{\dashsquiggle@}
+\xydefcsname@{dir2{~~}}{\dashsquiggle@ \double@\xybsqlh@}
+\xydefcsname@{dir3{~~}}{\dashsquiggle@ \triple@\xybsqlh@}
+\xyletcsnamecsname@{dir0{~~}}{dir{}}
+\xyletcsnamecsname@{dir{~~}}{dir1{~~}}
+
+\xydef@\dashsquiggle@{\squiggle@
+ \multiply\D@c\tw@ \multiply\U@c\tw@ \multiply\L@c\tw@ \multiply\R@c\tw@
+ \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@ \ht\z@=\U@c \dp\z@=\D@c
+ \def\Connect@@{\straight@\dashsquiggledSpread@}}
+\DOCMODE)
+
+ The spreading of squiggles is similarly simpler: we just shave $1/4$
+ squiggle size of each end of the conection in order to eliminate the
+ blank space at both ends:
+
+\DOCMODE(
+\xydef@\dashsquiggledSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi
+ \advance\X@c.5\A@ \advance\d@X.5\A@ \advance\Y@c.25\B@ \advance\d@Y.5\B@}
+\DOCMODE)
+
+ Finally ``dashed dotting'' synonyms:
+
+\DOCMODE(
+\xyletcsnamecsname@{dir1{..}}{dir{.}}
+\xyletcsnamecsname@{dir2{..}}{dir2{.}}
+\xyletcsnamecsname@{dir3{..}}{dir3{.}}
+\xyletcsnamecsname@{dir{..}}{dir1{.}}
+\xyletcsnamecsname@{dir{::}}{dir2{.}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[Plain tips]
+
+ The group of "plain tips" contains basic objects that are useful as
+ markers and arrowheads making connections, so each is shown at the
+ end of a dotted connection of the appropriate kind.
+
+ They may also be used as connectors and will build dotted
+ connections. \eg, |**@{>}| typesets
+$$
+ \xy 0*++{}; (10,3)*++{} **@{>} \endxy
+$$
+
+\begin{exercise}
+ Typeset the following two $+$s and a tilted square:
+\begin{code}
+$$\xy
+ *{+}; p+(6,3)*{+} **{} ?(1)
+ *@{-} *!/-5pt/^\dir{-}
+ *^\dir{-} *!/^-5pt/\dir{-}
+\endxy$$
+\end{code}
+\docode
+%
+ "Hint": the dash created by |\dir{-}| has the length |5pt| (here).
+%
+\answercode
+\answertext{One way is}
+\answertext\displaycode
+\answertext{Thus we first create the two $+$s as $p$ and $c$ and connect them
+ with the dummy connection |**{}| to setup the direction parameters.
+ Then we move `on top of $c$' with |?(1)| and position the four sides
+ of the square using |^| and |_| for local direction changes and
+ |/|<dimen>|/| for skewing the resulting object by moving its
+ reference point in the opposite direction.}%
+\end{exercise}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\DOCMODE(
+\xylet@\ctipEdge@=\czeroEdge@
+\DOCMODE)
+
+ \TODO: Change tips to have a tiny size of 2sp which may be taken as
+ an indication that it is a tip (this can be used by some features,
+ \eg, `arrow').
+
+\paragraph*{Arrow heads:}
+
+ The ones intended for single connections are just characters from
+ ??c![\xyatipfont] and ??c![\xybtipfont].
+
+\DOCMODE(
+\xydefcsname@{dir1{>}}{\tip@}
+\xydefcsname@{dir^{>}}{\atip@}
+\xydefcsname@{dir_{>}}{\btip@}
+\xyletcsnamecsname@{dir0{>}}{dir{}}
+\xyletcsnamecsname@{dir{>}}{dir1{>}}
+
+\xydefcsname@{dir1{<}}{\reverseDirection@\tip@}
+\xydefcsname@{dir^{<}}{\reverseDirection@\btip@}
+\xydefcsname@{dir_{<}}{\reverseDirection@\atip@}
+\xyletcsnamecsname@{dir0{<}}{dir{}}
+\xyletcsnamecsname@{dir{<}}{dir1{<}}
+
+\xydef@\tip@{\tip@x\tip@@}
+\xydef@\atip@{\tip@x\atip@@}
+\xydef@\btip@{\tip@x\btip@@}
+
+\xydef@\tip@x#1{#1\egroup
+ \ctipEdge@ %\Invisible@false \Hidden@false
+ \def\Leftness@{.5}\def\Upness@{.5}%
+ \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
+
+\xydef@\tip@@{\atip@@\btip@@}
+\xydef@\atip@@{\xyatipfont\DirectionChar}
+\xydef@\btip@@{\xybtipfont\DirectionChar}
+\DOCMODE)
+
+ Double and triple tips are realised by taking the two halfs and
+ `wringing them apart'; as the naming indicates they are meant to be
+ put at the end of |2|- and |3|-connections. This is currently done
+ the slightly hacky (but efficient) way of adding directly to
+ ??c![\DirectionChar]; maybe this should be using |\vDirection@|?
+
+\DOCMODE(
+\xydefcsname@{dir2{>}}{\Tip@}
+\xydefcsname@{dir2{<}}{\reverseDirection@\Tip@}
+
+\xydef@\Tip@{\kern2.5pt \vrule height2.5pt depth2.5pt width\z@
+ \Tip@@ \kern2.5pt \egroup
+ \U@c=2.5pt \D@c=2.5pt \L@c=2.5pt \R@c=2.5pt \Edge@c={\circleEdge}%
+% \Invisible@false \Hidden@false
+ \def\Leftness@{.5}\def\Upness@{.5}%
+ \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
+
+\xydef@\Tip@@{\count@=\DirectionChar
+ \advance\count@-4 \ifnum\count@<\z@ \advance\count@128 \fi
+ \xyatipfont\char\count@
+ \advance\count@ 8 \ifnum127<\count@ \advance\count@-128 \fi
+ \xybtipfont\char\count@}
+
+\xydefcsname@{dir3{>}}{\Ttip@}
+\xydefcsname@{dir3{<}}{\composite@{}{:(-1,0)\dir3{>}}}
+
+\xydef@\Ttip@{\kern3.2pt \vrule height3.2pt depth3.2pt width\z@
+ \Ttip@@ \kern3.2pt \egroup
+ \U@c=3.2pt \D@c=3.2pt \L@c=3.2pt \R@c=3.2pt \Edge@c={\circleEdge}%
+% \Invisible@false \Hidden@false
+ \def\Leftness@{.5}\def\Upness@{.5}%
+ \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
+
+\xydef@\Ttip@@{%
+ \setboxz@h\bgroup\reverseDirection@\line@ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@
+ \kern-\L@c \boxz@ \kern\L@c
+ {\vDirection@(1,-.31)\xydashl@ \xyatipfont\char\DirectionChar}%
+ {\vDirection@(1,+.31)\xydashl@ \xybtipfont\char\DirectionChar}}
+\DOCMODE)
+
+\paragraph*{Stopper:}
+
+ |\dir{||}| makes a `stopper' using just the appropriate
+ ??c![\xydashfont] character rotated $90^\circ$ and centered; the |^|
+ and |_| variants are just shifted appropriately and two are used to
+ make the |2| and |3| variants longer.
+
+\DOCMODE(
+\xydefcsname@{dir1{|}}{\stopper@}
+\xydefcsname@{dir^{|}}{\aboveDirection@\xydashl@
+ \shiftdir@\line@\z@ \pointlike@{}\xydashh@}
+\xydefcsname@{dir_{|}}{\belowDirection@\xydashl@
+ \shiftdir@\line@\z@ \pointlike@{}\xydashh@}
+\xydefcsname@{dir2{|}}{\stopper@ \double@\xydashh@}
+\xydefcsname@{dir3{|}}{\stopper@ \double@{2\xydashh@}}
+
+\xyletcsnamecsname@{dir0{|}}{dir{}}
+\xyletcsnamecsname@{dir{|}}{dir1{|}}
+
+\xydef@\stopper@{\tip@x\stopper@@}
+
+\xydef@\stopper@@{\setboxz@h{\count@=\SemiDirectionChar \advance\count@64 %
+ \ifnum127<\count@ \advance\count@-128 \fi \xydashfont\char\count@\/}%
+ \setboxz@h{\kern-.5\wdz@ \dimen@=\sd@Y\cosDirection\xydashl@
+ \ifnum\SemiDirectionChar=95 \dimen@=\sd@X\sd@Y\dimen@ \fi
+ \raise.5\dimen@\boxz@}%
+ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
+\DOCMODE)
+
+\paragraph*{Hooks:}
+
+ These are halfcircles opening towards or opposite ??c![\Direction] and
+ fastened by their center or either endpoint. Build by lots of box
+ manipulation with the ??c![\xybsqlfont] quarter circles\dots\smiley
+
+\DOCMODE(
+\xydefcsname@{dir1{(}}{\hook@}
+\xydefcsname@{dir^{(}}{\ahook@}
+\xydefcsname@{dir_{(}}{\bhook@}
+\xyletcsnamecsname@{dir0{(}}{dir{}}
+\xyletcsnamecsname@{dir{(}}{dir1{(}}
+
+\xydefcsname@{dir1{)}}{\reverseDirection@\hook@}
+\xydefcsname@{dir^{)}}{\reverseDirection@\bhook@}
+\xydefcsname@{dir_{)}}{\reverseDirection@\ahook@}
+\xyletcsnamecsname@{dir0{)}}{dir{}}
+\xyletcsnamecsname@{dir{)}}{dir1{)}}
+
+\xydef@\hook@{\tip@x\hook@@}
+\xydef@\hook@@{\setboxz@h{\xybsqlfont
+ \vDirection@(1,-1){.707107\xybsqll@}%
+ \hbox{\DirectionChar
+ \kern-\d@Y\raise\d@X\hbox{\count@=\DirectionChar \advance\count@-32 %
+ \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}}%
+ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
+
+\xydef@\ahook@{\tip@x\ahook@@}
+\xydef@\ahook@@{\setboxz@h{\xybsqlfont
+ \vDirection@(1,-1){.707107\xybsqll@}\kern-\d@X
+ \lower\d@Y\hbox{\DirectionChar
+ \kern-\d@Y\raise\d@X\hbox{\count@=\DirectionChar \advance\count@-32 %
+ \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}}%
+ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
+
+\xydef@\bhook@{\tip@x\bhook@@}
+\xydef@\bhook@@{\setboxz@h{\xybsqlfont
+ \vDirection@(-1,-1){.707107\xybsqll@}\DirectionChar
+ \kern\d@X\raise\d@Y\hbox{\count@=\DirectionChar \advance\count@-96 %
+ \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}%
+ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
+\DOCMODE)
+
+\paragraph*{Quarter turns:}
+
+ These are quarter circles fastened by their start or end point in
+ ??c![\Direction]. Build by box manipulation of the ??c![\xybsqlfont]
+ quarter circles. The intention is that the |`'| directionals are
+ half the corresponding |()| directional.
+
+\DOCMODE(
+\xydefcsname@{dir^{'}}{\reverseDirection@\bturn@}
+\xydefcsname@{dir_{'}}{\reverseDirection@\aturn@}
+
+\xydefcsname@{dir^{`}}{\aturn@}
+\xydefcsname@{dir_{`}}{\bturn@}
+
+\xydef@\aturn@{\tip@x\aturn@@}
+\xydef@\aturn@@{\setboxz@h{\xybsqlfont
+ \vDirection@(1,-1){.707107\xybsqll@}\kern-\d@X
+ \lower\d@Y\hbox{\DirectionChar}}%
+ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
+
+\xydef@\bturn@{\tip@x\bturn@@}
+\xydef@\bturn@@{\setboxz@h{\xybsqlfont
+ \vDirection@(-1,-1){.707107\xybsqll@}\DirectionChar}%
+ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\note??=[Constructed tips]
+
+ These tips are combinations of the plain tips provided for
+ convenience (and optimised for efficiency). New ones can be
+ constructed using ??c![\composite] and by declarations of the form
+%
+\begin{defs1}
+%
+ ??c![\newdir] <dir> |{|<composite>|}|\cr
+%
+\end{defs1}
+\noindent\unskip
+%
+ which defines ??c![\dir]<dir> as the <composite> (see note~??[composite
+ object box] for the details).
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ ??c![\newdir] is simple:
+
+\DOCMODE(
+\xydef@\newdir#1#{\newdir@{#1}}
+
+\xydef@\newdir@#1#2#3{\xydefcsname@{dir#1{#2}}{\composite@{}{#3}}}
+\DOCMODE)
+
+ Then the somewhat more efficient |\shiftdir@| used internally for
+ moving a tip in the current direction---it does so by making a local
+ hbox within which the argument tip is constructed and subsequently
+ shifted and made of zero size. Use as
+$$
+ |\shiftdir@|<tip@><dimen><tip@>
+$$
+ where <tip@> means a tip command without the leading |\hbox{|.
+
+\DOCMODE(
+\xydef@\shiftdir@#1#2{%
+ \setbox\z@=\hbox\bgroup#1\relax
+ \setboxz@h{\dimen@ii=#2\relax
+ \dimen@=-\cosDirection\dimen@ii \advance\dimen@-\L@c
+ \kern\dimen@ \lower\sinDirection\dimen@ii\boxz@}%
+ \wdz@\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
+\DOCMODE)
+
+ Then the tips, with the |\tipjot@| hook allowing changing the spacing
+ of tips used for single lines.
+
+\DOCMODE(
+\xylet@\tipjot@=\jot
+
+\xydefcsname@{dir1{>>}}{\shiftdir@\tip@\tipjot@ \tip@}
+\xydefcsname@{dir^{>>}}{\shiftdir@\atip@\tipjot@ \atip@}
+\xydefcsname@{dir_{>>}}{\shiftdir@\btip@\tipjot@ \btip@}
+\xydefcsname@{dir2{>>}}{\composite@{}{h!/\tipjot@/\dir2{>}*\dir2{>}}}
+\xydefcsname@{dir3{>>}}{\composite@{}{h!/\tipjot@/\dir3{>}*\dir3{>}}}
+\xyletcsnamecsname@{dir0{>>}}{dir{}}
+\xyletcsnamecsname@{dir{>>}}{dir1{>>}}
+
+\xydefcsname@{dir1{<<}}{\reverseDirection@ \shiftdir@\tip@\tipjot@ \tip@}
+\xydefcsname@{dir^{<<}}{\reverseDirection@ \shiftdir@\btip@\tipjot@ \btip@}
+\xydefcsname@{dir_{<<}}{\reverseDirection@ \shiftdir@\atip@\tipjot@ \atip@}
+\xydefcsname@{dir2{<<}}{\composite@{}{h!/-\tipjot@/\dir2{<}*\dir2{<}}}
+\xydefcsname@{dir3{<<}}{\composite@{}{h!/-\tipjot@/\dir3{<}*\dir3{<}}}
+\xyletcsnamecsname@{dir0{<<}}{dir{}}
+\xyletcsnamecsname@{dir{<<}}{dir1{<<}}
+
+\xydefcsname@{dir1{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
+ \pointlike@{}\jot}
+\xydefcsname@{dir^{||}}{\shiftdir@{\aboveDirection@\xydashl@\line@}\xydashh@
+ \shiftdir@{\aboveDirection@\xydashl@\line@}\z@ \pointlike@{}\jot}
+\xydefcsname@{dir_{||}}{\shiftdir@{\belowDirection@\xydashl@\line@}\xydashh@
+ \shiftdir@{\belowDirection@\xydashl@\line@}\z@ \pointlike@{}\jot}
+\xydefcsname@{dir2{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
+ \pointlike@{}\jot \double@\xydashh@}
+\xydefcsname@{dir3{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
+ \pointlike@{}\jot \double@{2\xydashh@}}
+\xyletcsnamecsname@{dir0{||}}{dir{}}
+\xyletcsnamecsname@{dir{||}}{dir1{||}}
+
+\xydefcsname@{dir1{>|}}{\shiftdir@\stopper@\z@ \tip@}
+\xydefcsname@{dir2{>|}}{\composite@{}{\dir2{>}*\dir2{|}}}
+\xydefcsname@{dir3{>|}}{\composite@{}{\dir3{>}*\dir3{|}}}
+\xyletcsnamecsname@{dir0{>|}}{dir{}}
+\xyletcsnamecsname@{dir{>|}}{dir1{>|}}
+
+\xydefcsname@{dir1{>>|}}{\shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
+\xydefcsname@{dir2{>>|}}{\composite@{}{h!/\tipjot@/\dir2{>}*\dir2{>}*\dir2{|}}}
+\xydefcsname@{dir3{>>|}}{\composite@{}{h!/\tipjot@/\dir3{>}*\dir3{>}*\dir3{|}}}
+\xyletcsnamecsname@{dir0{>>|}}{dir{}}
+\xyletcsnamecsname@{dir{>>|}}{dir1{>>|}}
+
+\xydefcsname@{dir1{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \tip@}
+\xydefcsname@{dir2{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \Tip@}
+\xydefcsname@{dir3{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \Ttip@}
+\xyletcsnamecsname@{dir0{|<}}{dir{}}
+\xyletcsnamecsname@{dir{|<}}{dir1{|<}}
+
+\xydefcsname@{dir1{|<<}}{\reverseDirection@
+ \shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
+\xydefcsname@{dir2{|<<}}{%
+ \composite@{}{h!/-\tipjot@/\dir2{<}*\dir2{<}*\dir2{|}}}
+\xydefcsname@{dir3{|<<}}{%
+ \composite@{}{h!/-\tipjot@/\dir3{<}*\dir3{<}*\dir3{|}}}
+\xyletcsnamecsname@{dir0{|<<}}{dir{}}
+\xyletcsnamecsname@{dir{|<<}}{dir1{|<<}}
+
+\xydefcsname@{dir1{|-}}{\shiftdir@\stopper@\z@
+ \shiftdir@\line@\z@ \pointlike@{}\jot}
+\xydefcsname@{dir^{|-}}{\shiftdir@{\aboveDirection@\xydashl@ \line@}\z@
+ \shiftdir@\line@\z@ \pointlike@{}\jot}
+\xydefcsname@{dir_{|-}}{\shiftdir@{\belowDirection@\xydashl@ \line@}\z@
+ \shiftdir@\line@\z@ \pointlike@{}\jot}
+\xydefcsname@{dir2{|-}}{\shiftdir@\stopper@\z@
+ \shiftdir@\line@\z@ \pointlike@{}\jot \double@\xydashh@}
+\xydefcsname@{dir3{|-}}{\shiftdir@\stopper@\z@
+ \shiftdir@\line@\z@ \pointlike@{}\jot \triple@\xydashh@}
+\xyletcsnamecsname@{dir0{|-}}{dir{}}
+\xyletcsnamecsname@{dir{|-}}{dir1{|-}}
+\xyletcsnamecsname@{dir{|=}}{dir2{|-}}
+
+\xydefcsname@{dir{+}}{%
+ \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
+\xyletcsnamecsname@{dir0{+}}{dir{}}
+
+\xydefcsname@{dir{x}}{\vDirection@(1,1)\jot
+ \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
+\xyletcsnamecsname@{dir0{x}}{dir{}}
+
+\xydefcsname@{dir{/}}{\vDirection@(1,-.3)\jot \stopper@}
+\xyletcsnamecsname@{dir0{/}}{dir{}}
+
+\xydefcsname@{dir{//}}{\vDirection@(1,-.3)\jot
+ \shiftdir@\stopper@\xydashh@ \stopper@}
+\xyletcsnamecsname@{dir0{//}}{dir{}}
+
+\xydefcsname@{dir{*}}{\solidpoint@}
+\xydef@\solidpoint@{%
+ \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\bullet$}}\jot}
+\xyletcsnamecsname@{dir0{*}}{dir{}}
+
+\xydefcsname@{dir{o}}{\hollowpoint@}
+\xydef@\hollowpoint@{%
+ \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\circ$}}\jot}
+\xyletcsnamecsname@{dir0{o}}{dir{}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{notes}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{figure*}[ht]
+\vss
+\begin{syntax}
+%
+ \multispan3|\cir| <radius> |{| <cir> |}|\hfil
+ & <cir>cle segment with <radius>
+\cr
+\noalign{\nobreak\smallskip\nobreak\hrule\nobreak\smallskip\nobreak}
+%
+ ??w![<radius>]
+ &\iss & <empty>
+ & use $R_c$ as the radius
+\cr
+ &\orr & <vector>
+ & use $X$ of the <vector> as radius
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<cir>]
+ &\iss & <empty>
+ & full circle of <radius>
+\cr
+ &\orr & <diag> <orient> <diag>
+ & partial circle from first <diag>onal through to the
+ second <diag>onal in the <orient>ation
+\cr
+\noalign{\smallbreak}
+%
+ ??w![<orient>]
+ &\iss & |^|
+ & anticlockwise
+\cr
+ &\orr & |_|
+ & clockwise
+\cr
+\end{syntax}
+\caption{\protect<cir>cles.}
+??=[f.cir]
+\vfill
+\end{figure*}
+
+
+\subsection{Circle segments}
+??=[objectlib.circles]
+
+\DOCMODE(
+\message{circles,}
+\DOCMODE)
+
+ Circle <object>s are round and typeset a segment of the circle
+ centered at the reference point. The syntax of circles is described
+ in figure~??[f.cir] with explanations below.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The |\cir| command is the hub: it parses the optional <radius> (to
+ |\R@|, default from $R_c$) and |{|<cir>|}|, bailing out with a
+ |\zerodot| if the radius is to small:
+
+\DOCMODE(
+\xydef@\cir#1#{\hbox\bgroup
+ \afterVECTORorEMPTY{\xy@@{\R@=\X@c}\cir@}{\xy@@{\R@=\R@c}\cir@}#1@}
+
+\xydef@\cir@#1@#2{%
+ \DN@{#1}\ifx\next@\empty\else \xyerror@{illegal circle <radius>: must be
+ <vector> or <empty>}{}\fi
+ \afterCIRorDIAG{\xyFN@\cir@cir}{\xyFN@\cir@diag}#2@}
+\DOCMODE)
+
+ The code to actually typeset the <cir> just parsed starts by checking
+ that the <cir> was immediately followed by the |@| we put there in
+ |\cir|:
+
+\DOCMODE(
+\xydef@\cir@cir{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\cir@cir}%gobble spaces
+ \else \ifx @\next \DN@ @{\cir@i}%
+ \else \xyerror@{illegal <cir>: must have form <diag><orient><diag> or
+ <empty>}{}%
+ \fi\fi \next@}
+\DOCMODE)
+
+ Similarly when an <empty> one was given---the parser will recognise
+ this as a <diag> but we hack that here:
+
+\DOCMODE(
+\xydef@\cir@diag{%
+ \DN@{\xyerror@{illegal <cir>: must have form <diag><orient><diag> or
+ <empty>}{}}%
+ \ifx @\next \ifnum\count@=8 %
+ \DN@ @{\def\CIRin@@{0}\def\CIRorient@@{\CIRfull@}\def\CIRout@@{7}\cir@i}%
+ \fi\fi \next@}
+\DOCMODE)
+
+ \dots and then use the constructed methods to build it:
+
+\DOCMODE(
+\xydef@\cir@i{%
+ \ifnum\CIRin@@=8 \xyerror@{incomplete <cir> specification}{%
+The <cir> you specified as <diag><orient><diag> is not sufficiently specific.}%
+ \def\CIRin@@{0}\fi
+ \ifdim\R@<.5\p@ \R@=\z@ \zerodot
+ \else \CIRorient@@ \cirbuild@ \fi
+ \L@c=\R@ \R@c=\R@ \D@c=\R@ \U@c=\R@ \def\Leftness@{.5}\def\Upness@{.5}%
+ \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\relax}%
+ \Edge@c={\circleEdge}\OBJECT@x}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Parsing:}
+
+ The |\afterCIRorDIAG| parser handles the parsing: it either
+%
+\begin{itemize}
+
+\item
+ parses the <cir> and sets "in", "orient", and "out", and passes
+ control to the first argument continuation, or
+
+\item
+ parses the single <diag> specified, store it in |\count@| (as |8| if
+ an <empty> one given), and pass control to the second continuation
+ argument,
+
+\end{itemize}
+%
+ where the <diag> internal representation number of note~??[diagonal]
+ of is used. An <empty> circle is treated as an <empty> diagonal;
+ specifying an <empty> first <diag> of a <cir> is equivalent to using
+ the value of the "in" method at call time.
+
+ The parser is very simple, setting methods stored in the usual
+ |@@|-terminated control sequences (\TODO: Rename all non-method
+ control sequences that end in |@@|\dots to use |@|<romannumeral>
+ suffixes\dots):
+
+\DOCMODE(
+\xydef@\CIRin@@{3}
+\xydef@\CIRout@@{3}
+\xylet@\CIRorient@@=\empty
+
+\xydef@\afterCIRorDIAG#1#2{\def\afterCIR@{#1}\def\afterCIRDIAG@{#2}\xyFN@\CIR@}
+
+\xylet@\afterCIR@=\empty
+\xylet@\afterCIRDIAG@=\empty
+
+\xydef@\CIR@{\count@=8 \afterDIAG{\edef\CIRin@@{\the\count@}\xyFN@\CIR@@}}
+
+\xydef@\CIR@@{%
+ \ifx \space@\next \expandafter\DN@\space{\xyFN@\CIR@@}%gobble spaces
+ \else\ifx ^\next
+ \DN@ ^{\def\CIRorient@@{\CIRacw@}%
+ \afterDIAG{\edef\CIRout@@{\the\count@}\afterCIR@}}%
+ \else\ifx _\next
+ \DN@_{\def\CIRorient@@{\CIRcw@}%
+ \afterDIAG{\edef\CIRout@@{\the\count@}\afterCIR@}}%
+ \else
+ \DN@{\def\CIRorient@@{\relax}\afterCIRDIAG@}%
+ \fi\fi\fi \next@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The default is to generate a "full circle" with the specified radius,
+ \eg,
+$$
+\def\quotesmash#1{\setbox0=\hbox{``$\vcenter{#1}$''}\ht0=8pt \dp0=3pt \box0}
+\begin{array}{ccc}
+ |\xy*\cir<4pt>{}\endxy|
+ &\hbox{typesets}& \quotesmash{\xy*\cir<4pt>{}\endxy}
+\cr
+ |\xy*{M}*\cir{}\endxy|
+ &\hbox{---}& \quotesmash{\xy*{M}*\cir{}\endxy}
+\end{array}
+$$
+ All the other circle segments are subsets of this and have the shape
+ that the full circle outlines.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Finally we present the "orient" methods. They use these `internal
+ methods' to actually draw the circles
+
+\DOCMODE(
+\xylet@\CIRtest@@=\relax
+\xydef@\CIRlo@@{0}
+\xydef@\CIRhi@@{0}
+\DOCMODE)
+
+ Below we call them "lo", "hi", and "test"; the first two are coded as
+ described in note ??[diagonal] and the last takes two arguments: a
+ dimension and something to do if the test succeeds. |\count@@| and
+ |\count@| should be set to "in" and "out" internally as well in case
+ |\cirbuild@| and friends below should be used.
+
+ The dummy "orient" used for simple circles is the simplest:
+
+\DOCMODE(
+\xydef@\CIRfull@{\def\CIRtest@@##1##2{##2}}
+\DOCMODE)
+
+ The kernel |\cirbuild@| builds the actual <object> using characters
+ from the ??c![\xycircfont] assumed coded like |xycirc10.mf|:
+ |\cirrestrict@@| choses a group and adjusts the radius |\R@| to fit it
+ exactly. The group is multiplied by 8 to get the group character
+ offset [|\count@|].
+
+\DOCMODE(
+\xydef@\cirbuild@{\cirrestrict@@ \multiply\count@8 %
+ \circhar@0\circhar@7\kern\dimen@
+ \circhar@1\circhar@6\kern\dimen@
+ \circhar@2\circhar@5\kern\dimen@
+ \circhar@3\circhar@4\kern\dimen@}
+
+\xydef@\circhar@#1{%
+ \setboxz@h{\circhar@@{#1}}\dimen@=\wdz@ \wdz@=\z@ \ht\z@=\R@ \dp\z@=\R@
+ \CIRtest@@#1{\styledboxz@}\setbox\z@=\copy\voidb@x}
+
+\xydef@\circhar@@#1{{\xycircfont \advance\count@#1\relax \char\count@}}
+\DOCMODE)
+
+ |\cirrestrict@@| computes the group $g$ [|\count@|] of circle segments
+ to use from the radius $r$ [|\R@|] using the formula (the reverse of
+ the one in |xycirc10.mf|)
+$$
+\def\arraystretch{1}
+g = \left\{ \begin{array}{ll}
+ \floor{r\over1|pt|}-1 &\textrm{if}~ 1|pt|\le r\lt 8|pt|\\
+ \floor{r\over2|pt|}+3 &\textrm{if}~ 8|pt|\le r\lt 16|pt|\\
+ \floor{r\over4|pt|}+7 &\textrm{if}~16|pt|\le r\lt 32|pt|\\
+ 15 &\textrm{if}~32|pt|\le r \end{array}
+\right.
+$$
+ (where we know from |\cir@i| that $r\ge\frac12|pt|$), and then
+ adjusts the radius to be exactly the one chosen through the use of
+ group $g$ using the formula in |xycirc10.mf|\dots this is necessary
+ because of the restriction on |tfm| files that they can only have 15
+ different nonzero heights and depths. Subsequent calls to
+ |\cirrestrict@@| should compute the same values.
+
+\DOCMODE(
+\xydef@\cirrestrict@@{\begingroup \dimen@=\R@
+ \setboxz@h{\xycircfont\char\z@\char\@ne}\A@=\wdz@
+ \ifdim\R@<8\A@ \count@=\dimen@ \divide\count@\A@ \advance\count@\m@ne
+ \else\ifdim\R@<16\A@ \count@=\dimen@
+ \dimen@=2\A@ \divide\count@\dimen@ \advance\count@3 %
+ \else\ifdim\R@<32\A@ \count@=\dimen@
+ \dimen@=4\A@ \divide\count@\dimen@ \advance\count@7 %
+ \else \count@=15 \fi\fi\fi
+ \R@=\A@
+ \ifnum\count@<8 \multiply\R@\count@ \advance\R@\A@
+ \else\ifnum\count@<12 \multiply\R@\count@ \multiply\R@\tw@ \advance\R@-6\A@
+ \else\ifnum\count@<16 \multiply\R@\count@ \multiply\R@ 4 \advance\R@-28\A@
+ \else \multiply\R@ 32 \fi\fi\fi
+ \edef\@tmp{\endgroup \R@=\the\R@ \count@=\the\count@}\@tmp}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ "Partial circle segments" with <orient>ation are the part of the full
+ circle that starts with a tangent vector in the direction of the
+ first <diag>onal (see note~??[diagonal]) and ends with a tangent
+ vector in the direction of the other <diag>onal after a clockwise
+ (for |_|) or anticlockwise (for |^|) turn, \eg,
+$$
+\def\quotesmash#1{\setbox0=\hbox{``$\vcenter{#1}$''}\ht0=8pt \dp0=3pt \box0}
+\begin{array}{ccc}
+ |\xy*\cir<4pt>{l^r}\endxy|
+ &\hbox{typesets}& \quotesmash{\xy*\cir<4pt>{l^r}\endxy}
+\\
+ |\xy*\cir<4pt>{l_r}\endxy|
+ &\hbox{---}& \quotesmash{\xy*\cir<4pt>{l_r}\endxy}
+\\
+ |\xy*\cir<4pt>{dl^u}\endxy|
+ &\hbox{---}& \quotesmash{\xy*\cir<4pt>{dl^u}\endxy}
+\\
+ |\xy*\cir<4pt>{dl_u}\endxy|
+ &\hbox{---}& \quotesmash{\xy*\cir<4pt>{dl_u}\endxy}
+\\
+ |\xy*+{M}*\cir{dr_ur}\endxy|
+ &\hbox{---}& \quotesmash{\xy*+{M}*\cir{dr_ur}\endxy}
+\end{array}
+$$
+ If the same <diag> is given twice then nothing is typeset, \eg,
+$$
+\def\quotesmash#1{\setbox0=\hbox{``$\vcenter{#1}$''}\ht0=8pt \dp0=3pt \box0}
+\begin{array}{ccc}
+ |\xy*\cir<4pt>{u^u}\endxy|
+ &\hbox{typesets}& \quotesmash{\xy*\cir<4pt>{u^u}\endxy}
+\end{array}
+$$
+ Special care is taken to setup the <diag>onal defaults:
+%
+\begin{itemize}
+
+\item
+ After |^| the default is the diagonal $90^\circ$ anticlockwise from
+ the one before the |^|.
+
+\item
+ After |_| the default is the diagonal $90^\circ$ clockwise from the
+ one before the |_|.
+
+\end{itemize}
+%
+ The <diag> before |^| or |_| is required for ??c![\cir] <objects>.
+
+\begin{exercise}
+ Typeset the following shaded circle with radius |5pt|:
+%
+\begin{code}
+$$\xy
+ *\cir<5pt>{}
+ *!<-.2pt,.2pt>\cir<5pt>{dr^ul}
+ *!<-.4pt,.4pt>\cir<5pt>{dr^ul}
+ *!<-.6pt,.6pt>\cir<5pt>{dr^ul}
+\endxy$$
+\end{code}
+\docode
+%
+\answertext{One way is to add extra half circles skewed such that they create
+ the illusion of a shade:}
+\answercode
+\answertext\displaycode
+\end{exercise}
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ These two macros implement the defaults and setup of "lo" and "hi"
+ for anticlockwise and clockwise segments. Here is what they set:
+$$
+\begin{array}{\otherbar c\otherbar cc\otherbar l\otherbar}
+\hline
+ ??w![<cir>] & "lo" & "hi" & "test"(s) \\
+\hline
+ d_1|^|d_2, d_1\le d_2 & d_1 -_8 1 & d_2 -_8 1 & {"lo"\le s}\wedge{s\lt "hi"}\\
+ d_1|^|d_2, d_1\gt d_2 & d_2 -_8 1 & d_1 -_8 1 & {s \lt"lo"} \vee {"hi"\le s}\\
+ d_1|_|d_2, d_1\lt d_2 & d_1 +_8 3 & d_2 +_8 3 & {s \lt"lo"} \vee {"hi"\le s}\\
+ d_1|_|d_2, d_1\ge d_2 & d_2 +_8 3 & d_1 +_8 3 & {"lo"\le s}\wedge{s\lt "hi"}\\
+\hline
+\end{array}
+$$
+ where $+_8$ and $-_8$ are $+$ and $-$ modulo 8; $d_1$ and $d_2$ are
+ in |\count@@| and |\count@|, respectively.
+
+\DOCMODE(
+\xydef@\CIRacw@{\count@@=\CIRin@@ \count@=\CIRout@@
+ \ifnum\count@=8 \count@=\count@@
+ \ifnum\count@<6 \advance\count@\tw@ \else \advance\count@-6 \fi \fi
+ \ifnum\count@@<\@ne \advance\count@@7 \else \advance\count@@\m@ne \fi
+ \ifnum\count@<\@ne \advance\count@7 \else \advance\count@\m@ne \fi
+ \ifnum\count@@>\count@ \let\CIRtest@@=\CIRtest@outside
+ \edef\CIRlo@@{\the\count@}\edef\CIRhi@@{\the\count@@}%
+ \else \let\CIRtest@@=\CIRtest@inside
+ \edef\CIRlo@@{\the\count@@}\edef\CIRhi@@{\the\count@}%
+ \fi}
+
+\xydef@\CIRcw@{\count@@=\CIRin@@ \count@=\CIRout@@
+ \ifnum\count@=8 \count@=\count@@
+ \ifnum\count@>\@ne \advance\count@-\tw@ \else \advance\count@6 \fi \fi
+ \ifnum\count@@<5 \advance\count@@\thr@@ \else \advance\count@@-5 \fi
+ \ifnum\count@<5 \advance\count@\thr@@ \else \advance\count@-5 \fi
+ \ifnum\count@@<\count@ \let\CIRtest@@=\CIRtest@outside
+ \edef\CIRlo@@{\the\count@@}\edef\CIRhi@@{\the\count@}%
+ \else \let\CIRtest@@=\CIRtest@inside
+ \edef\CIRlo@@{\the\count@}\edef\CIRhi@@{\the\count@@}%
+ \fi}
+
+\xydef@\CIRtest@inside#1#2{\let\next@=\relax
+ \ifnum\CIRlo@@>#1\else \ifnum#1<\CIRhi@@\DN@{#2}\fi\fi \next@}
+
+\xydef@\CIRtest@outside#1#2{\let\next@=\relax
+ \ifnum\CIRlo@@>#1\DN@{#2}\else \ifnum#1<\CIRhi@@\else\DN@{#2}\fi\fi \next@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Text}
+??=[objectlib.text]
+
+\DOCMODE(
+\message{text;}
+\DOCMODE)
+
+ Text in pictures is supported through the <object> construction
+%
+\begin{defs1}
+??c![\txt] <width> <style> |{|<text>|}|\cr
+\end{defs1}
+\noindent\unskip
+%
+ that builds an object containing <text> typeset to <width> using
+ <style>; in <text> |\\| can be used as an explicit line break; all
+ lines will be centered. <style> should either be a font command or
+ some other stuff to do for each line of the <text> and <width> should
+ be either |<|<dimen>|>| or <empty>.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The code just parses the <width> defaulting it to |<\maxdimen>| which
+ is recognised as `free form'.
+
+\DOCMODE(
+\xydef@\txt{\hbox\bgroup \xyFN@\txt@}
+
+\xydef@\txt@{%
+ \addLT@\ifx\next \addGT@{\addLT@\DN@##1}{\A@=##1\txt@i}%
+ \else \DN@{\A@=\maxdimen \txt@i}\fi \next@}
+
+\xydef@\txt@i#1#{%
+ \setboxz@h{#1\mathstrut}\dimen@=\ht\z@ \advance\dimen@\dp\z@
+ \baselineskip=1.1\dimen@ \lineskip=.2\dimen@ \lineskiplimit=\lineskip
+ \def\txtline@@##1{\txtline@{#1}{##1}}\object@\txt@ii}
+
+\xylet@\txtline@@=\eat@
+\xydef@\txtline@#1#2{\relax\setboxz@h{#1{\ignorespaces #2\unskip}}%
+ \ifdim\A@<\wdz@ \setboxz@h{\hsize=\A@
+ \leftskip=0pt plus4em \rightskip=\leftskip
+ \parfillskip=0pt \parindent=0pt %
+ \spaceskip=.3333em \xspaceskip=.5em %
+ \pretolerance=9999 \tolerance=9999 %
+ \hyphenpenalty=9999 \exhyphenpenalty=9999 %
+ \vbox{#1\noindent\ignorespaces #2\unskip}}%
+ \else\ifdim\A@<\maxdimen\setboxz@h to\A@{\hfil\boxz@\hfil}\fi\fi
+ \boxz@}
+
+\xydef@\txt@ii#1{\vbox{%
+ \let\\=\cr
+ \tabskip=\z@skip \halign{\relax\hfil\txtline@@{##}\hfil\cr\leavevmode#1\crcr}}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section{\Xy-pic options}
+??=[option]
+%
+ \NOTE: \LaTeXe\ users should also consult the paragraph on ``xy.sty''
+ in~\S??[env.loading].
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Loading}
+??=[option.loading]
+%
+ \Xy-pic is provided with a growing number of options supporting
+ specialised drawing tasks as well as exotic output devices with
+ special graphic features. These should all be loaded using this
+ uniform interface in order to ensure that the \Xy-pic environment is
+ properly set up while reading the option.
+%
+\begin{defs1}
+%
+ ??c![\xyoption] |{| <option> |}| \cr
+ ??c![\xyrequire] |{| <option> |}|
+%
+\end{defs1}
+\noindent\unskip
+%
+ ??c![\xyoption] will cause the loading of an \Xy-pic option file
+ which can have one of several names. These are tried in sequence:
+ |xy|<option>|.tex|, |xy|<option>|.doc|, |xy|<short>|.tex|, and
+ |xy|<short>|.doc|, where <short> is <option> truncated to 6 (six)
+ characters to conform with the TWG-TDS~\cite{TWG-TDS}.
+
+ ??c![\xyrequire] is the same except it is ignored if an option with
+ the same name is already present (thus does not check the version
+ etc.).
+
+\DOCMODE(
+\message{options;}
+
+\xylet@\xyoption@@=\relax
+
+\xydef@\xyoption#1{\DN@{#1}\edef\next@{\codeof\next@}%
+ \csname xyeveryrequest@\next@ @\endcsname
+ \xyinputorelse@{xy#1}{\xyoption@truncated#1@@@@@@@@@,#1@}%
+ \def\xyoption@@{#1}\edef\xyoption@@{\codeof\xyoption@@}
+ \expandafter\let\expandafter\next@\csname xy\xyoption@@ version\endcsname
+ \expandafter\let\csname xy\xyoption@@ loaded\endcsname=\next@
+ \runxywith@ \ignorespaces}
+
+\xydef@\xyoption@truncated#1#2#3#4#5#6#7@#8,#9@{%
+ \DN@{#7}\ifx\next@\empty \DN@##1##2{##2}\else\let\next@=\xyinputorelse@ \fi
+ \next@{xy#1#2#3#4#5#6}%
+ {\DN@{#1#2#3#4#5#6}\edef\next@{\codeof\next@}%
+ \xyerror@{No `\next@' option}{%
+Your \xyoption{#9} request could not be granted: the required^^J%
+file `xy#9.tex' could not be located. Please make sure that it is^^J%
+properly installed before continuing.}}}
+
+\xydef@\xyrequire#1{\DN@{#1}\edef\next@{\codeof\next@}%
+ \csname xyeveryrequest@\next@ @\endcsname
+ \expandafter\let\expandafter\next@\csname xy\codeof\next@ loaded\endcsname
+ \ifx \next@\relax \DN@{\xyoption{#1}}\else \DN@{\ignorespaces}\fi \next@}
+\DOCMODE)
+
+ Sometimes some declarations of an option or header file or whatever
+ only makes sense after some particular other option is loaded. In
+ that case the code should be wrapped in the special command
+%
+\begin{defs1}
+ ??c![\xywithoption] |{| <option> |}| |{| <code> |}| \cr
+\end{defs1}
+\noindent\unskip
+%
+ which indicates that if the <option> is already loaded then <code>
+ should be executed now, otherwise it should be saved and if <option>
+ ever gets loaded then <code> should be executed afterwards. \NOTE:
+ The <code> should allow more than one execution; it is saved with the
+ catcodes at the time of the ??c![\xywithoption] command.
+
+\DOCMODE(
+\xylet@\xywith@@=\empty
+
+\xydef@\runxywith@{\let\xywithdo@@=\xywithtest@ \xywith@@}
+
+\xydef@\xywithoption#1#2{\DN@{#1}\edef\next@{\codeof\next@}%
+ \expandafter\let\expandafter\nextii@\csname xy\next@ loaded\endcsname
+ \ifx \nextii@\relax
+ \expandafter\def\expandafter\xywith@@\expandafter{\xywith@@
+ \xywithdo@@{#1}{#2}}%
+ \else \expandafter\xywithrun@\expandafter{\next@}{#2}\fi}
+
+\xydef@\xywithtest@#1#2{\DN@{#1}\edef\next@{\codeof\next@}%
+ \ifx\next@\xyoption@@ \expandafter\xywithrun@\expandafter{\next@}{#2}\fi}
+
+\xydef@\xywithrun@#1#2{\csname xyeverywithoption@#1@\endcsname #2}
+\DOCMODE)
+
+ Finally, it is possible to declare <code> as some commands to be
+ executed before every actual execution of
+ ??c![\xywithoption]\-|{|<option>|}|\-|{|\dots|}|, and similarly
+ <code> to be executed before every |\xyoption{|<option>|}| and
+ |\xyrequire{|<option>|}| (collectively called `requests')::
+%
+\begin{defs1}
+ ??c![\xyeverywithoption] |{| <option> |}| |{| <code> |}| \cr
+ ??c![\xyeveryrequest] |{| <option> |}| |{| <code> |}| \cr
+\end{defs1}
+\noindent\unskip
+%
+ This is most often used by an option to activate some hook every time
+ it is requested itself.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ These last two use the usual expansion trickery to define or append
+ to the control sequences named |\xyevery|\-|request@|\-<option>|@|
+ and |\xyevery|\-|withoption@|\-<option>|@| used in the definitions
+ above.
+
+\DOCMODE(
+\xydef@\xyevery@#1#2#3{\DN@{#2}\edef\next@{\codeof\next@}%
+ \expandafter\ifx\csname xyevery#1@\next@ @\endcsname\relax
+ \expandafter\let\csname xyevery#1@\next@ @\endcsname=\empty \fi
+ \DNii@##1{\expandafter\def\expandafter##1\expandafter{##1#3}}%
+ \expandafter\nextii@\csname xyevery#1@\next@ @\endcsname}
+
+\xydef@\xyeveryrequest{\xyevery@{request}}
+\xydef@\xyeverywithoption{\xyevery@{withoption}}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Option file format}
+??=[option.fileformat]
+%
+ Option files must have the following structure:
+
+\begin{quote}
+ |%%| <identification> \\
+ |%%| <copyright, \etc>
+
+ |\ifx\xyloaded\undefined \input xy \fi|
+
+ |\xyprovide{|<option>|}{|<name>|}{|<version>|}%| \\
+ \null\qquad\qquad |{|<author>|}{|<email>|}{|<address>|}|
+
+ ??w![<body of the option>]
+
+ ??c![\xyendinput]
+\end{quote}
+%
+ The 6 arguments to ??c![\xyprovide] should contain the following:
+%
+\begin{description}
+
+\item[<option>]
+ Option load name as used in the ??c![\xyoption] command. This should
+ be safe and distinguishable for any operating system and is thus
+ limited to characters chosen among the lowercase letters (|a|--|z|),
+ digits (|0|--|9|), and dash (|-|), and all options should be uniquely
+ identifiable by the first 6 (six) characters only.
+
+\item[<name>]
+ Descriptive name for the option.
+
+\item[<version>]
+ Identification of the version of the option.
+
+\item[<author>]
+ The name(s) of the author(s).
+
+\item[<email>]
+ The electronic mail address(es) of the author(s) "or" the affiliation
+ if no email is available.
+
+\item[<address>]
+ The postal address(es) of the author(s).
+
+\end{description}
+%
+ This information is used not only to print a nice banner but also to
+ (1)~silently skip loading if the same version was preloaded and
+ (2)~print an error message if a different version was preloaded.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The ??c![\xyprovide] command checks that the option is not already
+ loaded and that the loaded version is the same as the preloaded one
+ by checking the existence and contents of the macro
+ |\xy|<option>|loaded|. Finally it calls ??c![\xycatcodes] such that
+ the option internals are loaded in `\TeX\ programming mode'.
+ ??c![\xyendinput] undoes this.
+
+\DOCMODE(
+\xydef@\xyprovide#1#2#3#4#5#6{%
+ \def\xyoption@@{#1}\edef\xyoption@@{\codeof\xyoption@@}\edef\next@{#3}%
+ \message{ Xy-pic option: #2 v.\next@}%
+ \expandafter\let\expandafter\nextii@\csname xy\xyoption@@ loaded\endcsname
+ \ifx \next@\nextii@ \message{not reloaded}\endinput
+ \else
+ \ifx \nextii@\relax\else \xyerror@{Option `\xyoption@@' version mismatch}{%
+You previously loaded, or the format has preloaded, a different version^^J%
+of this option. Just continue to try to load this version instead (and^^J%
+be prepared for a lot of warnings about redefinitions).}%
+ \fi
+ \expandafter\let\csname xy\xyoption@@ version\endcsname=\next@
+ \expandafter\let\expandafter\xyenddocmode@\csname DOCMODE\endcsname
+ \expandafter\let\csname DOCMODE\endcsname\xyprovidedocmode@
+ \xycatcodes
+ \fi \ignorespaces}
+
+\xydef@\xyendinput{\expandafter\let\csname DOCMODE\endcsname=\xyenddocmode@
+ \message{loaded}\xyuncatcodes\endinput}
+\DOCMODE)
+
+ The above is futher complicated because an option may loaded in its
+ |DOCMODE| form (ending in |.doc|). So we make sure that the mode
+ that skips documentation, defined in the |xy.tex| file header, is
+ active now.
+
+\DOCMODE(
+\expandafter\xylet@\expandafter\xyprovidedocmode@\csname DOCMODE\endcsname
+\xylet@\xyenddocmode@=\relax
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ The `dummy' option described in~\S??g[:dummy] is a minimal option
+ using the above features. It uses the special |DOCMODE| format to
+ include its own documentation for this document (like all official
+ \Xy-pic options) but this is not a requirement.
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Driver options}
+??=[option.drivers]
+%
+ The ??w![<driver>] options described in \GROUP~??g[:drivers] require
+ special attention because each driver can support several
+ ??w![extension] options, and it is sometimes desirable to change
+ <driver> or even mix the support provided by several.\footnote{The
+ kernel support described here is based on the (now defunct)
+ |xydriver| include file by Ross Moore.}
+
+ A <driver> option is loaded as other options with
+ |\xyoption{|<driver>|}| (or through \LaTeXe\ class or package options
+ as described in~\S??[env.loading]). The special thing about a
+ <driver> is that loading it simply declares the name of it,
+ establishes what extensions it will support, and selects it
+ temporarily. Thus the special capabilities of the driver will only
+ be exploited in the produced DVI file if some of these extensions are
+ also loaded and if the driver is still selected when output is
+ produced. Generally, the order in which the options are loaded is
+ immaterial. (Known exceptions affect only internal processing and
+ are not visible to the user in terms of language and expected output.)
+ In particular one driver can be preloaded in a format and a different
+ one used for a particular document.
+
+ The following declarations control this:
+%
+\begin{defs}
+??c![\UseSingleDriver] & forces one driver only \cr
+??c![\MultipleDrivers] & allows multiple drivers \cr
+??c![\xyReloadDrivers] & resets driver information \cr
+\end{defs}
+\noindent\unskip
+%
+ The first command restores the default behaviour: that ony one
+ <driver> is allowed, \ie, each loading of a <driver> option cancels
+ the previous. The second allows consecutive loading of drivers such
+ that when loading a <driver> only the extensions actually supported
+ are selected, leaving other extensions supported by previously
+ selected drivers untouched. Beware that this can be used to create
+ DVI files that cannot be processed by any actual DVI driver program!
+
+ The last command is sometimes required to reset the \Xy-pic <driver>
+ information to a sane state, for example, after having applied one of
+ the other two in the middle of a document, or when using simple
+ formats like plain \TeX\ that do not have a clearly distinguished
+ preamble.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Driver database.}
+
+ The main structure, the list of `loaded' and `selected' <driver>s
+ (ordered by age), is implemented as traditional \TeX\ `|\do|-lists'
+ (applications of |\do{|<driver>|}| to each element).
+
+\DOCMODE(
+\xydef@\xydriversloaded@@{\do{unload}}
+\xylet@\xydriversselected@@=\empty
+\DOCMODE)
+%
+ This is used to provide entry points into a secondary structure that
+ lists for each <driver> the extensions supported by that driver. As
+ should be apparent from the above, only the |unload| <driver> is
+ present initially: it represents the implementation technique used
+ for the extension when no <driver> is selected. Every extension must
+ add an entry which reestablishes the default implementation of the
+ extension:
+
+\DOCMODE(
+\xylet@\xydriver@unload@support@@=\empty
+\DOCMODE)
+%
+ All <driver>s will have a similar structure named
+ |\xydriver@|\-<driver>\-|@support@@| which contains the extensions
+ supported by that particular <driver>: the `signature' of each driver
+ as |\doii|-list with two arguments (hence the |ii|~\smiley~): the
+ extension and the command to install the <driver>-extension
+ combination.
+
+ The two selection principles differ significantly. When only a
+ single <driver> is selectable then all extensions need to be unloaded
+ "before" the selection. When multiple <driver>s are allowed then
+ only the added support needs to be executed.
+
+\DOCMODE(
+\xydef@\selectdriver@#1{\DN@{#1}\edef\next@{\codeof\next@}%
+ \expandafter\selectdriver@@\expandafter{\next@}}
+
+\xydef@\selectdriver@single#1{\xysetup@@{\def\xydriversselected@@{\do{#1}}%
+ \xyLoadDrivers@}\let\selectdriver@@=\changedriver@single}
+
+\xydef@\changedriver@single#1{\xysetup@@{\def\xydriversselected@@{\do{#1}}%
+ \xyReloadDrivers@}}
+
+\xydef@\selectdriver@multiple#1{\expandafter\xysetup@@\expandafter{%
+ \expandafter\def\expandafter\xydriversselected@@\expandafter{%
+ \xydriversselected@@ \do{#1}}%
+ \let\do=\activatedriver@ \xydriversselected@@}}
+
+\xydef@\UseSingleDriver{\let\selectdriver@@=\selectdriver@single}
+\xydef@\MultipleDrivers{\let\selectdriver@@=\selectdriver@multiple}
+
+\xydef@\xyLoadDrivers@{\let\do=\activatedriver@ \xydriversselected@@}
+\xydef@\xyReloadDrivers@{\activatedriver@{unload}\xyLoadDrivers@}
+\xylet@\xyReloadDrivers=\xyReloadDrivers@
+
+\xydef@\activatedriver@#1{%
+ \let\doii=\activatedriversupport@ \csname xydriver@#1@support@@\endcsname}
+
+\xydef@\activatedriversupport@#1#2{%
+ \expandafter\ifx\csname xy#1loaded\endcsname\relax\DN@{}%
+ \else\DN@{#2}\fi \next@}
+
+\UseSingleDriver
+\DOCMODE)
+
+ Finally we define the following to get complete independence of load
+ sequence: at every loading of an extension option known to be
+ supported, we run through the list of presently selected drivers to
+ activate any support for it, using the following:
+
+\DOCMODE(
+\xydef@\xyselectoptionsupport@{\let\do=\activatedriver@ \xydriversselected@@}
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ As the above suggests it sometimes makes sense to load <driver>s in
+ the actual textual part of a document, however, it is recommended
+ that only drivers "also" loaded in the preamble are reloaded later,
+ and that ??c![\xyReloadDrivers] is used when there is doubt about the
+ state of affairs. In case of confusion the special command
+ ??c![\xyShowDrivers] will list all the presently supported and
+ selected driver-extension pairs to the \TeX\ log.
+
+\DOCMODE(
+\xydef@\xyShowDrivers{{\W@{Loaded:}\let\do=\doShow \xydriversloaded@@
+ \let\next@=\empty
+ \def\do##1{\ifx\next@\empty \DN@{##1}%
+ \else \expandafter\DN@\expandafter{\next@, ##1}\fi}%
+ \xydriversselected@@\W@{Selected: \next@.}}}
+
+\def\doShow#1{\let\next@=\empty
+ \def\doii##1##2{\ifx\next@\empty \DN@{##1}%
+ \else \expandafter\DN@\expandafter{\next@, ##1}\fi}%
+ \csname xydriver@#1@support@@\endcsname
+ \W@{ <driver> #1 supports \next@.}}
+\DOCMODE)
+
+\DOCMODE1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ It is not difficult to add support for additional <driver>s; how is
+ described in the \TeX\-nical documentation.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\paragraph*{Driver internals.}
+
+ A <driver> option files must have the following structure:
+
+\begin{quote}
+ |%%| <identification> \\
+ |%%| <copyright, \etc>
+
+ |\ifx\xyloaded\undefined \input xy \fi|
+
+ |\xyprovide{|<option>|}{|<name>|}{|<version>|}%| \\
+ \null\qquad\qquad |{|<author>|}{|<email>|}{|<address>|}|
+
+ |\newdriver{%|\\
+ |\xyaddsupport{|<extension>|}|<cs>\\
+ \vdots\\
+ |}|
+
+ <body of the {<driver>} option>
+
+ ??c![\xyendinput]
+\end{quote}
+%
+ There should be an ??c![\xyaddsupport] command for each supported
+ <extension> which specicifies the <cs> (control sequence) with which
+ the indicated support is "activated".
+
+ The ??c![\newdriver] command first establishes the `support' list for
+ the <driver> (running the argument), then adds the <driver> to the
+ `loaded' list, and finally selects it now and for every subsequent
+ request of this <driver> option.
+
+ It is important that the <cs> that "activates" each driver/extension
+ combination only does "rebinding of hooks". In order to see what
+ hooks are available for an extension, look for declarations of the
+ form
+%
+\begin{defs1}
+ ??c![\xyaddunsupport] |{|<extension>|}| <cs>
+\end{defs1}
+\noindent\unskip
+%
+ and see what rebindings that <cs> does: those are the
+ hokks. "because" they are the ones that will be safely reestablished!
+ This should be adherede to because both activation and deactivation
+ <cs>s may be executed many times.
+
+ The procedure is as follows: (??_[newdr1])~add the driver and clear
+ its support control sequence unless it is already defined,
+ (??_[newdr2])~execute the support commands, and (??_[newdr3])~setup
+ to select it after loading.
+
+\DOCMODE(
+\xydef@\newdriver#1{%
+ \def\nextiii@##1{%?*[newdr1]
+ \expandafter\def\expandafter\xydriversloaded@@
+ \expandafter{\xydriversloaded@@\do{##1}}%
+ \expandafter\let\csname xydriver@\xyoption@@ @support@@\endcsname=\empty}%
+ \def\do##1{\DNii@{##1}\ifx\xyoption@@\nextii@ \let\nextiii@=\eat@ \fi}%
+ \xydriversloaded@@ \expandafter\nextiii@\expandafter{\xyoption@@}%
+ #1\relax %?*[newdr2]
+ \DN@##1{\xywithoption{##1}{%?*[newdr3]
+ \selectdriver@{##1}\xyeveryrequest{##1}{\selectdriver@{##1}}}}%
+ \expandafter\next@\expandafter{\xyoption@@}\ignorespaces}
+\DOCMODE)
+
+ The support commands merely add to the support |\do|-lists which in
+ turn (??_[adddr1])~adds |\doii{|<extension>|}{|\dots|}| to the
+ |\xydriver@|<driver>|@support@@| control sequence and adds a check
+ for when to apply it every time that <extension> is requested!
+
+
+\DOCMODE(
+\xydef@\xyaddsupport{\expandafter\xyadddriversupport@\expandafter{\xyoption@@}}
+\xydef@\xyaddunsupport{\xyadddriversupport@{unload}}
+
+\xydef@\xyadddriversupport@#1#2#3{%
+ \DNii@{#1}\edef\nextii@{\codeof\nextii@}%
+ \def\nextiii@{#2}\edef\nextiii@{\codeof\nextiii@}%
+%
+% CHECK that the <driver> is loaded!
+\def\next{\xybug@{<driver> \nextii@\space not loaded}}%
+\def\do##1{\DN@{##1}\edef\next@{\codeof\next@}%
+ \ifx\next@\nextii@ \let\next=\relax \fi}\xydriversloaded@@ \next
+%
+% CHECK that the specified <extension> is not already supported!
+\def\next{\xybug@{<driver> \nextii@\space already supports \nextiii@}}%
+\def\doii##1##2{\DN@{##1}\edef\next@{\codeof\next@}%
+ \ifx\next@\nextiii@ \let\next=\relax \fi}\xydriversloaded@@ \next
+%
+ \DN@##1##2{\ifx##1\relax \let##1=\empty \fi %?*[adddr1]
+ \expandafter\def\expandafter##1\expandafter{##1\doii{##2}{#3}}}%
+ \expandafter\expandafter\expandafter\next@
+ \expandafter\expandafter\csname xydriver@\nextii@ @support@@\endcsname
+ \expandafter{\nextiii@}%
+ \DN@##1{\expandafter\xyeverywithoption\expandafter{\nextiii@}{%
+ \xytestforsupport@{##1}}}%
+ \expandafter\next@\expandafter{\nextii@}\xydriversloaded@@
+ \ignorespaces}
+
+\xydef@\xytestforsupport@#1{\def\do##1{\DN@{##1}\DNii@{#1}%
+ \ifx\next@\nextii@ \expandafter\xyselectoptionsupport@ \fi}}
+\DOCMODE)
+
+\paragraph*{Driver related messages.}
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Most extensions will print a warning when a capability is used which
+ is not supported by the presently loaded <driver>. Such messages are
+ only printed once, however, (for some formats they are repeated at
+ the end). Similarly, when the support of an extension that exploits
+ a particular <driver> is used a warning message will be issued that
+ the DVI file is not portable.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ This is implemented by defining a control sequence for each such
+ warning and repeat it at the end. Warnings should be issued using
+ one of
+%
+\begin{defs1}
+|\xyununsupportwarning@| |{|<extension>|}| |{|<message>|}|\cr
+|\xyunsupportwarning@| |{|<driver>|}| |{|<extension>|}| \cr
+\end{defs1}
+
+\DOCMODE(
+\xynew@{if}\ifunsupportwarnings@
+
+\xydef@\xyunsupportwarning@#1#2{{%
+ \DN@{#1}\edef\next@{\codeof\next@}
+ \expandafter\ifx\csname xywarn@unload@\next@ @\endcsname\relax
+ \expandafter\gdef\csname xywarn@unload@\next@ @\endcsname{}%
+ \ifunsupportwarnings@ \xyclosedown@@\xyunsupportwarnings@@ \fi
+ \global\unsupportwarnings@true
+ \expandafter\gdef\expandafter\xyunsupportwarnings@@\expandafter{%
+ \xyunsupportwarnings@@ \W@{ #2.}}%
+ \W@{}%
+ \W@{Xy-pic Warning: `\next@' reproduction is NOT EXACT\xytracelineno@:}%
+ \W@{ #2.}%
+ \W@{}%
+ \fi}}
+
+\xydef@\xyunsupportwarnings@@{\W@{}%
+ \W@{Xy-pic Warning: The produced DVI file is NOT EXACT:}}
+
+\xynew@{if}\ifsupportwarnings@
+
+\xydef@\xysupportwarning@#1#2{{%
+ \DN@{#1}\edef\next@{\codeof\next@}\DNii@{#2}\edef\nextii@{\codeof\nextii@}%
+ \expandafter\ifx\csname xywarn@\next@ @\nextii@ @\endcsname\relax
+ \expandafter\gdef\csname xywarn@\next@ @\nextii@ @\endcsname{}%
+ \ifsupportwarnings@ \xyclosedown@@\xysupportwarnings@@ \fi
+ \global\supportwarnings@true
+ \expandafter\gdef\expandafter\xysupportwarnings@@\expandafter{%
+ \xysupportwarnings@@ \driverextensioncomplain@{#1}{#2}}%
+ \W@{}%
+ \W@{Xy-pic Warning: The produced DVI file is NOT PORTABLE\xytracelineno@:}%
+ \driverextensioncomplain@{#1}{#2}%
+ \W@{}%
+ \fi}}
+
+\xydef@\xysupportwarnings@@{%
+ \W@{Xy-pic Warning: The produced DVI file is NOT PORTABLE:}}
+
+\xydef@\driverextensioncomplain@#1#2{%
+ \DN@{#1}\edef\next@{\codeof\next@}\DNii@{#2}\edef\nextii@{\codeof\nextii@}%
+ \W@{ It contains <driver> `\next@' \string\special s for the `\nextii@'
+ extension.}}
+\DOCMODE)
+
+ Backwards compatibility\dots
+
+\DOCMODE(
+\xydef@\dvimessage@#1#2{\xysupportwarning@{#1}{#2}}
+
+\xynew@{if}\ifxydrivernoloads@
+\xydef@\xydrivernoload@#1{\xyerror@{Could not load xy#1.tex}{}%
+ \xydrivernoloads@true}
+
+\xydef@\xydriverfail@#1{\xyerror@{Sorry, #1 not supported.}{}}
+
+\xydef@\xyunload@#1{\xywarning@{Unloading #1.}}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section{Algorithms}
+??=[algo]
+
+ This section presents the more complicated algorithms used in
+ \Xy-pic.
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Directions}
+??=[algo.direction]
+
+\DOCMODE(
+\message{algorithms: directions,}
+\DOCMODE)
+
+ The "direction state" is described by the following parameters:
+%
+\begin{defs}
+"Direction" & `angle' of the direction on $]-4K\dots4K]$ unit square \cr
+"dX","dY" & the vector $c-p$ \cr
+"sdX","sdY" & sign of "dX" and "dY" \cr
+|\K@dXdY|,|\K@dYdX| & quotients $K\frac{"dX"}{"dY"}$ and
+ $K\frac{"dY"}{"dX"}$ (as dimensions in sp) \cr
+"DirectionChar","SemiDirectionChar" & |\chardefs| for directional
+ and semidirectional fonts \cr
+"cosDirection","sinDirection" & factors in the range $]-1\dots1]$
+ corresponding to cos and sin of Direction \cr
+\end{defs}
+%
+ where the ``$]-4K\dots4K]$ unit square'' has the following angles:
+$$
+\xy *[]=<3pc>{}="c"*\frm{-},
+ "c"; (-1,-1)**{},p+/4pc/ *+{0} **@{-}?>*@{>},
+ "c"; ( 0,-1)**{},p+/4pc/ *+{K} **@{-}?>*@{>},
+ "c"; ( 1,-1)**{},p+/4pc/ *+{2K} **@{-}?>*@{>},
+ "c"; ( 1, 0)**{},p+/4pc/ *+{3K} **@{-}?>*@{>},
+ "c"; ( 1, 1)**{},p+/4pc/ *+{4K} **@{-}?>*@{>},
+ "c"; ( 0, 1)**{},p+/4pc/ *+{{-}3K} **@{-}?>*@{>},
+ "c"; (-1, 1)**{},p+/4pc/ *+{{-}2K} **@{-}?>*@{>},
+ "c"; (-1, 0)**{},p+/4pc/ *+{{-}K} **@{-}?>*@{>},
+\endxy
+$$
+ where the intermediate $K$ angle in each interval correspond to
+ equidistant points on the unit square. Thus only for
+ $n\in\{-3,2,1,0,1,2,3,4\}$ the angle of direction $n*K$ is exactly
+ $n*45^\circ - 135^\circ$ ($0^\circ$ being the direction straight
+ right).
+
+ As usual |\DirectionfromtheDirection@| expands to code setting the
+ current direction.
+
+\DOCMODE(
+\xydef@\DirectionfromtheDirection@{\noexpand\Direction=\the\Direction
+ \noexpand\d@X=\the\d@X \noexpand\d@Y=\the\d@Y
+ \def\noexpand\sd@X{\sd@X}\def\noexpand\sd@Y{\sd@Y}%
+ \noexpand\K@dXdY=\the\K@dXdY \noexpand\K@dYdX=\the\K@dYdX
+ \chardef\noexpand\DirectionChar=\the\DirectionChar
+ \chardef\noexpand\SemiDirectionChar=\the\SemiDirectionChar
+ \def\noexpand\cosDirection{\cosDirection}%
+ \def\noexpand\sinDirection{\sinDirection}%
+ \noexpand\resetupDirection@}
+\DOCMODE)
+
+ The actual direction computation is done using
+ |\setupDirection@|.
+
+\paragraph*{Procedure:}
+%
+ Is really not so complicated. [??_[Dir1]]~"dX" and "dY" are computed
+ from $c-p$ and we skip if the current setting is based on these (this
+ is stored in the internal |\Directiontest@@| method);
+ [??_[Diri1]]~if the direction is one of the principal ones then
+ proceed with an optimised special case for those; otherwise proceed
+ with the generic code.
+
+\DOCMODE(
+\xydef@\Directiontest@@#1#2{#2}
+
+\xydef@\setupDirection@{%
+ \d@X=\X@c\advance\d@X-\X@p \d@Y=\Y@c\advance\d@Y-\Y@p %?*[Dir1]
+ \Directiontest@@\relax\setupDirection@i}
+
+\xydef@\setupDirection@i{\DN@{\setupDirection@ii}%?*[Diri1]
+ \ifdim\d@X=\d@Y
+ \ifdim\zz@\d@Y \DN@{}%
+ \else\ifdim\d@X<\z@ \DN@{\dlDirection@{-1.4142\d@X}}%
+ \else \DN@{\urDirection@{1.4142\d@X}}\fi\fi
+ \else\ifdim\d@X<\d@Y
+ \ifdim\zz@\d@X \DN@{\uDirection@\d@Y}%
+ \else\ifdim\zz@\d@Y \DN@{\lDirection@{-\d@X}}%
+ \else\ifdim-\d@X=\d@Y \DN@{\ulDirection@{-1.4142\d@X}}\fi\fi\fi
+ \else
+ \ifdim\zz@\d@X \DN@{\dDirection@{-\d@Y}}%
+ \else\ifdim\zz@\d@Y \DN@{\rDirection@\d@X}%
+ \else\ifdim\d@X=-\d@Y \DN@{\drDirection@{1.4142\d@X}}\fi\fi\fi
+ \fi\fi \next@}
+\DOCMODE)
+
+ The procedures for the special <diag>onal cases are summarised in
+ this table:
+$$
+\let\|=\otherbar
+\begin{array}{\|c\|r\|rl\|c\|rl\|}
+\hline
+\mbox{<diag>onal} & "Direction" & \cos("Direction"),& \sin("Direction")
+ & "sign"("dX","dY") & "Char" & "Semi" \\
+\hline
+ |dl| & 0 & {-\sqrt{\frac12}},& {-\sqrt{\frac12}} & -,- & 127 & 127 \\
+ |d| & K & 0,& -1 & +,- & 15 & 31 \\
+ |dr| & 2K & {\sqrt{\frac12}},& {-\sqrt{\frac12}} & +,- & 31 & 63 \\
+ |r| & 3K & 1,& 0 & +,+ & 47 & 95 \\
+ |ur| & 4K & {\sqrt{\frac12}},& {\sqrt{\frac12}} & +,+ & 63 & 127 \\
+ |u| &-3K & 0,& 1 & +,+ & 79 & 31 \\
+ |ul| &-2K & {-\sqrt{\frac12}},& {\sqrt{\frac12}} & -,+ & 95 & 63 \\
+ |l| & -K & -1,& 0 & -,+ & 111 & 95 \\
+\hline
+\end{array}
+$$
+ In each case the argument is used as the unit circle, \ie, non-zero
+ of "dX" and "dY", and $|<|K\frac{"dX"}{"dY"}|,|K\frac{"dY"}{"dX"}|>|
+ := "KK"*|<|"dX"|,|"dY"|>|$\dots
+
+\DOCMODE(
+\xydef@\dlDirection@{\Direction=\z@
+ \def\cosDirection{-.7071}\def\sinDirection{-.7071}\def\sd@X{-}\def\sd@Y{-}%
+ \chardef\DirectionChar=127\relax\chardef\SemiDirectionChar=127\relax
+ \K@dXdY=1\K@ \K@dYdX=1\K@ \fixedDirection@}
+
+\xydef@\dDirection@{\Direction=\K@
+ \def\cosDirection{0}\def\sinDirection{-1}\def\sd@Y{-}%\def\sd@X{+}
+ \edef\sd@X{\ifdim\X@c<\X@p-\else+\fi}%
+ \chardef\DirectionChar=15\relax\chardef\SemiDirectionChar=31\relax
+ \K@dXdY=\z@ \K@dYdX=\KK@\K@ \fixedDirection@}
+
+\xydef@\drDirection@{\dimen@ii=2\K@ \Direction=\dimen@ii
+ \def\cosDirection{+.7071}\def\sinDirection{-.7071}\def\sd@X{+}\def\sd@Y{-}%
+ \chardef\DirectionChar=31\relax\chardef\SemiDirectionChar=63\relax
+ \K@dXdY=-1\K@ \K@dYdX=-1\K@ \fixedDirection@}
+
+\xydef@\rDirection@{\dimen@ii=3\K@ \Direction=\dimen@ii
+ \def\cosDirection{+1}\def\sinDirection{0}\def\sd@X{+}%\def\sd@Y{+}%
+ \edef\sd@Y{\ifdim\Y@c<\Y@p-\else+\fi}%
+ \chardef\DirectionChar=47\relax\chardef\SemiDirectionChar=95\relax
+ \K@dXdY=\KK@\K@ \K@dYdX=\z@ \fixedDirection@}
+
+\xydef@\urDirection@{\dimen@ii=4\K@ \Direction=\dimen@ii
+ \def\cosDirection{+.7071}\def\sinDirection{+.7071}\def\sd@X{+}\def\sd@Y{+}%
+ \chardef\DirectionChar=63\relax\chardef\SemiDirectionChar=127\relax
+ \K@dXdY=1\K@ \K@dYdX=1\K@ \fixedDirection@}
+
+\xydef@\uDirection@{\dimen@ii=-3\K@ \Direction=\dimen@ii
+ \def\cosDirection{0}\def\sinDirection{+1}\def\sd@Y{+}%\def\sd@X{+}
+ \edef\sd@X{\ifdim\X@c<\X@p-\else+\fi}%
+ \chardef\DirectionChar=79\relax\chardef\SemiDirectionChar=31\relax
+ \K@dXdY=\z@ \K@dYdX=\KK@\K@ \fixedDirection@}
+
+\xydef@\ulDirection@{\dimen@ii=-2\K@ \Direction=\dimen@ii
+ \def\cosDirection{-.7071}\def\sinDirection{+.7071}\def\sd@X{-}\def\sd@Y{+}%
+ \chardef\DirectionChar=95\relax\chardef\SemiDirectionChar=63\relax
+ \K@dXdY=-1\K@ \K@dYdX=-1\K@ \fixedDirection@}
+
+\xydef@\lDirection@{\Direction=-\K@
+ \def\cosDirection{-1}\def\sinDirection{0}\def\sd@X{-}%\def\sd@Y{+}%
+ \edef\sd@Y{\ifdim\Y@c<\Y@p-\else+\fi}%
+ \chardef\DirectionChar=111\relax\chardef\SemiDirectionChar=95\relax
+ \K@dXdY=\KK@\K@ \K@dYdX=\z@ \fixedDirection@}
+
+\xydef@\fixedDirection@#1{\dimen@ii=#1\relax
+ \d@X=\cosDirection\dimen@ii \d@Y=\sinDirection\dimen@ii
+ \resetupDirection@}
+\DOCMODE)
+
+ Here is the procedure for the generic code.
+%
+\begin{itemize}
+
+\item[{??_[Dirii1]}]
+ Make sign variables and slopes: $"sdX" := "sign"("dX")$, $"sdY" :=
+ "sign"("dY")$, $K\frac{"dX"}{"dY"} :=
+ "sdX"*"sdY"*\floor{\abs{"KK"*"dX"} / \abs{"dY"/"KK"}}$, and
+ $K\frac{"dY"}{"dX"} := "sdX"*"sdY"*\floor{\abs{"KK"*"dY"} /
+ \abs{"dX"/"KK"}}$, where the somewhat exotic computation method is
+ used to ensure that the `native' floor function provided by \TeX\
+ |\divide| can be used (it only acts predictably for positive
+ numbers), that overflow is avoided even for large $"dX","dY"$, and
+ that it is reasonable to use the convention of |\quotient@| that
+ division by zero is like multiplying with one\dots Also takes care
+ not to multiply too big dimensions with each other.
+
+\item[{??_[Dirii2]}]
+ If ${-K} \le K\frac{"dX"}{"dY"} \le K$ then the direction is mostly
+ up or down: if $"dY"\lt0$ [down, ??_[Dirii2a]]: $"Direction" := -
+ K\frac{"dX"}{"dY"} + 1K$; else [up, ??_[Dirii2b]]: $"Direction" := -
+ K\frac{"dX"}{"dY"} - 3K$.
+
+\item[{??_[Dirii3]}]
+ If ${-K} \lt K\frac{"dY"}{"dX"} \lt K$ then direction is mostly left
+ or right: if $"dX"\lt0$ [left, ??_[Dirii3a]]: $"Direction" :=
+ K\frac{"dY"}{"dX"} - K$; else [right, ??_[Dirii3b]]: $"Direction" :=
+ K\frac{"dY"}{"dX"} + 3K$.
+
+\item[{??_[Dirii4]}]
+ Compute character codes for direction and semidirection fonts.
+ [??_[Dirii4a]]: $"DirectionChar" := (8K+"Direction"+K/32)
+ \hbox{~div~} (K/16) - 1$; while $"DirectionChar" \gt 127:
+ "DirectionChar" -:= 128$. [??_[Dirii4b]]: $"SemiDirectionChar" :=
+ (8K+"Direction"+K/64) \hbox{~div~} (K/32) - 1$; while
+ $"SemiDirectionChar" \gt 127: "SemiDirectionChar" -:= 128$. In both
+ cases the $8K$ are added to ensure that \TeX\ will round down.
+ \HACK: The |16|, |\KK@|, and |64| in these lines are really $K/64$,
+ $K/32$, and $K/16$\dots
+
+\item[{??_[Dirii5]}]
+ Build "cosDirection" and "sinDirection" from appropriate characters
+ in the |\xydashfont|. [??_[Dirii5]]: $"cosDirection" :=
+ "wd"(|\xydashfont| "SemiDirectionChar")$. [??_[Dirii5b]] $C :=
+ "SemiDirectionChar"-64$, if $C\lt0$: $C := C+128$, $"sinDirection" :=
+ "wd"(|\xydashfont| C)$.
+
+\item[{??_[Dirii6]}]
+ Register this "dX","dY" for next time.
+
+\end{itemize}
+
+\DOCMODE(
+\xydef@\setupDirection@ii{%
+ \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi %?*[Dirii1]
+ \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
+ \K@dXdY=\sd@X\d@X \ifdim\K@dXdY<500pt \multiply\K@dXdY\KK@ \fi
+ \dimen@=\sd@Y\d@Y
+% \advance\dimen@.5\KK@ \divide\dimen@\KK@
+ \advance\dimen@\ifdim\dimen@<\z@-\fi.5\KK@ \divide\dimen@\KK@
+ \ifdim\dimen@=\z@\else %\count@=\dimen@ \divide\count@\tw@
+ \advance\K@dXdY by.5\dimen@\relax \divide\K@dXdY\dimen@
+ \fi \K@dXdY=\sd@X\sd@Y\K@dXdY
+ \K@dYdX=\sd@Y\d@Y \ifdim\K@dYdX<500pt \multiply\K@dYdX\KK@ \fi
+ \dimen@=\sd@X\d@X
+% \advance\dimen@.5\KK@ \divide\dimen@\KK@
+ \advance\dimen@\ifdim\dimen@<\z@-\fi.5\KK@ \divide\dimen@\KK@
+ \ifdim\dimen@=\z@\else %\count@=\dimen@ \divide\count@\tw@
+ \advance\K@dYdX by.5\dimen@\relax \divide\K@dYdX\dimen@
+ \fi \K@dYdX=\sd@X\sd@Y\K@dYdX
+ \Direction=\maxdimen
+ \ifnum\K@dXdY<-\K@ \else \ifnum\K@<\K@dXdY \else %?*[Dirii2]
+ \ifdim \d@Y<\z@ %?*[Dirii2a]
+ \Direction=\K@ \advance\Direction-\K@dXdY
+ \else %?*[Dirii2b]
+ \Direction=\K@ \multiply\Direction-\thr@@ \advance\Direction-\K@dXdY
+ \fi\fi\fi
+ \ifnum-\K@<\K@dYdX \ifnum\K@dYdX<\K@ %?*[Dirii3]
+ \ifdim \d@X<\z@ %?*[Dirii3a]
+ \Direction=-\K@ \advance\Direction\K@dYdX
+ \else %?*[Dirii3b]
+ \Direction=\K@ \multiply\Direction\thr@@ \advance\Direction\K@dYdX
+ \fi\fi\fi
+ \ifnum\Direction=\maxdimen
+ \Direction=\K@dYdX \advance\Direction-\K@dXdY
+ \advance\Direction\ifnum\Direction<\z@-\fi\@ne \divide\Direction\tw@
+ \ifnum\K@dXdY<\z@ \advance\Direction\K@ \advance\Direction\K@
+ \else \advance\Direction-\K@ \advance\Direction-\K@ \fi
+ \fi
+ \imposeDirection@i
+ \resetupDirection@ %?*[Dirii6]
+ }
+
+\xydef@\imposeDirection@{\count@@=\Direction
+ \loop@\ifnum\count@@>4096 \advance\count@@-8192 \repeat@
+ \loop@\ifnum\count@@<-4096 \advance\count@@8192 \repeat@
+ \def\sd@X{+}\ifnum\count@@<\K@ \relax
+ \ifnum\count@@>-3072 \def\sd@X{-}\fi\fi
+ \def\sd@Y{+}\ifnum\count@@<3072 \relax
+ \ifnum\count@@>-\K@ \relax\def\sd@Y{-}\fi\fi
+ \imposeDirection@i
+ \d@X=\cosDirection\xydashl@ \d@Y=\sinDirection\xydashl@
+ \resetupDirection@}
+
+\xydef@\imposeDirection@i{%
+ \count@@=\K@ \multiply\count@@ by8 \advance\count@@\Direction %?*[Dirii4]
+ \count@=\count@@ \advance\count@\KK@ \divide\count@64 \advance\count@\m@ne %?*[Dirii4a]
+ \loop@\ifnum127<\count@ \advance\count@-128 \repeat@
+ \chardef\DirectionChar\count@
+ \advance\count@@16 \divide\count@@\KK@ \advance\count@@\m@ne %?*[Dirii4b]
+ \loop@\ifnum127<\count@@ \advance\count@@-128 \repeat@
+ \chardef\SemiDirectionChar\count@@
+ \setbox8=\hbox{\xydashfont\SemiDirectionChar\/}% %?*[Dirii5]
+ \quotient@@\cosDirection{\sd@X\wd8}\xydashl@
+ \setbox8=\hbox{\xydashfont\count@=\SemiDirectionChar\advance\count@-64 %?*[Dirii5b]
+ \ifnum\count@<\z@ \advance\count@128 \fi \char\count@\/}%
+ \quotient@@\sinDirection{\sd@Y\wd8}\xydashl@}
+
+\xydef@\getxyDirection@#1{\xy@@\bgroup\xy@@ix@{#1}%
+ \xy@@{\expandafter\POS\the\toks9\relax\setupDirection@
+ \edef\next@{\egroup \Direction=\the\Direction}\next@ \imposeDirection@ }}
+\DOCMODE)
+
+ Finally some special cases used by the <direction>s and directional
+ library objects. All manipulate the Direction dependent parameters
+ and then call |\resetupDirection@|: |\reverseDirection| reverses it;
+ |\above|- and |\belowDirection@| are for |^| and |_|, and
+ $|\vDirection@(|x|,|y|){|L|}|$ is for $|:(|x|,|y|)|$, \ie, computes
+ a new direction as the vector
+$$
+ |<| X - x*\cos\alpha*L - y*({-}\sin\alpha)*L |,|
+ Y - x*\sin\alpha*L - y*\cos\alpha*L |>|
+$$
+ where $\alpha$ is the previous direction angle.
+
+\DOCMODE(
+\xydef@\reverseDirection@{%
+ \d@X=-\d@X \d@Y=-\d@Y
+ \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
+ \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
+ \dimen@=4\K@ \ifnum\Direction<\z@ \advance\Direction\dimen@
+ \else \advance\Direction-\dimen@ \fi
+ \count@=\DirectionChar \ifnum\count@<64 \advance\count@64 %
+ \else \advance\count@-64 \fi \chardef\DirectionChar=\count@
+ \edef\cosDirection{\if-\cosDirection\else-\cosDirection\fi}%
+ \edef\sinDirection{\if-\sinDirection\else-\sinDirection\fi}%
+ \resetupDirection@}
+
+\xydef@\aboveDirection@#1{%
+ \dimen@=\d@X \d@X=-\d@Y \d@Y=\dimen@
+ \dimen@=\K@dXdY \K@dXdY=-\K@dYdX \K@dYdX=-\dimen@
+ \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
+ \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
+ \dimen@=2\K@ \ifdim 1\Direction<\dimen@\else \dimen@=-6\K@ \fi
+ \advance\Direction\dimen@
+ \count@=\DirectionChar \ifnum\count@<96 \advance\count@32 %
+ \else \advance\count@-96 \fi \chardef\DirectionChar=\count@
+ \count@=\SemiDirectionChar \ifnum\count@<64 \advance\count@64 %
+ \else \advance\count@-64 \fi \chardef\SemiDirectionChar=\count@
+ \let\tmp@=\cosDirection
+ \edef\cosDirection{\if-\sinDirection\else-\sinDirection\fi}%
+ \let\sinDirection=\tmp@
+ \dimen@=#1\relax \d@X=\cosDirection\dimen@ \d@Y=\sinDirection\dimen@
+ \resetupDirection@}
+
+\xydef@\belowDirection@#1{%
+ \dimen@=\d@X \d@X=\d@Y \d@Y=-\dimen@
+ \dimen@=\K@dXdY \K@dXdY=-\K@dYdX \K@dYdX=-\dimen@
+ \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
+ \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
+ \dimen@=-2\K@\ifdim 1\Direction<\dimen@\dimen@=6\K@\fi
+ \advance\Direction\dimen@
+ \count@=\DirectionChar \ifnum\count@<32 \advance\count@96 %
+ \else \advance\count@-32 \fi \chardef\DirectionChar=\count@
+ \count@=\SemiDirectionChar \ifnum\count@<64 \advance\count@64 %
+ \else \advance\count@-64 \fi \chardef\SemiDirectionChar=\count@
+ \let\tmp@=\sinDirection
+ \edef\sinDirection{\if-\cosDirection\else-\cosDirection\fi}%
+ \let\cosDirection=\tmp@
+ \dimen@=#1\relax \d@X=\cosDirection\dimen@ \d@Y=\sinDirection\dimen@
+ \resetupDirection@}
+
+\xydef@\vDirection@(#1,#2)#3{\dimen@ii=#3\relax
+ \dimen@=#1\dimen@ii \dimen@ii=#2\dimen@ii
+ \d@X=\cosDirection\dimen@ \advance\d@X-\sinDirection\dimen@ii
+ \d@Y=\sinDirection\dimen@ \advance\d@Y \cosDirection\dimen@ii
+ \X@p=\X@c \advance\X@p-\d@X \Y@p=\Y@c \advance\Y@p-\d@Y
+ \setupDirection@\ignorespaces}
+\DOCMODE)
+
+ The above all make use of the following; use them also when the
+ direction state is known to be correct: |\resetDirection@| should be
+ called when $p$ and/or $c$ are moved along the line $\vec{pc}$,
+ |\resetupDirerection| when the entire direction state is changed in a
+ consistent manner.
+
+\DOCMODE(
+\xydef@\resetDirection@{%
+ \d@X=\X@c\advance\d@X-\X@p \d@Y=\Y@c\advance\d@Y-\Y@p
+ \let\next@=\resetupDirection@
+ \ifdim\sd@X\d@X<\z@ \let\next@=\setupDirection@i \fi
+ \ifdim\sd@Y\d@Y<\z@ \let\next@=\setupDirection@i \fi
+ \next@}
+
+\xydef@\resetupDirection@{%
+ \edef\Directiontest@@##1##2{\noexpand\DN@{##2}%
+ \noexpand\ifdim\noexpand\d@X=\the\d@X\relax
+ \noexpand\ifdim\noexpand\d@Y=\the\d@Y\relax \noexpand\DN@{##1}%
+ \noexpand\fi\noexpand\fi \noexpand\next@}}
+
+\xydef@\unsetupDirection@{\def\Directiontest@@##1##2{##2}}
+\DOCMODE)
+
+ Finally the initial direction: up!
+
+\DOCMODE(
+\uDirection@\xydashl@
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Edges}
+??=[algo.edge]
+
+ An "Edge" is a token list describing the edge of an object. It must
+ have the form |{|<expandable token> <unexpandable tokens>|}|.
+ To find the edge of an object then first make it the current object
+ and then do
+$$
+ |\the\Edge@c|<code>
+$$
+ where <code> determines what should be done:
+%
+\begin{itemize}
+
+\item[0]
+ $c$ is changed to be equal to the point on the edge intersecting with
+ the line segment from $p$ (for ??c![E] <corner>, also this was the
+ v2.6 behaviour).
+
+ \NOTE: This should not change any of $A$, $B$, or any component of
+ the state except $X_c$ and $Y_c$!
+
+\item[1]
+ Test whether the center of $p$, \ie, $|<|X_p|,|Y_p|>|$, is `inside'
+ the $c$ object (or on the edge). Sets the test |\ifInside@|
+ accordingly.
+
+\item[2]
+ Set |\dimen@| to the distance from the center to the edge towards~$p$
+ (as set with code~0).
+
+ \NOTE: This is only positive in the direction towards $p$
+ (thus negative-sized circles and rectangles make it negative).
+
+\item[3]
+ $c$ is changed to be equal to the point on the edge furthest in the
+ direction towards $p$ (for ??c![P] <corner>).
+
+ \NOTE: This should not change any of $A$, $B$, or any component of
+ the state except $X_c$ and $Y_c$!
+
+\item[4]
+ Replace $c$ with rectangle with corners where the line from $p$
+ intersects with the edge of $c$ (thus this is the inner rectangle
+ with corners as the current direction dictates).
+
+\item[5]
+ Replace $c$ with smallest rectangle that encloses the current object
+ completely.
+
+\end{itemize}
+%
+ (if this reminds the reader of a `dictionary' as used by
+ object-oriented programming languages then they probably share this
+ author's regret that \TeX\ is not object-oriented :-)
+
+\DOCMODE(
+\message{edges,}
+
+\xynew@{if}\ifInside@
+\DOCMODE)
+
+\paragraph*{Points:}
+
+ The simplest shape is none at all -- a point.
+
+\DOCMODE(
+\xydef@\zeroEdge#1{%
+ \ifcase#1\relax \or \Inside@false \or \dimen@=\z@
+ \or \else \Edge@c={\rectangleEdge}\fi}
+\DOCMODE)
+
+\paragraph*{Circles and Ellipses:}
+
+ Next we define round things, with several special cases for the
+ individual variants described below: centered circular, centered
+ elliptical, and general elliptical. The only `intelligent' choice
+ is for the `Under' method where the object is forced to be a centered
+ variant before applying either the circular or elliptical version.
+
+\DOCMODE(
+\xydef@\circleEdge#1{\ifcase#1\expandafter\circleEdge@
+ \or \expandafter\circleUnder@ \or \dimen@=\R@c
+ \or \expandafter\circleProp@ \or \expandafter\circleInner@
+ \else \expandafter\circleOuter@ \fi}
+
+\xydef@\circleEdge@{\DN@{\ellipseEdge@}%
+ \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
+ \ifdim\R@c=\U@c\DN@{\circlecentredEdge@}%
+ \else\DN@{\ellipsecentredEdge@}\fi
+ \fi\fi \next@}
+
+\xydef@\circleProp@{\DN@{\reverseDirection@\ellipseEdge@}%
+ \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
+ \ifdim\R@c=\U@c\DN@{\reverseDirection@\circlecentredEdge@}%
+ \else\DN@{\reverseDirection@\ellipsecentredEdge@}\fi
+ \fi\fi \next@}
+
+\xydef@\circleUnder@{\Inside@false
+ \ifdim\X@p=\X@c \relax \ifdim\Y@p=\Y@c \Inside@true \fi \fi
+ \ifInside@ \else \expandafter \circleCentre@ \fi}
+
+\xydef@\circleCentre@{{%
+ \ifdim\L@c=\R@c \relax\else
+ \dimen@=\R@c\advance\dimen@-\L@c \divide\dimen@\tw@
+ \advance\X@c\dimen@ \advance\R@c-\dimen@ \fi
+ \d@X=\X@c \advance\d@X-\X@p \d@X=\ifdim\d@X<\z@-\fi\d@X
+ \ifdim\U@c=\D@c\relax \else
+ \dimen@=\U@c\advance\dimen@-\D@c \divide\dimen@\tw@
+ \advance\Y@c\dimen@ \advance\U@c-\dimen@ \fi
+ \d@Y=\Y@c \advance\d@Y-\Y@p \d@Y=\ifdim\d@Y<\z@-\fi\d@Y
+ \DN@{}\ifdim\d@X>\R@c \relax \else \ifdim\d@Y>\U@c \relax
+ \else \ifdim\U@c=\R@c \DN@{\circlecentredUnder@}%
+ \else \DN@{\ellipsecentredUnder@}\fi
+ \fi\fi \next@}}
+
+\xydef@\circleInner@{\DN@{\ellipseInner@}%
+ \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
+ \ifdim\R@c=\U@c\DN@{\circlecentredInner@}%
+ \else\DN@{\ellipsecentredInner@}\fi
+ \fi\fi \next@}
+
+\xydef@\circleOuter@{\DN@{\ellipseOuter@}%
+ \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
+ \ifdim\R@c=\U@c\DN@{\circlecentredOuter@}%
+ \else\DN@{\ellipsecentredOuter@}\fi
+ \fi\fi \next@}
+\DOCMODE)
+
+\subparagraph*{True circles, centered:} Code~0 moves $|<|X_c|,|Y_c|>|$ to the
+ point $|<|X_c - R_c*\cos\alpha|,| Y_c - R_c*\sin\alpha|>|$ where
+ $\alpha$ is the current direction angle, code~1 tests whether the
+ $p$ center is located between those two points., code~2 just returns
+ the radius, code~3 is as code~0 and code~4 is the only nontrivial
+ one, replacing with the inner symmetric rectangle with corner at the
+ point of code~0.
+
+\DOCMODE(
+\xydef@\circlecentredEdge@{%
+ \dimen@=-\cosDirection\R@c \advance\X@c\dimen@
+ \dimen@=-\sinDirection\R@c \advance\Y@c\dimen@}
+
+\xydef@\circlecentredUnder@{%
+ \loop\ifdim\R@c>100\p@ \circlescale@ \repeat
+ \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\R@c
+ \edef\tmp@{\expandafter\removePT@\the\d@X}\advance\dimen@-\tmp@\d@X
+ \edef\tmp@{\expandafter\removePT@\the\d@Y}\advance\dimen@-\tmp@\d@Y
+ \ifdim\dimen@>\z@ \aftergroup\Inside@true \fi}
+
+%%\xydef@\circlescale@{\divide\R@c\KK@ \divide\d@X\KK@ \divide\d@Y\KK@ }
+\xydef@\circlescale@{\divide\R@c\KK@ \divide\d@X\KK@ \divide\d@Y\KK@ }
+
+\xydef@\circlecentredInner@{%
+ \L@c=\sd@X\cosDirection\R@c \D@c=\sd@Y\sinDirection\R@c
+ \R@c=\L@c \U@c=\D@c \Edge@c={\rectangleEdge}}
+
+\xydef@\circlecentredOuter@{%
+ \L@c=\R@c \D@c=\R@c \U@c=\D@c \Edge@c={\rectangleEdge}}
+\DOCMODE)
+
+\subparagraph*{Ellipsis, centered:} When $c$ is at the centre of an
+ elliptical object, first rescale the axes to make the object
+ circular. Rescale $dX$ and $dY$ appropriately, reset the direction
+ and move to the edge as previously. Then scale back to
+ the original shape, adjusting $X_c$ and $Y_c$ appropriately.
+
+\DOCMODE(
+\xydef@\ellipsecentredEdge@{\bgroup \X@p=\X@c \Y@p=\Y@c
+ \ifdim\U@c>\R@c
+ \X@c=\cosDirection\U@c \Y@c=\sinDirection\U@c
+ \quotient@\tmp@\U@c\R@c \X@c=\tmp@\X@c \R@c=\U@c
+ \else
+ \X@c=\cosDirection\R@c \Y@c=\sinDirection\R@c
+ \quotient@\tmp@\R@c\U@c \Y@c=\tmp@\Y@c
+ \fi
+ \advance\X@c\X@p \advance\Y@c\Y@p
+ \setupDirection@ \X@c=\X@p \Y@c=\Y@p \circlecentredEdge@
+ \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
+ \ifdim\U@c>\L@c \quotient@\tmp@\L@c\U@c \d@X=\tmp@\d@X
+ \else \quotient@\tmp@\U@c\R@c \d@Y =\tmp@\d@Y \fi
+ \X@c=\X@p \advance\X@c\d@X \Y@c=\Y@p \advance\Y@c\d@Y
+ \edef\next@{\egroup \X@c=\the\X@c \Y@c=\the\Y@c}\next@ }%
+
+\xydef@\ellipsecentredUnder@{%
+ \ifdim\R@c>64\p@ \circlescale@ \divide\U@c\KK@
+ \else \ifdim\U@c>64\p@ \circlescale@ \divide\U@c\KK@ \fi\fi
+ \edef\tmp@{\expandafter\removePT@\the\R@c}\d@Y=\tmp@\d@Y
+ \edef\tmp@{\expandafter\removePT@\the\U@c}\d@X=\tmp@\d@X
+ \R@c=\tmp@\R@c \circlecentredUnder@ }
+\DOCMODE)
+
+ For elliptical objects the Outer-rectangle retains all the
+ extents, so just change the edge-type.
+
+\DOCMODE(
+\xydef@\ellipsecentredOuter@{\Edge@c={\rectangleEdge}}
+\DOCMODE)
+
+ For elliptical objects the Inner-rectangle needs to
+ be calculated for each direction. This is done by
+ first finding the edge, using |\ellipseEdge@| or
+ |\ellipsecentredEdge@| when appropriate.
+
+\DOCMODE(
+\xydef@\ellipsecentredInner@{%
+ \bgroup \X@p=\X@c \Y@p=\Y@c \ellipsecentredEdge@
+% \advance\X@c-\X@p \L@c=\ifdim\X@c<\z@-\fi\L@c
+ \advance\X@c-\X@p \L@c=\ifdim\X@c<\z@-\fi\X@c
+% \advance\Y@c-\Y@p \D@c=\ifdim\Y@c<\z@-\fi\D@c
+ \advance\Y@c-\Y@p \D@c=\ifdim\Y@c<\z@-\fi\Y@c
+ \edef\next@{\egroup \L@c=\the\L@c \D@c=\the\D@c}\next@
+ \R@c=\L@c \U@c=\D@c \Edge@c={\rectangleEdge}}
+\DOCMODE)
+
+\subparagraph*{Non-centered variants:} The code for the more general
+ |\ellipseEdge@| uses a Newton iteration to solve a quadratic
+ equation.
+
+ First locate the actual centre of the ellipse and
+ the lengths of the major axis $a$ and minor axis $b$.
+ Let $(x,y)$ denote the displacement of the required
+ edge point from the centre of the ellipse,
+ so that ${x^2\over a^2}+{y^2\over b^2}=1$.
+ Now let $(dx,dy)$ be the displacement from the centre
+ to the reference point; then $x=dx+s \cos\theta$ and
+ $y=dy+s\sin\theta$ where $s$ is the distance to $(x,y)$
+ in the required direction $\theta$.
+ We must find the value of $s$, presumed to satisfy $s\ge0$.
+
+ If $a\lt b$ we search for a root of
+\begin{eqnarray*}
+f\left({s\over a}\right) &= \;\;
+\left(\tilde{dx}+{s\over a}\cos\theta\right)^2
++\left(\tilde{dy}+{s\over a}{a\over b}\sin\theta\right)^2 & \cr
+f'\left({s\over a}\right) &= \;\;
+2\left(\tilde{dx}+{s\over a}\cos\theta\right)\cos\theta
++ 2\left(\tilde{dy}+{s\over a}{a\over b}\sin\theta\right)
+{a\over b}\sin\theta
+\end{eqnarray*}
+ where $\tilde{dx} = dx/a$ and $\tilde{dy} = dy/b$.
+ By choosing a starting value $s_0=2a+2b$ the Newton-iteration
+ converges rapidly to the correct root, provided $b\gt0$.
+\smallskip
+\noindent
+ If $a\gt b$ then we solve a similar quadratic in ${s\over b}$.
+
+ \TODO:
+ The case of $a=0$ or $b=0$, so that the ellipse degenerates
+ to a line segment, should be trapped earlier.
+ Such an object would be more easily handled as a degenerate
+ case of a rectangle.
+
+ \TODO:
+ In the case when the reference point lies outside the ellipse
+ the Newton iteration is not guaranteed to converge.
+ A simple test --- $s$ growing rather than decreasing in size ---
+ detects possible converge problems and exits the iteration.
+ The following message is issued \dots
+ $$|Xy-pic warning: poor convergence.|$$
+ Often, particularly when the reference point is on or near
+ the edge of the ellipse,
+ an acceptable approximation to the edge has been found anyway.
+
+\DOCMODE(
+\xydef@\ellipseEdge@{\bgroup
+ \A@=\R@c \B@=\U@c
+ \ifdim\R@c=\L@c \d@X=\z@
+ \else \d@X=.5\R@c \advance\d@X-.5\L@c
+ \advance\A@\L@c \divide\A@\tw@ \fi
+ \ifdim\U@c=\D@c \d@Y=\z@
+ \else \d@Y=.5\U@c \advance\d@Y-.5\D@c
+ \advance\B@\D@c \divide\B@\tw@ \fi
+ \bgroup
+ \L@c=\A@ \U@c=\B@
+ \R@p=\U@c \advance\R@p\L@c \multiply\R@p\tw@
+ \ifdim\B@<\A@ \quotient@\tmp@\U@c\L@c \R@c=\tmp@\p@ \D@c=\p@
+ \quotient@\tmp@\R@p\L@c \R@p=\tmp@\p@
+ \else
+ \ifdim\A@<\B@ \quotient@\tmp@\L@c\U@c \D@c=\tmp@\p@ \R@c=\p@
+ \quotient@\tmp@\R@p\U@c \R@p=\tmp@\p@
+ \else
+ \R@c=\p@ \D@c=\p@ \quotient@\tmp@\R@p\U@c \R@p=\tmp@\p@
+ \fi\fi
+ \quotient@\sd@X\d@X\L@c \d@X=\sd@X\p@
+ \quotient@\sd@Y\d@Y\U@c \d@Y=\sd@Y\p@
+ \loop
+ \bgroup \U@p=-\p@ \D@p=\z@
+ \ifdim\R@c<\p@
+ \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\R@p
+ \advance\d@X\cosDirection\dimen@
+ \else \advance\d@X\cosDirection\R@p \fi
+ \edef\sd@X{\expandafter\removePT@\the\d@X}%
+ \advance\U@p\sd@X\d@X
+ \ifdim\R@c<\p@
+ \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\d@X
+ \advance\D@p\cosDirection\dimen@
+ \else \advance\D@p\cosDirection\d@X \fi
+%
+ \ifdim\D@c<\p@
+ \edef\tmp@{\expandafter\removePT@\the\D@c}\dimen@=\tmp@\R@p
+ \advance\d@Y\sinDirection\dimen@
+ \else \advance\d@Y\sinDirection\R@p \fi
+ \edef\sd@Y{\expandafter\removePT@\the\d@Y}%
+ \advance\U@p\sd@Y\d@Y
+ \ifdim\D@c<\p@
+ \edef\tmp@{\expandafter\removePT@\the\D@c}\dimen@=\tmp@\d@Y
+ \advance\D@p\sinDirection\dimen@
+ \else \advance\D@p\sinDirection\d@Y \fi
+ \multiply\D@p\tw@
+ \dimen@=\ifdim\U@p<\z@-\fi\U@p
+ \ifdim\dimen@<.01\p@ \U@p=\z@
+ \else
+ \quotient@\tmp@\U@p\D@p \U@p=\tmp@\p@
+ \ifdim\U@p<\z@\xywarning@{poor convergence}\U@p=\z@
+ \else \advance\R@p-\U@p \U@p=\ifdim\U@p<\z@-\fi\U@p
+ \fi \fi
+ \edef\next@{\egroup \R@p=\the\R@p \U@p=\the\U@p \D@p=\the\D@p}\next@
+ \ifdim\U@p>\z@ \repeat
+ \edef\next@{\egroup \dimen@=\the\R@p}\next@
+ \edef\tmp@{\expandafter\removePT@\the\dimen@}%
+ \ifdim\B@<\A@ \dimen@=\tmp@\B@ \else \dimen@=\tmp@\A@ \fi
+ \dimen@=-\dimen@
+ \advance\X@c\cosDirection\dimen@
+ \advance\Y@c\sinDirection\dimen@
+ \edef\next@{\egroup \X@c=\the\X@c \Y@c=\the\Y@c}\next@ }%
+\DOCMODE)
+
+ The `Under' procedure is identical to the centered version.
+
+\DOCMODE(
+\xydef@\ellipseOuter@{\Edge@c={\rectangleEdge}}
+
+\xydef@\ellipseInner@{%
+ \bgroup \X@p=\X@c \Y@p=\Y@c \ellipseEdge@
+ \d@X=\X@c\advance\d@X-\X@p
+ \ifdim\d@X>\z@ \R@p=\d@X \L@p=\R@p
+ \ifdim\L@c=\R@c\else\advance\L@p\L@c \advance\L@p-\R@c \fi
+ \else \L@p=-\d@X \R@p=\L@p
+ \ifdim\L@c=\R@c \else\advance\R@p\R@c \advance\R@p-\L@c \fi
+ \fi
+ \d@Y=\Y@c\advance\d@Y-\Y@p
+ \ifdim\d@Y>\z@ \U@p=\d@Y \D@p=\U@p
+ \ifdim\D@c=\U@c\else\advance\D@p\D@c \advance\D@p-\U@c \fi
+%\else \D@p=-\d@X \R@p=\D@p
+ \else \D@p=-\d@Y \U@p=\D@p % <<<<<<========
+ \ifdim\D@c=\U@c\else\advance\U@p\U@c \advance\U@p-\D@c \fi
+ \fi
+ \edef\next@{\egroup
+ \L@c=\the\L@p \D@c=\the\D@p \R@c=\the\R@p \U@c=\the\U@p}%
+ \next@ \Edge@c={\rectangleEdge}}
+\DOCMODE)
+
+\paragraph*{Rectangles:}\leavevmode
+
+ Rectangles intersection is slightly more complicated and handled
+ separately for the horizontal and vertical case.
+
+\DOCMODE(
+\xydef@\rectangleEdge#1{\ifcase#1\expandafter\rectangleEdge@
+ \or \expandafter\rectangleUnder@ \or \expandafter\rectangleDist@
+ \or \expandafter\rectangleProp@ %%%\or \expandafter\rectangleInner@ BUG!
+ \else \relax \fi}
+\DOCMODE)
+
+ \BUG: no `Inner' for rectangles!
+
+\DOCMODE(
+% \rectangleEdge@
+% Sets <X,Y> to the intersection of a line from <X-dX,Y-dY> to <X,Y>
+% and the rectangle from <X-L,Y-D> to <X+R,Y+U>:
+%
+% %1a dY<0, dX<0: X := X + min{R, U*|dX/dY|},
+% Y := Y + min{U, R*|dY/dX|};
+% b dY<0, dX=0: Y := Y + U;
+% c dY<0, dX>0: X := X - min{L, U*|dX/dY|},
+% Y := Y + min{U, L*|dY/dX|};
+%
+% %2a dY=0, dX<0: X := X + R;
+% b dY=0, dX=0: ;
+% c dY=0, dX>0: X := X - L;
+%
+% %3a dY>0, dX<0: X := X + min{R, D*|dX/dY|},
+% Y := Y - min{D, R*|dY/dX|};
+% b dY>0, dX=0: Y := Y - D;
+% c dY>0, dX>0: X := X - min{L, D*|dX/dY|},
+% Y := Y - min{D, L*|dY/dX|};
+%
+% %4 \resetupDirection@ to register that even though dX,dY changed all
+% Direction parameters are is still valid!
+%
+% NOTE: d=0 really means |d| < .05pt.
+%
+\xydef@\rectangleEdge@{%
+ \ifdim\d@Y<-.05\p@ \rectangleEdge@i %1
+ \else\ifdim\d@Y<.05\p@ \rectangleEdge@ii %2
+ \else \rectangleEdge@iii\fi\fi
+ \resetupDirection@}
+
+\xydef@\rectangleEdge@i{%
+ \ifdim\d@X<-.05\p@
+ \settomin@\X@c+\R@c\U@c\d@X\d@Y \settomin@\Y@c+\U@c\R@c\d@Y\d@X%1a
+ \else\ifdim\d@X<.05\p@ \advance\Y@c\U@c %1b
+ \else \settomin@\X@c-\L@c\U@c\d@X\d@Y \settomin@\Y@c+\U@c\L@c\d@Y\d@X %1c
+ \fi\fi}
+
+\xydef@\rectangleEdge@ii{%
+ \ifdim\d@X<-.05\p@ \advance\X@c\R@c %2a
+ \else\ifdim\d@X<.05\p@ %2b
+ \else \advance\X@c-\L@c %2c
+ \fi\fi}
+
+\xydef@\rectangleEdge@iii{%
+ \ifdim\d@X<-.05\p@
+ \settomin@\X@c+\R@c\D@c\d@X\d@Y \settomin@\Y@c-\D@c\R@c\d@Y\d@X%3a
+ \else\ifdim\d@X<.05\p@ \advance\Y@c-\D@c %3b
+ \else \settomin@\X@c-\L@c\D@c\d@X\d@Y \settomin@\Y@c-\D@c\L@c\d@Y\d@X %3c
+ \fi\fi}
+
+\xydef@\settomin@#1#2#3#4#5#6{%
+ % Perform d := #2 min{#3, #4*|#5/#6|}; #1 := #1+d ...
+ \edef\nextii@{\A@=\the\A@ \B@=\the\B@}\quotient@\next@{#5}{#6}\nextii@
+ \dimen@=\sd@X\sd@Y\next@#4\relax
+ \ifdim#3<\dimen@ \dimen@=#3\fi \advance#1#2\dimen@}
+\DOCMODE)
+
+ Checking that $p$ is under is simpler: Normally it is not but
+ if $c=p$ or ($-L_c \lt X_p-X_c \lt R_c$ and $-D_c \lt Y_p-Y_c \lt
+ U_c$) then it is.
+
+\DOCMODE(
+\xydef@\rectangleUnder@{\Inside@false
+ \ifdim\X@p=\X@c \ifdim\Y@p=\Y@c \Inside@true \fi\fi
+ \ifInside@ \else
+ \dimen@=\X@p \advance\dimen@-\X@c
+ \ifdim \dimen@>-\L@c \relax \ifdim\dimen@<\R@c
+ \dimen@=\Y@p \advance\dimen@-\Y@c
+ \ifdim \dimen@>-\D@c \relax \ifdim\dimen@<\U@c
+ \Inside@true
+ \fi\fi\fi\fi\fi }
+\DOCMODE)
+
+ Calculating the width is like computing the edge point, just simpler:
+ (??_[rDist])~Set $A$ to the horizontal and $B$ to the vertical
+ distance applicable; if either is zero (or close) use the other
+ unmodified . (??_[rDisti])~If both nonzero use
+ $\min(A/\cos\alpha,B/\sin\alpha)$ where $\alpha$ is the current angle.
+
+\DOCMODE(
+\xydef@\rectangleDist@{\let\next@=\rectangleDist@i %?*[rDist]
+ \ifdim\d@X<-.05\p@ \dimen@=\R@c
+ \else\ifdim\d@X<.05\p@ \dimen@=\z@ \DN@{\dimen@=\dimen@ii}%
+ \else \dimen@=\L@c \fi\fi
+ \ifdim\d@Y<-.05\p@ \dimen@ii=\U@c
+ \else\ifdim\d@Y<.05\p@ \DN@{}%
+ \else \dimen@ii=\D@c \fi\fi
+ \next@}
+
+\xydef@\rectangleDist@i{%?*[rDisti]
+ \begingroup \quotient@\next\p@{\sd@X\cosDirection\p@}%
+ \edef\next{\endgroup \dimen@=\next\dimen@}\next
+ \begingroup \quotient@\next\p@{\sd@Y\sinDirection\p@}%
+ \edef\next{\endgroup \dimen@ii=\the\dimen@ii}\next
+ \ifdim\dimen@ii<\dimen@ \dimen@=\dimen@ii \fi}
+\DOCMODE)
+
+ Setting $c$ to the `proportional edge point' is straight out of
+ v2.6's |\setlabel@@| macro\dots
+
+\DOCMODE(
+% First rotate to opposite direction.
+
+% Then compute Leftf,Upf [\next@,\nextii@]:
+% 0,(D-2K)/2K for 2K < D <= 4K [right]
+% (2K-D)/2K,0 for 0 < D <= 2K [down]
+% 1,-D/2K for -2K < D <= 0 [left]
+% (D+4K)/2K,1 for -4K < D <= -2K [up]
+
+% Finally set <X,Y> to
+% < X - L + Leftf*(R+L) , Y + U - Upf*(D+U) >
+
+\xydef@\rectangleProp@{%
+ \enter@{\A@=\the\A@ \B@=\the\B@ \DirectionfromtheDirection@}%
+ \reverseDirection@
+ \dimen@=1\Direction \count@=\K@ \multiply\count@\tw@
+ \ifnum \Direction>\count@
+ \DN@{0}%
+ \advance\dimen@-2\K@ \quotient@\nextii@{\dimen@}{2\K@}%
+ \else\ifnum \Direction>\z@
+ \dimen@=-\dimen@ \advance\dimen@2\K@ \quotient@\next@{\dimen@}{2\K@}%
+ \DNii@{0}%
+ \else\ifnum \Direction>-\count@
+ \DN@{1}%
+ \quotient@\nextii@{-\dimen@}{2\K@}%
+ \else
+ \advance\dimen@4\K@ \quotient@\next@{\dimen@}{2\K@}%
+ \DNii@{1}%
+ \fi\fi\fi
+ \advance\X@c-\L@c \dimen@=\L@c \advance\dimen@\R@c
+ \ifdim\dimen@=\z@ \advance\X@c 2\L@c \else \advance\X@c\next@\dimen@ \fi
+ \advance\Y@c+\U@c \dimen@=\D@c \advance\dimen@\U@c
+ \ifdim\dimen@=\z@ \advance\Y@c-2\U@c \advance\Y@c\Upness@\U@c
+ \else \advance\Y@c-\nextii@\dimen@ \fi
+ \leave@}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Connections}
+??=[algo.connection]
+
+\DOCMODE(
+\message{connections;}
+\DOCMODE)
+
+ Connections describe how a particular <object> may be used to connect
+ $p$ to $c$. The following parameters and methods are defined by any
+ connection; they should be used in the indicated
+ sequence:??w[connection methods]
+%
+\begin{description}
+
+\item[|\Invisible@@|, |\Hidden@@|, and |\Drop@@|:] as for <object>.
+
+\item[|\Creset@@|:]
+ (Re)set the connection parameters to allow use of the following to
+ move to a point on the connection (this is what the interpretation of
+ <pos> |?| does first). All effects obtained by the following methods
+ are undone: |\Creset@@| reestablishes the state to what it was just
+ after the |\Connect@@| every time.
+
+\item[|\Cshavep@@| or |\Cshavec@@|:]
+ Change $p$ or $c$ to a zero-sized object at the start or finish of
+ the connection (the first |<| and |>| <place> components).
+
+\item[|\Calong@@{|<factor>|}|:]
+ Move $c$ to point the <factor> along the connection and set the
+ direction parameters as a tangent to it in this point (the
+ |(|<factor>|)| <place> component).
+
+\item[|\Cslidep@@{|<dimen>|}| or |\Cslidec@@{|<dimen>|}|:]
+ Move $p$ or $c$ the <dimen>sion further in the current direction.
+ Can be used both before and after the |\Calong@@| method (these
+ handle subsequent |<| and |>| as well as the |/|<slide>|/| <place>
+ component).
+
+\item[|\Cintercept@@|:]
+ Set $c$ to a zerosized object at the point where the connection
+ crosses the straight line from $p$ to $c$ (the |!{|\dots|}| <place>
+ component).
+
+\item[|\Cbreak@@| and |\Clast@@|:]
+ These support typesetting of the connection in several `subsegments'
+ as used by the arrow option. The idea is the following, using the
+ internal "lastbreak" and "nextbreak" positions:
+\begin{enumerate}
+
+\item |\Connect@@| sets $"lastbreak":=p$ and $"nextbreak":=c$
+
+\item The commands |\Cslidec@@|, |\Cslidep@@|, and |\Cintercept@@|, set
+ "nextbreak" logically to the position that is obtained by the
+ manipulation.
+
+\item |\Cbreak@@| retypesets the connection except only the piece
+ from "lastbreak" to the current $c$ object, which "must" be at on top
+ of "nextbreak", is typeset. Afterwords it sets
+ $"lastbreak":="nextbreak"$ and $"nextbreak":=c$ (where $c$ is the
+ original $c$ of the connection).
+
+\item The command |\Clast@@| typesets from "lastbreak" and the remainder of
+ the connection, and resets $"lastbreak":=p$ and $"nextbreak":=c$.
+
+\end{enumerate}
+\end{description}
+%
+ Notice that it is not necessary for "nextbreak" to actually exist, in
+ fact in the kernel it is just an alias for $c$ at the time
+ |\Cbreak@@| is called.
+
+ These are the defaults for basic \Xy-pictures that only has straight
+ connections hence the macros all starting with |\no|\dots are rather
+ simple -- in particular they just merge with zerosized objects at the
+ locations cutoff locations (this was inherited from the broken
+ |arrow| code~\smiley~).
+
+\DOCMODE(
+\xydef@\Creset@@{}
+\xydef@\Cshavep@@{\noCshavep@@}
+\xydef@\Cshavec@@{\noCshavec@@}
+\xydef@\Cslidep@@{\noCslidep@@}
+\xydef@\Cslidec@@{\noCslidec@@}
+\xydef@\Calong@@{\noCalong@@}
+\xydef@\Cintercept@@{\noCintercept@@}
+\xydef@\Cbreak@@{\noCbreak@@}
+\xydef@\Clast@@{\noClast@@}
+
+\xylet@\lastbreak@@=\empty
+
+\xydef@\noCshavep@@{\setupDirection@
+ \enter@{\cfromthec@ \DirectionfromtheDirection@}%
+ \reverseDirection@ \cfromp@ \the\Edge@c\z@
+ \pfromc@ \leave@ \resetDirection@}
+
+\xydef@\noCshavec@@{\setupDirection@ \the\Edge@c\z@ \resetDirection@}
+
+\xydef@\noCslidep@@#1{\dimen@=#1\relax
+ \advance\X@p\cosDirection\dimen@ \advance\Y@p\sinDirection\dimen@
+ \resetDirection@}
+
+\xydef@\noCslidec@@#1{\dimen@=#1\relax
+ \advance\X@c\cosDirection\dimen@ \advance\Y@c\sinDirection\dimen@
+ \resetDirection@}
+
+\xydef@\noCalong@@#1{%
+ \d@X=#1\d@X \d@Y=#1\d@Y \X@c=\X@p \Y@c=\Y@p \advance\X@c\d@X \advance\Y@c\d@Y
+ \resetupDirection@}
+\DOCMODE)
+
+ Next the intercept method that just uses |\intersect@|.
+
+\DOCMODE(
+\xydef@\noCintercept@@{\enter@{\pfromthep@}%
+ \begingroup\Creset@@ \edef\tmp@{\endgroup
+ \X@origin=\the\X@p \Y@origin=\the\Y@p \R@c=\the\d@X \U@c=\the\d@Y}\tmp@
+ \loop@\dimen@=\ifdim\R@c<\z@-\fi\R@c \advance\dimen@\ifdim\U@c<\z@-\fi\U@c
+ \ifdim\dimen@>10\p@ \advance\R@c \ifdim\R@c<\z@-\fi 16sp \divide\R@c\KK@
+ \advance\U@c \ifdim\U@c<\z@-\fi 16sp \divide\U@c\KK@ \repeat@
+ \intersect@ \leave@}
+\DOCMODE)
+
+ And finally the dummy `break' method which of course does nothing
+ except the required shifting.
+
+\DOCMODE(
+\xydef@\noCbreak@@{\edef\lastbreak@@{\cfromthec@}}
+\xydef@\noClast@@{\Creset@@ \edef\lastbreak@@{\cfromthep@}}
+\DOCMODE)
+
+ The kernel only defines one kind of connection which is used by
+ default: `filling' many copies of the connect object on the straight
+ line from $p$ to $c$.
+
+ First the `dummy' connection type |no| used for <object>s where it
+ doesn't really make sense to `connect', and used to provide defaults
+ for easy operations:
+
+\DOCMODE(
+\xydef@\no@@{\setupDirection@ \edef\lastbreak@@{\cfromthep@}%
+ \enter@{\cfromthec@\pfromthep@\DirectionfromtheDirection@}%
+ \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
+ \edef\next@{{\sd@X}{\sd@Y}}\expandafter\straightcheckoverlap@\next@
+ \setupDirection@ \the\Edge@c\z@
+ \swap@\reverseDirection@\the\Edge@c\z@\swap@\reverseDirection@
+ \resetDirection@
+ \edef\Cshavep@@{\DirectionfromtheDirection@
+ \pfromthep@\noexpand\resetDirection@}%
+ \edef\Cshavec@@{\DirectionfromtheDirection@
+ \cfromthec@\noexpand\resetDirection@}%
+ \leave@
+ \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
+ \def\Calong@@{\noCalong@@}\def\Cintercept@@{\noCintercept@@}%
+ \def\Cbreak@@{\noCbreak@@}\def\Clast@@{\noClast@@}\noinsert@}
+
+\xydef@\noinsert@{\ifHidden@\else
+ \ifdim\Y@c>\Y@max \Y@max=\Y@c \fi \ifdim\Y@p>\Y@max \Y@max=\Y@p \fi
+ \ifdim\Y@c<\Y@min \Y@min=\Y@c \fi \ifdim\Y@p<\Y@min \Y@min=\Y@p \fi
+ \ifdim\X@c>\X@max \X@max=\X@c \fi \ifdim\X@p>\X@max \X@max=\X@p \fi
+ \ifdim\X@c<\X@min \X@min=\X@c \fi \ifdim\X@p<\X@min \X@min=\X@p \fi
+ \fi}
+\DOCMODE)
+
+ Next `straight' connections that use the following special parameters
+ to customises how to repeat a `filler' object as many times as needed
+ to draw the connection:
+%
+\begin{description}
+
+\item[|\lastobjectbox@|:] box to fill with; assumed to be `trimmed' to have
+ only the size needed for the filler; size is $w*(h+d)$).
+
+\end{description}
+%
+ The method is called as |\straight@{|<spread>|}| where <spread> is a
+ macro to expand "after" the number of fillers $N$ (in |\count@@|) is
+ known and with $A=w$ and $B=d+h$ but "before" any filling is done.
+ May change $N$ as well as $"dX","dY",X,Y,w,d,h$ in order to affect
+ the filling.
+
+\subparagraph*{Procedure:}
+%
+ [??_[Strgt1]] setup direction parameters, clear the break state, and
+ define the |\Creset@@| macro to reestablish this initial state;
+ [??_[Strgt2]] build macro to discover if the edges of the objects
+ overlap (it edges were removed); [??_[Strgt3]] move both $p,c$ to the
+ edges of the objects\dots and define the |\Cshave*@@| macros
+ accordingly; [??_[Strgt4]] choose either to ignore the connection if
+ requested or there is overlap between the objects of choose either
+ vbox or hbox version (see below)\dots; and [??_[Strgt5]] build
+ |\Calong@@|, |\Cbreak@@|, and |\Clast@@| macros, and reset $pc$.
+
+ \NOTE: Assumes that the direction is not tampered with between Creset
+ is defined and used\dots
+
+\DOCMODE(
+\xydef@\Spread@@{}
+\xydef@\checkoverlap@@{}
+
+\xydef@\straight@#1{\setupDirection@ \def\Spread@@{#1}% %?*[Strgt1]
+ \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
+ \edef\lastbreak@@{\cfromthep@}%
+ \edef\next@{{\sd@X}{\sd@Y}}\expandafter\straightcheckoverlap@\next@ %?*[Strgt2]
+ \setupDirection@ \the\Edge@c\z@
+ \swap@\reverseDirection@\the\Edge@c\z@\swap@\reverseDirection@
+ \resetDirection@
+ \edef\Cshavep@@{\DirectionfromtheDirection@
+ \pfromthep@\noexpand\resetDirection@}%
+ \edef\Cshavec@@{\DirectionfromtheDirection@
+ \cfromthec@\noexpand\resetDirection@}%
+ \noinsert@ %?*[Strgt3b]
+ \straight@typeset %?*[Strgt4]
+ \def\Cbreak@@{\straightCbreak@}\def\Clast@@{\straightClast@}%
+% \DN@{\solidSpread@}\ifx\next@\Spread@@
+% \checkXy@rules@\solidhrule@pre\solidvrule@pre\relax
+% \fi
+ \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%?*[Strgt5]
+ \def\Calong@@{\noCalong@@}\def\Cintercept@@{\noCintercept@@}%
+ \Creset@@}
+
+\xydef@\straightcheckoverlap@#1#2{\def\checkoverlap@@{%
+ \ifdim#1\X@p>#1\X@c \let\next@=\relax \fi
+ \ifdim#2\Y@p>#2\Y@c \let\next@=\relax \fi}}
+
+\xydef@\straight@typeset{%
+ \ifInvisible@ \let\next@=\relax
+ \else\ifdim 1\Direction<-2\K@ \DN@{\straightv@}%
+ \else\ifdim 1\Direction<\z@ \DN@{\straighth@}%
+ \else\ifdim 1\Direction<2\K@ \DN@{\straightv@}%
+ \else \DN@{\straighth@}%
+ \fi\fi\fi\fi \checkoverlap@@ \next@}
+\DOCMODE)
+
+ The methods |\straightCbreak@| and |\straightClast@| implement the
+ break method parametrised on the `typeset' primitive which is usually
+ |\straight@typeset| which is a simplified version of |\straight@|
+ that does not initialise. This relies on the connection being
+ straight: the |Cbreak@@| method executes $p,c :=
+ p|.|"lastbreak",c|.|"nextbreak"$ and |Clast@@| executes $p,c :=
+ p|.|"lastbreak",c$, where in both cases the |[Inner]| modifier is
+ applied just before the merging to make sure the edge is respected by
+ the merged object.
+
+\DOCMODE(
+\xylet@\nextbreak@@=\empty
+
+\xydef@\straightCbreak@{\connectRestore@
+ \edef\nextbreak@@{\cfromthec@}%
+ \Creset@@ \swap@ \the\Edge@c4\enter@{\cmergethec@}\lastbreak@@ \leave@
+ \swap@ \the\Edge@c4\enter@{\cmergethec@}\nextbreak@@ \leave@
+ \setupDirection@
+ \the\Edge@c\z@
+ \swap@ \reverseDirection@ \the\Edge@c\z@ \swap@ \reverseDirection@
+ \resetDirection@ \noinsert@ \straight@typeset
+ \Creset@@ \let\lastbreak@@=\nextbreak@@}
+
+\xydef@\straightClast@{\connectRestore@
+ \Creset@@ \swap@ \the\Edge@c4\enter@{\cmergethec@}\lastbreak@@ \leave@
+ \swap@
+ \setupDirection@
+ \the\Edge@c\z@
+ \swap@\reverseDirection@ \the\Edge@c\z@ \swap@\reverseDirection@
+ \resetDirection@ \noinsert@ \straight@typeset
+ \Creset@@ \edef\lastbreak@@{\cfromthep@}}
+\DOCMODE)
+
+ Now for the typesetting -- to summarise: these are parametrised on
+ direction parameters and use $X,Y$: endpoint of connection
+ (`Direction end'). $"dX","dY"$: connection distance (`Direction
+ vector'). |\Leftness@| of <object>. |\lastobjectbox@| to fill with;
+ assumed to be `trimmed'. |\Spread@@| to expand to modify the default
+ spreading used. |\Drop@@| to expand to actually typeset the finished
+ connection when it is in box0! \NOTE: Must make box0 void to avoid
+ `box leaks'.
+
+ Two variants exist: one for mostly horisontal and one for mostly
+ vertical filling. We detail the `mostly horisontal' one:
+
+ [??_[StrH0]] start box;
+%
+ [??_[StrH1]] compute initial adjustment ($X$ right and $Y$ up) and
+ $A := w$, $B := h+d$, $N = \floor(\abs{"dX"} / A)$,
+ and run user supplied Spread;
+%
+ [??_[StrH2]] adjust first filler position horizontally:
+ if $dX\gt0$ then $X := X-w$;
+%
+ [??_[StrH4]] adjust first filler vertically: $Y := Y -
+ "sdX"*L*("dY"/"dX")*w$ where $L = \textup{if} dX>0 \textup{then}
+ (1-Leftness) \textup{else} Leftness$;
+%
+ [??_[StrH3]] recompute the move dimensions ($A$ right and $B$ up):
+ $A := -"sdX"(\abs{dX} - w) / (N-1)$,
+ $B := "sdY"\abs{"sdX"(w)*"dY"/"dX" - dY} / (N-1)$,
+ and set the filler box to have $w := A$;
+%
+ [??_[StrH5]] output first filler adjusted $X,Y$ and the following $N-1$
+ each $A$ further right and raised $B$ more than the previous;
+%
+ and finally end object with usual bravour!
+
+\DOCMODE(
+\xydef@\straighth@{\setbox\z@=\hbox{%
+ \setbox8=\copy\lastobjectbox@
+ \A@=\wd8\relax \B@=\dp8\relax \advance\B@\ht8\relax %?*[StrH1]
+ \ifdim \A@=\z@ \count@@=\m@ne
+ \else \dimen@=\sd@X\d@X \divide\dimen@\A@ \count@@=\dimen@ \fi
+ \Spread@@
+ \ifdim\d@X>\z@ \advance\X@c-\wd8\relax\fi %?*[StrH2]
+ \dimen@=-\sd@X\wd8\relax %?*[StrH4]
+ \multiply\dimen@\K@dYdX \divide\dimen@\K@
+ \ifdim\d@X>\z@ \advance\Y@c\dimen@ \advance\Y@c-\Leftness@\dimen@
+ \else \advance\Y@c\Leftness@\dimen@ \fi
+ \dimen@=\wd8\relax \A@=\sd@X\d@X \advance\A@-\dimen@ %?*[StrH3]
+ \B@=\sd@X\dimen@ \multiply\B@\K@dYdX \divide\B@\K@
+ \advance\B@-\d@Y \B@=\sd@Y\B@
+ \count@=\count@@ \advance\count@\m@ne
+ \ifnum\z@<\count@ \divide\A@\count@ \divide\B@\count@ \fi
+ \A@=-\sd@X\A@ \B@=\sd@Y\B@ \wd8=\A@
+ \kern\X@c \count@=\z@ %?*[StrH5]
+ \loop@\ifnum\count@<\count@@ \advance\count@\@ne
+ \raise\Y@c\copy8\relax \advance\Y@c\B@ \repeat@}%
+ \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
+\DOCMODE)
+
+ The mosly vertical is analogous. \BUG: |\dimen@| holds the unadjusted
+ $h+d$ throughout -- somehow it works anyway!
+
+\DOCMODE(
+\xydef@\straightv@{\setbox\z@=\vtop{%
+ \setbox8=\copy\lastobjectbox@
+ \A@=\wd8\relax \B@=\dp8\relax \advance\B@\ht8\relax
+ \ifdim \B@=\z@ \count@@=\m@ne
+ \else \dimen@=\sd@Y\d@Y \divide\dimen@\B@ \count@@=\dimen@ \fi
+ \Spread@@
+ \dimen@=\dp8\relax \advance\dimen@\ht8\relax
+ \B@=\sd@Y\d@Y \advance\B@-\dimen@
+ \A@=\sd@Y\dimen@ \multiply\A@\K@dXdY \divide\A@\K@ \advance\A@-\d@X
+ \A@=\sd@X\A@ \count@=\count@@ \advance\count@\m@ne
+ \ifnum\z@<\count@ \divide\B@\count@ \divide\A@\count@ \fi
+ \B@=\sd@Y\B@ \A@=\sd@X\A@ \ht8=\B@ \dp8=\z@
+ \ifdim\d@Y<\z@
+ \advance\Y@c\dimen@ \advance\Y@c\Upness@\B@
+ \else
+ \advance\dimen@\Upness@\B@ \advance\Y@c-\dimen@ \advance\Y@c\B@
+ \fi
+ \advance\Y@c\B@
+ \ifdim\d@X<\z@ \else \advance\X@c-\wd8\relax \fi
+ \null \kern-\Y@c \count@=\z@
+ \loop@\ifnum\count@<\count@@ \advance\count@\@ne
+ \nointerlineskip \moveright\X@c\copy8\relax \advance\X@c\A@
+ \repeat@}%
+ \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
+\DOCMODE)
+
+\DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\section*{End \& log}
+
+ \Xy-pic ends with a message saying so.
+
+\DOCMODE(
+\message{ Xy-pic loaded}\xyuncatcodes \endinput
+\DOCMODE)
+
+ \Xy-pic is maintained using the RCS ``Revision Control System'' by
+ Walther F.~Tichy. The following is the revision history since the
+ first release to Usenet.
+
+\DOCMODE(
+% $Log: xy.doc,v $
+% Revision 3.7 1999/02/16 15:12:50 krisrose
+% Interim release (Y&Y fonts now free).
+%
+% Revision 3.6 1998/03/06 01:28:05 krisrose
+% Releasing (with Y&Y fonts).
+%
+% Revision 3.5 1997/05/28 13:05:01 krisrose
+% Fixed missing breaks bug.
+%
+% Revision 3.4 1997/05/18 01:14:25 krisrose
+% Essential bugfixes.
+%
+% Revision 3.3 1996/12/19 03:31:56 krisrose
+% Maintenance release
+%
+% Revision 3.2 1995/09/19 18:22:27 kris
+% Bug fix release.
+%
+% Revision 3.1 1995/09/05 20:31:32 kris
+% Releasing!
+%
+% Revision 3.0 1995/07/07 20:14:21 kris
+% Major release w/new User's Guide!
+%
+% Revision 2.14 1995/07/05 22:20:09 kris
+% Buglets...
+%
+% Revision 2.13 1995/07/04 15:11:17 kris
+% Ready to release v3?
+%
+% Revision 2.12 1994/10/25 11:55:12 kris
+% Interim release just before v3 [works with AMS-LaTeX 1.2]...
+%
+% Revision 2.11 1994/07/05 10:37:32 kris
+% Third 3beta release [bug fixes].
+% Experimental graph feature included (for ECCT-94 presentation).
+%
+% Revision 2.10 1994/06/15 12:55:07 kris
+% Second 3beta release: bug fixes.
+%
+% Revision 2.9 1994/06/09 14:59:19 kris
+% Release 3beta.
+%
+% Revision 2.8 1994/04/11 09:31:09 kris
+% Second (bug fix) 3alpha release [corrected].
+%
+% Revision 2.7 1994/03/08 02:06:01 kris
+% Release 3alpha.
+%
+% Revision 2.6.9.1 1994/03/07 04:22:46 kris
+% Last internal 3alpha and pre-2.7 release.
+%
+% MAJOR REWRITE and REORGANISATION:
+% File xypic.doc split into separate files: xy.doc for `kernel' and other
+% files with the `extensions' and `features'.
+% Documented in special DOCMODE LaTeX-based format supported by xydoc.sty.
+%
+% Revision 2.6.1.1 1992/07/01 07:08:24 kris
+% Send to EuroTeX '92...
+%
+% Revision 2.6 1992/06/24 01:23:34 kris
+% Added hooks using font xyqc10.
+% Added new POSitions: * and !.
+% Added triple lines \Ssolid and \Ddashed.
+%
+% Revision 2.5 1992/02/24 03:30:54 kris
+% Fixed bugs in \Direction calculation logic...
+% Added (FACTOR) to \rotate to allow arbitrary rotation.
+% ` intermediate points now accept an optional /RADIUS argument.
+% Added \Tip with wide tip.
+% [See ChangeLog for further details].
+%
+% Revision 2.4 1992/01/22 02:15:10 kris
+% Fixed bugs [with thanks]:
+% No spurious arrow heads with LaTeX: \pit now undefined [Werner Struckmann]
+% \Solid works: sets \Density [Dave Bowen]
+% Short diagonal lines work...major rewrite of \connectv@ [Eric Domenjoud]
+%
+% Revision 2.3 1992/01/13 23:28:12 kris
+% Swapped definitions of \ddtoX and \uutoX [found by Nico Verwer].
+% Diagonal lines were wrong [Eric Domenjoud].
+%
+% Revision 2.2 1992/01/09 04:05:40 kris
+% Still problems with rules in frames and horizontal/vertical \solids. Grrr.
+%
+% Revision 2.1 1992/01/02 14:54:07 kris
+% Release version.
+%
+% Revision 1.40 1991/12/17 04:53:23 kris
+% Version distributed as `final draft' on Usenet.
+\DOCMODE)
+
+\DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Tell Emacs that this is a LaTeX document and how it is formatted:
+% Local Variables:
+% mode:latex
+% fill-prefix:"\t"
+% fill-column:77
+% paragraph-separate:"^[ \t\f]*$\\|^[^\t]\\|\\\\\\\\\\|\\$\\$\\|[^\n\\\\][%&]"
+% paragraph-start:"^[ \t\f]*$\\|^[^\t]\\|\\\\\\\\\\|\\$\\$\\|[^\n\\\\][%&]"
+% TeX-parse-self:nil
+% LaTeX-indent-level:1
+% TeX-brace-indent-level:1
+% End: