diff options
Diffstat (limited to 'Master/texmf-dist/source/generic/xypic/xy.doc')
-rw-r--r-- | Master/texmf-dist/source/generic/xypic/xy.doc | 8324 |
1 files changed, 0 insertions, 8324 deletions
diff --git a/Master/texmf-dist/source/generic/xypic/xy.doc b/Master/texmf-dist/source/generic/xypic/xy.doc deleted file mode 100644 index 54ac9fca7d0..00000000000 --- a/Master/texmf-dist/source/generic/xypic/xy.doc +++ /dev/null @@ -1,8324 +0,0 @@ -%% $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: |